Fix typos in RAPI docstrings, add unittest
[ganeti-local] / test / cfgupgrade_unittest.py
1 #!/usr/bin/python
2 #
3
4 # Copyright (C) 2010 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21
22 """Script for testing tools/cfgupgrade"""
23
24 import os
25 import sys
26 import unittest
27 import shutil
28 import tempfile
29 import operator
30
31 from ganeti import constants
32 from ganeti import utils
33 from ganeti import errors
34 from ganeti import serializer
35 from ganeti import netutils
36
37 import testutils
38
39
40 def _RunUpgrade(path, dry_run, no_verify, ignore_hostname=True):
41   cmd = [sys.executable, "%s/tools/cfgupgrade" % testutils.GetSourceDir(),
42          "--debug", "--force", "--path=%s" % path]
43
44   if ignore_hostname:
45     cmd.append("--ignore-hostname")
46   if dry_run:
47     cmd.append("--dry-run")
48   if no_verify:
49     cmd.append("--no-verify")
50
51   result = utils.RunCmd(cmd, cwd=os.getcwd())
52   if result.failed:
53     raise Exception("cfgupgrade failed: %s, output %r" %
54                     (result.fail_reason, result.output))
55
56
57 class TestCfgupgrade(unittest.TestCase):
58   def setUp(self):
59     self.tmpdir = tempfile.mkdtemp()
60
61     self.config_path = utils.PathJoin(self.tmpdir, "config.data")
62     self.noded_cert_path = utils.PathJoin(self.tmpdir, "server.pem")
63     self.rapi_cert_path = utils.PathJoin(self.tmpdir, "rapi.pem")
64     self.rapi_users_path = utils.PathJoin(self.tmpdir, "rapi", "users")
65     self.rapi_users_path_pre24 = utils.PathJoin(self.tmpdir, "rapi_users")
66     self.known_hosts_path = utils.PathJoin(self.tmpdir, "known_hosts")
67     self.confd_hmac_path = utils.PathJoin(self.tmpdir, "hmac.key")
68     self.cds_path = utils.PathJoin(self.tmpdir, "cluster-domain-secret")
69     self.ss_master_node_path = utils.PathJoin(self.tmpdir, "ssconf_master_node")
70
71   def tearDown(self):
72     shutil.rmtree(self.tmpdir)
73
74   def _LoadConfig(self):
75     return serializer.LoadJson(utils.ReadFile(self.config_path))
76
77   def _CreateValidConfigDir(self):
78     utils.WriteFile(self.noded_cert_path, data="")
79     utils.WriteFile(self.known_hosts_path, data="")
80     utils.WriteFile(self.ss_master_node_path,
81                     data="node.has.another.name.example.net")
82
83   def testNoConfigDir(self):
84     self.assertFalse(utils.ListVisibleFiles(self.tmpdir))
85     self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True)
86     self.assertRaises(Exception, _RunUpgrade, self.tmpdir, True, True)
87
88   def testWrongHostname(self):
89     self._CreateValidConfigDir()
90
91     utils.WriteFile(self.config_path, data=serializer.DumpJson({
92       "version": constants.CONFIG_VERSION,
93       "cluster": {},
94       }))
95
96     hostname = netutils.GetHostname().name
97     assert hostname != utils.ReadOneLineFile(self.ss_master_node_path)
98
99     self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True,
100                       ignore_hostname=False)
101
102   def testCorrectHostname(self):
103     self._CreateValidConfigDir()
104
105     utils.WriteFile(self.config_path, data=serializer.DumpJson({
106       "version": constants.CONFIG_VERSION,
107       "cluster": {},
108       }))
109
110     utils.WriteFile(self.ss_master_node_path,
111                     data="%s\n" % netutils.GetHostname().name)
112
113     _RunUpgrade(self.tmpdir, False, True, ignore_hostname=False)
114
115   def testInconsistentConfig(self):
116     self._CreateValidConfigDir()
117     # There should be no "config_version"
118     cfg = {
119       "version": 0,
120       "cluster": {
121         "config_version": 0,
122         },
123       }
124     utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg))
125     self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True)
126
127   def testInvalidConfig(self):
128     self._CreateValidConfigDir()
129     # Missing version from config
130     utils.WriteFile(self.config_path, data=serializer.DumpJson({}))
131     self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True)
132
133   def _TestSimpleUpgrade(self, from_version, dry_run):
134     cfg = {
135       "version": from_version,
136       "cluster": {},
137       }
138     self._CreateValidConfigDir()
139     utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg))
140
141     self.assertFalse(os.path.isfile(self.rapi_cert_path))
142     self.assertFalse(os.path.isfile(self.confd_hmac_path))
143     self.assertFalse(os.path.isfile(self.cds_path))
144
145     _RunUpgrade(self.tmpdir, dry_run, True)
146
147     if dry_run:
148       expversion = from_version
149       checkfn = operator.not_
150     else:
151       expversion = constants.CONFIG_VERSION
152       checkfn = operator.truth
153
154     self.assert_(checkfn(os.path.isfile(self.rapi_cert_path)))
155     self.assert_(checkfn(os.path.isfile(self.confd_hmac_path)))
156     self.assert_(checkfn(os.path.isfile(self.cds_path)))
157
158     newcfg = self._LoadConfig()
159     self.assertEqual(newcfg["version"], expversion)
160
161   def testRapiUsers(self):
162     self.assertFalse(os.path.exists(self.rapi_users_path))
163     self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
164
165     utils.WriteFile(self.rapi_users_path_pre24, data="some user\n")
166     self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), False)
167
168     self.assert_(os.path.islink(self.rapi_users_path_pre24))
169     self.assert_(os.path.isfile(self.rapi_users_path))
170     for path in [self.rapi_users_path, self.rapi_users_path_pre24]:
171       self.assertEqual(utils.ReadFile(path), "some user\n")
172
173   def testRapiUsers24AndAbove(self):
174     self.assertFalse(os.path.exists(self.rapi_users_path))
175     self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
176
177     os.mkdir(os.path.dirname(self.rapi_users_path))
178     utils.WriteFile(self.rapi_users_path, data="other user\n")
179     self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), False)
180
181     self.assert_(os.path.islink(self.rapi_users_path_pre24))
182     self.assert_(os.path.isfile(self.rapi_users_path))
183     for path in [self.rapi_users_path, self.rapi_users_path_pre24]:
184       self.assertEqual(utils.ReadFile(path), "other user\n")
185
186   def testRapiUsersExistingSymlink(self):
187     self.assertFalse(os.path.exists(self.rapi_users_path))
188     self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
189
190     os.symlink(self.rapi_users_path, self.rapi_users_path_pre24)
191     utils.WriteFile(self.rapi_users_path_pre24, data="hello world\n")
192
193     self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), False)
194
195     self.assert_(os.path.isfile(self.rapi_users_path))
196     self.assert_(os.path.islink(self.rapi_users_path_pre24))
197     for path in [self.rapi_users_path, self.rapi_users_path_pre24]:
198       self.assertEqual(utils.ReadFile(path), "hello world\n")
199
200   def testUpgradeFrom_2_0(self):
201     self._TestSimpleUpgrade(constants.BuildVersion(2, 0, 0), False)
202
203   def testUpgradeFrom_2_1(self):
204     self._TestSimpleUpgrade(constants.BuildVersion(2, 1, 0), False)
205
206   def testUpgradeFrom_2_2(self):
207     self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), False)
208
209   def testUpgradeFrom_2_3(self):
210     self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), False)
211
212   def testUpgradeCurrent(self):
213     self._TestSimpleUpgrade(constants.CONFIG_VERSION, False)
214
215   def testUpgradeDryRunFrom_2_0(self):
216     self._TestSimpleUpgrade(constants.BuildVersion(2, 0, 0), True)
217
218   def testUpgradeDryRunFrom_2_1(self):
219     self._TestSimpleUpgrade(constants.BuildVersion(2, 1, 0), True)
220
221   def testUpgradeDryRunFrom_2_2(self):
222     self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), True)
223
224   def testUpgradeDryRunFrom_2_3(self):
225     self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), True)
226
227   def testUpgradeCurrentDryRun(self):
228     self._TestSimpleUpgrade(constants.CONFIG_VERSION, True)
229
230
231 if __name__ == "__main__":
232   testutils.GanetiTestProgram()