root / test / py / cmdlib / instance_migration_unittest.py @ ff1c051b
History | View | Annotate | Download (5.7 kB)
1 | d1b2ffe8 | Thomas Thrainer | #!/usr/bin/python
|
---|---|---|---|
2 | d1b2ffe8 | Thomas Thrainer | #
|
3 | d1b2ffe8 | Thomas Thrainer | |
4 | d1b2ffe8 | Thomas Thrainer | # Copyright (C) 2013 Google Inc.
|
5 | d1b2ffe8 | Thomas Thrainer | #
|
6 | d1b2ffe8 | Thomas Thrainer | # This program is free software; you can redistribute it and/or modify
|
7 | d1b2ffe8 | Thomas Thrainer | # it under the terms of the GNU General Public License as published by
|
8 | d1b2ffe8 | Thomas Thrainer | # the Free Software Foundation; either version 2 of the License, or
|
9 | d1b2ffe8 | Thomas Thrainer | # (at your option) any later version.
|
10 | d1b2ffe8 | Thomas Thrainer | #
|
11 | d1b2ffe8 | Thomas Thrainer | # This program is distributed in the hope that it will be useful, but
|
12 | d1b2ffe8 | Thomas Thrainer | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | d1b2ffe8 | Thomas Thrainer | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | d1b2ffe8 | Thomas Thrainer | # General Public License for more details.
|
15 | d1b2ffe8 | Thomas Thrainer | #
|
16 | d1b2ffe8 | Thomas Thrainer | # You should have received a copy of the GNU General Public License
|
17 | d1b2ffe8 | Thomas Thrainer | # along with this program; if not, write to the Free Software
|
18 | d1b2ffe8 | Thomas Thrainer | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | d1b2ffe8 | Thomas Thrainer | # 02110-1301, USA.
|
20 | d1b2ffe8 | Thomas Thrainer | |
21 | d1b2ffe8 | Thomas Thrainer | |
22 | d1b2ffe8 | Thomas Thrainer | """Tests for LUInstanceFailover and LUInstanceMigrate
|
23 | d1b2ffe8 | Thomas Thrainer |
|
24 | d1b2ffe8 | Thomas Thrainer | """
|
25 | d1b2ffe8 | Thomas Thrainer | |
26 | d1b2ffe8 | Thomas Thrainer | from ganeti import constants |
27 | d1b2ffe8 | Thomas Thrainer | from ganeti import objects |
28 | d1b2ffe8 | Thomas Thrainer | from ganeti import opcodes |
29 | d1b2ffe8 | Thomas Thrainer | |
30 | d1b2ffe8 | Thomas Thrainer | from testsupport import * |
31 | d1b2ffe8 | Thomas Thrainer | |
32 | d1b2ffe8 | Thomas Thrainer | import testutils |
33 | d1b2ffe8 | Thomas Thrainer | |
34 | d1b2ffe8 | Thomas Thrainer | |
35 | d1b2ffe8 | Thomas Thrainer | class TestLUInstanceMigrate(CmdlibTestCase): |
36 | d1b2ffe8 | Thomas Thrainer | def setUp(self): |
37 | d1b2ffe8 | Thomas Thrainer | super(TestLUInstanceMigrate, self).setUp() |
38 | d1b2ffe8 | Thomas Thrainer | |
39 | d1b2ffe8 | Thomas Thrainer | self.snode = self.cfg.AddNewNode() |
40 | d1b2ffe8 | Thomas Thrainer | |
41 | d1b2ffe8 | Thomas Thrainer | hv_info = ("bootid",
|
42 | d1b2ffe8 | Thomas Thrainer | [{ |
43 | d1b2ffe8 | Thomas Thrainer | "type": constants.ST_LVM_VG,
|
44 | d1b2ffe8 | Thomas Thrainer | "storage_free": 10000 |
45 | d1b2ffe8 | Thomas Thrainer | }], |
46 | d1b2ffe8 | Thomas Thrainer | ({"memory_free": 10000}, )) |
47 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_node_info.return_value = \
|
48 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
49 | d1b2ffe8 | Thomas Thrainer | .AddSuccessfulNode(self.master, hv_info) \
|
50 | d1b2ffe8 | Thomas Thrainer | .AddSuccessfulNode(self.snode, hv_info) \
|
51 | d1b2ffe8 | Thomas Thrainer | .Build() |
52 | d1b2ffe8 | Thomas Thrainer | |
53 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_blockdev_find.return_value = \
|
54 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
55 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.master, objects.BlockDevStatus())
|
56 | d1b2ffe8 | Thomas Thrainer | |
57 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_migration_info.return_value = \
|
58 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
59 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.master, True) |
60 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_accept_instance.return_value = \
|
61 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
62 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.snode, True) |
63 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_instance_migrate.return_value = \
|
64 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
65 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.master, True) |
66 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_instance_get_migration_status.return_value = \
|
67 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
68 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.master, objects.MigrationStatus())
|
69 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_instance_finalize_migration_dst.return_value = \
|
70 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
71 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.snode, True) |
72 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_instance_finalize_migration_src.return_value = \
|
73 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
74 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.master, True) |
75 | d1b2ffe8 | Thomas Thrainer | |
76 | d1b2ffe8 | Thomas Thrainer | self.inst = self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8, |
77 | d1b2ffe8 | Thomas Thrainer | admin_state=constants.ADMINST_UP, |
78 | d1b2ffe8 | Thomas Thrainer | secondary_node=self.snode)
|
79 | d1b2ffe8 | Thomas Thrainer | self.op = opcodes.OpInstanceMigrate(instance_name=self.inst.name) |
80 | d1b2ffe8 | Thomas Thrainer | |
81 | d1b2ffe8 | Thomas Thrainer | def testPlainDisk(self): |
82 | d1b2ffe8 | Thomas Thrainer | inst = self.cfg.AddNewInstance(disk_template=constants.DT_PLAIN)
|
83 | d1b2ffe8 | Thomas Thrainer | op = self.CopyOpCode(self.op, |
84 | d1b2ffe8 | Thomas Thrainer | instance_name=inst.name) |
85 | d1b2ffe8 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
86 | d1b2ffe8 | Thomas Thrainer | op, "Instance's disk layout 'plain' does not allow migrations")
|
87 | d1b2ffe8 | Thomas Thrainer | |
88 | d1b2ffe8 | Thomas Thrainer | def testMigrationToWrongNode(self): |
89 | d1b2ffe8 | Thomas Thrainer | node = self.cfg.AddNewNode()
|
90 | d1b2ffe8 | Thomas Thrainer | op = self.CopyOpCode(self.op, |
91 | d1b2ffe8 | Thomas Thrainer | target_node=node.name) |
92 | d1b2ffe8 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
93 | d1b2ffe8 | Thomas Thrainer | op, "Instances with disk template drbd cannot be migrated to"
|
94 | d1b2ffe8 | Thomas Thrainer | " arbitrary nodes")
|
95 | d1b2ffe8 | Thomas Thrainer | |
96 | d1b2ffe8 | Thomas Thrainer | def testMigration(self): |
97 | d1b2ffe8 | Thomas Thrainer | op = self.CopyOpCode(self.op) |
98 | d1b2ffe8 | Thomas Thrainer | self.ExecOpCode(op)
|
99 | d1b2ffe8 | Thomas Thrainer | |
100 | d1b2ffe8 | Thomas Thrainer | |
101 | d1b2ffe8 | Thomas Thrainer | class TestLUInstanceFailover(CmdlibTestCase): |
102 | d1b2ffe8 | Thomas Thrainer | def setUp(self): |
103 | d1b2ffe8 | Thomas Thrainer | super(TestLUInstanceFailover, self).setUp() |
104 | d1b2ffe8 | Thomas Thrainer | |
105 | d1b2ffe8 | Thomas Thrainer | self.snode = self.cfg.AddNewNode() |
106 | d1b2ffe8 | Thomas Thrainer | |
107 | d1b2ffe8 | Thomas Thrainer | hv_info = ("bootid",
|
108 | d1b2ffe8 | Thomas Thrainer | [{ |
109 | d1b2ffe8 | Thomas Thrainer | "type": constants.ST_LVM_VG,
|
110 | d1b2ffe8 | Thomas Thrainer | "storage_free": 10000 |
111 | d1b2ffe8 | Thomas Thrainer | }], |
112 | d1b2ffe8 | Thomas Thrainer | ({"memory_free": 10000}, )) |
113 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_node_info.return_value = \
|
114 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
115 | d1b2ffe8 | Thomas Thrainer | .AddSuccessfulNode(self.master, hv_info) \
|
116 | d1b2ffe8 | Thomas Thrainer | .AddSuccessfulNode(self.snode, hv_info) \
|
117 | d1b2ffe8 | Thomas Thrainer | .Build() |
118 | d1b2ffe8 | Thomas Thrainer | |
119 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_blockdev_find.return_value = \
|
120 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
121 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.master, objects.BlockDevStatus())
|
122 | d1b2ffe8 | Thomas Thrainer | |
123 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_instance_shutdown.return_value = \
|
124 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
125 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.master, True) |
126 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_blockdev_shutdown.return_value = \
|
127 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
128 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.master, True) |
129 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_blockdev_assemble.return_value = \
|
130 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
131 | ff5def9b | Dimitris Aragiorgis | .CreateSuccessfulNodeResult(self.snode, ("/dev/mock", "/var/mock")) |
132 | d1b2ffe8 | Thomas Thrainer | self.rpc.call_instance_start.return_value = \
|
133 | d1b2ffe8 | Thomas Thrainer | self.RpcResultsBuilder() \
|
134 | d1b2ffe8 | Thomas Thrainer | .CreateSuccessfulNodeResult(self.snode, True) |
135 | d1b2ffe8 | Thomas Thrainer | |
136 | d1b2ffe8 | Thomas Thrainer | self.inst = self.cfg.AddNewInstance(disk_template=constants.DT_DRBD8, |
137 | d1b2ffe8 | Thomas Thrainer | admin_state=constants.ADMINST_UP, |
138 | d1b2ffe8 | Thomas Thrainer | secondary_node=self.snode)
|
139 | d1b2ffe8 | Thomas Thrainer | self.op = opcodes.OpInstanceFailover(instance_name=self.inst.name) |
140 | d1b2ffe8 | Thomas Thrainer | |
141 | d1b2ffe8 | Thomas Thrainer | def testPlainDisk(self): |
142 | d1b2ffe8 | Thomas Thrainer | inst = self.cfg.AddNewInstance(disk_template=constants.DT_PLAIN)
|
143 | d1b2ffe8 | Thomas Thrainer | op = self.CopyOpCode(self.op, |
144 | d1b2ffe8 | Thomas Thrainer | instance_name=inst.name) |
145 | d1b2ffe8 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
146 | d1b2ffe8 | Thomas Thrainer | op, "Instance's disk layout 'plain' does not allow failovers")
|
147 | d1b2ffe8 | Thomas Thrainer | |
148 | d1b2ffe8 | Thomas Thrainer | def testMigrationToWrongNode(self): |
149 | d1b2ffe8 | Thomas Thrainer | node = self.cfg.AddNewNode()
|
150 | d1b2ffe8 | Thomas Thrainer | op = self.CopyOpCode(self.op, |
151 | d1b2ffe8 | Thomas Thrainer | target_node=node.name) |
152 | d1b2ffe8 | Thomas Thrainer | self.ExecOpCodeExpectOpPrereqError(
|
153 | d1b2ffe8 | Thomas Thrainer | op, "Instances with disk template drbd cannot be failed over to"
|
154 | d1b2ffe8 | Thomas Thrainer | " arbitrary nodes")
|
155 | d1b2ffe8 | Thomas Thrainer | |
156 | d1b2ffe8 | Thomas Thrainer | def testMigration(self): |
157 | d1b2ffe8 | Thomas Thrainer | op = self.CopyOpCode(self.op) |
158 | d1b2ffe8 | Thomas Thrainer | self.ExecOpCode(op)
|
159 | d1b2ffe8 | Thomas Thrainer | |
160 | d1b2ffe8 | Thomas Thrainer | |
161 | d1b2ffe8 | Thomas Thrainer | if __name__ == "__main__": |
162 | d1b2ffe8 | Thomas Thrainer | testutils.GanetiTestProgram() |