Merge lp:~jtv/maas/maascli-fake-config into lp:~maas-committers/maas/trunk

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 1218
Proposed branch: lp:~jtv/maas/maascli-fake-config
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 165 lines (+81/-44)
2 files modified
src/maascli/testing/config.py (+75/-0)
src/maascli/tests/test_api.py (+6/-44)
To merge this branch: bzr merge lp:~jtv/maas/maascli-fake-config
Reviewer Review Type Date Requested Status
Raphaël Badin (community) Approve
Review via email: mp+128466@code.launchpad.net

Commit message

Extract creation of a fake maascli ProfileConfig for testing.

Description of the change

This is one of those places where the code needed breaking up in order for my real work to progress. It has been remarked upon that the creation of the fake is really horrible code (or perhaps it's fairer to say that the data structure is horrible) and so I would like to avoid having to duplicate it in later tests for different modules.

Jeroen

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) :
review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

Attempt to merge into lp:maas failed due to conflicts:

text conflict in src/maascli/tests/test_api.py

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Ouch. Gavin was refactoring the same code while I was moving it. I more or less ported his changes to the new module.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'src/maascli/testing'
2=== added file 'src/maascli/testing/__init__.py'
3=== added file 'src/maascli/testing/config.py'
4--- src/maascli/testing/config.py 1970-01-01 00:00:00 +0000
5+++ src/maascli/testing/config.py 2012-10-08 13:38:55 +0000
6@@ -0,0 +1,75 @@
7+# Copyright 2012 Canonical Ltd. This software is licensed under the
8+# GNU Affero General Public License version 3 (see the file LICENSE).
9+
10+"""Fake `ProfileConfig` for testing."""
11+
12+from __future__ import (
13+ absolute_import,
14+ print_function,
15+ unicode_literals,
16+ )
17+
18+__metaclass__ = type
19+__all__ = [
20+ 'FakeConfig',
21+ 'make_configs',
22+ 'make_profile',
23+ ]
24+
25+from maastesting.factory import factory
26+
27+
28+class FakeConfig(dict):
29+ """Fake `ProfileConfig`. A dict that's also a context manager."""
30+ def __enter__(self, *args, **kwargs):
31+ return self
32+
33+ def __exit__(self, *args, **kwargs):
34+ pass
35+
36+
37+def make_handler():
38+ """Create a fake handler entry."""
39+ return {
40+ 'name': factory.make_name('handler'),
41+ 'doc': "Short\n\nLong",
42+ 'params': [],
43+ 'actions': [{
44+ 'name': factory.make_name('action'),
45+ 'doc': "Doc\n\nstring",
46+ }],
47+ }
48+
49+
50+def make_resource(anon=True, auth=True):
51+ """Create a fake resource entry."""
52+ auth = make_handler() if auth else None
53+ anon = make_handler() if anon else None
54+ name = factory.make_name('resource')
55+ return {'auth': auth, 'anon': anon, 'name': name}
56+
57+
58+def make_profile(name=None):
59+ """Create a fake profile dict."""
60+ if name is None:
61+ name = factory.make_name('profile')
62+ return {
63+ 'name': name,
64+ 'url': 'http://%s.example.com/' % name,
65+ 'credentials': factory.make_name('credentials'),
66+ 'description': {
67+ 'resources': [
68+ make_resource(),
69+ make_resource(),
70+ ],
71+ },
72+ }
73+
74+
75+def make_configs(number_of_configs=1):
76+ """Create a dict mapping config names to `FakeConfig`."""
77+ result = {}
78+ while len(result) < number_of_configs:
79+ profile = factory.make_name('profile')
80+ result[profile] = FakeConfig(make_profile(profile))
81+ return FakeConfig(result)
82
83=== modified file 'src/maascli/tests/test_api.py'
84--- src/maascli/tests/test_api.py 2012-10-08 11:18:45 +0000
85+++ src/maascli/tests/test_api.py 2012-10-08 13:38:55 +0000
86@@ -24,6 +24,7 @@
87 )
88 from maascli.command import CommandError
89 from maascli.config import ProfileConfig
90+from maascli.testing.config import make_configs
91 from maascli.utils import (
92 handler_command_name,
93 safe_name,
94@@ -42,55 +43,16 @@
95 )
96
97
98-class FakeConfig(dict):
99- """Fake `ProfileConfig`. A dict that's also a context manager."""
100- def __enter__(self, *args, **kwargs):
101- return self
102-
103- def __exit__(self, *args, **kwargs):
104- pass
105-
106-
107 class TestRegisterAPICommands(TestCase):
108 """Tests for `register_api_commands`."""
109
110- def make_handler(self):
111- return {
112- 'name': factory.make_name('handler'),
113- 'doc': "Short\n\nLong",
114- 'params': [],
115- 'actions': [
116- {'name': factory.make_name('action'),
117- 'doc': "Doc\n\nstring"},
118- ],
119- }
120-
121- def make_resource(self, anon=True, auth=True):
122- auth = self.make_handler() if auth else None
123- anon = self.make_handler() if anon else None
124- name = factory.make_name("resource")
125- return {"auth": auth, "anon": anon, "name": name}
126-
127 def make_profile(self):
128 """Fake a profile."""
129- profile_name = factory.make_name('profile')
130- profile = {
131- 'name': profile_name,
132- 'url': 'http://%s.example.com/' % profile_name,
133- 'credentials': factory.make_name("credentials"),
134- 'description': {
135- 'resources': [
136- self.make_resource(),
137- self.make_resource(),
138- ],
139- },
140- }
141- fake_open = self.patch(ProfileConfig, 'open')
142- fake_open.return_value = FakeConfig({profile_name: profile})
143- return profile
144+ self.patch(ProfileConfig, 'open').return_value = make_configs()
145+ return ProfileConfig.open.return_value
146
147 def test_registers_subparsers(self):
148- profile_name = self.make_profile()["name"]
149+ profile_name = self.make_profile().keys()[0]
150 parser = ArgumentParser()
151 self.assertIsNone(parser._subparsers)
152 api.register_api_commands(parser)
153@@ -101,10 +63,10 @@
154 profile = self.make_profile()
155 parser = ArgumentParser()
156 api.register_api_commands(parser)
157- for resource in profile["description"]["resources"]:
158+ for resource in profile.values()[0]["description"]["resources"]:
159 for action in resource["auth"]["actions"]:
160 # Profile names are matched as-is.
161- profile_name = profile["name"]
162+ profile_name = profile.keys()[0]
163 # Handler names are processed with handler_command_name before
164 # being added to the argument parser tree.
165 handler_name = handler_command_name(resource["name"])