This file is indexed.

/usr/share/doc/ganeti/html/design-cmdlib-unittests.html is in ganeti-doc 2.16.0~rc2-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Unit tests for cmdlib / LogicalUnit’s &#8212; Ganeti 2.16.0~rc2 documentation</title>
    <link rel="stylesheet" href="_static/style.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    './',
        VERSION:     '2.16.0~rc2',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true,
        SOURCELINK_SUFFIX: '.txt'
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Removal of the Config Lock Overhead" href="design-configlock.html" />
    <link rel="prev" title="Chained jobs" href="design-chained-jobs.html" /> 
  </head>
  <body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="design-configlock.html" title="Removal of the Config Lock Overhead"
             accesskey="N">next</a></li>
        <li class="right" >
          <a href="design-chained-jobs.html" title="Chained jobs"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">Ganeti 2.16.0~rc2 documentation</a> &#187;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="unit-tests-for-cmdlib-logicalunit-s">
<h1><a class="toc-backref" href="#id1">Unit tests for cmdlib / LogicalUnit’s</a><a class="headerlink" href="#unit-tests-for-cmdlib-logicalunit-s" title="Permalink to this headline"></a></h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Created:</th><td class="field-body">2013-Jul-22</td>
</tr>
<tr class="field-even field"><th class="field-name">Status:</th><td class="field-body">Implemented</td>
</tr>
<tr class="field-odd field"><th class="field-name">Ganeti-Version:</th><td class="field-body">2.10.0</td>
</tr>
</tbody>
</table>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#unit-tests-for-cmdlib-logicalunit-s" id="id1">Unit tests for cmdlib / LogicalUnit’s</a><ul>
<li><a class="reference internal" href="#current-state-and-shortcomings" id="id2">Current state and shortcomings</a></li>
<li><a class="reference internal" href="#proposed-changes" id="id3">Proposed changes</a><ul>
<li><a class="reference internal" href="#test-boundaries" id="id4">Test boundaries</a></li>
<li><a class="reference internal" href="#test-framework" id="id5">Test framework</a><ul>
<li><a class="reference internal" href="#mcpu-mocking" id="id6">MCPU mocking</a></li>
<li><a class="reference internal" href="#configuration-mocking" id="id7">Configuration mocking</a></li>
<li><a class="reference internal" href="#lock-mocking" id="id8">Lock mocking</a></li>
<li><a class="reference internal" href="#rpc-mocking" id="id9">RPC mocking</a></li>
<li><a class="reference internal" href="#iallocator-mocking" id="id10">IAllocator mocking</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#future-work" id="id11">Future work</a></li>
</ul>
</li>
</ul>
</div>
<p>This is a design document describing unit tests for the cmdlib module.
Other modules are deliberately omitted, as LU’s contain the most complex
logic and are only sparingly tested.</p>
<div class="section" id="current-state-and-shortcomings">
<h2><a class="toc-backref" href="#id2">Current state and shortcomings</a><a class="headerlink" href="#current-state-and-shortcomings" title="Permalink to this headline"></a></h2>
<p>The current test coverage of the cmdlib module is at only ~14%. Given
the complexity of the code this is clearly too little.</p>
<p>The reasons for this low coverage are numerous. There are organisational
reasons, like no strict requirements for unit tests for each feature.
But there are also design and technical reasons, which this design
document wants to address. First, it’s not clear which parts of LU’s
should be tested by unit tests, i.e. the test boundaries are not clearly
defined. And secondly, it’s too hard to actually write unit tests for
LU’s. There exists no good framework or set of tools to write easy to
understand and concise tests.</p>
</div>
<div class="section" id="proposed-changes">
<h2><a class="toc-backref" href="#id3">Proposed changes</a><a class="headerlink" href="#proposed-changes" title="Permalink to this headline"></a></h2>
<p>This design document consists of two parts. Initially, the test
boundaries for cmdlib are laid out, and considerations about writing
unit tests are given. Then the test framework is described, together
with a rough overview of the individual parts and how they are meant
to be used.</p>
<div class="section" id="test-boundaries">
<h3><a class="toc-backref" href="#id4">Test boundaries</a><a class="headerlink" href="#test-boundaries" title="Permalink to this headline"></a></h3>
<p>For the cmdlib module, every LogicalUnit is seen as a unit for testing.
Unit tests for LU’s may only execute the LU but make sure that no side
effect (like filesystem access, network access or the like) takes
place. Smaller test units (like individual methods) are sensible and
will be supported by the test framework. However, they are not the main
scope of this document.</p>
<p>LU’s require the following environment to be provided by the test code
in order to be executed:</p>
<dl class="docutils">
<dt>An input opcode</dt>
<dd>LU’s get all the user provided input and parameters from the opcode.</dd>
<dt>The command processor</dt>
<dd>Used to get the execution context id and to output logging  messages.
It also drives the execution of LU’s by calling the appropriate
methods in the right order.</dd>
<dt>The Ganeti context</dt>
<dd><p class="first">Provides node-management methods and contains</p>
<blockquote class="last">
<div><ul class="simple">
<li>The configuration. This gives access to the cluster configuration.</li>
<li>The Ganeti Lock Manager. Manages locks during the execution.</li>
</ul>
</div></blockquote>
</dd>
<dt>The RPC runner</dt>
<dd>Used to communicate with node daemons on other nodes and to perform
operations on them.</dd>
<dt>The IAllocator runner</dt>
<dd>Calls the IAllocator with a given request.</dd>
</dl>
<p>All of those components have to be replaced/adapted by the test
framework.</p>
<p>The goal of unit tests at the LU level is to exercise every possible
code path in the LU at least once. Shared methods which are used by
multiple LU’s should be made testable by themselves and explicit unit
tests should be written for them.</p>
<p>Ultimately, the code coverage for the cmdlib module should be higher
than 90%. As Python is a dynamic language, a portion of those tests
only exists to exercise the code without actually asserting for
anything in the test. They merely make sure that no type errors exist
and that potential typos etc. are caught at unit test time.</p>
</div>
<div class="section" id="test-framework">
<h3><a class="toc-backref" href="#id5">Test framework</a><a class="headerlink" href="#test-framework" title="Permalink to this headline"></a></h3>
<p>The test framework will it make possible to write short and concise
tests for LU’s. In the simplest case, only an opcode has to be provided
by the test. The framework will then use default values, like an almost
empty configuration with only the master node and no instances.</p>
<p>All aspects of the test environment will be configurable by individual
tests.</p>
<div class="section" id="mcpu-mocking">
<h4><a class="toc-backref" href="#id6">MCPU mocking</a><a class="headerlink" href="#mcpu-mocking" title="Permalink to this headline"></a></h4>
<p>The MCPU drives the execution of LU’s. It has to perform its usual
sequence of actions, but additionally it has to provide easy access to
the log output of LU’s. It will contain utility assertion methods on the
output.</p>
<p>The mock will be a sub-class of <code class="docutils literal"><span class="pre">mcpu.Processor</span></code> which overrides
portions of it in order to support the additional functionality. The
advantage of being a sub-class of the original processor is the
automatic compatibility with the code running in real clusters.</p>
</div>
<div class="section" id="configuration-mocking">
<h4><a class="toc-backref" href="#id7">Configuration mocking</a><a class="headerlink" href="#configuration-mocking" title="Permalink to this headline"></a></h4>
<p>Per default, the mocked configuration will contain only the master node,
no instances and default parameters. However, convenience methods for
the following use cases will be provided:</p>
<blockquote>
<div><ul class="simple">
<li>“Shortcut” methods to add objects to the configuration.</li>
<li>Helper methods to quickly create standard nodes/instances/etc.</li>
<li>Pre-populated default configurations for standard use-cases (i.e.
cluster with three nodes, five instances, etc.).</li>
<li>Convenience assertion methods for checking the configuration.</li>
</ul>
</div></blockquote>
</div>
<div class="section" id="lock-mocking">
<h4><a class="toc-backref" href="#id8">Lock mocking</a><a class="headerlink" href="#lock-mocking" title="Permalink to this headline"></a></h4>
<p>Initially, the mocked lock manager always grants all locks. It performs
the following tasks:</p>
<blockquote>
<div><ul class="simple">
<li>It keeps track of requested/released locks.</li>
<li>Provides utility assertion methods for checking locks (current and
already released ones).</li>
</ul>
</div></blockquote>
<p>In the future, this component might be extended to prevent locks from
being granted. This could eventually be used to test optimistic locking.</p>
</div>
<div class="section" id="rpc-mocking">
<h4><a class="toc-backref" href="#id9">RPC mocking</a><a class="headerlink" href="#rpc-mocking" title="Permalink to this headline"></a></h4>
<p>No actual RPC can be made during unit tests. Therefore, those calls have
to be replaced and their results mocked. As this will entail a large
portion of work when writing tests, mocking RPC’s will be made as easy as
possible. This entails:</p>
<blockquote>
<div><ul class="simple">
<li>Easy construction of RPC results.</li>
<li>Easy mocking of RPC calls (also multiple ones of the same type during
one LU execution).</li>
<li>Asserting for RPC calls (including arguments, affected nodes, etc.).</li>
</ul>
</div></blockquote>
</div>
<div class="section" id="iallocator-mocking">
<h4><a class="toc-backref" href="#id10">IAllocator mocking</a><a class="headerlink" href="#iallocator-mocking" title="Permalink to this headline"></a></h4>
<p>Calls (also multiple ones during the execution of a LU) to the
IAllocator interface have to be mocked. The framework will provide,
similarly to the RPC mocking, provide means to specify the mocked result
and to assert on the IAllocator requests.</p>
</div>
</div>
</div>
<div class="section" id="future-work">
<h2><a class="toc-backref" href="#id11">Future work</a><a class="headerlink" href="#future-work" title="Permalink to this headline"></a></h2>
<p>With unit tests for cmdlib in place, further unit testing for other
modules can and should be added. The test boundaries therefore should be
aligned with the boundaries from cmdlib.</p>
<p>The mocked locking module can be extended to allow testing of optimistic
locking in LU’s. In this case, on all requested locks are actually
granted to the LU, so it has to adapt for this situation correctly.</p>
<p>A higher test coverage for LU’s will increase confidence in our code and
tests. Refactorings will be easier to make as more problems are caught
during tests.</p>
<p>After a baseline of unit tests is established for cmdlib, efficient
testing guidelines could be put in place. For example, new code could be
required to not lower the test coverage in cmdlib. Additionally, every
bug fix could be required to include a test which triggered the bug
before the fix is created.</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table Of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Unit tests for cmdlib / LogicalUnit’s</a><ul>
<li><a class="reference internal" href="#current-state-and-shortcomings">Current state and shortcomings</a></li>
<li><a class="reference internal" href="#proposed-changes">Proposed changes</a><ul>
<li><a class="reference internal" href="#test-boundaries">Test boundaries</a></li>
<li><a class="reference internal" href="#test-framework">Test framework</a><ul>
<li><a class="reference internal" href="#mcpu-mocking">MCPU mocking</a></li>
<li><a class="reference internal" href="#configuration-mocking">Configuration mocking</a></li>
<li><a class="reference internal" href="#lock-mocking">Lock mocking</a></li>
<li><a class="reference internal" href="#rpc-mocking">RPC mocking</a></li>
<li><a class="reference internal" href="#iallocator-mocking">IAllocator mocking</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#future-work">Future work</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="design-chained-jobs.html"
                        title="previous chapter">Chained jobs</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="design-configlock.html"
                        title="next chapter">Removal of the Config Lock Overhead</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="_sources/design-cmdlib-unittests.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <div><input type="text" name="q" /></div>
      <div><input type="submit" value="Go" /></div>
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="design-configlock.html" title="Removal of the Config Lock Overhead"
             >next</a></li>
        <li class="right" >
          <a href="design-chained-jobs.html" title="Chained jobs"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">Ganeti 2.16.0~rc2 documentation</a> &#187;</li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2018, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Google Inc..
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.6.7.
    </div>
  </body>
</html>