Revision 2fd213a6

b/doc/hooks.rst
148 148
:pre-execution: master node, the target node
149 149
:post-execution: master node, the target node
150 150

  
151
OP_NODE_EVACUATE
152
++++++++++++++++
153

  
154
Relocate secondary instances from a node.
155

  
156
:directory: node-evacuate
157
:env. vars: NEW_SECONDARY, NODE_NAME
158
:pre-execution: master node, target node
159
:post-execution: master node, target node
160

  
161 151
OP_NODE_MIGRATE
162 152
++++++++++++++++
163 153

  
......
344 334
:pre-execution: master node
345 335
:post-execution: master node, primary and secondary nodes
346 336

  
347
OP_INSTANCE_REPLACE_DISKS
348
+++++++++++++++++++++++++
349

  
350
Replace an instance's disks.
351

  
352
:directory: mirror-replace
353
:env. vars: MODE, NEW_SECONDARY, OLD_SECONDARY
354
:pre-execution: master node, primary and secondary nodes
355
:post-execution: master node, primary and secondary nodes
356

  
357 337
OP_INSTANCE_GROW_DISK
358 338
+++++++++++++++++++++
359 339

  
b/test/docs_unittest.py
86 86

  
87 87

  
88 88
class TestHooksDocs(unittest.TestCase):
89
  HOOK_PATH_OK = frozenset([
90
    "master-ip-turnup",
91
    "master-ip-turndown",
92
    ])
93

  
89 94
  def test(self):
90 95
    """Check whether all hooks are documented.
91 96

  
......
98 103
    assert len(lu2opcode) == len(mcpu.Processor.DISPATCH_TABLE), \
99 104
      "Found duplicate entries"
100 105

  
101
    for name in dir(cmdlib):
102
      obj = getattr(cmdlib, name)
103

  
104
      if (isinstance(obj, type) and
105
          issubclass(obj, cmdlib.LogicalUnit) and
106
          hasattr(obj, "HPATH")):
107
        self._CheckHook(name, obj, hooksdoc, lu2opcode)
108

  
109
  def _CheckHook(self, name, lucls, hooksdoc, lu2opcode):
110
    opcls = lu2opcode.get(lucls, None)
111

  
112
    if lucls.HTYPE is None:
113
      return
106
    hooks_paths = frozenset(re.findall("^:directory:\s*(.+)\s*$", hooksdoc,
107
                                       re.M))
108
    self.assertTrue(self.HOOK_PATH_OK.issubset(hooks_paths),
109
                    msg="Whitelisted path not found in documentation")
110

  
111
    raw_hooks_ops = re.findall("^OP_(?!CODE$).+$", hooksdoc, re.M)
112
    hooks_ops = set()
113
    duplicate_ops = set()
114
    for op in raw_hooks_ops:
115
      if op in hooks_ops:
116
        duplicate_ops.add(op)
117
      else:
118
        hooks_ops.add(op)
114 119

  
115
    # TODO: Improve this test (e.g. find hooks documented but no longer
116
    # existing)
120
    self.assertFalse(duplicate_ops,
121
                     msg="Found duplicate opcode documentation: %s" %
122
                         utils.CommaJoin(duplicate_ops))
117 123

  
118
    if opcls:
119
      self.assertTrue(re.findall("^%s$" % re.escape(opcls.OP_ID),
120
                                 hooksdoc, re.M),
121
                      msg=("Missing hook documentation for %s" %
122
                           (opcls.OP_ID)))
124
    seen_paths = set()
125
    seen_ops = set()
123 126

  
124
    pattern = r"^:directory:\s*%s\s*$" % re.escape(lucls.HPATH)
127
    self.assertFalse(duplicate_ops,
128
                     msg="Found duplicated hook documentation: %s" %
129
                         utils.CommaJoin(duplicate_ops))
125 130

  
126
    self.assert_(re.findall(pattern, hooksdoc, re.M),
127
                 msg=("Missing documentation for hook %s/%s" %
128
                      (lucls.HTYPE, lucls.HPATH)))
131
    for name in dir(cmdlib):
132
      lucls = getattr(cmdlib, name)
133

  
134
      if (isinstance(lucls, type) and
135
          issubclass(lucls, cmdlib.LogicalUnit) and
136
          hasattr(lucls, "HPATH")):
137
        if lucls.HTYPE is None:
138
          continue
139

  
140
        opcls = lu2opcode.get(lucls, None)
141

  
142
        if opcls:
143
          seen_ops.add(opcls.OP_ID)
144
          self.assertTrue(opcls.OP_ID in hooks_ops,
145
                          msg="Missing hook documentation for %s" %
146
                              opcls.OP_ID)
147
        self.assertTrue(lucls.HPATH in hooks_paths,
148
                        msg="Missing documentation for hook %s/%s" %
149
                            (lucls.HTYPE, lucls.HPATH))
150
        seen_paths.add(lucls.HPATH)
151

  
152
    missed_ops = hooks_ops - seen_ops
153
    missed_paths = hooks_paths - seen_paths - self.HOOK_PATH_OK
154

  
155
    self.assertFalse(missed_ops,
156
                     msg="Op documents hook not existing anymore: %s" %
157
                         utils.CommaJoin(missed_ops))
158

  
159
    self.assertFalse(missed_paths,
160
                     msg="Hook path does not exist in opcode: %s" %
161
                         utils.CommaJoin(missed_paths))
129 162

  
130 163

  
131 164
class TestRapiDocs(unittest.TestCase):

Also available in: Unified diff