<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"><channel><title>QA Specs</title><link>https://specs.openstack.org/openstack/qa-specs</link><description /><language>en</language><copyright>2023, OpenStack QA Team</copyright><item><title>Team and repository tags</title><link>https://specs.openstack.org/openstack/qa-specs/README.html</link><description>&lt;section id="team-and-repository-tags"&gt;

&lt;a class="reference external image-reference" href="https://governance.openstack.org/tc/reference/tags/index.html"&gt;&lt;img alt="https://governance.openstack.org/tc/badges/qa-specs.svg" src="https://governance.openstack.org/tc/badges/qa-specs.svg"/&gt;&lt;/a&gt;
&lt;/section&gt;
&lt;section id="qa-specs-repository"&gt;

&lt;p&gt;This is a git repository for doing design review on QA enhancements as
part of the OpenStack program. This provides an ability to ensure that
everyone has signed off on the approach to solving a problem early
on.&lt;/p&gt;
&lt;p&gt;This repository includes the Tempest and DevStack projects.&lt;/p&gt;
&lt;section id="repository-structure"&gt;
&lt;h2&gt;Repository Structure&lt;/h2&gt;
&lt;p&gt;The structure of the repository is as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;specs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="n"&gt;devstack&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
        &lt;span class="n"&gt;implemented&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="n"&gt;other&lt;/span&gt;
        &lt;span class="n"&gt;implemented&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="n"&gt;tempest&lt;/span&gt;
        &lt;span class="n"&gt;implemented&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="expected-work-flow"&gt;
&lt;h2&gt;Expected Work Flow&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create a blueprint stub in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest&lt;/span&gt;&lt;/code&gt;,  &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack&lt;/span&gt;&lt;/code&gt;, or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;other&lt;/span&gt;&lt;/code&gt;
blueprint repository&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Propose review to qa-specs repository (ensure bp:blueprint_name is
in the commit message.  DevStack specs should go into the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack/&lt;/span&gt;&lt;/code&gt; subdirectory
but otherwise follow the same process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Read&lt;/span&gt; &lt;span class="pre"&gt;the&lt;/span&gt; &lt;span class="pre"&gt;full&lt;/span&gt; &lt;span class="pre"&gt;specification&lt;/span&gt;&lt;/code&gt; to the gerrit address of the spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bring forward the proposed item to the openstack-qa meeting for summary&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Review happens on proposal by qa-core members and others&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iterate until review is Approved or Rejected&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once a Review is Approved…&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Update blueprint, Copy summary text of blueprint to there&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Read&lt;/span&gt; &lt;span class="pre"&gt;the&lt;/span&gt; &lt;span class="pre"&gt;full&lt;/span&gt; &lt;span class="pre"&gt;specification&lt;/span&gt;&lt;/code&gt; to the git address of the spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Profit!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="revisiting-specs"&gt;
&lt;h2&gt;Revisiting Specs&lt;/h2&gt;
&lt;p&gt;We don’t always get everything right the first time. If we realize we
need to revisit a specification because something changed, either we
now know more, or a new idea came in which we should embrace, we’ll
manage this by proposing an update to the spec in question.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="learn-as-we-go"&gt;
&lt;h2&gt;Learn as we go&lt;/h2&gt;
&lt;p&gt;This is a new way of attempting things, so we’re going to be low in
process to begin with to figure out where we go from here. Expect some
early flexibility in evolving this effort over time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="tempest-specs-for-new-tests"&gt;
&lt;h2&gt;Tempest Specs For New Tests&lt;/h2&gt;
&lt;p&gt;If you’re writing a new spec to improve the testing coverage in Tempest the
requirements for what is included in the specification are slightly less
stringent and different from other proposals. This is because blueprints for
more tests are more about tracking the effort in a single place and assigning
a unified topic in gerrit for ease of review, it’s less about the
implementation details. Blueprints/specifications for new tests should only
ever be opened for overarching development efforts. For example there should
only ever only need to be a single blueprint for adding tests for a project.&lt;/p&gt;
&lt;p&gt;Most of these efforts require a method to track the work items outside of
launchpad. Both etherpad and google docs have been used very successfully for
this. The goal is to list out all the tests that need to be written and allow
people to mark that they intend to work on a specific test. This prevents
duplication of effort as well as provide overall status tracking. An external
tool like etherpad or google docs is better at this because it allows
concurrent use and more dynamic editing than launchpad.&lt;/p&gt;
&lt;p&gt;The only details required in the proposed change section for a spec about new
tests are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;What is being tested and the scope of what will be covered by the blueprint&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What external tool is being used to track the development.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If no external tracking is being used just explain why.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="devstack-specs"&gt;
&lt;h2&gt;DevStack Specs&lt;/h2&gt;
&lt;p&gt;Specs for DevStack fall into a couple of broad categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Support for new {project|driver|cool widget}&lt;/p&gt;
&lt;p&gt;This is where the discussion of “Does this support belong in the
DevStack repo?” should take place.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Significant re-factoring&lt;/p&gt;
&lt;p&gt;One primary section that these types of changes require is an analysis
of backward compatibility and Grenade impacts.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The existing template is mostly suitable for DevStack use, a quick
s/tempest/devstack/ handles the majority of changes.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Wed, 12 Apr 2023 00:00:00 </pubDate></item><item><title>Tempest support for API microversions testing</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/api-microversions-testing-support.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/api-microversions-testing-support"&gt;https://blueprints.launchpad.net/tempest/+spec/api-microversions-testing-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Since Kilo, nova has implemented API microversions and the other components
(Ironic, etc) also implemented it now. However, currently Tempest does not
have any support for microversions and doesn’t test it at all.
This proposal is to add microversions testing support in Tempest.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;On microversions mechanism, each microversion change is very small.
For example, version 2.2’s change is:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Add&lt;/span&gt; &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;keypairs&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;span class="n"&gt;Change&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;keypairs&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;
&lt;span class="n"&gt;Change&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;keypairs&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;202&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In long term, a lot of microversions will be implemented because all API
changes should be done with microversions. Now Ironic also implements this
microversions and the other projects have a plan to implement it.
So we need to implement consistent basic test way for these projects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;section id="test-classes-for-each-microversion"&gt;
&lt;h3&gt;Test classes for each microversion&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Implement test classes for each microversion
When adding a new microversion which changes an API, basically we need
to implement a test class for the API. In addition, each test class
contains its microversion range with class values like min_microversion
and max_microversion. For example, we have added a new attribute ‘type’
to os-keypairs response on nova’s microversion 2.2, and the corresponding
test class will be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;KeyPairsV22Test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseKeypairTest&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;min_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2.2'&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;as os-keypairs test class. In the above case, max_microversion is not
contained. That means unlimited as max_microversion. If we change the API
again with microversion ‘2.100’ as an example, the test class will be:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;KeyPairsV22Test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseKeypairTest&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;min_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2.2'&lt;/span&gt;
    &lt;span class="n"&gt;max_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2.99'&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and we need to add a test like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;KeyPairsV100Test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseKeypairTest&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;min_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2.100'&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add configuration options for specifying test target microversions
We need to specify test target microversions because the supported
microversions are different between OpenStack clouds. For operating
multiple microversion tests in a single Tempest operation, configuration
options should represent the range of test target microversions.
New configuration options also are min_microversion and max_microversion,
and the test classes will be selected like the following:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;TestClass&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;min_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;max_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'latest'&lt;/span&gt;
&lt;span class="n"&gt;TestClass&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;min_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;max_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2.2'&lt;/span&gt;
&lt;span class="n"&gt;TestClass&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;min_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2.3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'latest'&lt;/span&gt;
&lt;span class="n"&gt;TestClass&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;min_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2.5'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_microversion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2.10'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Configuration
(min,    max)&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Test classes
(Passed microversion)&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;None,     None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A(Not passed), B(Not passed), C &amp;amp; D - Skipped&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;None,     ‘2.3’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A(Not passed), B(Not passed), C(‘2.3’), D - Skipped&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;‘2.2’,    ‘latest’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A(‘2.2’), B(‘2.2’), C(‘2.3’), D(‘2.5’)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;‘2.2’,    ‘2.3’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A(‘2.2’), B(‘2.2’), C(‘2.3’), D - Skipped&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;‘2.10’,   ‘2.10’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A(‘2.10’), B - Skipped, C(‘2.10’), D(‘2.10’)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;None,     ‘latest’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A(Not passed), B(Not passed), C(‘2.3’), D(‘2.5’)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;‘latest’, ‘latest’&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;A(‘latest’), B - Skipped, C(‘latest’), D - Skipped&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;So basically the configuration min_microversion value is passed on the
microversion header. However if the selected class’ min_microversion
is bigger, the class’ min_microversion is passed instead.
If you’d like to always pass the maximum micoversion then, you need to
set the max_microversion and the min_microversion to be the same value,
like the 5th example above.&lt;/p&gt;
&lt;p&gt;The default configuration values should be (None, None) like 1st example
for running on the existing clouds which don’t support microversions.
So we need to change the configuration values with openstack-dev/devstack
and openstack-infra/project-config for operating microversion tests on the
gate.&lt;/p&gt;
&lt;p&gt;The microversion ‘latest’ is a magic keyword as final example. When passing
‘latest’ as the microversion to each component(Nova, etc.), the component
takes the latest microversion action on the server side. Some microversions
will be backwards incompatible and the ‘latest’ action can break the gate
test if Tempest doesn’t support the microversion at the time. To avoid such
situation, we should not specify ‘latest’ on regular gate jobs. It is nice
to specify it as experimental job to know we need to update Tempest for
supporting the latest microversion.&lt;/p&gt;
&lt;p&gt;These configuration options should be added for each project(Nova, Ironic,
etc.) because the microversion numbers are different between projects.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="json-schema-for-each-microversion-nova-specific"&gt;
&lt;h3&gt;JSON-Schema for each microversion (Nova specific)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Define responses for each microversion
Backwards compatible changes also need new microversions on Nova’s
microversions and Tempest is verifying it by checking Nova API responses
don’t contain any extra attributes with JSON-Schema additionalProperties
feature. So we need to define the responses for each microversions and
Tempest needs to switch the response definition of JSON-Schema by the
microversion.
Now the responses are defined under tempest_lib/api_schema/response/compute/
of tempest-lib and the one of the base microversion v2.1 is defined under
./v2_1 . Each microversion is a little different from the previous one and
it is necessary to define the difference under ./v2_2, ./v2_3, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make service clients switch response definition for each microversion
Service clients of Nova will switch the definition based on the microversion.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="tempest-lib-migration-plan"&gt;
&lt;h3&gt;Tempest-lib migration plan&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Steps:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Implement the microversion testing framework in Tempest.
The framework includes skipping methods etc for microversion tests based
on the provided configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement base framework for service clients to pass microversion to a
request header in Tempest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement tests case for Nova microversion v2.2 as sample in Tempest.
This includes schema and service client change also.
We can test the microversion testing framework at this time, and it will
be ready to migrate the framework to tempest-lib.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrate the microversion testing framework to tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="external-consumption"&gt;
&lt;h3&gt;External consumption&lt;/h3&gt;
&lt;p&gt;Once all frameworks are migrated to Tempest-lib, other projects can
use the same for their microversion testing.
Document needs to be updated how to consume the microversion testing
framework with some example.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="projects"&gt;
&lt;h2&gt;Projects&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;openstack/tempest&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack/tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack-dev/devstack&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack-infra/project-config&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ken’ichi Ohmichi &amp;lt;&lt;a class="reference external" href="mailto:ken-oomichi%40wx.jp.nec.com"&gt;ken-oomichi&lt;span&gt;@&lt;/span&gt;wx&lt;span&gt;.&lt;/span&gt;jp&lt;span&gt;.&lt;/span&gt;nec&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ghanshyam Mann &amp;lt;&lt;a class="reference external" href="mailto:ghanshyam.mann%40nectechnologies.in"&gt;ghanshyam&lt;span&gt;.&lt;/span&gt;mann&lt;span&gt;@&lt;/span&gt;nectechnologies&lt;span&gt;.&lt;/span&gt;in&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yuiko Takada &amp;lt;&lt;a class="reference external" href="mailto:yui-takada%40tg.jp.nec.com"&gt;yui-takada&lt;span&gt;@&lt;/span&gt;tg&lt;span&gt;.&lt;/span&gt;jp&lt;span&gt;.&lt;/span&gt;nec&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Mitaka-1&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement base test classe for microversions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pass a test target microversion to service clients&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a test class for a single microversion(as sample)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrate tested microversion testing framework to Tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consume those interface from Tempest-lib and remove from Tempest&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the configurations on openstack-infra/project-config for master&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/242296/"&gt;https://review.openstack.org/#/c/242296/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 12 May 2022 00:00:00 </pubDate></item><item><title>RBAC Testing Multiple Policies</title><link>https://specs.openstack.org/openstack/qa-specs/specs/patrole/implemented/rbac-testing-multiple-policies.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/patrole/+spec/rbac-testing-multiple-policies"&gt;bp rbac-testing-multiple-policies&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Patrole currently RBAC tests an API endpoint by checking whether a policy
action is allowed, according to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;oslo.policy&lt;/span&gt;&lt;/code&gt; and then executes
the API endpoint that does policy enforcement with the role specified
under &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.rbac.rbac_test_role&lt;/span&gt;&lt;/code&gt;. However, this approach does not account
for API endpoints that enforce multiple policy actions, either directly
(within the implementation of the API endpoint itself) or indirectly (across
different helper functions and API endpoints). The current approach to RBAC
testing in Patrole, therefore, does not always provide complete policy
coverage. Just like multiple calls are made to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;oslo.policy&lt;/span&gt;&lt;/code&gt; by various
endpoints, Patrole should do the same.&lt;/p&gt;
&lt;p&gt;For example, take an API that enforces 2 policy actions, A and B, where A is
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin_api&lt;/span&gt;&lt;/code&gt; and B is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin_or_owner&lt;/span&gt;&lt;/code&gt;. Calling the API with
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbac_test_role&lt;/span&gt;&lt;/code&gt; as admin role will necessarily pass, because admin role has
permissions to execute policy actions A and B and will also be able to execute
the API endpoint. However, the test will fail for non-admin role, with the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbac_rule_validation&lt;/span&gt;&lt;/code&gt; decorator evaluating &lt;em&gt;only&lt;/em&gt; policy action B. This is
because a non-admin role (i.e. Member) role &lt;em&gt;has&lt;/em&gt; permissions to perform policy
action B (which is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin_or_owner&lt;/span&gt;&lt;/code&gt;) but does &lt;em&gt;not&lt;/em&gt; have permissions to
execute the API endpoint, since the endpoint enforces an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin_api&lt;/span&gt;&lt;/code&gt; policy:
this results in a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Forbidden&lt;/span&gt;&lt;/code&gt; exception being raised, and the test failing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed change is to modify the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbac_rule_validation&lt;/span&gt;&lt;/code&gt; decorator to
be able to take a list of policy actions, rather than just one policy action.
For each policy action, a call will be made to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;oslo.policy&lt;/span&gt;&lt;/code&gt; to confirm
whether the test role is allowed to perform the action. Each result from
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;oslo.policy&lt;/span&gt;&lt;/code&gt; will be logical-ANDed together. For example, if policy action
A evaluates to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; and policy action B evaluates to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;, then the
final outcome is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;: therefore, the user should not be able to perform
the API call successfully. As such, Patrole can deduce whether a role is
allowed to call an API that enforces multiple policies.&lt;/p&gt;
&lt;p&gt;To provide a concrete example, the following test:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@rbac_rule_validation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"nova"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"os_compute_api:os-lock-server:unlock:unlock_override"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_unlock_server_override&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_test_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wait_until&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# In order to trigger the unlock:unlock_override policy instead&lt;/span&gt;
    &lt;span class="c1"&gt;# of the unlock policy, the server must be locked by a different&lt;/span&gt;
    &lt;span class="c1"&gt;# user than the one who is attempting to unlock it.&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os_admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;servers_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lock_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addCleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;servers_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unlock_server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rbac_utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;toggle_rbac_role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;servers_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unlock_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;can be changed to:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@rbac_rule_validation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"nova"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"os_compute_api:os-lock-server:unlock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"os_compute_api:os-lock-server:unlock:unlock_override"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_unlock_server_override&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_test_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wait_until&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os_admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;servers_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lock_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addCleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;servers_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unlock_server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rbac_utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;toggle_rbac_role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;servers_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unlock_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;According to the Nova documentation for locking a server, the “unlock_override”
policy is “performed only after the check os_compute_api:os-lock-server:unlock
passes”. With this change, Patrole will generate its “expected” result based on
whether the test role can perform &lt;em&gt;all&lt;/em&gt; the policies passed to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rules&lt;/span&gt;&lt;/code&gt;;
otherwise, if the test role cannot perform at least one policy, the expected
result will be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;. Afterward, the API action will be called with the test
role and the outcome of which will be compared with the expected result.&lt;/p&gt;
&lt;p&gt;If the expected and actual results match, then the test will pass. Otherwise,
Patrole can generate a detailed error message explaining which policies passed
to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rules&lt;/span&gt;&lt;/code&gt; caused test failure. For example, in the above example, if the
test role has permissions to perform “os_compute_api:os-lock-server:unlock” but
not “os_compute_api:os-lock-server:unlock:unlock_override”, then Patrole will
emit an error saying that “os_compute_api:os-lock-server:unlock:unlock_override”
was responsible for test failure. This will help cloud deployers and developers
to determine the source of test failure and to pinpoint inconsistent custom
policy configurations.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Currently, there are no other viable alternatives. It is not feasible or
desirable to repeatedly call each API endpoint against each policy action that
the endpoint enforces, for various fairly obvious reasons:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Code redundancy should be minimized, to make code readability and
maintenance easier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This introduces serious run time concerns in Patrole’s gates.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications Impact&lt;/h3&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOG&lt;/span&gt;&lt;/code&gt; statements will have to be updated to convey multiple policy actions
to the user, especially following test failure.&lt;/p&gt;
&lt;p&gt;If a Patrole test tests may policies, after test failure, it would be useful
for users for Patrole to log which policies caused the test failure. This can
be determined by iteratively calling &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;oslo.policy&lt;/span&gt;&lt;/code&gt; for each policy provided
to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbac_rule_validation&lt;/span&gt;&lt;/code&gt; decorator and storing the list of policies
that are not compatible with the role and the expected test outcome.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The performance impact is negligible. This change will result in barely
slower test run time, because multiple calls will be made to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;oslo.policy&lt;/span&gt;&lt;/code&gt;
rather than just one, per Patrole test.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other Deployer Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer Impact&lt;/h3&gt;
&lt;p&gt;The proposed change requires that developers be &lt;cite&gt;prudent&lt;/cite&gt; about which policy
actions they include in the proposed &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;actions&lt;/span&gt;&lt;/code&gt; parameter. Including an
excessively high number of policy actions is not maintainable and is
cumbersome from a development standpoint. For example, Cinder enforces
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_extension:volume_host_attribute&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;volume_extension:volume_mig_status_attribute&lt;/span&gt;&lt;/code&gt;, along with a number of
different policy actions, for many, many endpoints. Repeating these policy
actions for every Cinder RBAC test would be redundant and bad design.
(If it could be proven that these policy actions are enforced for &lt;em&gt;every&lt;/em&gt;
Cinder API endpoint, then the policy actions could be auto-injected by the
Patrole framework and logical-ANDed with the policy actions explicitly
specified in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;actions&lt;/span&gt;&lt;/code&gt;. However, this approach goes beyond the scope of this
spec).&lt;/p&gt;
&lt;p&gt;It is recommended that this enhancement be used &lt;em&gt;judiciously&lt;/em&gt; by developers.
Only endpoints that enforce multiple relatively &lt;em&gt;unique&lt;/em&gt; policy actions
should be included in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;actions&lt;/span&gt;&lt;/code&gt; list. Uniqueness can be inferred, for
example, from
&lt;a class="reference external" href="https://specs.openstack.org/openstack/keystone-specs/specs/keystone/pike/policy-in-code.html"&gt;Keystone’s&lt;/a&gt;
and
&lt;a class="reference external" href="https://specs.openstack.org/openstack/nova-specs/specs/newton/implemented/policy-in-code.html"&gt;Nova’s&lt;/a&gt;
self-documenting in-code policy definitions.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Felipe Monteiro &amp;lt;&lt;a class="reference external" href="mailto:felipe.monteiro%40att.com"&gt;felipe&lt;span&gt;.&lt;/span&gt;monteiro&lt;span&gt;@&lt;/span&gt;att&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Samantha Blanco &amp;lt;&lt;a class="reference external" href="mailto:samantha.blanco%40att.com"&gt;samantha&lt;span&gt;.&lt;/span&gt;blanco&lt;span&gt;@&lt;/span&gt;att&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rick Bartra &amp;lt;&lt;a class="reference external" href="mailto:rb560u%40att.com"&gt;rb560u&lt;span&gt;@&lt;/span&gt;att&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Enhance the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbac_rule_validation&lt;/span&gt;&lt;/code&gt; decorator with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;actions&lt;/span&gt;&lt;/code&gt; parameter
and deprecate the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rule&lt;/span&gt;&lt;/code&gt; parameter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write a helper function in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbac_rule_validation&lt;/span&gt;&lt;/code&gt; to iteratively call
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbac_policy_parser.RbacPolicyParser.allowed&lt;/span&gt;&lt;/code&gt; for each policy action
specified in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;actions&lt;/span&gt;&lt;/code&gt;, logically ANDing them together, and returning
the result to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rbac_rule_validation&lt;/span&gt;&lt;/code&gt; decorator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactoring tests to use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;actions&lt;/span&gt;&lt;/code&gt; instead of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;rule&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing new unit tests to test the proposed enhancement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Selectively adding multiple policy actions to some tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirming that all API tests work with the proposed enhancement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updating documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Patrole documentation should be updated to convey the new parameter along with
intended use, as described in this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/kilo/config-reference/content/policy-json-file.html"&gt;Policy terminology&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/keystone-specs/specs/keystone/pike/policy-in-code.html"&gt;Keystone policy in code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/nova-specs/specs/newton/implemented/policy-in-code.html"&gt;Nova policy in code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 13 Jun 2019 00:00:00 </pubDate></item><item><title>Add Swift API Tests for Icehouse</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/add-icehouse-swift-tests.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt;
&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="add-swift-api-tests-for-icehouse"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/add-icehouse-swift-tests"&gt;https://blueprints.launchpad.net/tempest/+spec/add-icehouse-swift-tests&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add Swift API tests which are added in Icehouse release (version 1.13.1)&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Between Havana and Icehouse releases, some new features are added in Swift.
However, Tempest currently has only subset of API tests of those features.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add API tests for following new functions.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;New-style container synchronization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Getting contents inline by TempURL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST request to delete multiple containers and objects in bulk&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PUT object with ‘If-None-Match: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;*&lt;/span&gt;&lt;/code&gt;’ header&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New file test_container_sync_middleware.py will be created to include tests
of new container synchronization. Test cases for other two features are added in
existing appropriate files.&lt;/p&gt;
&lt;p&gt;In new container sync feature, ‘realm’ and ‘cluster’ names are used in
“X-Container-Sync-To” header like
//&amp;lt;realm_name&amp;gt;/&amp;lt;cluster_name&amp;gt;/&amp;lt;account&amp;gt;/&amp;lt;container&amp;gt; to specify where to
synchronize objects as substitute for URL which is
used in old-style container sync. Realm and cluster names are defined
in Swift’s container-sync-realms.conf, therefore it is also necessary to
specify realm and cluster names in tempest.conf. Following two config values
must be added:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;realm_name&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;realm&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;cluster_name&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;cluster&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Daisuke Morita &amp;lt;&lt;a class="reference external" href="mailto:morita.daisuke%40lab.ntt.co.jp"&gt;morita&lt;span&gt;.&lt;/span&gt;daisuke&lt;span&gt;@&lt;/span&gt;lab&lt;span&gt;.&lt;/span&gt;ntt&lt;span&gt;.&lt;/span&gt;co&lt;span&gt;.&lt;/span&gt;jp&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-3&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Write test cases for Swift’s new functions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add config values to run tests of new-style container sync&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Working progress will be tracked in &lt;a class="reference external" href="http://goo.gl/qRLgZe"&gt;http://goo.gl/qRLgZe&lt;/a&gt; (Google Doc).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 13 Jun 2019 00:00:00 </pubDate></item><item><title>Consistent service method names</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/consistent-service-method-names.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/consistent-service-method-names"&gt;https://blueprints.launchpad.net/tempest/+spec/consistent-service-method-names&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Make service method names consistent&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Service clients are Tempest own REST clients for operating each OpenStack
project’s APIs. And  we have a plan to migrate service clients’ methods to
tempest-lib.
However these methods’ names are inconsistent, and it would be difficult
to use these methods from viewpoint of library users.
So we need to make these names consistent and set up the way to keep them
consistent before migrating.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Basically all methods’ names should be “&amp;lt;verb&amp;gt;_&amp;lt;resource/object name&amp;gt;”, not
“&amp;lt;resource/object name&amp;gt;_&amp;lt;verb&amp;gt;”.
There are following patterns we need to consider method names for REST API
methods.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;POST /resources        (Create a resource)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PUT /resources/&amp;lt;id&amp;gt;    (Update a resource)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DELETE /resources/&amp;lt;id&amp;gt; (Delete a resource)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /resources         (Get a list of resources)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /resources/&amp;lt;id&amp;gt;    (Get the detail information of a resource)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/tempest-consistent-service-method-names"&gt;https://etherpad.openstack.org/p/tempest-consistent-service-method-names&lt;/a&gt; is
an investigation of current method names. Based on the investigation, this
spec proposes consistent method names of each patterns. In addition, this
proposes hacking checks for keeping consistent method names. The patch
&lt;a class="reference external" href="https://review.openstack.org/168762"&gt;https://review.openstack.org/168762&lt;/a&gt; is a prototype for these hacking checks.
The details of them are following.&lt;/p&gt;
&lt;section id="post-resources"&gt;
&lt;h3&gt;POST /resources&lt;/h3&gt;
&lt;p&gt;Naming rule: “create_&amp;lt;resource name&amp;gt;”&lt;/p&gt;
&lt;p&gt;All creation methods follow this rule, so we don’t need to rename creation
methods. The hacking check of this rule is “If a method calls self.post(),
the method name should be create_&amp;lt;resource name&amp;gt;”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="put-resources-id"&gt;
&lt;h3&gt;PUT /resources/&amp;lt;id&amp;gt;&lt;/h3&gt;
&lt;p&gt;Naming rule: “update_&amp;lt;resource name&amp;gt;”&lt;/p&gt;
&lt;p&gt;All update methods follow this rule, so we don’t need to rename update methods.
The hacking check of this rule is “If a method calls self.put(), the method
name should be update_&amp;lt;resource name&amp;gt;”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="delete-resources-id"&gt;
&lt;h3&gt;DELETE /resources/&amp;lt;id&amp;gt;&lt;/h3&gt;
&lt;p&gt;Naming rule: “delete_&amp;lt;resource name&amp;gt;”&lt;/p&gt;
&lt;p&gt;There are two patterns for deletion method, “delete_&amp;lt;resource name&amp;gt;” and
“remove_&amp;lt;resource name&amp;gt;”. The number of “delete_&amp;lt;resource name&amp;gt;” is 72, and
the one of the other is 11. In addition, “delete_&amp;lt;resource name&amp;gt;” is simple
name because it is the same as HTTP method. The hacking check of this rule is
“If a method calls self.delete(), the method name should be delete_&amp;lt;resource
name&amp;gt;”.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="get-resources"&gt;
&lt;h3&gt;GET /resources&lt;/h3&gt;
&lt;p&gt;Naming rule: “list_&amp;lt;resource name&amp;gt;s”&lt;/p&gt;
&lt;p&gt;There are three patterns for listing resources, “list_&amp;lt;resource name&amp;gt;s”,
“get_&amp;lt;resource name&amp;gt;_list” and “&amp;lt;resource name&amp;gt;_list”. The number of the
first is 115, the one of the second is 3 and the one of the third is 2.&lt;/p&gt;
&lt;p&gt;Some Nova APIs provide a resource list with detail information like
‘os-hypervisors/detail’ and ‘os-availability-zone/detail’. These method names
are get_hypervisor_list_details and get_availability_zone_list_detail now.
This spec proposes these methods are merged to this naming rule like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;list_availability_zones&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'os-availability-zone'&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s1"&gt;'/detail'&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;..&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;by adding the argument detail.
“GET /resources” and “GET /resources/&amp;lt;id&amp;gt;” call the same method self.get()
for sending a request to servers. So it is difficult to check the methods
which call self.get() should be based on rules of “GET /resources” or “GET
/resources/&amp;lt;id&amp;gt;”. Then this spec proposes the same hacking check for
“GET /resources” or “GET /resources/&amp;lt;id&amp;gt;”. That means the hacking check is
“If a method calls self.get(), the method name should be show_&amp;lt;resource name&amp;gt;
or list_&amp;lt;resource name&amp;gt;s.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="get-resources-id"&gt;
&lt;h3&gt;GET /resources/&amp;lt;id&amp;gt;&lt;/h3&gt;
&lt;p&gt;Naming rule: “show_&amp;lt;resource name&amp;gt;”&lt;/p&gt;
&lt;p&gt;There are two patterns for getting the detail of a resource, “show_&amp;lt;resource
name&amp;gt;” and “get_&amp;lt;resource name&amp;gt;”. The number of the first is 12, and the one
of the second is 126. So the number of the second is bigger.
However, this spec proposes all “GET /resources/&amp;lt;id&amp;gt;” methods should be named
to “show_&amp;lt;resource name&amp;gt;” because of clarifying differences from methods which
are for “GET /resources”. There are methods for “GET /resources” also and some
resource names are the same between a single noun and multiple nouns like
“chassis”. So it is better to avoid using “get_&amp;lt;resource name&amp;gt;” for clarifying
the method behavior. The hacking check of this rule is mentioned at the above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="separate-service-client-modules-for-each-resource"&gt;
&lt;h3&gt;Separate service client modules for each resource&lt;/h3&gt;
&lt;p&gt;Some service clients contain the methods for multiple resources in a single
module. For example, server_client module contains the methods for “/servers”
and “/server_groups”. Current separation of modules are inconsistent, and
this spec proposes all service client modules will be separated into a single
module by each resource.
In addition, current modules of service clients contain “JSON” in these names
but we need to remove them. Because current service clients supports JSON only
and “JSON” in these names are meaningless now.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ken’ichi Ohmichi &amp;lt;&lt;a class="reference external" href="mailto:oomichi%40mxs.nes.nec.co.jp"&gt;oomichi&lt;span&gt;@&lt;/span&gt;mxs&lt;span&gt;.&lt;/span&gt;nes&lt;span&gt;.&lt;/span&gt;nec&lt;span&gt;.&lt;/span&gt;co&lt;span&gt;.&lt;/span&gt;jp&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Masayuki Igawa &amp;lt;&lt;a class="reference external" href="mailto:igawa%40mxs.nes.nec.co.jp"&gt;igawa&lt;span&gt;@&lt;/span&gt;mxs&lt;span&gt;.&lt;/span&gt;nes&lt;span&gt;.&lt;/span&gt;nec&lt;span&gt;.&lt;/span&gt;co&lt;span&gt;.&lt;/span&gt;jp&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Liberty&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rename service clients’ methods based on this proposal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rename service clients’ classes based on this proposal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Separate service clients’ modules per resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add hacking rules based on this proposal.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We have discussed this working items at Vancouver Summit.
The log is &lt;a class="reference external" href="https://etherpad.openstack.org/p/YVR-QA-Tempest-service-clients"&gt;https://etherpad.openstack.org/p/YVR-QA-Tempest-service-clients&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 13 Jun 2019 00:00:00 </pubDate></item><item><title>Improve IPv6 API testing parity in tempest</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/ipv6-api-testing-parity.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/ipv6-api-testing-parity"&gt;https://blueprints.launchpad.net/tempest/+spec/ipv6-api-testing-parity&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Current tempest API tests do not validate IPv6 to the same extent
as IPv4.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;IPv6 is evolving in Neutron and the community is working hard to add the
necessary support. However, the current API tests in tempest do not
validate IPv6 to the same extent as IPv4.&lt;/p&gt;
&lt;p&gt;Also, Neutron now supports two extended attributes for IPv6 subnets
(ipv6-ra-mode and ipv6-address-mode) in the Juno timeframe.&lt;/p&gt;
&lt;p&gt;This BP would add the necessary IPv6 tests in tempest.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Neutron BP: IPv6 Subnet attributes are implemented as part of the following BP
- &lt;a class="reference external" href="https://blueprints.launchpad.net/neutron/+spec/ipv6-two-attributes"&gt;https://blueprints.launchpad.net/neutron/+spec/ipv6-two-attributes&lt;/a&gt;&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The possible values for the subnet attributes are as follows.&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ipv6-ra-mode {dhcpv6-stateful, dhcpv6-stateless, slaac}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ipv6-address-mode {dhcpv6-stateful, dhcpv6-stateless, slaac}&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;The two IPv6 attributes provide flexibility to choose the type of IPv6 network.
However, not all combinations of the two attributes are valid. Valid and
invalid combinations are captured in the Neutron ipv6-provider-nets-slaac.rst
blueprint and also at the following link.
- &lt;a class="reference external" href="https://www.dropbox.com/s/9bojvv9vywsz8sd/IPv6%20Two%20Modes%20v3.0.pdf"&gt;https://www.dropbox.com/s/9bojvv9vywsz8sd/IPv6%20Two%20Modes%20v3.0.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Along with test cases related to subnet attributes, this BP would implement
new test cases in tempest to bring in parity between IPv4 and IPv6 tests.
To start with, new tests would be required in Neutron for
Ports/Security-Groups/Subnets/FWaaS api tests.&lt;/p&gt;
&lt;p&gt;The following etherpad link would be used to track all the test cases.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/ipv6-api-testing-parity"&gt;https://etherpad.openstack.org/p/ipv6-api-testing-parity&lt;/a&gt;&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Sridhar Gaddam &amp;lt;&lt;a class="reference external" href="mailto:sridhargaddam%40enovance.com"&gt;sridhargaddam&lt;span&gt;@&lt;/span&gt;enovance&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sean M. Collins &amp;lt;&lt;a class="reference external" href="mailto:sean_collins2%40cable.comcast.com"&gt;sean_collins2&lt;span&gt;@&lt;/span&gt;cable&lt;span&gt;.&lt;/span&gt;comcast&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno release&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The work items include IPv6 API test cases like&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Subnet test cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port operations including Bulk operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security Groups and Rules - &lt;a class="reference external" href="https://review.openstack.org/#/c/94130"&gt;https://review.openstack.org/#/c/94130&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FWaaS test cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validating if Neutron calculates and assigns IPv6 addresses properly
(i.e., based on EUI-64 where applicable).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Any new test cases related to the same topic would be tracked using the following
external etherpad link.
&lt;a class="reference external" href="https://etherpad.openstack.org/p/ipv6-api-testing-parity"&gt;https://etherpad.openstack.org/p/ipv6-api-testing-parity&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Neutron IPv6 Subnet attributes (ipv6-ra-mode and ipv6-address-mode) are added
in the Juno+ timeframe for selecting the type of IPv6 network.
Hence, a config flag needs to be added to tempest to skip the tests while
running on icehouse jobs.  The required changes in tempest would be addressed
as part of BP ipv6-subnet-attributes.rst.
&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/ipv6-subnet-attributes"&gt;https://blueprints.launchpad.net/tempest/+spec/ipv6-subnet-attributes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Similarly, devstack needs to populate the flag during the setup. The required
changes in devstack would be addressed as part of the following BP.
&lt;a class="reference external" href="https://blueprints.launchpad.net/devstack/+spec/tempest-ipv6-attributes-support"&gt;https://blueprints.launchpad.net/devstack/+spec/tempest-ipv6-attributes-support&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron: Support Router Advertisement Daemon (radvd) for IPv6
&lt;a class="reference external" href="https://review.openstack.org/#/c/101306/"&gt;https://review.openstack.org/#/c/101306/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Neutron: Support for IPv6 dhcpv6-stateless and dhcpv6-statefull modes in Neutron.
&lt;a class="reference external" href="https://review.openstack.org/#/c/102411/"&gt;https://review.openstack.org/#/c/102411/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 13 Jun 2019 00:00:00 </pubDate></item><item><title>Keystone v3 based check and gate jobs</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/keystone-v3-jobs.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt; &lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="keystone-v3-based-check-and-gate-jobs"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/keystone-v3-jobs"&gt;https://blueprints.launchpad.net/tempest/+spec/keystone-v3-jobs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Check and gate jobs using keystone V3&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;All check and gate jobs at the moment rely on keystone v2 as identity
service.  Blueprint multi-keystone-api-version-tests introduces in tempest
the ability to run tests relying on keystone V3 API only.
The version of the keystone API to be used is controlled via a configuration
flag. Dedicated jobs are requied to exercise the V3 option, in preparation
for keystone V2 deprecation planned for Juno.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Setup keystone v3 jobs to be run initially as experimental only.
They will be promoted then to check and eventually gate.&lt;/p&gt;
&lt;p&gt;Running fully v3 jobs is beyond the scope of tempest and infrastructure
alone, as it requires changes in other OpenStack projects:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;python bindings to either support keystone v3 API or consume Keystone
Client Session Objects (see &lt;a class="reference external" href="http://www.jamielennox.net/blog/2014/02/24/client-session-objects/"&gt;http://www.jamielennox.net/blog/2014/02/24/client-session-objects/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;core services to be integrated with keystone v3 model and API
Such changes are defined in details in dedicated blueprints.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As dependencies will be implemented in Juno, it won’t be possible
to run full v3 jobs against Icehouse. The keystone v3 jobs can still
be used against icehouse, with the limitation that only the authentication
of tempest clients and creation of isolated user and projects will be
based on the v3 API.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;It would be possible to run all tests via v2 and v3 in parallel.
However this would significantly increase the gate duration.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Andrea Frittoli &amp;lt;&lt;a class="reference external" href="mailto:andrea.frittoli%40hp.com"&gt;andrea&lt;span&gt;.&lt;/span&gt;frittoli&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-final&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Define a localrc variable in devstack for auth_version=v3&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define an option in devstack-gate to setup the localrc variable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define two jobs in the experimental pipeline for tempest:
dsvm-keystonev3-full and dsvm-neutron-keystonev3-full&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Track the progress of dependencies, and enhance jobs accordingly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the jobs on demand until all issues are fixed and results are stable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Promote the jobs to check for tempest&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Promote the jobs to check for all projects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Promote the jobs to gate&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;A fully v3 check job depends on having v3 support in a number of places&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;tempest framework and its tests &lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/multi-keystone-api-version-tests"&gt;https://blueprints.launchpad.net/tempest/+spec/multi-keystone-api-version-tests&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;official python bindings and CLI tools&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack services&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The current jobs will only be partially v3 until all dependencies are met.
The migration strategy from identity API v2 to v3 will be documented as part of
&lt;a class="reference external" href="https://blueprints.launchpad.net/keystone/+spec/document-v2-to-v3-transition"&gt;https://blueprints.launchpad.net/keystone/+spec/document-v2-to-v3-transition&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 13 Jun 2019 00:00:00 </pubDate></item><item><title>Multiple strategies for ssh access to VMs</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/ssh-auth-strategy.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt; &lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="multiple-strategies-for-ssh-access-to-vms"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/ssh-auth-strategy"&gt;https://blueprints.launchpad.net/tempest/+spec/ssh-auth-strategy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Different strategies for ssh access to VMs in tests.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Ssh access to created servers is in several cases key to properly validate the
result of an API call or a scenario (use case) test. This is true for compute
but not limited to it. Network and volume verification must often rely on test
servers, and ssh access to the VM helps significantly for the verification.&lt;/p&gt;
&lt;p&gt;Support for ssh access to VMs in tempest tests is both heterogeneous as well
as incomplete. Not all tests honour the same config options. The existing
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;run_ssh&lt;/span&gt;&lt;/code&gt; option is only taken into account by some of the tests, the compute
API ones. Not all tests use the same strategy for ssh access, and several tests
do not perform any ssh verification at all. The reason often is that ssh
verification is a common source of “flakiness” and timeouts in tests, and
allocation of the resources required for ssh verification can be expensive.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Consolidate the available configuration options and make sure they are
honoured everywhere. Configuration shall be declaritive, i.e. tempest users
shall configure how they expect ssh to work, and if that’s not compatible
with the deployed cloud tempest shall raise an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;InvalidConfiguration&lt;/span&gt;&lt;/code&gt;.
Improve the configuration help text to guide configuration for instance
validation.&lt;/p&gt;
&lt;p&gt;Current configuration options relevant to instance validation are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.auth.allow_tenant_isolation&lt;/span&gt;&lt;/code&gt;: affects the fixed network name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.[image|image_alt]_ssh_user&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.image_ssh_password&lt;/span&gt;&lt;/code&gt;: not image specific, and it’s used
by only two tests, without checking against the ssh_auth_method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.image_alt_ssh_password&lt;/span&gt;&lt;/code&gt;: unused&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.run_ssh&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.ssh_auth_method&lt;/span&gt;&lt;/code&gt;: used for resource setup by API compute
tests, but not honoured by the tests. The image[_alt]_ssh_[user|password]
settings are  meant to be used when this is set to “configured”.
At the moment it is not enforced nor documented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.ssh_connect_method&lt;/span&gt;&lt;/code&gt;: used for resource setup by API
compute tests, not honoured by the tests. When set to floating, it
should be verified that a floating IP range is configured&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.ssh_user&lt;/span&gt;&lt;/code&gt;: currently used for ssh verification by most
API and scenario tests, which is a problem because configuration supports
different images, each with an own ssh user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.ping_timeout&lt;/span&gt;&lt;/code&gt;: used by scenario test only&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.ssh_timeout&lt;/span&gt;&lt;/code&gt;: used by RemoteClient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.ssh_channel_timeout&lt;/span&gt;&lt;/code&gt;: used by RemoteClient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.fixed_network_name&lt;/span&gt;&lt;/code&gt;: used by API and scenario tests.
It’s the name of the network for the primary IP with nova networking;
or with neutron networking when tenant isolation is disabled.
The logic, as implemented by test_list_server_filters shall be moved
to an helper and reused everywhere. It may be used for ssh validation
only if floating IPs are disabled&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.network_for_ssh&lt;/span&gt;&lt;/code&gt;: used by RemoteClient and some scenario
tests to discover an IP for ssh validation. It can be used if floating
IP for ssh is disabled, in which case the fixed_network_name could be
used as well; except for the case of multi-nic testing, which would
require more logic anyways to enable the 2nd nic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.ip_version_for_ssh&lt;/span&gt;&lt;/code&gt;: used by &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RemoteClient&lt;/span&gt;&lt;/code&gt;.
It should be overridable via parameter instead of one config for all
tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.use_floatingip_for_ssh&lt;/span&gt;&lt;/code&gt;: used by some scenario tests,
duplicate of ssh_connect_method, which is not used at the moment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.compute.path_to_private_key&lt;/span&gt;&lt;/code&gt;: unused&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.network.tenant_network_reachable&lt;/span&gt;&lt;/code&gt;: used by scenario tests. In
some cases it’s used for tests that want to verify both tenant and
public network connectivity. In other cases it’s used to find out which
IP to be used for instance validation, which overlaps with the
ssh_connect_method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.network.public_network_id&lt;/span&gt;&lt;/code&gt;: used for allocation of floating
IPs when neutron is enabled.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Target configuration shall include a new group “validation” used for all
option related to validation of API call results, and the following options:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.validation.connect_method&lt;/span&gt;&lt;/code&gt;: default ssh method. Tests may
still use different method if they want to do so (fixed or floating)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.validation.auth_method&lt;/span&gt;&lt;/code&gt;: default auth method. Tests may
still use a different method if they want to do so (only ssh key
supported for now). Additional methods will be handled in a
separate spec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.validation.ip_version_for_ssh&lt;/span&gt;&lt;/code&gt;: default IP version for ssh&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.validation.*timeout&lt;/span&gt;&lt;/code&gt; (for ping, connect and ssh)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.*.*ssh_user&lt;/span&gt;&lt;/code&gt; (for the various images available)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.network.fixed_network_name&lt;/span&gt;&lt;/code&gt;: default fixed network name; this
parameter is only valid in case of nova network (with flat networking),
and for now with pre-provisioned accounts. Once the bp
test-accounts-continued is implemented this may still be used as
default fixed network name if not specified in accounts.yaml.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.network.floating_network_name&lt;/span&gt;&lt;/code&gt;: default floating network name,
used to allocate floating IPs when neutron is enabled. Deprecates
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.network.public_network_id&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CONF.network.tenant_network_reachable&lt;/span&gt;&lt;/code&gt;: used when the configured
ssh_connect_method is “fixed”. If this is set to false raise an
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;InvalidConfiguration&lt;/span&gt;&lt;/code&gt; exception&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Configuration options that are renamed or that planned for removal
should go through the deprecation process.&lt;/p&gt;
&lt;p&gt;A few options are image specific: image name, ssh user / password,
typical time to boot / ssh.
Such options would be better handled in a dedicated images.yaml file
rather than in tempest.conf. This will be handled in a separate spec.&lt;/p&gt;
&lt;p&gt;Define an helper functions that read, validate and process the
configuration, which in future will help decoupling
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_test_server&lt;/span&gt;&lt;/code&gt; from CONF, for migration to tempest-lib.&lt;/p&gt;
&lt;p&gt;Extend the existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RemoteClient&lt;/span&gt;&lt;/code&gt; to provide tools for:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ping: attempts a single ping to a target to server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;connect: attempts a single TCP connect on a generic port to a target server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ssh: attempts a single ssh connection to a target server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;validaton: validates a server by using a configurable sequence of the above;
cares about retries and timeouts&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bits of implementation for that are already available in scenario
tests. They should be consolidated in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;RemoteClient&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Define a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;validation_resources&lt;/span&gt;&lt;/code&gt; function, similar to the existing
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_resources&lt;/span&gt;&lt;/code&gt;, to be used in the class level &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_setup&lt;/span&gt;&lt;/code&gt;,
which allocates required reusable resources, such as: a key pair, a
security group with rules in it, and a floating ip. It returns all the
resources in form of a dict, ready to be used in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_test_server&lt;/span&gt;&lt;/code&gt;.
Tests which use more than one server will allocated additional floating
IPs on demand. Once bp test-accounts-continued is implemented as well
we may consider consolidating &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;validation_resources&lt;/span&gt;&lt;/code&gt; and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;network_resources&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Centralize &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_test_server&lt;/span&gt;&lt;/code&gt;, and make sure all tests use
this central implementation. Add the following features:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;it includes an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sshable&lt;/span&gt;&lt;/code&gt; boolean parameter in the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;create_test_server&lt;/span&gt;&lt;/code&gt;
helper function, defaults to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;False&lt;/span&gt;&lt;/code&gt;. If set to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; it ensures the
server is created with all the required resources associated, e.g. that it
has a public key injected, and IP address on a public network, a security
group that allows for ICMP and ssh communication. The default to false
ensures that resources are used only when required.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;it accepts a resources dict with reusable items, which can be: a key_name,
a security_group with rules for ssh and icmp in, a floating_ip. These are
passed in as parameters in preparation for the migration to tempest-lib.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;it extends the valid value for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;wait_until&lt;/span&gt;&lt;/code&gt; with new types of wait
abilities: &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PINGABLE&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SSHABLE&lt;/span&gt;&lt;/code&gt;. For instance if an &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SSHABLE&lt;/span&gt;&lt;/code&gt;
server is requested the create method takes care of performing basic ssh
validation as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;it returns a tuple &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;(created_server,&lt;/span&gt; &lt;span class="pre"&gt;remote_client)&lt;/span&gt;&lt;/code&gt;, where the remote
client is already initialized with access resources such as public key,
admin password, IP address, ssh account name.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_test_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wait_until&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sshable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sshable&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;run_ssh&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="n"&gt;helpers&lt;/span&gt;
        &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extend&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;but&lt;/span&gt; &lt;span class="n"&gt;do&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;override&lt;/span&gt;
            &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key_name&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;defined&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;resources&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;
            &lt;span class="n"&gt;sg&lt;/span&gt; &lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;sg&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;rules&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;append&lt;/span&gt;
            &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;append&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;network&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;
            &lt;span class="n"&gt;floating&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;resources&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;allocate&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt;
        &lt;span class="n"&gt;validation&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servers_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;wait&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ip_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'floating'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;attach&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
         &lt;span class="n"&gt;build&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;helpers&lt;/span&gt; &lt;span class="n"&gt;above&lt;/span&gt;
         &lt;span class="n"&gt;remote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RemoteClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="n"&gt;wait&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ping&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;connect&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;ssh&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;remote&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;myvm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;servers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_test_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;sshable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wait_until&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'SSHABLE'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;myvm&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'remote_client'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write_to_console&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"I could do something more useful"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A server can still be made ssh-able “by-hand” for more complex scenarios, such
as hot-plug tests, where the server may only be connected at a later stage to
a public network.&lt;/p&gt;
&lt;p&gt;In case a test class contains tests which make use of ssh-able servers, network
resources must be prepared for the tenant (if not yet available), so that it
is possible to have network access to the VM.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;As run_ssh is currently disabled, an alternative could be to completely
drop ssh verification from API tests. However a number of cases cannot really
be verified unless ssh verification is on (e.g. reboot, rebuild, config drive).&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Andrea Frittoli &amp;lt;&lt;a class="reference external" href="mailto:andrea.frittoli%40hp.com"&gt;andrea&lt;span&gt;.&lt;/span&gt;frittoli&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Nithya Ganesan &amp;lt;&lt;a class="reference external" href="mailto:nithya.ganesan%40hp.com"&gt;nithya&lt;span&gt;.&lt;/span&gt;ganesan&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;,
Joseph Lanoux &amp;lt;&lt;a class="reference external" href="mailto:joseph.lanoux%40hp.com"&gt;joseph&lt;span&gt;.&lt;/span&gt;lanoux&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Kilo-2&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Introduce new configuration options, and helpers to read them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a validation_resources function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create shared create_test_server function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create shared ssh verification function / extend RemoteClient&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrate tests to the new format (multiple patches)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deprecate un-used / removed configuration options&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup experimental / periodic jobs that run with validation
enabled - the aim is to promote both run_ssh and sshable to
be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;True&lt;/span&gt;&lt;/code&gt; by default, as well maintain the code path healthy
until that happens&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 13 Jun 2019 00:00:00 </pubDate></item><item><title>Tempest Run Command</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/tempest-run-cmd.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/tempest-run-cmd"&gt;https://blueprints.launchpad.net/tempest/+spec/tempest-run-cmd&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Describes a domain-specific &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest&lt;/span&gt; &lt;span class="pre"&gt;run&lt;/span&gt;&lt;/code&gt; command to be used as the primary
entry point for running Tempest tests.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;There are a wide range of Tempest use cases ranging from OpenStack gate
testing to the testing of existing public and private clouds across multiple
environments and configurations. Each of these user scenarios has its own
requirements and challenges.&lt;/p&gt;
&lt;p&gt;Currently, tempest doesn’t actually control it’s own execution. It instead
relies on an external test runner, it does not provide a consistent experience
for consumers of Tempest. Users also often have impression that tempest
controls it’s own execution. In addition, because these test runners are in no
way specific to Tempest any, items that are domain specific (such as
configuration) must be performed out-of-band using shell scripts or other means.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Since an effort is already underway to create a set of Tempest-specific
command line tooling, this spec further defines a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest&lt;/span&gt; &lt;span class="pre"&gt;run&lt;/span&gt;&lt;/code&gt; command.
This spec addresses the following problems:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Providing a flexible runner that enables multiple approaches to the test
discovery and execution processes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Facilitating ease of configuration and execution of Tempest across multiple
environments and configurations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Builds on testrepository directly in order to leverage current and future
testrepository capabilities&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This spec outlines the beginning steps and basic functionality of the initial
implementation of the run command. It is expected that the functionality of run
will grow over time to suit the needs of tempest in the future.&lt;/p&gt;
&lt;p&gt;The command implementation can be broken down into three components:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Converting the selection regex logic from ostestr into a reusable module&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A command line interface that users will interact with&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A client that drives the execution of tests by interfacing directly with
testrepository&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The logical flow of the proposed test runner is as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Parse any command line arguments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set necessary environment variables for Tempest based on inputs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Determine the set of tests to run using ostestr regex builder&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call into testrepository with the testr-specific arguments&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Receive the results from test execution&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perform any post-processing on the test results, if applicable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="command-line-interface"&gt;
&lt;h3&gt;Command Line Interface&lt;/h3&gt;
&lt;p&gt;The list of proposed command line arguments are as follows:&lt;/p&gt;
&lt;p&gt;Test Execution:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;parallel&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;serial&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;workers&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;workers&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Test Selection and Discovery:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;whitelist&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;exclude&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;blacklist&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;Sample&lt;/span&gt; &lt;span class="n"&gt;regex&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;tempest&lt;/span&gt;\&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Comments about this regex&lt;/span&gt;
      &lt;span class="n"&gt;tempest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scenario&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_server_basic_ops&lt;/span&gt; &lt;span class="c1"&gt;# Matches this test explicitly&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Aliases for most commonly used regexes:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;smoke&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By default the regex will run the equivalent of the full jobs in tox. (running
everything but tests tagged as slow)&lt;/p&gt;
&lt;p&gt;Output:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;subunit&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;By default the console output will be output from subunit-trace&lt;/p&gt;
&lt;p&gt;Tempest Configuration:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Part of having tempest run having domain specific knowledge is that it’s aware
of tempest workspaces and when running in it. However, workspaces aren’t a
requirement for actually running tempest, and there is are existing workflows
where you have a separate tempest config file. (which previously could only
be specified by environment variables) This option is providing an easier to
use place on the CLI for doing this. This is a key advantage of having tempest
own it’s runner is that it provides another place for passing this type of
information into tempest which we previously could only do via env vars or the
config file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testrepository-integration"&gt;
&lt;h3&gt;Testrepository Integration&lt;/h3&gt;
&lt;p&gt;One of the goals of this spec is to develop an entry point from Tempest
that integrates directly with testrepository rather than calling out to
testr via subprocess. This integration is a more robust design that
allows new features in testrepository to propagate more easily to the Tempest
runner. Inversely, as the Tempest runner evolves, features that would be
useful to any test runner can be pushed down the stack into testrepository.&lt;/p&gt;
&lt;p&gt;The planned integration point of the tempest run command with testrepository
is the &lt;a class="reference external" href="https://github.com/testing-cabal/testrepository/blob/master/testrepository/commands/__init__.py#L165"&gt;CLI UI for testr&lt;/a&gt;. However, this only one possible approach. The
final solution is likely to evolve during development.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="projects"&gt;
&lt;h2&gt;Projects&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;openstack/tempest&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extract the regex building logic from ostestr into an externally consumable
module&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest&lt;/span&gt; &lt;span class="pre"&gt;run&lt;/span&gt;&lt;/code&gt; entry point in Tempest using cliff&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handle setup of Tempest specific options such as Tempest configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement test selection logic using the ostestr bits and based on the
provided filtering options (regexes, tags, etc.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:
- mtreinish
- slowrie&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Newton-2&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/newton-qa-tempest-cli"&gt;Newton Design Summit CLI Session&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/mitaka-qa-tempest-run-cli"&gt;Mitaka Design Summit CLI Session&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Previous Implementations and Specs&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/os-testr/blob/master/os_testr/os_testr.py"&gt;os-testr runner&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/197378/8/tempest/cmd/run.py"&gt;Prototype by mtreinish&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/qa-specs/blob/master/specs/tempest/tempest-cli-improvements.rst"&gt;Previous Tempest CLI spec&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 13 Jun 2019 00:00:00 </pubDate></item><item><title>Whitebox Tempest Plugin</title><link>https://specs.openstack.org/openstack/qa-specs/specs/other/whitebox-tempest-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/whitebox-tempest-plugin"&gt;https://blueprints.launchpad.net/tempest/+spec/whitebox-tempest-plugin&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Tempest defines its scope as only what is accessible through the various REST
APIs. Some cloud features cannot be properly tested when using only the REST
API. For example, in the context of Nova using the libvirt driver, certain
features can only be fully tested by examining the XML of the instances.
Specifically, live-migrating an instance with dedicated CPUs can appear to
succeed, while in actuality the live migration has caused the instance to no
longer have dedicated CPUs. Only by looking at the instance’s XML can we
validate that the dedicated CPU SLA has been respected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The whitebox-tempest-plugin is a Tempest plugin whose scope explicitly requires
peeking behind the curtain. In other words, if a feature or behavior can be
fully tested using only a REST API, such a test does not belong in
whitebox-tempest-plugin. On the other hand, if fully testing a feature or
behavior requires accessing the control plane like a human operator or admin
would, such a test belongs in whitebox-tempest plugin.&lt;/p&gt;
&lt;p&gt;The plugin provides a framework for tests to look behind the curtain. It
currently contains Tempest-style clients that can examine an instance’s XML,
examine the database, read and write INI configuration options, and restart
services. All of these are used by tests that are concentrated around Nova NFV
features like CPU pinning and NUMA-aware live-migration.&lt;/p&gt;
&lt;p&gt;While currently heavily centered on Nova and NFV, whitebox-tempest-plugin aims
to be useful for testing any OpenStack project.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;While various team-specific or project-specific Tempest plugins exist whose
scope sometimes intersects with whitebox-tempest-plugin, the whitebox testing
use case does not currently have an alternative community solution.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="projects"&gt;
&lt;h2&gt;Projects&lt;/h2&gt;
&lt;p&gt;Whitebox-tempest-plugin is self-contained. It includes a devstack plugin to add
whitebox-specific options to tempest.conf.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;The current whitebox-tempest-plugin team is composed of Joe Hakim Rahme (rahmu),
Sean Mooney (sean-k-mooney) and Artom Lifshitz (notartom).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;Ussuri.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The current roadmap consists of:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Start using whitebox-tempest-plugin in the Nova NFV Zuul job.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whitebox supports undercloud/overcloud TripleO deployments, but there is no
upstream CI coverage for this. Work is in progress to add a TripleO CI job.
The new job will use a multinode standalone TripleO deployment, which is also
in the process of being developed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Whitebox requires the following Python modules:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;sshtunnel (needed to access the overcloud database, will be dropped once the
TripleO CI job is done, as a standalone TripleO deployment does not have the
undercloud/overcloud distinction).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;pymysql (needed to intereact with the database)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Nova NFV Zuul job: &lt;a class="reference external" href="https://review.opendev.org/#/c/679656/"&gt;https://review.opendev.org/#/c/679656/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TripleO CI job:  &lt;a class="reference external" href="https://review.opendev.org/#/c/705113/"&gt;https://review.opendev.org/#/c/705113/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 May 2019 00:00:00 </pubDate></item><item><title>Increase the number of scenario tests for Neutron</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/neutron-advanced-scenarios.html</link><description>&lt;dl&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This work is licensed under a Creative Commons Attribution 3.0 Unported
License.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://creativecommons.org/licenses/by/3.0/legalcode"&gt;http://creativecommons.org/licenses/by/3.0/legalcode&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="increase-the-number-of-scenario-tests-for-neutron"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/neutron-advanced-scenarios"&gt;https://blueprints.launchpad.net/tempest/+spec/neutron-advanced-scenarios&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Increase the number and coverage of scenario tests in Tempest for Neutron.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently there is a limited number of scenario tests in Tempest for Neutron.
Attempts have been made in the recent past to increase this number. However,
these efforts have not been very effective due to the following factors:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A very small number of developers currently contributing code for Neutron
scenario tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The lack of a structured process to make sure developers achieve progress.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Under this blueprint, a structured process will be followed with the overall
goal of creating a community of engaged and well supported scenario tests
developers. This process consists of the following steps:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;A “How to develop scenario tests for Neutron” tutorial will be developed as
an extension to the &lt;a class="reference external" href="https://docs.openstack.org/tempest/latest/field_guide/scenario.html"&gt;Tempest documentation&lt;/a&gt;.
This tutorial will include clear and strict guidelines for documentation and
logging. On one hand, each test is unique, and complex operations will most
likely be included in supporting methods or shared between modules, so
documentation should provide sufficient information about the test for
people outside the Tempest or Neutron efforts, hopefully even for “simple”
users who will use the scenarios to test their deployment. On the other
hand, tests operation should be logged in detail so it is clear what
progress and operations took place prior to any failure that might arise.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A set of scenario tests will be well specified taking as a starting point
the result of the design summit in Atlanta and captured at the
&lt;a class="reference external" href="https://etherpad.openstack.org/p/TempestAndNeutronJuno"&gt;Juno design summit etherpad&lt;/a&gt;. The
specification of these scenarios will be done in close cooperation with the
Neutron core team. The specification of each scenario will include a list
of people with expertise to support the test developer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A message will be sent to the openstack-dev mailing list inviting developers
to select one of the scenarios specified at the &lt;a class="reference external" href="https://etherpad.openstack.org/p/TempestAndNeutronJuno"&gt;Juno design summit etherpad&lt;/a&gt;. Developers will
assign themselves to the scenarios they have interest on by signing their
name next to the corresponding specification in the above mentioned
etherpad.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Progress will be tracked for each scenario on a weekly basis.&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The main goal of this tracking is to make sure developers are getting
the support they need.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tracking will insure developers get prompt reviews from Neutron and
Tempest cores.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Progress will be discussed at the Neutron and Tempest weekly IRC
meetings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The tracking will be kept at the &lt;a class="reference external" href="https://etherpad.openstack.org/p/TempestAndNeutronJuno"&gt;Juno design summit etherpad&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test owners will be designated. Owners will be in charge of maintaining the
code, debug future failures, enhancing code documentation and logging, as
well as providing reasonable support for relevant questions (though adequate
docs should minimize such questions), thus easing new contributors into the
community&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The tests developed as result of this process will reside in the tempest tree
hierarchy at tempest/scenario&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Miguel Lavalle &amp;lt;&lt;a class="reference external" href="mailto:miguel%40mlavalle.com"&gt;miguel&lt;span&gt;@&lt;/span&gt;mlavalle&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-3&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create tutorial on Tempest scenario tests for Neutron: Juno-1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create specification of scenarios to develop: Juno-1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send message to openstack-dev inviting developers to review tutorial and
select scenarios to implement: Juno-1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Merge new Neutron scenarios to Tempest tree: Juno-3&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Mon, 24 Sep 2018 00:00:00 </pubDate></item><item><title>Tempest CLI Improvements</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/tempest-cli-improvements.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/tempest-cli-improvements"&gt;https://blueprints.launchpad.net/tempest/+spec/tempest-cli-improvements&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Make the Tempest CLI design more consistent and intuitive by utilizing the
setuptools and cliff python libraries.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;There are currently some Tempest CLI endpoints created when tempest is
installed but there is no consistency in the console command names or function.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Create an intuitive set of CLI endpoints for Tempest.&lt;/p&gt;
&lt;section id="add-cliff-support-to-tempest"&gt;
&lt;h3&gt;Add cliff Support to Tempest&lt;/h3&gt;
&lt;p&gt;Cliff enables creation of console scripts by using a clean class
structure for building applications and commands.&lt;/p&gt;
&lt;p&gt;See: &lt;a class="reference external" href="https://pypi.org/project/cliff/"&gt;https://pypi.org/project/cliff/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For example setup.cfg would have:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;entry_points&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;console_scripts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tempest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="n"&gt;tempest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;cleanup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tempest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;CleanupCmd&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and tempest.cmd.main would look something like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cliff.app&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;App&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cliff.commandmanager&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CommandManager&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cliff.command&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Command&lt;/span&gt;
&lt;span class="c1"&gt;# ...&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Tempest cli application'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'0.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;command_manager&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CommandManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'tempest.cm'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize_app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'tempest initialize_app'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;prepare_to_run_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'prepare_to_run_command &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__class__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clean_up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Tempest app clean_up &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__class__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Tempest error: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# A sample command implementation would look like:&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CleanupCmd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Utility for cleaning up ..."&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_parser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prog_name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CleanupCmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_parser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prog_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'--init-saved-state'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"store_true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'init_saved_state'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Init help..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# More args ...&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;take_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;cu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Cleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Cleanup Done!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="s1"&gt;'setup.py install'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;

    &lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;saved&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="proposed-command-structure"&gt;
&lt;h3&gt;Proposed command structure&lt;/h3&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt;
    &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dry&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;saved&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tempest&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;

&lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;
    &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;TBD&lt;/span&gt;

&lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;
    &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;

&lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="n"&gt;javelin&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;devstack&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;
        &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tenant&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;David Paterson&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Liberty-1&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add support for Cliff.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define endpoints and commands in setup.cfg.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create stubbed tempest.cmd.main module providing main cliff-based CLI facade.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor and migrate existing commands. For each command a new class that extends cliff.command.Command will need to be implemented:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;javelin2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;run-tempest-stress&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest-cleanup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;verify-tempest-config&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrate &lt;a class="reference external" href="https://github.com/redhat-openstack/tempest/blob/master/tools/config_tempest.py"&gt;config_tempest.py&lt;/a&gt; from downstream repository and integrate with cliff.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;cliff - adds framework for creating CLI applications and commands.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/tempest-cli"&gt;https://etherpad.openstack.org/p/tempest-cli&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/YVR-QA-Tempest-CLI"&gt;https://etherpad.openstack.org/p/YVR-QA-Tempest-CLI&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/YVR-QA-Liberty-Priorities"&gt;https://etherpad.openstack.org/p/YVR-QA-Liberty-Priorities&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/cliff/latest/"&gt;https://docs.openstack.org/cliff/latest/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/redhat-openstack/tempest/blob/master/tools/config_tempest.py"&gt;https://github.com/redhat-openstack/tempest/blob/master/tools/config_tempest.py&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 24 Sep 2018 00:00:00 </pubDate></item><item><title>Placeholder</title><link>https://specs.openstack.org/openstack/qa-specs/specs/other/implemented/placeholder.html</link><description>

&lt;p&gt;This is just a placeholder file to avoid sphinx errors. Please remove this
file when you add a new rst file.&lt;/p&gt;
</description><pubDate>Wed, 21 Jun 2017 00:00:00 </pubDate></item><item><title>Placeholder</title><link>https://specs.openstack.org/openstack/qa-specs/specs/other/placeholder.html</link><description>

&lt;p&gt;This is just a placeholder file to avoid sphinx errors. Please remove this
file when you add a new rst file.&lt;/p&gt;
</description><pubDate>Wed, 21 Jun 2017 00:00:00 </pubDate></item><item><title>RBAC Policy Testing</title><link>https://specs.openstack.org/openstack/qa-specs/specs/patrole/implemented/rbac-policy-testing.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/rbac-policy-testing"&gt;https://blueprints.launchpad.net/tempest/+spec/rbac-policy-testing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OpenStack deployments have standard RBAC (Role-Based Access Control)
policies that are customized in different ways by users of OpenStack.
These policies need to be enforced and verified to ensure secure
operation of an Openstack Deployment.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently there is no unified way to test that RBAC
policies are correctly enforced. This is important because these policies
define how potentially sensitive information and functionality are accessed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed solution involves creating a plugin that enables RBAC tests to be
written in such a way that they can verify that an individual policy was
correctly enforced on the specified rbac_role. Tests should primarily be written
as an extension of an existing Tempest test that is wrapped in the plugin’s
functionality. The plugin determines what roles should have access to a given
API based on the policy.json file for that service.&lt;/p&gt;
&lt;p&gt;For example, a test can be written that only tests the policies for
“compute_extension:services” as follows:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requires_ext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'os-services'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'compute'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@rbac_rule_validation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Compute"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"compute_extension:services"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;idempotent_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ec55d455-bab2-4c36-b282-ae3af0efe287'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_services_ext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;rbac_utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;switchToRbacRole&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_services&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;rbac_utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;switchToRbacRole&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A key aspect of these tests is that they are testing only a single policy, even
though a normal flow might require the usage of actions covered by multiple policies.
To enable this, the role used for the tests will alternate between “admin” and
the “rbac_role” specified in the config options. This is done so that there is no
chance of other policies besides the one being tested changing the outcome of the test.
To switch roles, the switch_role method of rbac_utils is called. Calling the method with
switchToRbacRole=True tells Keystone to set the current role to the “rbac_role” while
switchToRbacRole=False tells Keystone to set the current role to “admin”.&lt;/p&gt;
&lt;p&gt;This effort involves creating the plugin for new tests that verify correct
RBAC policy enforcement. This effort will include sample tests but is
not intended to provide full testing coverage of all policies and APIs.
The core code will exist in an external repository containing a plugin, while
individual tests will be written within the plugin. There is not currently
any functionality that needs to be added to tempest/lib, but that may change as more
tests are written.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative is to utilize the cinnamon-role plugin that was being
considered.&lt;/p&gt;
&lt;p&gt;Advantages: Utilizing the cinnamon-role plugin enables RBAC functionality
to be wrapped around existing tests with minimal extra effort.&lt;/p&gt;
&lt;p&gt;Disadvantages: Cinnamon-role doesn’t allow for testing
of individual API endpoints by switching role mid-test.&lt;/p&gt;
&lt;p&gt;Another alternative is to add the RBAC test framework into Tempest’s core functionality.&lt;/p&gt;
&lt;p&gt;Advantages: Easier deployment, don’t need extra addons.&lt;/p&gt;
&lt;p&gt;Disadvantages: Rbac testing is not something that is considered part of Tempest’s
core functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="projects"&gt;
&lt;h2&gt;Projects&lt;/h2&gt;
&lt;p&gt;List the qa projects that this spec effects. For example:
* openstack/tempest&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;david-purcell [&lt;a class="reference external" href="mailto:david.purcell%40att.com"&gt;david&lt;span&gt;.&lt;/span&gt;purcell&lt;span&gt;@&lt;/span&gt;att&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;]
jallirs [&lt;a class="reference external" href="mailto:randeep.jalli%40att.com"&gt;randeep&lt;span&gt;.&lt;/span&gt;jalli&lt;span&gt;@&lt;/span&gt;att&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;]
syjulian [&lt;a class="reference external" href="mailto:julian.sy%40att.com"&gt;julian&lt;span&gt;.&lt;/span&gt;sy&lt;span&gt;@&lt;/span&gt;att&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;]
fm577c [&lt;a class="reference external" href="mailto:felipe.monteiro%40att.com"&gt;felipe&lt;span&gt;.&lt;/span&gt;monteiro&lt;span&gt;@&lt;/span&gt;att&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;]
sblanco1 [&lt;a class="reference external" href="mailto:samantha.blanco%40att.com"&gt;samantha&lt;span&gt;.&lt;/span&gt;blanco&lt;span&gt;@&lt;/span&gt;att&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;]&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;ocata-2&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create plugin for role testing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add supporting code to tempest/lib/rbac if needed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add initial group of tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 21 Jun 2017 00:00:00 </pubDate></item><item><title>Reintegrate Tempest-Lib</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/reintegrate-tempest-lib.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/tempest-lib-reintegration"&gt;https://blueprints.launchpad.net/tempest/+spec/tempest-lib-reintegration&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;For several releases we’ve had tempest-lib which is a separate python repo
and python package that contains a stable library interface suitable for
external consumption. The idea behind the project is to migrate common pieces
from tempest into the new repo. However, this migration process and having
code which once lived in tempest be somewhere else adds a lot of friction to
the process. For example, after a service client migration if we need to update
or add a test which requires a client change it requires landing a change in
tempest-lib, pushing a tempest-lib release with that change included, landing
a global-requirements and upper-constraints bump, and then finally we can use
the change in tempest. This has proven to be very expensive process and caused
a lot of headaches as we’ve moved more code into tempest-lib.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed change is to copy all the library code that currently exists in
the tempest-lib repo and migrate it to tempest/lib in the tempest repo. We then
will declare all public interface under that directory as stable interfaces,
just like we did in tempest-lib. Any public interface that lands in tempest.lib
will be assumed to be a stable interface once it lives in the namespace.&lt;/p&gt;
&lt;p&gt;The tempest-lib repository will stay around, however, instead of continuing to
push migrated pieces into it or maintaining a passthrough layer with
semver versioning in the tempest-lib repo we’ll just push a final 1.0.0 release
and mark the it as deprecated. We’ll add a python deprecation warning which will
be emitted when tempest-lib is used to recommend users directly use
tempest.lib. This will mean users will continue to have tempest-lib work the way
it does today, but will have to migrate to it’s new home in the tempest repo
if they want any bug fixes or features. By doing this we avoid the maintanence
overhead with having to add and keep the passthrough layer. It also means we’re
less likely to slip up by trying to implement a passthrough layer which could
potentially break tempest-lib consumers. There isn’t anything that would break
users if they stay on tempest-lib since we will never remove the repo, we just
won’t have any active development there. &lt;strong&gt;We will never remove the tempest-lib
repo or the pypi releases for it.&lt;/strong&gt; We just likely will never push another
release or any patches to it post deprecation and re-integration.&lt;/p&gt;
&lt;p&gt;This reintegration of tempest-lib should change our release cadence for tempest
a bit. Previously we’ve pushed tempest releases on every start of a new
OpenStack release, a major new feature change lands in tempest, and when we EOL
a stable branch. However, since we’ll likely be more frequently adding things
to the library interface bumping the version will likely happen more frequently.
The release versioning scheme for tempest will change slightly. We’ll still keep
the monotonically increasing integer, but we’ll also have a minor versions to
indicate tempest-lib versions in a semver-like manner inside that. For example,
tempest-10.0.0 will indicate the first release in the series with mitaka
support. Then 10.1.0 will be the first tempest.lib release in that series with
feature adds, and 10.0.1 would be a tempest.lib bugfix release after the mitaka
release (but before the feature release). The minor versions will be reset
to 0 at the start of every major version. Continuing from the previous example,
at the Kilo EOL the version will be 11.0 regardless of how many tempest.lib
version bumps we pushed.&lt;/p&gt;
&lt;p&gt;Tempest-lib “migrations” which are really efforts to stabilize the interfaces
are still valuable. But, instead of going through the process of migrating all
the code to an external repo we just have to move the code to tempest.lib in
the tempest repo. Then we can add the tempest-lib shim if desired.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h2&gt;Alternatives&lt;/h2&gt;
&lt;section id="maintain-the-status-quo"&gt;
&lt;h3&gt;Maintain the status quo&lt;/h3&gt;
&lt;p&gt;We can keep the status quo. This works for the most part, but it adds a lot of
friction to the development workflow. Especially as we try to mature or add on
to existing interfaces. The perfect example of this is with anything involving
the service clients. The OpenStack APIs evolve over time (hopefully using
microversions) and we need to update the clients to use the new features in
tests this becomes a lengthy and drawn out process.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="create-a-passthrough-tempest-lib-wrapper"&gt;
&lt;h3&gt;Create a passthrough tempest-lib wrapper&lt;/h3&gt;
&lt;p&gt;We could keep tempest-lib around, but instead of holding code directly it could
be just be a passthrough to tempest.lib. This would be done for 2 reasons,
backwards compatibility for current tempest-lib users and to enable using semver
versioning of the library interface.Tempest-lib could become a library with a
shim passthrough to tempest.lib for all the modules exposed via the library
interface. We’d then start the 1.x.x release series for tempest-lib after the
lib code has been moved back to tempest. Tempest-lib would depend on tempest in
requirements.txt and we could control the tempest versions used by the
passthrough in tempest-lib’s requirements. For example, the rest_client module
in tempest-lib would end up looking something like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;tempest.lib.common&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;rest_client&lt;/span&gt;

&lt;span class="n"&gt;__all__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'RestClient'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ResponseBody'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ResponseBodyData'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s1"&gt;'ResponseBodyList'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RestClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rest_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RestClient&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ResponseBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rest_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseBody&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ResponseBodyData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rest_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseBodyData&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ResponseBodyList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rest_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseBodyList&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Matthew Treinish &amp;lt;&lt;a class="reference external" href="mailto:mtreinish%40kortar.org"&gt;mtreinish&lt;span&gt;@&lt;/span&gt;kortar&lt;span&gt;.&lt;/span&gt;org&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Mitaka Release&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Take ownership of tempest on pypi &lt;a class="footnote-reference brackets" href="#id3" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable publishing tempest to pypi &lt;a class="footnote-reference brackets" href="#id4" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add reno release notes to both tempest and tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Iterate through reintegration:
* Move all the code from tempest-lib to tempest.lib in the tempest repo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add tempest docs about the lib interface and the new release versioning&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Push new tempest release to mark reintegration of lib&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add python warning for tempest-lib deprecation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Push tempest-lib release 1.0&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the existing migration tooling to work with the new lib location&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This shouldn’t be dependent on any other effors, however it may cause conflicts
with other BPs in progress, especially with in-progress efforts to do lib
migrations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id3" role="note"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="http://sourceforge.net/p/pypi/support-requests/590/"&gt;http://sourceforge.net/p/pypi/support-requests/590/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id4" role="note"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/275958/"&gt;https://review.openstack.org/#/c/275958/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 21 Jun 2017 00:00:00 </pubDate></item><item><title>Create Separate Functional Testing Library</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/tempest-library.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/tempest-library"&gt;https://blueprints.launchpad.net/tempest/+spec/tempest-library&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With a recent desire to create a number of functional tests for individual
OpenStack projects a common toolkit for building functional tests is needed.
Using Tempest’s core functionality start a new functional testing library to
reuse this code in spinning up new project specific test suites.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;For several years Tempest has been the integrated test suite for OpenStack.
However, recently as the scope and complexity of Tempest have continued to grow
we’ve found that there is a need for project specific functional testing. With
the ease of spinning up devstack slaves for testing this is a simple thing to
add to the ci infrastructure. However writing the functional test suite is not
as straightforward and would require a great deal of duplicated effort between
the projects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Take what common test infrastructure we have currently in tempest and split it
out into a separate library. This library will live in a separate repository,
published on pypi, have a separate bug tracker, and enforce a stable api for
use. (which will be enforced with unit testing) The intent is for this library
to be usable to build a functional test suite using the same building blocks as
Tempest.&lt;/p&gt;
&lt;p&gt;As functionality is moved from Tempest into the library it may need to be
refactored slightly to be portable. For example, the RestClient and the service
clients will need to be refactored to not depend on the tempest config file.
These changes should occur at the same time the functionality is added to the
library.&lt;/p&gt;
&lt;p&gt;Once a set of functionality is ported to the library it can be removed from
tempest tree and the library used instead. We should do this as soon as the
functionality lands in the library. This will ensure that we aren’t maintaining
2 sets of the same code. It will also help ensure the functionality of the code
by actually using the library interface inside of tempest. For example consider
this workflow with python-novaclient CLI tests:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add CLI base test classes with core functionality to the new library&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch the tempest CLI tests to use the library instead&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove code in tempest which has been switched to the library&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a functional test suite to the novaclient repository and copy the
appropriate CLI tests from tempest&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove the copied novaclient CLI tests from tempest&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The first 3 steps from this example will be applied to anything that moves into
the library. Steps 4 and 5 only apply when we’ve decided a certain class of
testing no longer belongs in tempest.&lt;/p&gt;
&lt;p&gt;The first working example of this should be the CLI tests because they were only
added to Tempest before having non-Tempest devstack jobs was a simple matter. By
there very nature they should be a project specific functional test so adding
CLI framework to the library should make it quite simple to move those tests out
of Tempest.&lt;/p&gt;
&lt;p&gt;The other aspect to consider is that the library will be consumed by the
projects functional tests, not mandating functionality. All the pieces should
be optional, so that projects can use what they need to. For example, while the
tempest clients will be available in the library there should be no requirement
to use it. Also, until decisions are made around removing a certain class of
testing from tempest we shouldn’t be removing tests from tempest.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative is that we modify code inside of Tempest to do the same basic
functionality. The issue with this is that tempest will become overloaded with
having too many jobs. Additionally, the new library could conceivably contain
features and code that would have no place inside of Tempest, but would belong
in the project specific functional testing. Additionally, splitting it out into
separate library will make the publishing and release a simpler matter, since
we wouldn’t necessarily want to be publishing all of tempest on pypi as a
test-requirement for the projects.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Matthew Treinish &amp;lt;&lt;a class="reference external" href="mailto:mtreinish%40kortar.org"&gt;mtreinish&lt;span&gt;@&lt;/span&gt;kortar&lt;span&gt;.&lt;/span&gt;org&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Ken’ichi Ohmichi &amp;lt;&lt;a class="reference external" href="mailto:oomichi%40mxs.nes.nec.co.jp"&gt;oomichi&lt;span&gt;@&lt;/span&gt;mxs&lt;span&gt;.&lt;/span&gt;nes&lt;span&gt;.&lt;/span&gt;nec&lt;span&gt;.&lt;/span&gt;co&lt;span&gt;.&lt;/span&gt;jp&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Kilo Release&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Start new repository for the library&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create launchpad page for the project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create PyPI entry for the project&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy base test class and other core functionality to run tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy and remove config and tempest specific code from CLI test framework&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add devstack support for installing the library from git&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup the infra jobs to make it co-gating along with all the projects that
consume it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrate other commmon features and utilities related to testing, for example:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Exceptions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Common decorators&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Matchers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SSH validation code&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy and convert the Tempest REST Client&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Clean up the REST Client code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Separate the base REST Client code from Tempest specific code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move the REST Client specific exception to base REST Client code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the base REST Client code to tempest-lib repository&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch Tempest to use the base REST Client code of tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cleanup in Tempest service clients&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use ResponseBody/List on all service clients for consistent interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove CONF values from service clients&lt;/p&gt;
&lt;p&gt;Current service clients contain CONF values from tempest.conf but they
should be independent from tempest.conf as library functions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add documentation and examples for using the libraries interfaces&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This shouldn’t be dependent on any other effors, however it may cause conflicts
with other BPs in progress, so care should be made when porting things to ensure
all the in progress efforts don’t end up being lost in the aftermath of a
library conversion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-March/028920.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-March/028920.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 21 Jun 2017 00:00:00 </pubDate></item><item><title>Implement Cinder V2 API test</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/cinder-v2-api-tests.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt;
&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="implement-cinder-v2-api-test"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/cinder-v2-api-tests"&gt;https://blueprints.launchpad.net/tempest/+spec/cinder-v2-api-tests&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Implement Cinder v2 API test by sharing service client and test code with v1.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Tempest doesn’t have enough Cinder v2 api tests. We need to add more tests
for it. Cinder v2 api only has some small updates, so v1 and v2 tests could
share service client and test code. In this way, we don’t need to maintain
many duplictate test codes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes that Cinder v1 and v2 tests share service client and
test code. It includes the following changes:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create common service clients&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create common base test class&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make each v1 test class inherit the v2 test class&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the Cinder API test directory structure&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="create-common-service-clients"&gt;
&lt;h3&gt;1. Create common service clients&lt;/h3&gt;
&lt;p&gt;v1 and v2 service client only have very little difference. Most codes should
be same. So we could create a common service client and inherit it by v1 and
v2.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[v1 service client] -&amp;gt; [CommonServiceClient]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[v2 service client] -&amp;gt; [CommonServiceClient]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="create-common-base-test-class"&gt;
&lt;h3&gt;2. Create common base test class&lt;/h3&gt;
&lt;p&gt;Now each Cinder API test class inherits like:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[v1 test class] -&amp;gt; [BaseVolumeV1Test] -&amp;gt; [BaseVolumeTest]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[v2 test class] -&amp;gt; [BaseVolumeV2Test] -&amp;gt; [BaseVolumeTest]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To share API test classes, we need to create common base test class instead
of BaseVolumeV1Test/BaseVolumeV2Test. The class instance can switch its
behavior based on some variable which represents an API version.
After applying this common class to every API test classes, the existing
BaseVolumeV1Test and BaseVolumeV2Test can be removed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="make-each-v1-test-class-inherit-the-v2-test-class"&gt;
&lt;h3&gt;3. Make each v1 test class inherit the v2 test class&lt;/h3&gt;
&lt;p&gt;We need to change v2 test classes’ inheritances to the common base test class
and change v1 test classes’ inheritances to v2 test class:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[v1 test class] -&amp;gt; [v2 test class] -&amp;gt; [CommonVolumeTest]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In v1 test class, the variable which represents an API version should be “1”,
and the variable should be “2” in v2 test class:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeApiV2Test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CommonVolumeTest&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;_api_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeApiV1Test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SomeApiV2Test&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;_api_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="change-the-cinder-api-test-directory-structure"&gt;
&lt;h3&gt;4. Change the Cinder API test directory structure&lt;/h3&gt;
&lt;p&gt;Current test directory structure is&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;tempest/api/volume/    : v1 API test files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/volume/v2/ : v2 API test files&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This structure is not understandable, and it is better to move v1 API test
files to some directory which shows v1’s one clearly.&lt;/p&gt;
&lt;p&gt;This blueprint proposes to change the structure to&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;tempest/api/volume/    : common test files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/volume/v1/ : v1 API specific test files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/volume/v2/ : v2 API specific test files&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The test cases which can share the code between v1 and v2 will be stored in
“tempest/api/volume/”.
For specific test cases which don’t have shared code, the inheritance model
from (3) won’t work. The hierarchy would be:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;[v1 test class] -&amp;gt; [CommonVolumeTest]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[v2 test class] -&amp;gt; [CommonVolumeTest]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and these test files would be stored in:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;tempest/api/volume/v1/&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/volume/v2/&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Zhi Kun Liu &amp;lt;&lt;a class="reference external" href="mailto:liuzhikun%40gmail.com"&gt;liuzhikun&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other Contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Chandan Kumar &amp;lt;&lt;a class="reference external" href="mailto:chkumar246%40gmail.com"&gt;chkumar246&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;
jun xie &amp;lt;&lt;a class="reference external" href="mailto:junxiebj%40cn.ibm.com"&gt;junxiebj&lt;span&gt;@&lt;/span&gt;cn&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-2&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add common service client for v1 and v2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a common class for Cinder v1/v2 API tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a common admin class for Cinder v1/v2 API tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new test cases using the new shared test classes
Using a google docs spreadsheet to manage the task progress:
(&lt;a class="reference external" href="https://docs.google.com/spreadsheets/d/1ztFAn1D677zTVBahZB0sLjQkcU2_oIthZ-eRNRHI4LM"&gt;cinder_v2_api_tests&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Fri, 21 Oct 2016 00:00:00 </pubDate></item><item><title>Centralized Tempest Workspace Management</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/centralized-workspaces.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/centralized-workspaces"&gt;https://blueprints.launchpad.net/tempest/+spec/centralized-workspaces&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Create a consistent means for creation and management of Tempest workspaces.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently there is no way to track workspaces in a consistent manner. This
becomes problematic as the number of workspaces increases.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Create a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;.tempest&lt;/span&gt;&lt;/code&gt; file in the user’s home directory to be used as a source
of truth for Tempest workspaces. Users can register new workspaces via the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest&lt;/span&gt; &lt;span class="pre"&gt;workspace&lt;/span&gt; &lt;span class="pre"&gt;register&lt;/span&gt;&lt;/code&gt; command. New workspaces are automatically
registered via &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest&lt;/span&gt; &lt;span class="pre"&gt;init&lt;/span&gt;&lt;/code&gt;. The workspace manager automatically unregisters
any workspaces that no longer exist.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Action&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Command&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Register a workspace:&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tempest workspace register –name &amp;lt;name&amp;gt; –path &amp;lt;path&amp;gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Rename a workspace:&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tempest workspace update –key &amp;lt;key&amp;gt; –old-value &amp;lt;old&amp;gt; –new-value &amp;lt;new&amp;gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;List workspaces:&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;tempest workspace list&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;section id="example-usage"&gt;
&lt;h3&gt;Example Usage&lt;/h3&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;cd&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;devstack&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;devstack&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;staging&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;staging&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
&lt;span class="o"&gt;+----------+----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="n"&gt;Location&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------+---------------&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;devstack&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;devstack&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;staging&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;staging&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+----------+----------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="projects"&gt;
&lt;h2&gt;Projects&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;openstack/tempest&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;slowrie&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dwalleck&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;Target Milestone for completion:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Mitaka-2&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create argparse to handle new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;workspace&lt;/span&gt;&lt;/code&gt; command and subcommands&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create tracking file and class to represent it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add code to list that unregisters workspaces when locations no longer exist&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/tempest-cli-improvements"&gt;https://etherpad.openstack.org/p/tempest-cli-improvements&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Sep 2016 00:00:00 </pubDate></item><item><title>Refactor Client Managers</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/client-manager-refactor.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt;
&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="refactor-client-managers"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/client-manager-refactor"&gt;https://blueprints.launchpad.net/tempest/+spec/client-manager-refactor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current client managers depends on a relatively large number of
configuration items, that is the combination of all clients parameters.
This makes its migration to tempest-lib troublesome.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;We have several plans about the client manager:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;make it as stable interface in tempest.lib. This will help in turn the
migration of credential providers and service clients to the .lib namespace.
And it will give people writing tempest plug-in a home for their custom
service clients&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;change it so that it is possible for plug-in developer to add their service
clients dynamically into the client manager, so we can have a consistent
way of accessing test clients from tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The current client managers depends on CONF, and it’s structure does not
easily allow for runtime registration of extra clients.&lt;/p&gt;
&lt;p&gt;For instance, in &lt;em&gt;Manager&lt;/em&gt; class:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;network_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NetworkClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;catalog_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;region&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;endpoint_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;endpoint_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;build_interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build_interval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;build_timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;build_timeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Another issue with the current structure is that new API versions lead to
proliferation of client attributes in the client manager classes. With
service clients being split into pieces, the size of the client manager
grows accordingly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Split the client manager in two parts.&lt;/p&gt;
&lt;p&gt;The first part provides lazy loading of clients, and it does not depend on
tempest CONF, as it is planned for migration to tempest.lib.
It covers the six client groups for the six core services covered by tempest in
the big tent. It exposes an interface to register further service clients.&lt;/p&gt;
&lt;p&gt;Lazy loading of clients provides protection against clients that try to
make API calls at __init__ time; it also helps in running tempest with the
minimum amount of CONF required for the clients in use by a specific test run.&lt;/p&gt;
&lt;p&gt;The second part passes tempest CONF values to the first one. It registers
any non-core client, whether still in tempest tree or coming from a plug-in.&lt;/p&gt;
&lt;p&gt;The client registration interface could look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register_clients_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service_clients&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                           &lt;span class="n"&gt;group_params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;client_params&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Register a client group to the client manager&lt;/span&gt;

&lt;span class="sd"&gt;    The client manager in tempest only manages the six core client.&lt;/span&gt;
&lt;span class="sd"&gt;    Any extra client, provided via tempest plugin-in, must be registered&lt;/span&gt;
&lt;span class="sd"&gt;    via this API.&lt;/span&gt;

&lt;span class="sd"&gt;    All clients registered via this API must support all parameters&lt;/span&gt;
&lt;span class="sd"&gt;    defined in common parameters.&lt;/span&gt;

&lt;span class="sd"&gt;    Clients registered via this API must ensure uniqueness of client&lt;/span&gt;
&lt;span class="sd"&gt;    names within the client group.&lt;/span&gt;

&lt;span class="sd"&gt;    :param name: Name of the client group, e.g. 'orchestration'&lt;/span&gt;
&lt;span class="sd"&gt;    :param service_clients: A list with all service clients&lt;/span&gt;
&lt;span class="sd"&gt;    :param description: A description of the group&lt;/span&gt;
&lt;span class="sd"&gt;    :param group_params: A set of extra parameters expected by clients&lt;/span&gt;
&lt;span class="sd"&gt;                         in this group&lt;/span&gt;
&lt;span class="sd"&gt;    :param client_params: each is a set of client specific parameters,&lt;/span&gt;
&lt;span class="sd"&gt;                          where the key matches service_client.__name__&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The tempest plugin &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;TempestPlugin&lt;/span&gt;&lt;/code&gt; interface is extended with a method to
return the service client data specific to a plugin. Each plugin defines
a new service clients group and the relevant data.&lt;/p&gt;
&lt;p&gt;Service Clients data is stored in a singleton &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ServiceClientsData&lt;/span&gt;&lt;/code&gt;.
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ServiceClientsData&lt;/span&gt;&lt;/code&gt; is instantiated by the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;TempestTestPluginManager&lt;/span&gt;&lt;/code&gt;,
which obtains the service client data from each plugin and registers it.&lt;/p&gt;
&lt;p&gt;Client managers used by tests consume the service client data singleton,
and dynamically defines a set of attributes which can be used to access the
clients.&lt;/p&gt;
&lt;p&gt;Attributes names are statically defined for now. They will be the same names as
now, to minimize the impact on the codebase. For plugins, attributes names
include the group name, to avoid name conflicts across service clients that
belong to different plugins.&lt;/p&gt;
&lt;p&gt;In future we may define a standard naming convention for attribute
names and to enforce it by deriving names automatically. Future names may not
contain the ‘_client’ suffix, to save space and allow for always specifying
the client provider in test code, so to make the code more readable.
This naming convention will not be implemented as part of this spec.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Keep the manager on tempest side, and have big tent teams write their own
managers. Carry long list of clients as parameters in cred providers and
other parts of tempest&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Andrea Frittoli &amp;lt;&lt;a class="reference external" href="mailto:andrea.frittoli%40hpe.com"&gt;andrea&lt;span&gt;.&lt;/span&gt;frittoli&lt;span&gt;@&lt;/span&gt;hpe&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Newton-1&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Core functionality in manager part1, with unit test coverage and migration
of one client group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migration of other client groups (one per patch)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementation of the registration interface (does not depend on step 2)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Registration of non-core clients from tempest tree&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Registration of non-core clients from plugins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Separate manager part1 into it’s own module, and include maanger.py along&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Work has stared on this: Change-id I3aa094449ed4348dcb9e29f224c7663c1aefeb23&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Sep 2016 00:00:00 </pubDate></item><item><title>Tempest List Plugins Command</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/list-plugins.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/list-plugins"&gt;https://blueprints.launchpad.net/tempest/+spec/list-plugins&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Provides a means to list to currently installed Tempest plugins.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The Tempest project recently implemented a plugin system to allow external
test repositories to be included in Tempest test runs in a seamless fashion.
Tempest plugins are essentially Python packages that implement a specific
interface and are installed via standard Python tools. However, there is
not a straightforward means for knowing which plugins are currently installed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Providing a means via the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest&lt;/span&gt;&lt;/code&gt; command line tooling to list the
installed plugins provides a consistent experience to the user. The command
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest&lt;/span&gt; &lt;span class="pre"&gt;plugins&lt;/span&gt; &lt;span class="pre"&gt;list&lt;/span&gt;&lt;/code&gt; would provide the user with basic information about
the installed plugins:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tempest&lt;/span&gt; &lt;span class="n"&gt;plugins&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
&lt;span class="o"&gt;+------------+---------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;EntryPoint&lt;/span&gt;                                  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------+---------------------------------------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;HelloWorld&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;hello_world_tempest_plugin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;MyPlugin&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Example2&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;example_tempest_plugin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ExamplePlugin&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+------------+---------------------------------------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="projects"&gt;
&lt;h2&gt;Projects&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;openstack/tempest&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;slowrie
dwalleck&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Mitaka-2&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create means to query the stevedore.ExtensionManager for registered entrypoints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a function that turns the list of plugins into user readable output&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add an entry point for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;plugins&lt;/span&gt; &lt;span class="pre"&gt;list&lt;/span&gt;&lt;/code&gt; command in the tempest.cmd package&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;prettytable&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/mitaka-qa-tempest-run-cli"&gt;https://etherpad.openstack.org/p/mitaka-qa-tempest-run-cli&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/tempest/blob/005ff334d485c4ca231d7ee8396d3eb979a9ce59/tempest/test_discover/plugins.py#L74"&gt;https://github.com/openstack/tempest/blob/005ff334d485c4ca231d7ee8396d3eb979a9ce59/tempest/test_discover/plugins.py#L74&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/openstack/tempest/tree/master/tempest/cmd"&gt;https://github.com/openstack/tempest/tree/master/tempest/cmd&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Sep 2016 00:00:00 </pubDate></item><item><title>No truncation in service clients return value and move to tempest-lib</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/method-return-value-and-move-service-clients-to-lib.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/method-return-value-and-move-service-clients-to-lib"&gt;https://blueprints.launchpad.net/tempest/+spec/method-return-value-and-move-service-clients-to-lib&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Make service clients not to truncate response and move those to tempest-lib&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Service clients are Tempest own REST clients for operating each OpenStack
project’s APIs. And  we have a plan to migrate service clients’ methods to
tempest-lib.&lt;/p&gt;
&lt;p&gt;1.
Currently these method cut out the top key from response like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show_host_detail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Show detail information for the host."""&lt;/span&gt;

     &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"os-hosts/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
     &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validate_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show_host_detail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;service_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseBodyList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'host'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;However this cutting is wrong as library function, because the caller
cannot know the complete response returned from corresponding APIs.&lt;/p&gt;
&lt;p&gt;One example is resource links which are currently truncated by service
clients. So if caller needs to use those resource links, they can not get
from current service clients.&lt;/p&gt;
&lt;p&gt;2.
Currently JSON schemas which are used to validate the response in service
clients are present in Tempest. When service clients will be migrated to
Tempest-lib, those schemas should be accessible for service clients in
Tempest-lib.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Stop cutting out the top key of a response
we need to remove this kind of cutting from service client methods like:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show_host_detail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""Show detail information for the host."""&lt;/span&gt;

    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"os-hosts/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validate_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show_host_detail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;service_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseBodyList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'host'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;service_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseBodyList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Move JSON Response Schema to Tempest-lib
Currently Tempest have JSON response schema in ‘tempest/api_schema’
which are used in service clients to validate API response.
During Vancouver summit, it was decided that for short term solution
we can move those schema in Tempest-lib along with service clients.&lt;/p&gt;
&lt;p&gt;In long term, each project should provide some way to get those schema
through API or something else.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the service client code to tempest-lib repository&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch Tempest to use the service client code of tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Migration of service clients can be done gradually with one client
class at a time.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ken’ichi Ohmichi &amp;lt;&lt;a class="reference external" href="mailto:oomichi%40mxs.nes.nec.co.jp"&gt;oomichi&lt;span&gt;@&lt;/span&gt;mxs&lt;span&gt;.&lt;/span&gt;nes&lt;span&gt;.&lt;/span&gt;nec&lt;span&gt;.&lt;/span&gt;co&lt;span&gt;.&lt;/span&gt;jp&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Ghanshyam Mann &amp;lt;&lt;a class="reference external" href="mailto:ghanshyam.mann%40nectechnologies.in"&gt;ghanshyam&lt;span&gt;.&lt;/span&gt;mann&lt;span&gt;@&lt;/span&gt;nectechnologies&lt;span&gt;.&lt;/span&gt;in&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Liberty&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Modify service clients’ methods return value based on this proposal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move JSON schema to Tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move Service Clients to Tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/consistent-service-method-names"&gt;https://blueprints.launchpad.net/tempest/+spec/consistent-service-method-names&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We have discussed this working items at Vancouver Summit.
The log is &lt;a class="reference external" href="https://etherpad.openstack.org/p/YVR-QA-Tempest-service-clients"&gt;https://etherpad.openstack.org/p/YVR-QA-Tempest-service-clients&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 24 Mar 2016 00:00:00 </pubDate></item><item><title>Simplify credentials management</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/simplify-credentials-management.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt;
&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="simplify-credentials-management"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/simplify-credentials-management"&gt;https://blueprints.launchpad.net/tempest/+spec/simplify-credentials-management&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Refactor the way credentials/client managers are obtained by the test
classes so that it is clear which class attributes reference the client
managers with specific credentials.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Credentials are allocated by defining an array that enumerates the needed
credentials for a given test class.  For instance:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s1"&gt;'operator'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object_storage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operator_role&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
               &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'operator_alt'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object_storage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operator_role&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setup_credentials&lt;/span&gt;&lt;/code&gt; class method of the base test class is called,
the client managers associated with credentials are mapped to class attributes
with the prefix &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os_roles&lt;/span&gt;&lt;/code&gt;.  Credentials can also be allocated in this
manner:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'primary'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'alt'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this case the client managers are aliased to three class attributes, for
instance &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;manager&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;os_primary&lt;/span&gt;&lt;/code&gt; are all set to the client
manager using the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;primary&lt;/span&gt;&lt;/code&gt; credentials. This can be confusing for someone
trying to understand a test case, because it is not intuitive for the setting
of a class variable to result in attributes being set and what the names of
those attributes are.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed change is to explicitly assign the attribute values in the given
class’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setup_credentials&lt;/span&gt;&lt;/code&gt; class method; for instance:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os_roles_operator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_client_manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object_storage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operator_role&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;force_new&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os_roles_operator_alt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_client_manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object_storage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operator_role&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;force_new&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For classes that use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;primary&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;alt&lt;/span&gt;&lt;/code&gt; and/or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;admin&lt;/span&gt;&lt;/code&gt; credentials, the
logic would look like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os_primary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_client_manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credential_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'primary'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;All aliasing would be removed.&lt;/p&gt;
&lt;p&gt;In either case the credential de-allocation logic can remain the way it is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;John Warren &amp;lt;&lt;a class="reference external" href="mailto:jswarren%40us.ibm.com"&gt;jswarren&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;tempest/scenario/test_server_multinode.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/scenario/test_security_groups_basic_ops.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/scenario/test_aggregates_basic_ops.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/scenario/manager.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/database/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/compute/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/compute/test_authorization.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/compute/servers/test_servers_negative.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/telemetry/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/baremetal/admin/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/object_storage/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/object_storage/test_object_services.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/object_storage/test_account_services.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/object_storage/test_account_quotas.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/object_storage/test_container_acl_negative.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/object_storage/test_account_services_negative.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/object_storage/test_container_sync.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/object_storage/test_container_acl.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/object_storage/test_account_quotas_negative.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/data_processing/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/network/admin/test_floating_ips_admin_actions.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/network/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/volume/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/volume/test_volume_transfers.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/identity/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/identity/v3/test_projects.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/identity/v2/test_tenants.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/image/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;tempest/api/orchestration/base.py and subclasses&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Wed, 24 Feb 2016 00:00:00 </pubDate></item><item><title>Tempest External Plugin Interface</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/tempest-external-plugin-interface.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/external-plugin-interface"&gt;https://blueprints.launchpad.net/tempest/+spec/external-plugin-interface&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Create an external plugin interface to enable loading additional tempest-like
tests from out of tree to enable projects to maintain their own testing out
of tree.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;As part of the recent governance change to rework OpenStack under a big tent
the QA program needs to be able to handle an influx of “OpenStack” projects.
As part of this pivot most QA projects are shifting from directly supporting
every project in-tree to moving towards providing projects to self service.
A missing piece of this was the tempest external plugin model, all the other
QA projects contain support for extending functionality with out of tree
plugins but tempest was putting the burden on the user for constructing this.
Moving forward having a unified supported model for enabling this is necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The first step for the plugin interface is to handle the loading of the
additional tests in the plugin. The additional paths of the external tests will
need to be passed into the unittest discovery mechanism. To do this registering
an entry point that tempest will be able to load as part of it’s run command
will be used. This will enable any installed python package which contains a
tempest entry point to be seamlessly discovered and used as part of a wider
“Tempest” test suite.&lt;/p&gt;
&lt;p&gt;You would register the entrypoint when using pbr by adding an entry to
your setup.cfg like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;entry_points&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;tempest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_plugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;plugin_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plugin_dir&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;load_plugin&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will register a new plugin to tempest to use the additional testing.
Stevedore will probably be leveraged on the tempest side in the new cli
run command to load the plugins when run to add the additional pieces. The
hook referred to in the setup.cfg will return the test path to use for unittest
discovery. The stevedore manager in tempest will then use this returned path to
construct a set of test paths to use for discovery including tempest in-tree
tests and all installed plugins, this will give the appearance when running
tempest of a unified test suite.&lt;/p&gt;
&lt;p&gt;As for the plugins themselves they will contain a few key pieces, mainly the
tests, additional configuration.&lt;/p&gt;
&lt;p&gt;An example of the base directory structure for a plugin to start with would
look something like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;plugin_dir&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
  &lt;span class="n"&gt;tests&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="n"&gt;scenario&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;However, this is just suggested bare minimum, it is not going to cover every
potential plugins use case so have additional files or directories in plugins
will be expected.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The various pieces here:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;config.py will contain 2 things first is the registration method which
will provide all the necessary information to tempest to execute the plugin
remotely and second the additional configuration options. There will be a
unified method on the plugin class, likely called register_opts(), (and
also list opts so that we have a call for sample config generation) which
will register all the new groups and new options. This puts the burden on
the plugin to either create new groups for options or to extend existing
groups where appropriate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The tests dir will contain the actual tests. The example above used 2
subdirs for api tests and scenario tests, but that isn’t a hard requirement.
Any desired organization of tests can be used in a plugin. However a single
parent dir for all tests is used to make the test discovery logic in tempest
a bit easier to deal with.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services will contain the additional api clients based on the RestClient
from tempest-lib if needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;It is also worth noting that we should strive to make these plugins be able to
fully self execute on their own with a traditional test runner without any need
to use tempest. The use of the plugin is only to enable easier integration with
the wider test suite for other projects. A cookiecutter repo (either as part of
the existing devstack-plugin-cookiecutter or a separate repo) will be leveraged
to enable a fast path template for projects to use when initially setting up a
new tempest plugin.&lt;/p&gt;
&lt;p&gt;There are several things from tempest-lib which are missing which are really
needed to leverage out-of-tree plugins, mainly the base test class fixtures
and the credential providers. These are not requirements for starting work
on the plugins as the plugins can temporarily depend on tempest code for that
however, in the medium term we should migrate these to tempest-lib to lock down
the interface for using them.&lt;/p&gt;
&lt;p&gt;Another thing which we’ll be changing is our contract around the tempest config
file. Traditionally we have said not to rely on config options from directly
from tempest but this will change with plugins since code out of tree will have
to rely on existing options as a base set to build off of. This means in the
future we’ll have to provide better guarantees on the stability of tempest’s
config file.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An alternative approach would be to not use loadable entrypoint and instead
place the burden on the tempest end user to load the plugins. So when calling
tempest run you would specify a list of plugins to load at the same time.
The disadvantage of this approach is that it requires the user to know where
the plugins are located on the system. While using an entrypoint only requires
the additional code to be installed and then tempest will use external location
automatically.&lt;/p&gt;
&lt;p&gt;Additionally, if a plugin interface was not added there would be nothing
stopping anyone from using tempest-lib and the same mechanism as what is
expected in a plugin to create an isolated tempest-like test suite. (in fact
several projects have already done this) This was also the previously
recommended approach for out of tree tempest tests. The disadvantage with only
doing this is that everything is treated in isolation so each test suite would
have to be dealt with in isolation. However, with the scope of what’s allowed
in tempest clearly defined now we expect many more of these external suites to
be added in the future. Being able to deal with them in a single manner and
using a single workflow to deal with all of them at once is much more desirable,
and a far lower burden on the end user.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="projects"&gt;
&lt;h2&gt;Projects&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;openstack/tempest&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;openstack/tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;mtreinish&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Liberty-2&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add support to tempest run to load installed entry-points&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the tempest documentation to outline project scope and changes to
in-tree tempest policy (including things like config file changes)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create documentation for using plugins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add missing interfaces to tempest-lib&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create cookie-cutter repo for tempest-plugins&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A tempest unified cli which adds a new run interface is required before we
have a place to add the extension loading support to&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding an additional interface to unittest to handle a list of discovery
points might be needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 14 Dec 2015 00:00:00 </pubDate></item><item><title>Inspect counters for data collection and gating purposes</title><link>https://specs.openstack.org/openstack/qa-specs/specs/devstack/counter-inspection.html</link><description>

&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;OpenStack projects vary on their impact to the underlying infrastructure
that they rely on greatly. This is hard to measure without going to a
full scale deployment, but we should be able to measure the impact by
inspecting counters already maintained by the system.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a new “OpenStack QA Tools” repository to house small tools
written in python for purposes such as this.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a tool, &lt;cite&gt;os-collect-counters&lt;/cite&gt;, which collects relevant counters
from any backends it can reach using its own configuration and
outputs a JSON mapping with all counters. Includes ability to delta
with a previous run to allow showing impact on the counters for a
given time window.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Initial counters will be at a minimum a set of MySQL counters (such
as Innodb_bytes_written) and published messages from the RabbitMQ
management interface, summarized by scope that can be inferred
from each queue name.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leverage existing subunit/statsd/graphite infrastructure to record results of
several tests in the devstack gate.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;For each run, the JSON from &lt;cite&gt;os-collect-counters&lt;/cite&gt; will be added as an
attachment to the subunit stream.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The counters in the attachment will be fed into statsd/graphite to
allow establishing trends.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This will be facilitated by adding attachment storage plugins to
subunit2sql. The plugin used for OpenStack gate jobs will be
specific to OpenStack’s infrastructure and look for the specifically
named attachment to push into statsd/graphite.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitor counters for stable indicators and identify the best predictors of
problems.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Once stable counters are identified, create an upper bounds for
these counters to help prevent new changes in the system from
accidentally introducing an inordinate amount of cost into the tested
code paths.&lt;/p&gt;
&lt;p&gt;Since there are daunting social issues around failing gate tests
on global collisions, warnings and bugs about said warnings are
likely the only reasonable outcome we can achieve. It will take a
considerable amount of community agreement to make these limits hard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;A new python repo, &lt;a class="reference external" href="https://review.openstack.org/#/c/244428/"&gt;os-performance-tools&lt;/a&gt;, has already been created, and
will be maintained for the purposes of extracting and pushing counters
into statsd/graphite. This will include a subunit2sql attachments plugin
and code to output the counters as a subunit attachment.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Clint Byrum &amp;lt;&lt;a class="reference external" href="mailto:clint%40fewbar.com"&gt;clint&lt;span&gt;@&lt;/span&gt;fewbar&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Mitaka-2&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create tools to emit counters from a running installation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify devstack gate job output to include counters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add subunit2sql attachment plugin to subunit2sql workers
to push counters to infra graphite&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Analyze data for stable counters and useful trends&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add upper bounds check to devstack gate&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Thu, 01 Oct 2015 00:00:00 </pubDate></item><item><title>Branchless Tempest - Service Extensions</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/branchless-tempest-extensions.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/branchless-tempest-extensions"&gt;https://blueprints.launchpad.net/tempest/+spec/branchless-tempest-extensions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is the follow on work for branchless tempest for new service
extensions that are added over the course of a release.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In moving to branchless Tempest we’re now running Tempest across
multiple OpenStack code branches. Today that’s icehouse and juno,
however it will be icehouse, juno, kepler in the future.&lt;/p&gt;
&lt;p&gt;What happens when a new extension is added to Nova in Juno, and tests
in tempest are wanted for that part of the API? Today that test would
fail because it could not pass icehouse.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The proposed change is to add another layer to the devstack-gate
feature grid which specifies which extensions are supported at each
release.&lt;/p&gt;
&lt;p&gt;Today in the nova definition we’ve got&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;nova&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cond&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;crt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This would imagine a world where the definition would look as follows&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;nova&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cond&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;crt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;icehouse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="n"&gt;compute&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;floating&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ips&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aggregates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The non existence of an extensions list means assume ‘all’. It is also
expected that you’d be able to specify ‘rm-compute-ext’ much like
rm-services, so that you could do something as follows.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;nova&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cells&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;rm&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;compute&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;aggregates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;That would disable those nova extensions any time it was configured.&lt;/p&gt;
&lt;p&gt;For this to function there needs to be changes in&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;devstack-gate&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;to parse these additional stanzas and pass them down to devstack&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;devstack&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;to take extension lists for projects and set the correct
extensions up based on it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;to compute the ‘all’ case correctly for master (especially if we
support the rm-compute-ext stanza)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;to set the correct tempest fields for enabled features when these
map to feature flags.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Nova API microversions might obviate the need here in the branch case,
as we’d be able to specify a specific test has a specific required
version. However that wouldn’t solve the cells case.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None yet&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;Not Known&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The work items span projects&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;see above&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Only those listed above&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 24 Sep 2015 00:00:00 </pubDate></item><item><title>meta data and uuid for tests</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/meta-data-and-uuid-for-tests.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/meta"&gt;https://blueprints.launchpad.net/tempest/+spec/meta&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The purpose of this spec is to define a standard for attaching meta data such
as Universally Unique Identifiers (UUIDs) to tests that are to be used by
tempest. This specification should be enforced both for tests that are to live
in the tempest repository as well as tests that will eventually reside within
their own repositories.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;While there are many reasons to want meta data attached to tests. One of
the complaints that led to this specification is the lack of a unique
identifier for tests. If you cannot track a specific test over time, long term
data carries less meaning and progress is more complicated to track.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Each test will have a decorator that will accept a required arguments
containing a uuid and meta as kwargs. This open ended approach for meta data
should insure flexibility for the future. Such as allow Defcore to directly
tag tests with capability data moving forward.&lt;/p&gt;
&lt;p&gt;This change will also require the development of a tool for inserting the
decorators with uuid content for all the existing tests. This tool can also be
used as a uniqueness validation and missing uuid checker in the gate.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;It was also suggest that meta data can be written into parseable doc strings.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;This change will require the following components be developed.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;uniqueness tester / detect missing meta / insert meta&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tool will check for unique UUID decorators for all test_* methods in
test_*py files. This is done in a single pass to build a list of undecorated
tests, which can the be used as a gate check in the qa pipeline. From
this list another tool will generate unique UUID metadata and insert it
into all undecorated tests.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta_decorator_check&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;scans the directory/files in path, parses for methods missing the
decorator or finds tests with duplicate UUIDs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the same tool you can add the –insert-missing arg. This will generate
and insert the missing decorators.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta_decorator_check&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;missing&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;decorator&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The UUID and meta decorator format will be as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="s1"&gt;'@test.meta(uuid='&lt;/span&gt;&lt;span class="mi"&gt;12345678&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5678&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;567812345678&lt;/span&gt;&lt;span class="s1"&gt;',&lt;/span&gt;
            &lt;span class="n"&gt;otherdata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'another value'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For sphinx autodoc generation it will append the following to the doc string:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12345678-1234-5678-1234-567812345678'&lt;/span&gt;
&lt;span class="n"&gt;otherdata&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'another value'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To insure the data is passed to subunit output we add the testtools attr:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'12345678-1234-5678-1234-567812345678'&lt;/span&gt;
&lt;span class="n"&gt;otherdata&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'another value'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;hacking&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;New hacking will need to be added to insure that a decorator is set for all
tests. First a new rule to be added to tempest/hacking/checks.py.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;all_tests_need_uuid_metadata&lt;/p&gt;
&lt;p&gt;“””Check that a test has unique UUID metadata&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;All tests should have a unique UUID identifier in the metadata
of the form:
&lt;a class="reference external" href="mailto:'%40test"&gt;‘&lt;span&gt;@&lt;/span&gt;test&lt;/a&gt;.meta(uuid=’12345678-1234-5678-1234-567812345678’)
to give a stable point of reference.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;T108”””&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The Tempest coding guide will be updated to reflect the new hacking
rule.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;David Lenwell (davidlenwell, &lt;a class="reference external" href="mailto:dlenwell%40gmail.com"&gt;dlenwell&lt;span&gt;@&lt;/span&gt;gmail&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;)
Chris Hoge (hogepodge, &lt;a class="reference external" href="mailto:chris%40openstack.org"&gt;chris&lt;span&gt;@&lt;/span&gt;openstack&lt;span&gt;.&lt;/span&gt;org&lt;/a&gt;)
Sergey Slipushenko (automated test tagging)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;K-3&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;creation of decorator&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;creation of the generate_meta / uniqueness testing tool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;use the generate_meta tool to generate default meta data for all existing
tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;implementation of gate tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;update tempest coding guide with new hacking rule&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;No known external dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 24 Sep 2015 00:00:00 </pubDate></item><item><title>Resource Cleanup</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/resource-cleanup.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt; &lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="resource-cleanup"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/resource-cleanup"&gt;https://blueprints.launchpad.net/tempest/+spec/resource-cleanup&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tempest test resource cleanup&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The cleanup/release of test resources created/allocated in the class level
test fixtures is invoked in the class level tearDown fixture.
However tearDownClass is invoked by the unittest framework only in case
setUpClass is successful. This is causing resources being leaked when:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;a skip exception is raised after resources (typically test accounts)
have already been allocated&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;there is a temporary failure in the system under test which causes the
setUpClass to fail&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The test-accounts bp introduces the possibility to run parallel tests
using a configured list of pre-provisioned test accounts. Test accounts
are allocated and released by each test class, and a failure to release
leads to exhaustion of test accounts.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Disallow overriding &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setUpClass&lt;/span&gt;&lt;/code&gt; defined in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BaseTestCase&lt;/span&gt;&lt;/code&gt; with a hacking
rule. Define &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setUpClass&lt;/span&gt;&lt;/code&gt; so that it calls one (or more) other methods to be
overridden by descendants. Decorate it with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;@safe_setup&lt;/span&gt;&lt;/code&gt; decorator.
This way tearDownClass will always be invoked.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@classmethod&lt;/span&gt;
&lt;span class="nd"&gt;@safe_setup&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUpClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setUpClassCalled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;While doing this change, an extra benefit can  be gained by structuring
the setup in a series of methods, to enforce the least possible resource
allocation before failure and thus quick cleanup as well.&lt;/p&gt;
&lt;p&gt;PoC for this is available here: &lt;a class="reference external" href="https://review.openstack.org/#/c/115353"&gt;https://review.openstack.org/#/c/115353&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@classmethod&lt;/span&gt;
&lt;span class="nd"&gt;@safe_setup&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUpClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setUpClassCalled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
    &lt;span class="c1"&gt;# All checks that may generate a skip&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup_skip_checks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# Any setup code that does not require / generate test resources&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup_pre_resources&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# Allocation of all required credentials&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup_allocate_credentials&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# Shortcuts to clients&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup_clients&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# Allocation of shared test resources&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup_create_resources&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# Any setup code to be run after resource allocation&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup_post_resources&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The tearDownClass fixture requires fixing in several places, because
several tearDownClass implementation would become unsafe, as they expect
attributes defined during setUpClass, which may not be there anymore.&lt;/p&gt;
&lt;p&gt;Disallow overriding &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tearDownClass&lt;/span&gt;&lt;/code&gt; defined in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BaseTestCase&lt;/span&gt;&lt;/code&gt; with
an hacking rule. Define &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tearDownClass&lt;/span&gt;&lt;/code&gt; so that it invokes a descendant
specific cleanup code, and finally cleans-up credentials.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@classmethod&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tearDownClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;at_exit_set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;discard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resource_cleanup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_cleanup_credentials&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# Defined in BaseTestCase&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Two alternatives have been identified.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="massive-fixture-decoration"&gt;
&lt;h3&gt;Massive fixture decoration&lt;/h3&gt;
&lt;p&gt;Decorate all &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setUpClass&lt;/span&gt;&lt;/code&gt; implementation with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;@safe_setup&lt;/span&gt;&lt;/code&gt; and all
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tearDownClass&lt;/span&gt;&lt;/code&gt; implementation with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;@safe_teardown&lt;/span&gt;&lt;/code&gt;.
This approach requires a mass change to tempest, which as the benefit of
being almost scriptable (PoC: &lt;a class="reference external" href="https://review.openstack.org/#/c/115123/"&gt;https://review.openstack.org/#/c/115123/&lt;/a&gt;).
It has the downfall of requiring every new test class to add those two
decorators.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="migrate-to-testresources"&gt;
&lt;h3&gt;Migrate to TestResources&lt;/h3&gt;
&lt;p&gt;This may still be an option on the long term, but at the moment the
effort of the migration would be more than the benefit from it.
Additional work to ensure cleanup of resources would still be required
anyways.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Andrea Frittoli &amp;lt;&lt;a class="reference external" href="mailto:andrea.frittoli%40hp.com"&gt;andrea&lt;span&gt;.&lt;/span&gt;frittoli&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-final&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Define base fixtures&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrate base classes and tests to use the new framework (multiple patches)
Work tracked in &lt;a class="reference external" href="https://etherpad.openstack.org/p/tempest-resource-cleanup"&gt;https://etherpad.openstack.org/p/tempest-resource-cleanup&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hacking rule to prevent overriding of setUpClass and tearDownClass&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 24 Sep 2015 00:00:00 </pubDate></item><item><title>Devstack external plugins</title><link>https://specs.openstack.org/openstack/qa-specs/specs/devstack/implemented/devstack-external-plugins.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/devstack-external-plugins"&gt;https://blueprints.launchpad.net/tempest/+spec/devstack-external-plugins&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Support external plugins for devstack.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Devstack has a pretty strong plugin support, you just have to drop
your extra feature in the extras.d/ directory and it will
automatically parse the file and install the feature as long you have
enabled it in your local.conf.&lt;/p&gt;
&lt;p&gt;This all works very well but that’s not very flexible for projects
that are not able to be integrated directly in devstack
core. Currently an external OpenStack project who wants to tell its
users how to test a feature has to explain how to download a file to
put in the &lt;cite&gt;extras.d&lt;/cite&gt; directory and enabling it.&lt;/p&gt;
&lt;p&gt;As for integrated projects they may wants to take care of how they do
devstack directly in their own repo and get devstack to use that
instead of having to request for a change in devstack repository.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Devstack would provide a new enable_plugin function call that would be
of the following format:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;enable_plugin&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;openstack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;external_feature&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;refname&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;cite&gt;name&lt;/cite&gt; is an arbitrary name picked for enablement, &lt;cite&gt;repo&lt;/cite&gt; is the
full url to a git repo, and &lt;cite&gt;refname&lt;/cite&gt; is the optional ref
description (defaulting to &lt;cite&gt;master&lt;/cite&gt; if none is provided).&lt;/p&gt;
&lt;p&gt;Devstack would then checkout that repository in &lt;cite&gt;${DEST}/name&lt;/cite&gt; and
look for a &lt;cite&gt;/devstack/&lt;/cite&gt; directory in there from the root of the repo.&lt;/p&gt;
&lt;p&gt;Files in there would have :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;/devstack/settings&lt;/cite&gt; - a file that gets sourced to override global settings,
those variables become instantly available in the global namespace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;cite&gt;/devstack/plugin.sh&lt;/cite&gt; - dispatcher for the various phases&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Devstack when executed will then:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Get the configuration of the &lt;cite&gt;extras.d&lt;/cite&gt; repos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone the extras repository to &lt;cite&gt;${DEST}&lt;/cite&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run all the &lt;cite&gt;extras.d&lt;/cite&gt; scripts at a particular phase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run all the plugins &lt;cite&gt;plugin.sh&lt;/cite&gt; at a particular phase&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This would let the out of tree projects that needs to communicate about their
config to export data via settings that would let the other configure based on
their setup.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative would be to stay as the status quo like we have now and have
them to curl the extras file from the external repository and place it in the
&lt;cite&gt;extras.d&lt;/cite&gt; directory.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Chmouel Boudjnah &amp;lt;&lt;a class="reference external" href="mailto:chmouel%40chmouel.com"&gt;chmouel&lt;span&gt;@&lt;/span&gt;chmouel&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Sean Dague &amp;lt;&lt;a class="reference external" href="mailto:sean%40dague.net"&gt;sean&lt;span&gt;@&lt;/span&gt;dague&lt;span&gt;.&lt;/span&gt;net&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Kilo-2&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add support in devstack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get an example repository setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get a project like nova-docker to use it.
* (glusterfs is a good current candidate)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>DevStack Logging and Service Names</title><link>https://specs.openstack.org/openstack/qa-specs/specs/devstack/implemented/devstack-logging-and-service-names.html</link><description>

&lt;p&gt;&lt;cite&gt;NOTE: This spec is still a work in progress, it is being posted to get some early
feedback on scope and ordering of steps.&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/devstack-logging-and-service-names"&gt;https://blueprints.launchpad.net/tempest/+spec/devstack-logging-and-service-names&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;DevStack is in need of updates to its log file handling and service naming, both
of which were appropriate for the originalscreen-based installs with a handful
of services.&lt;/p&gt;
&lt;p&gt;This spec contains both the log file reform as well as the service name updates
as they are a bit intertwined so some steps will address them both as necessary.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;DevStack’s logging configuration was initially based on saving &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/code&gt; logs,
as part of the development of not using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;screen&lt;/span&gt;&lt;/code&gt; the logging was kept compatible
and it became obvious that the original special case was not required.&lt;/p&gt;
&lt;p&gt;Historically DevStack has used abbreviated service names for identifying services
to enable, naming log files and as window names in screen.  OpenStack has grown
to the point that the abbreviated names are too confusing and non-obvious,
especially for the not-so-recently renamed Neutron.&lt;/p&gt;
&lt;p&gt;These topics were covered at the Paris summit, notes in the &lt;a class="reference external" href="https://etherpad.openstack.org/p/kilo-summit-devstack-grenade"&gt;OpenStack Etherpad&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;section id="logging"&gt;
&lt;h3&gt;Logging&lt;/h3&gt;
&lt;p&gt;Update DevStack’s logging configuration to set a logging directory rather than parsing
that out of a filename.  Ultimately eliminate the use of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SCREEN_LOGDIR&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOGDIR&lt;/span&gt;&lt;/code&gt; as the primary setting in local.conf for log locations, default to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;${DEST}/logs&lt;/span&gt;&lt;/code&gt; if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOGFILENAME&lt;/span&gt;&lt;/code&gt; is not set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Continue to use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOGFILENAME&lt;/span&gt;&lt;/code&gt; if set, if &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOGFILE&lt;/span&gt;&lt;/code&gt; is not set continue to set it to
$(dirname &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;$LOGFILENAME&lt;/span&gt;&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deprecate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SCREEN_LOGDIR&lt;/span&gt;&lt;/code&gt; and use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOGDIR&lt;/span&gt;&lt;/code&gt; instead.  For a compatibility period
leave symlinks in the old screen log locations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;screen-&lt;/span&gt;&lt;/code&gt; from the beginning of the service log filenames&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service log files will implicitly be renamed as the service names change (see above)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Grenade should work seamlessly as it lets both DevStack runs do their thing and
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack-gate&lt;/span&gt;&lt;/code&gt; contains all of the specifics that need updating fro Grenade jobs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="service-names"&gt;
&lt;h3&gt;Service Names&lt;/h3&gt;
&lt;p&gt;Use fully-formed names for service names (like ceilometer does today): &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;nova-compute&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;glance-registry&lt;/span&gt;&lt;/code&gt;, etc.  The names will use the project name, as used in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack/lib/*&lt;/span&gt;&lt;/code&gt;
followed by ‘-’ and a descriptive name of the service.&lt;/p&gt;
&lt;p&gt;Also allow multiple instances of service names, as in running the fake hypervisor has
a number of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;nova-cpu&lt;/span&gt;&lt;/code&gt; instances.  Append an instance counter to the name similar to
how &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;n-cpu-N&lt;/span&gt;&lt;/code&gt; is currently handled.  Optionally use a ‘:’ as the separator between the
service name and instance number.  This will be used in the log file name so it must be
shell-safe.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;There needs to be a mapping of the old abbreviated names to the full names to handle
backward compatibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This will make &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ENABLED_SERVICES&lt;/span&gt;&lt;/code&gt; very long by default and harder to scan visually.
Is this a real concern? With the recent forced update to using Bash 4 we could use an
associative array to do the mapping and the enabled list in a single shot.&lt;/p&gt;
&lt;p&gt;(Note:  We just started doing something in Grenade to handle mapping abbreviated
service names-&amp;gt; processes (&lt;a class="reference external" href="https://review.openstack.org/#/c/113405/5/check-sanity"&gt;https://review.openstack.org/#/c/113405/5/check-sanity&lt;/a&gt;)
This would help move that logic into DevStack and also help provide other mappings
(ie, service name -&amp;gt; database name))&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Log filenames will change, but there is more on that front (see below).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Grenade will need to be updated before the backward compatibility can be removed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;dtroyer&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Logging: change the log file names in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SCREEN_LOGDIR&lt;/span&gt;&lt;/code&gt; so the actual files
with the timestamp in the names end with the timestamp:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sch&lt;/span&gt;&lt;span class="mf"&gt;.2014&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;193405.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="n"&gt;becomes&lt;/span&gt;  &lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="mf"&gt;.2014&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;193405&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logging: change &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack-gate&lt;/span&gt;&lt;/code&gt; to look for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;*.log&lt;/span&gt;&lt;/code&gt;
rather than symlinks to select the log files it copies out of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;screen-logs&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logging: switch from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SCREEN_LOGDIR&lt;/span&gt;&lt;/code&gt; to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;LOGDIR&lt;/span&gt;&lt;/code&gt; for log tests.  This will
move the log files out of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SCREEN_LOGDIR&lt;/span&gt;&lt;/code&gt; so leave backward-compatibility
symlinks in the old locations.  (This is the reason for #2 as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack-gate&lt;/span&gt;&lt;/code&gt;
selects the files top copy by the symlink attribute.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logging: follow up in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack-gate&lt;/span&gt;&lt;/code&gt; to use LOGDIR directly and copy log files
from there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logging: after a time, remove the symlinks from &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SCREEN_LOGDIR&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services: change how multiple instances of services are handled, currently in
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lib/nova&lt;/span&gt; &lt;span class="pre"&gt;start_nova_compute()&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;stop_nova_compute()&lt;/span&gt;&lt;/code&gt;.  If the separator
is changed the config filenames will also change, reconsider if parsing is necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services: build the new service naming structures and compatibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Services and Logging: switch logging to use the new service names and ensure nothing
gets lost in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;devstack-gate&lt;/span&gt;&lt;/code&gt; copies.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The only dependencies are in the order of changes required in multiple projects.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Fuzzy test framework</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/fuzzy-test.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/fuzzy-test"&gt;https://blueprints.launchpad.net/tempest/+spec/fuzzy-test&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The negative testing framework tests single aspects of an API server in an
automatic manner based on json schema’s. Using this functionality fuzzy tests
can be created with the same process but with a different focus.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Tempest does not have any coverage of security aspects. Using such a framework
to detect security vulnerabilities will be an important new testing area for
Tempest.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Focus of this framework is vulnerabilities identification and denial of
service (DoS) attacks. It can use the api schema definitions as input to
produce flawed requests.&lt;/p&gt;
&lt;section id="denial-of-service"&gt;
&lt;h3&gt;Denial of service&lt;/h3&gt;
&lt;p&gt;DoS patterns are easy to validate and are considered as first step.
A certain service produces a portion of flawed requests together with valid
requests like authentication. To validate if a DoS attack was successful a set
of usual Tempest API test can be used for this purpose. To produce the needed
load the stress test framework of Tempest can be used to produce a higher load
rate.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="vulnerabilities-identification"&gt;
&lt;h3&gt;Vulnerabilities identification&lt;/h3&gt;
&lt;p&gt;Identification of security issues can be very complex and automatic detection
can be only done very limited. To identify issues that may are vulnerabilities
the following data needs to be analyzed:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Result of a request:
Success codes or internal server errors are potential threats that need be
analyzed and logged by the framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;System availability:
A check if all the OpenStack components are available be used as validation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Request logging:
Tempest rest client loges all requests. This is needed to identify request
or scenarios that causes a threat.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="data-generation"&gt;
&lt;h3&gt;Data generation&lt;/h3&gt;
&lt;p&gt;The data generation should support different sources and this could be a
possible interface to 3PP fuzzy testing products. With the multibackend
functionality of the negative testing framework (see
&lt;a class="reference external" href="https://review.openstack.org/#/c/73982/"&gt;https://review.openstack.org/#/c/73982/&lt;/a&gt;) different test generators can be used.
These generator must stick to the interface define in the base class
(tempest.common.negative.base).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Use third party product for fuzzy test generation and don’t integrate it in
Tempest.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Marc Koderer (mkoderer)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-3&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Will be tracked in:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/bp_fuzzy_test"&gt;https://etherpad.openstack.org/p/bp_fuzzy_test&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Add service tags to tests</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/add-service-tags.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt;
&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="add-service-tags-to-tests"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/add-service-tags"&gt;https://blueprints.launchpad.net/tempest/+spec/add-service-tags&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add new tags to all tests that specify which services get exercised by the
test.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When running tempest there is no clear way to specify only run tests that hit
a subset of services. For example, if you wanted to only run tests that used
cinder for the purposes of verifying a new driver there isn’t a method to
easily filter the tests run so that only cinder tests are run. The only option
is to manually construct a regex filter that executes the tests which you think
hit cinder’s api.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;To add a new decorator which will set a service attr for the test specified.
The decorator will have a single parameter which will be a list of the services
that the test exercises. The decorator will only except valid service
functional names in the list, for example compute, volumes, etc. If an invalid
service is passed into the decorator it will error out. The end result will be
that if you run tempest with the functional name of a service as a regex filter
you will only run the tests that touch the service directly or indirectly (ie
through a proxy api, like nova’s images api) So for the example in the problem
statement you would run:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;testr&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;parallel&lt;/span&gt; &lt;span class="n"&gt;volumes&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Or some variation of the command and only tests that uses cinder would be run.&lt;/p&gt;
&lt;p&gt;The service decorator is only required if the service name is not in the path
for the test. If a test exercises a service that contains the name in the path
then it’s redundant to use the service decorator because the regex filter will
already match. For the scenario tests since the is normally not a service name
in the path service tags are required for each test. This will be enforced with
a hacking rule.&lt;/p&gt;
&lt;p&gt;A test that is properly decorated will look something like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'compute'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'volume'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'image'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'network'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_minimum_basic_scenario&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;which indicates that test_minimum_basic_scenario uses the compute, volume,
image, and networking APIs.&lt;/p&gt;
&lt;p&gt;An additional feature of adding service tags is that by tagging the tests we
know that the service is required to run the test. This means we can skip the
test if the required service is set as not available in the config file. This
means that an additional skip decorator or skip exception won’t be needed if
for tests where service tagging is applicable. However, for cases where service
tags shouldn’t be used, such as places where the patch already contains the
name, the other skip methods will be required. (which they should already have)&lt;/p&gt;
&lt;p&gt;The decorator will be put in tempest/test.py while all the test methods in
any of the tempest test categories are subject to having the decorator applied
to them. Of course that’s assuming the previously mentioned usage conditions
are met by the test in question.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Matthew Treinish &amp;lt;&lt;a class="reference external" href="mailto:mtreinish%40kortar.org"&gt;mtreinish&lt;span&gt;@&lt;/span&gt;kortar&lt;span&gt;.&lt;/span&gt;org&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-1&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add service decorator&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add service tags to scenario tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Hacking Extension to force service tags in scenario tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Hacking Extension to ensure service tag isn’t in module path&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add service tags to applicable volume api tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add service tags to applicable compute api tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add service tags to applicable image api tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add service tags to applicable identity api tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add service tags to applicable network api tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add service tags to applicable orchestration api tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add service tags to applicable object api tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>API schema unification</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/api-schema-unification.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/api-schema-unification"&gt;https://blueprints.launchpad.net/tempest/+spec/api-schema-unification&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;API schema’s are used for different purposes in Tempest. This blueprint tries
to unify all existing ways.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Tempest currently has two sources of schema definitions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The response validation framework (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest/api_schema&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The negative test framework, which automatically creates requests
(&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;etc/schema&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Differences in a nutshell:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;File type
- &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;etc/schema&lt;/span&gt;&lt;/code&gt; files are json based
- &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest/api_schema&lt;/span&gt;&lt;/code&gt; files are python modules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data type
- &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;etc/schema&lt;/span&gt;&lt;/code&gt; contains Tempest related data (result code check base on
generators)
- &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest/api_schema&lt;/span&gt;&lt;/code&gt; contains data that can be imported from projects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Content
- &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;etc/schema&lt;/span&gt;&lt;/code&gt; is used for request generation
- &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tempest/api_schema&lt;/span&gt;&lt;/code&gt; is used for response validation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Move all schema’s to tempest/api_schema and use .py files instead of .json
files. This gives the possibility to use inheritance (or any other python
magic) to reduce code duplication. Inside of the py files the data format
will be dicts instead of json. This is due to the fact that all existing
definitions are already defined as dicts.&lt;/p&gt;
&lt;p&gt;The proposed folder structure:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;tempest&lt;/span&gt;
&lt;span class="o"&gt;|-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;api_schema&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="c1"&gt;# old content of ``etc/schema``&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;compute&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v3&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="c1"&gt;# old content of ``tempest/api_schema``&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;compute&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="o"&gt;|-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="next-steps"&gt;
&lt;h3&gt;Next steps&lt;/h3&gt;
&lt;p&gt;Out of scope of this blueprint but next steps:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Replace dicts with json definitons&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Having same/similar json style&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using same load mechanism&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;To be discussed.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Marc Koderer (mkoderer)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-final&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Move all files to one location&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rewrite all .json files to .py files and adapt negative testing framework&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unify filenames to have consistence between /response and /request&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Branchless Tempest</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/branchless-tempest.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/branchless-tempest"&gt;https://blueprints.launchpad.net/tempest/+spec/branchless-tempest&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tempest historically has been treated like a core service, with a
stable/foo release branch cut at every release of OpenStack. However,
Tempest is largely black box testing for the OpenStack API. The API is
represented by major versions, not by release tags, so Tempest should
not need branches. This change would have a number of interesting
cascading impacts, all of which should be positive for the health of
the project.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Our current release method for Tempest is to create a stable/foo
branch at every release of the OpenStack core services. This has a
number of side effects.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;tests are only added to master, and rarely backported. Completely
valid stable/havana testing has been lost.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;behavior changes can happen between stable/havana and master
because the version of the test run between them is different&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;what version of Tempest should a CDing public cloud test against?
(i.e. releases aren’t meaningful to lots of consumers)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;stable/havana ends up being used as a global flag for what features
are supported in OpenStack. But that’s not meaningful because most
environments run with a specific list of features enabled, not just
anything we shipped in stable/havana.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tempest has organically grown up as a tool that works really well in
our upstream gate, and medium well for people testing real
deployments. One of the reasons for this difference is that we use the
stable/foo Tempest branches to make assumptions about the relationship
of services, and devstack, which set up Tempest. Breaking this
convenience relationship will make us be much more dilligent in being
explicit about Tempest as a tool designed to run under any setup
environment.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Under the proposed branchless environment we’d do the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Not set a stable/icehouse Tempest branch&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;stable/icehouse integrated services would be tested with Tempest master&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest master would be gated on successful runs against:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;integrated services on master branches&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;integrated services on stable/icehouse branches&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(Note: this would double the # of jobs to be run on Tempest
proposed changes)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;post release, devstack-gate would change to explicitly set not only
the services that Tempest expects to tests, but also the extensions
it expects to test on each branch&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This has cascading implications, probably best described as scenarios
(I’ll use nova as the example service for all scenarios, mostly
because I’m more familiar with the extensions model, not because it’s
being picked on):&lt;/p&gt;
&lt;section id="scenario-1-new-tests-for-new-features"&gt;
&lt;h3&gt;Scenario 1: New Tests for new features&lt;/h3&gt;
&lt;p&gt;If a new feature is added to Nova in Juno, and a new test is added to
Tempest for this feature, this test will need to be behind a feature
flag (as the feature wasn’t available in Icehouse).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;nova stable/icehouse - Test Skipped, feature not available&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nova master - Test run&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This has the added benefit of making sure that a new Nova change is
added in such a way that it’s somehow discoverable that it’s not there
(i.e. behind an unloaded extension), and that Tempest has a knob for
configuring or not configuring it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="scenario-2-bug-fix-on-core-project-needing-tempest-change"&gt;
&lt;h3&gt;Scenario 2: Bug fix on core project needing Tempest change&lt;/h3&gt;
&lt;p&gt;Previously a behavior change in nova master that needed a Tempest
change could be changed via the tempest 2 step:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;propose change to nova, get a nova +2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;propose skip on Tempest, +Aed after nova +2 on change&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;land nova change in master and stable/icehouse (if required)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;land changed test in Tempest&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this new model the change &lt;em&gt;will also&lt;/em&gt; need to be backported to
stable/icehouse simultaneously. Or we decide that this is behavior
that should not be tested for, and drop the test entirely.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="scenario-3-new-tests-for-existing-features"&gt;
&lt;h3&gt;Scenario 3: New Tests for existing features&lt;/h3&gt;
&lt;p&gt;When adding new tests for existing features the new tests will need to
simultaneously pass when tested against nova master and nova
stable/icehouse. If we discover there is a difference of behavior
between the two, we’ll need to harmonize that behavior before landing
the test. We end up with 3 options:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;fix nova master to reflect nova stable/icehouse behavior (nova regression)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;fix nova stable/icehouse to reflect nova master behavior (missing
backport)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;decide to not land the Tempest test as it is attempting to verify
behavior we don’t consider stable&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="scenario-4-obsolete-tests"&gt;
&lt;h3&gt;Scenario 4: Obsolete Tests&lt;/h3&gt;
&lt;p&gt;A feature, like Nova XML v2 is deprecated is icehouse, and
(hypothetically) removed in juno. Howeve the XML v2 tests are in
Tempest, and we still need to test icehouse releases.&lt;/p&gt;
&lt;p&gt;This would be handled by a slow deprecation / feature flag:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Tempest v2 XML feature flag added (default to false)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Devstack-gate modified to set to true for stable/icehouse&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests are skipped in master, run in stable/icehouse&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once stable/icehouse is no longer supported upstream (Feb 2015),
tests are removed from Tempest entirely.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will mean that Tempest will contain more legacy code, however
that’s a trade off we take with the benefits this provides.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="additional-implications"&gt;
&lt;h3&gt;Additional Implications&lt;/h3&gt;
&lt;p&gt;This will have some interesting additional fallout:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;stable/* branches won’t be broken so often: with the massive number
of tempest patches that will require a working stable/* gate to
land, stable/* will get a lot more regular testing, and be in a
working state more often&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API guaruntees will tighten up. We’ll not only be testing that the
API does what we expect in Tempest, but also that it acts the same
across multiple versions. The added friction to breaking that kind
of behavior will slow down any future breaks there. This means a
practical increase of API compatibility requirements.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative is to continue with the current approach which uses
stable/* branches in Tempest. However that has caused more
unintentional coupling with devstack that we’d like, and I believe
that long term it’s the wrong approach for a test suite like Tempest.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Sean Dague &amp;lt;&lt;a class="reference external" href="mailto:sean%40dague.net"&gt;sean&lt;span&gt;@&lt;/span&gt;dague&lt;span&gt;.&lt;/span&gt;net&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Can optionally can list additional ids if they intend on doing
substantial implementation work on this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;Target Milestone for completion:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;April 17th for main infrastructure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Juno release cycle to handle various backports to devstack
stable/icehouse to support all tempest feature flags&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The work items span projects&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;devstack-gate generic branch override support (DONE)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;infrastructure jobs to gate Tempest on stable/icehouse (when
available)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;devstack-gate changes to select not only services, but also features
supported at each release&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;devstack support for setting stable/icehouse features&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;additional Tempest feature flags for optional features not yet
addressed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Only those listed above&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Move success response checking to tempest clients</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/client-checks-success.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/client-checks-success"&gt;https://blueprints.launchpad.net/tempest/+spec/client-checks-success&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To ensure API stability, api calls from tempest should check that the response
code in the success case is the expected value. Right now these checks are done
by the callers of the apis and in an inconsistent way. There is no policy or
guideline for when to check. It would be better if the response code was
always checked and api callers did not have to worry about this.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;It has been the policy that tests of an api should validate the response code.
Failure is handled by clients raising exceptions but the caller was supposed
to check the response on success. But many api tests also call other apis as
part of preparing for the actual test calls. In some cases we check the
response for those and in other cases we don’t, but really all calls should
be checked. Expecting code that calls apis to handle this is unnecessary and
error prone.&lt;/p&gt;
&lt;p&gt;The new code added to validate nova apis with schemas does the checking in
the client. We should move all checking to the client except where multiple
success return codes are possible.&lt;/p&gt;
&lt;p&gt;There are two methods on RestClient that handle this:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;validate_response(cls, schema, resp, body)&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This is used with the new schema validation.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;expected_success(self, expected_code, read_code)&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This was an earlier attempt to rationalize response checking but is only used
by the image clients.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Move all response checking to the clients. Use validate_response to check the
success code, adding schemas for apis that do not have them yet.
Then we can remove all checks from the test code
itself except where there are multiple possible 2xx responses. In that case
the caller should also check for a specific value.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Continue to clutter the test code with an inconsistent set of checks that will
be required after every api call.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;David Kranz &amp;lt;&lt;a class="reference external" href="mailto:dkranz%40redhat.com"&gt;dkranz&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;Target Milestone for completion:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Juno&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Change all api calls in the tempest clients to check response code, adding
new schemas as necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove all checking for 2xx from tests unless a specific value is expected
out of several that could be returned by the api.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Clients Return One Value</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/clients-return-one-value.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/clients-return-one-value"&gt;https://blueprints.launchpad.net/tempest/+spec/clients-return-one-value&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently tempest clients return a response code and body. Since we moved
response checking to clients, almost all callers of the clients ignore the
response code: &lt;a class="reference internal" href="client-checks-success.html"&gt;&lt;span class="doc"&gt;Move success response checking to tempest clients&lt;/span&gt;&lt;/a&gt;. It would be
much cleaner if clients returned a single response
object that was the body, with a property to get the response status and
headers if needed.&lt;/p&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Introduce a new ResponseBody class in rest_client:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ResponseBody&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;"""&lt;/span&gt;
&lt;span class="sd"&gt;    Class that wraps an http response and body into a single value.&lt;/span&gt;
&lt;span class="sd"&gt;    Callers that receive this object will normally use it as a dict but&lt;/span&gt;
&lt;span class="sd"&gt;    can extract the response if needed.&lt;/span&gt;
&lt;span class="sd"&gt;    """&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;body_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"request: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Body: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Change all the tempest clients to return this object and change all the calls
to the clients, getting rid of the current ‘_’ for the response.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;In theory this could be done in the rest client itself, rather than in each
service client, but that would imply much more regularity of the service
clients than we have. Also, it would then be necessary to change everything
at once because all the tests currently expect two values.&lt;/p&gt;
&lt;p&gt;The primary consideration is to not return unused values almost all the time.
Another alternative would be to have an argument to the rest client methods
that says whether a response should also be returned. I think the current
proposal is cleaner.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Unfortunately each client class must be changed lockstep with all calls to
that client.&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;David Kranz &amp;lt;&lt;a class="reference external" href="mailto:dkranz%40redhat.com"&gt;dkranz&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Yair Fried &amp;lt;&lt;a class="reference external" href="mailto:yfried%40redhat.com"&gt;yfried&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;Target Milestone for completion:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;kilo-1&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items-for-each-service-client"&gt;
&lt;h3&gt;Work Items (for each service client)&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Change all methods in the tempest clients to return ResponseBody.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change all calls to clients to receive just the response body and check
the response code if necessary.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Add a config file verification tool</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/config-verification.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt;
&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="add-a-config-file-verification-tool"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/config-verification"&gt;https://blueprints.launchpad.net/tempest/+spec/config-verification&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Add a new tempest tool that will query the services’ APIs to check if config
options are set correctly.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The tempest config file has tons of options and the number is just growing.
Additionally some of the options aren’t exactly trivial to set completely.
For example, the api extensions options are either all or a list of all the
enabled extensions. Most of the services support discovery of almost all the
options we use in the config file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;To write a tool which will use an existing config file and verify that
everything is set matching what the services report as being enabled. It will
start by reading in the config file and then use the tempest clients to query
the services to check that things like api versions, catalog types, and
extensions match what is reported by the services. It will also have a flag to
overwrite the config file with the values with reported by the services.&lt;/p&gt;
&lt;p&gt;This new tool will be added to the tools/ directory in the root of the tempest
tree along with the other helper utilities in tempest.&lt;/p&gt;
&lt;p&gt;The usage statement for the new tool will be something like the following:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;verify_tempest_config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;optional&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;    &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;exit&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;  &lt;span class="n"&gt;Update&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;api&lt;/span&gt; &lt;span class="n"&gt;queries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt;
                &lt;span class="n"&gt;assumes&lt;/span&gt; &lt;span class="n"&gt;whatever&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;incorrect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;In&lt;/span&gt;
                &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt; &lt;span class="n"&gt;checks&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;could&lt;/span&gt; &lt;span class="n"&gt;either&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;
                &lt;span class="n"&gt;incorrect&lt;/span&gt; &lt;span class="n"&gt;catalog&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;
                &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;assumed&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;incorrect&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt;
                &lt;span class="n"&gt;thus&lt;/span&gt; &lt;span class="n"&gt;changed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;will&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;
                &lt;span class="n"&gt;created&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orig&lt;/span&gt; &lt;span class="n"&gt;appended&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;nocopy&lt;/span&gt;  &lt;span class="n"&gt;Don&lt;/span&gt;&lt;span class="s1"&gt;'t create a copy of original config file when running&lt;/span&gt;
                &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To test the functionality of the tool unit tests will be added to verify that
both the verification functionality and the config file updating work as
intended.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative would be having a tool that generated the config file directly
however this has a chicken and egg problem. If you want to autconfigure tempest
using feature discovery you need to have auth to talk to the services, and the
auth is part of the config file. So instead of having some hybrid between a
generator and existing config having a tool which verifies an existing config
file would clean up any confusion. Also having an option to overwrite it with
the autodiscovery results will essentially be a config generator.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Matthew Treinish &amp;lt;&lt;a class="reference external" href="mailto:mtreinish%40kortar.org"&gt;mtreinish&lt;span&gt;@&lt;/span&gt;kortar&lt;span&gt;.&lt;/span&gt;org&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-1&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add basic verification script&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add config file updating feature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit tests for config verification functionality&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit tests for config file updating functionality&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Javelin 2</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/javelin2.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/javelin2"&gt;https://blueprints.launchpad.net/tempest/+spec/javelin2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;During the Juno Summit we discovered that Grenade was not doing the
resource validation that we believed it was. This had always been a
fragile part in grenade because complex validation of resources is
somewhat tough in bash. Instead we should build a tool in Tempest that
provides a way to create, validate, and destroy resources for us in
testing.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;We need a tool that will create a set of resources, can validate that
that set of resources exists at some later point in time (temporally
disconnected with no shared memory state), and can delete that set of
resources. Having this tool we can very easily test that resources
(users, images, servers, objects, etc) survive an upgrade undisturbed
in grenade testing.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Create a new javelin tool in tempest as part of the cmd directory.&lt;/p&gt;
&lt;p&gt;The usage of javelin is as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;destroy&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tenant&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tenant&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It requires admin keystone credentials to run because it must perform
user/tenant creation and inspection.&lt;/p&gt;
&lt;p&gt;Resources are specified in a resources.yaml file:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;tenants&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;javelin&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;discuss&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gungnir&lt;/span&gt;
    &lt;span class="n"&gt;tenant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin2&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gungnir2&lt;/span&gt;
    &lt;span class="n"&gt;tenant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;discuss&lt;/span&gt;

&lt;span class="c1"&gt;# resources that we want to create&lt;/span&gt;
&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin_cirros&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cirros&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.3.2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;
    &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ami&lt;/span&gt;
    &lt;span class="n"&gt;aki&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cirros&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.3.2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vmlinuz&lt;/span&gt;
    &lt;span class="n"&gt;ari&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cirros&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.3.2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x86_64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;initrd&lt;/span&gt;

&lt;span class="n"&gt;servers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;peltast&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin&lt;/span&gt;
    &lt;span class="n"&gt;flavor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;small&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin_cirros&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hoplite&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin&lt;/span&gt;
    &lt;span class="n"&gt;flavor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;medium&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;javelin_cirros&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;An important piece of the resource definition is the &lt;em&gt;owner&lt;/em&gt; field,
which is the user (that we’ve created) that is the owner of that
resource. All operations on that resource will happen as that regular
user to ensure that admin level access does not mask issues.&lt;/p&gt;
&lt;p&gt;The check phase will act like a unit test, using well known assert
methods to verify that the correct resources exist.&lt;/p&gt;
&lt;p&gt;This whole exercises has, and will continue to, enlighten us on ways
that the Tempest rest_client is difficult to consume outside of
Tempest tests. It should go a long way to making that a cleaner
distinction.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The alternative is to fix the grenade javelin exercises, though
they’ve been non functional for long enough that this doesn’t seem to
be a fruitful direction.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:sean%40dague.net"&gt;sean&lt;span&gt;@&lt;/span&gt;dague&lt;span&gt;.&lt;/span&gt;net&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Additional::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="mailto:emilien.macchi%40enovance.com"&gt;emilien&lt;span&gt;.&lt;/span&gt;macchi&lt;span&gt;@&lt;/span&gt;enovance&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;Juno-2&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;initial pass of javelin2 that supports create / check of similar
resources as were in grenade javelin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;integration of javelin2 into grenade&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;addition of destroy phase to clean up javelin2&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;expand # of resources beyond what was in grenade to ensure we aren’t
failing once we get beyond singletons&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;expansion of resources beyond what was in grenade
- ceilometer resources
- neutron resources&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;unit tests in tempest&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Check minimum version for CLI tests</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/minversion-check-for-cli-tests.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/minversion-check-for-cli-tests"&gt;https://blueprints.launchpad.net/tempest/+spec/minversion-check-for-cli-tests&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are CLI tests added to Tempest for commands which may not be available
yet in released versions of the clients, so downstream packagers would not
have those commands available for CI and the tests will fail.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The use case is testing stable/icehouse server code, i.e. nova, with packaged
versions of the clients that are supported for the stable/icehouse release of
Nova, which is python-novaclient-2.17.0 in the 2014.1 release of the server
code.&lt;/p&gt;
&lt;p&gt;With branchless Tempest there is no stable/icehouse branch for Tempest, and so
when new CLI tests are added to Tempest on master which require commands
or other functions in the clients, they can fail for downstream packagers
if the required commands/functions are not in released versions of the clients
on pypi.python.org, where the packager may be getting their source tar.gz from.&lt;/p&gt;
&lt;p&gt;One specific example here is the server-group-list CLI test added for the Nova
client which is not in a released version of python-novaclient. Anyone running
Tempest against a released version of the client will fail this new CLI test.&lt;/p&gt;
&lt;p&gt;Note that the community gate CI does not have an issue with this since Tempest
is run against trunk level code for the clients rather than released versions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add a simple decorator that can be used in the tempest/cli tests for checking
that the installed version of the client is at a minimum version to support the
test, otherwise the test is skipped.&lt;/p&gt;
&lt;p&gt;The decorator would be applied to feature tests introduced since Icehouse due
to the branchless Tempest strategy and the lack of a stable/icehouse branch.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There are not really any good alternatives to this issue for downstream
packagers/deployers if they are not running CI against trunk levels of code
for the clients. They can reset HEAD for Tempest to some arbitrary commit
around the time of the server release they are testing, e.g. sometime around
the 2014.1 release for stable/icehouse testing, but then they are frozen to
that commit in Tempest and do not get future bug fixes that would have been
backported when there were stable branches for Tempest. The other alternative
is manually excluding the unsupported CLI tests but this is cumbersome and
only works around the issue after the fact rather than putting the check in
the code when the test runs.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Matt Riedemann &amp;lt;&lt;a class="reference external" href="mailto:mriedem%40us.ibm.com"&gt;mriedem&lt;span&gt;@&lt;/span&gt;us&lt;span&gt;.&lt;/span&gt;ibm&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-2&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p&gt;Write the decorator code. The work in progress patch is here:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/100031/"&gt;https://review.openstack.org/#/c/100031/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apply the decorator to the CLI tests, with a primary focus on any tests
added after the 2014.1 Icehouse release, especially for those tests which
require newer client code than what is in a released version.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This is only an issue introduced by the “Branchless Tempest” blueprint but is
not technically tied to that blueprint’s implementation, but is listed here
for posterity:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/branchless-tempest"&gt;https://blueprints.launchpad.net/tempest/+spec/branchless-tempest&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>More Selectable Swift Tests</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/more-selectable-swift-tests.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt;
&lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="more-selectable-swift-tests"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/more-selectable-swift-tests"&gt;https://blueprints.launchpad.net/tempest/+spec/more-selectable-swift-tests&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enable to run API tests more flexibly for various Swift installation&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Currently, Tempest can select API test cases by referring discoverable_apis
config setting in tempest.conf. However, this feature supports only selecting
removable functions using WSGI middlewares although Swift has many
functional selectabilities other than using middlewares.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Add config parameters in tempest.conf for selecting tests for following Swift
body’s functionalities.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;(Old-style) Container Sync: mirroring objects in the container to another
container&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Object Versioning: versioning all objects in the container&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Discoverability: providing details about the Swift installation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Above features are independent of middleware settings. Whether to use some
middlewares or not is defined in Swift’s proxy server, on the other hand,
container sync and object versioning require settings in storage server and
running background daemons. Discoverability function is enabled/disabled at
proxy servers, but this function is to expose Swift’s installed middlewares
and other features, so the setting is independent of middleware settings.&lt;/p&gt;
&lt;p&gt;Config values are added in tempest.conf as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;feature&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;container_sync&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;object_versioning&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;discoverability&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Daisuke Morita &amp;lt;&lt;a class="reference external" href="mailto:morita.daisuke%40lab.ntt.co.jp"&gt;morita&lt;span&gt;.&lt;/span&gt;daisuke&lt;span&gt;@&lt;/span&gt;lab&lt;span&gt;.&lt;/span&gt;ntt&lt;span&gt;.&lt;/span&gt;co&lt;span&gt;.&lt;/span&gt;jp&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-3&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add config values to select tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Insert skip annotations into appropriate test cases&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Tempest support for multiple keystone API versions</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/multi-keystone-api-version-tests.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt; &lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="tempest-support-for-multiple-keystone-api-versions"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/multi-keystone-api-version-tests"&gt;https://blueprints.launchpad.net/tempest/+spec/multi-keystone-api-version-tests&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Decouple tempest from keystone version specifics and run tests with keystone v3&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Tempest code is tightly coupled with keystone V2 specific implementations.
Common classes (such as rest client and tenant isolation), test base classes
and test themselves all assume the identity service is provided by a keystone
v2 endpoint.
Tempest shall be able to run with a keystone V3 identity service, and newer versions
as they become available.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;A new configuration flag is introduced to specify the auth version to be used.
The flag is defined as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StrOpt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'auth_version'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'v2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Identity API version to be used for authentication "&lt;/span&gt;
                &lt;span class="s2"&gt;"for API tests."&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And it’s used to select the matching version of Credentials and Auth Provider:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_version&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'v2'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;credential_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;KeystoneV2Credentials&lt;/span&gt;
    &lt;span class="n"&gt;auth_provider_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;KeystoneV2AuthProvider&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_version&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'v3'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;credential_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;KeystoneV3Credentials&lt;/span&gt;
    &lt;span class="n"&gt;auth_provider_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;KeystoneV3AuthProvider&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvalidConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Unsupported auth version'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A number of refactors are required to achieve this and make sure we don’t need
to change test code again when moving to different keystone API versions.&lt;/p&gt;
&lt;p&gt;Authentication are factored out in an authentication provider. Credentials are handled
via a dedicated class, provided to tests by a credential manager.
Clients managers receive credentials and are the sole responsible for instantiating
clients and provide them to tests. At the moment client managers instantiate all
available clients when created. This is unnecessary, and it leads to issues when not
all openstack services are available for test. Client managers are thus changed to
lazy instantiation of clients.&lt;/p&gt;
&lt;p&gt;Manager __init__ method signature before and after refactor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Before&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tenant_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'json'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'json'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Authentication in rest client before and after refactor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Before&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
           &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_set_auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
           &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
       &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'X-Auth-Token'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;

       &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp_body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                       &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
       &lt;span class="c1"&gt;# Authenticate the request with the auth provider&lt;/span&gt;
       &lt;span class="n"&gt;req_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req_headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req_body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_provider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
           &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Access to credentials IDs from the tests, before and after refactor:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Before&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

       &lt;span class="c1"&gt;# Retrieve the ResellerAdmin tenant id&lt;/span&gt;
       &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os_admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;identity_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_users&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="n"&gt;reseller_user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;usr&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                               &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

       &lt;span class="c1"&gt;# Retrieve the ResellerAdmin tenant id&lt;/span&gt;
       &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tenants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os_admin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;identity_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_tenants&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="n"&gt;reseller_tenant_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tnt&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tnt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tenants&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tnt&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                                 &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_tenant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

       &lt;span class="c1"&gt;# Retrieve the ResellerAdmin user id&lt;/span&gt;
       &lt;span class="n"&gt;reseller_user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_credentials&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;

       &lt;span class="c1"&gt;# Retrieve the ResellerAdmin tenant id&lt;/span&gt;
       &lt;span class="n"&gt;reseller_tenant_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_credentials&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Areas affected by refactor:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Rest client (tempest/common/rest_client.py): move auth code to an external auth provider&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client managers (tempest/manager.py, tempest/clients.py, tempest/scenario/manager.py): work with a Credentials class. Lazy load of clients.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests base classes (tempest/api/**/base.py): adapt where needed to modified rest client, client manager and credentials&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests: adapt where needed to modified rest client, client manager and credentials&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could change all the code in place - without refactoring - adding checks for the
configured auth version. This would still require touching a considerable chunk
of tempest code, without the benefit for future keystone versions.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Andrea Frittoli &amp;lt;&lt;a class="reference external" href="mailto:andrea.frittoli%40hp.com"&gt;andrea&lt;span&gt;.&lt;/span&gt;frittoli&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-1&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Move auth from rest_client to auth provider&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide unit tests for the new auth and credential classes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor Manager, Credentials class everywhere&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client Manager provide client lazy load&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tenant isolation support for V3&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide multi auth-version for API tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide multi auth-version for scenario tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide multi auth-version for CLI tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide multi auth-version for 3rd part tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide multi auth-version for stress framework&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add experimental job with auth_version = v3&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Python bindings and CLI are not yet all V3 ready. Some of the work in this blueprint
will have to be postponed until this is fixed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Tempest Post-run Cleanup</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/post-run-cleanup.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/post-run-cleanup"&gt;https://blueprints.launchpad.net/tempest/+spec/post-run-cleanup&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The existing script, /tempest/stress/cleanup.py, can be used to do some
basic cleanup after a Tempest run, but a more robust tool is needed
to report as much information as possible about dangling objects (leaks)
left behind after a tempest run in an attempt to help find out why the
object(s) was left behind and report a bug against the root cause. Also
the tool should completely reset the environment to the pre-run state
should tempest leave behind any dangling objects.&lt;/p&gt;
&lt;p&gt;The idea is that the user should be able look at the report generated
and find the root cause as to why an object was not deleted. Also the
tool will return the system back into a state where tempest can be
re-run with the expectation that the same test results will be returned.&lt;/p&gt;
&lt;p&gt;Currently there can be a good deal of manual work needed, depending
on what tests fail, to return to this pre-run state. This blueprint
is designed to alleviate this issue.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-changes"&gt;
&lt;h2&gt;Proposed changes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Keep /tempest/stress/cleanup.py as a starting point and extend it.
It should be moved to from /tempest/stress to tempest/cmd/ and
an entry point should be added for it as well. This way it is installed
as a binary when setup.py is run, which also allows it to be unit
tested.  Currently the tools uses the tempest OpenStack clients and
this will remain unchanged.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fix cleanup.py to delete objects by looping through each tenant/user,
over the way it currently works, which is to use the admin user and
“all_tenants” argument, as some object types don’t support this
argument, Floating IPs for example.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Currently cleanup.py deletes all objects across all users/tenants.
Add two runtime arguments: –init-saved-state, that creates a JSON
file containg the pre-tempest run state and –preserve-state, that
will preserve the deployment’s pre-tempest run state, including tenants
and users defined in tempest.conf. This will enforce that the
deployment is in the same state it was prior to running tempest and
allow tempest to be run again without having to reconfigure tempest
and recreate the tempest test users etc. For example, if
–preserve-state is true cleanup will load the JSON file (created by
running cleanup with –init-saved-state flag prior to tempest run)
containing the preserved state of the environment and marshal the data
to some defined instance variables. Then, when cleanup is looping
through floating ips we would have something like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;for f in floating_ips:&lt;/dt&gt;&lt;dd&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;if not preserve or (preserve and f[‘id’] not in self.floating_ips):&lt;/dt&gt;&lt;dd&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;try:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;admin_manager.floating_ips_client.delete_floating_ip(f[‘id’])&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;except Exception:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;…&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cleanup.py currently deletes servers (instances), keypairs,
security groups, floating ips, users, tenants, snapshots and volumes.
It should also delete any stacks, availability zones and any other objects
created by Tempest, full list TBD.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As mentioned in the overview section above some test failures leave the
system in a strange state. For example, an instance cannot be deleted
because it is in Error state.  Even after using CLI to reset the instance
to Active state, future delete calls just result in Error state once
again. Such a case indicates a bug in OpenStack.  This tool should
should provide as much detail as possible as to what went wrong so
a defect can be opened against the problem(s).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add argument, –dry-run, that runs cleanup in reporting mode only, showing
what would be deleted without doing the actual deletes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="scenario-1-run-cleanup-py"&gt;
&lt;h3&gt;Scenario 1: run cleanup.py&lt;/h3&gt;
&lt;p&gt;This is the current behavior, which deletes all objects in the system,
with the exception of the missing ones, stacks and availability zones
for example.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="scenario-2-run-cleanup-py-preserve-state"&gt;
&lt;h3&gt;Scenario 2: run cleanup.py –preserve-state&lt;/h3&gt;
&lt;p&gt;Same as Scenario 1 except that objects defined in tempest.conf, that
are used in a Tempest run are preserved.&lt;/p&gt;
&lt;p&gt;For example (exceptions are variables defined in tempest.conf):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;delete all users except: username, alt_username, admin_username&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete all tenants except: tenant_name, alt_tenant_name, admin_tenant_name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete all images except: image_ref, image_ref_alt&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="additional-implications"&gt;
&lt;h3&gt;Additional Implications&lt;/h3&gt;
&lt;p&gt;There are cases where cruft will be left in the database do to openstack defects
that don’t allow objects to be removed during the cleanup process.
In such cases resetting the system to the pre-existing state requires direct
interaction with the database.  It may be useful to design the cleanup script
so that it has a pluggable interface,  where downstream functionality can be
added to automate required database interactions for example. Although
the API delete failure indicates an upstream bug that needs to be fixed, until
that bug is fixed testing the environment further is blocked until the records
are deleted.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;David Paterson &amp;lt;&lt;a class="reference external" href="mailto:davpat2112%40yahoo.com"&gt;davpat2112&lt;span&gt;@&lt;/span&gt;yahoo&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Can optionally can list additional ids if they intend on doing
substantial implementation work on this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;Target Milestone for completion:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Juno release cycle, approximately the week of July 24th, 2014.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;refactor location of cleanup.py&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;register new runtime arguments in cleanup.py&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;enable filtering deletions based on –preserve-state argument
and values defined in tempest.conf&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;write code for detailed reporting on dangling resources and
possible root cause for cleanup failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;implement code for –dry-run argument, report only mode.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;Only those listed above&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Rearrange Nova Response Schemas</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/rearrange-nova-response-schemas.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/rearrange-nova-response-schemas"&gt;https://blueprints.launchpad.net/tempest/+spec/rearrange-nova-response-schemas&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Rearrange Nova Response Schemas&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Compute response schemas were implemented for v2 and v3 APIs.
At that time common parts were defined in common schemas and
version specific into respective directories (v2 &amp;amp; v3).&lt;/p&gt;
&lt;p&gt;Now v3 API is not valid for Nova and v2 and v2.1 API`s response are same.
After removing v3 schemas (&lt;a class="reference external" href="https://review.openstack.org/#/c/141274/"&gt;https://review.openstack.org/#/c/141274/&lt;/a&gt;)
we have only 1 set of schemas for v2 (/v2.1) APIs but those end up in
scattered structure.&lt;/p&gt;
&lt;p&gt;It is difficult to read and understand API’ complete schema as they are defined
in multiple files.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Rearrange current schemas into better file/directory structure and if needed
then, defined schemas name more clearly as per API methods.&lt;/p&gt;
&lt;p&gt;As Nova v2.1 APIs are current API (&lt;a class="reference external" href="https://review.openstack.org/#/c/149948/"&gt;https://review.openstack.org/#/c/149948/&lt;/a&gt;),
we should move all current schema files to directory name v2.1. As nova is going
to release microversion also, schema files for microversion needs to go in their
respective new directories.&lt;/p&gt;
&lt;p&gt;Below are the re arrangement details-&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Directory structure-&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;api_schema/response/compute/v2.1/  -&amp;gt; will contain all the schema files for v2.1.
api_schema/response/compute/v2.2/  -&amp;gt; will contain all the schema files for v2.2.
and so on&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Each resource schema will be defined in single files under v2.1 directory&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;For example -hypervisors.py will have all schema of hypervisor resource API.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each schema name should be clear enough to easily understand the API for
which they are defined. For example -&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;list_hypervisors - list hypervisors API schema&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;list_hypervisors_detail - detail list of hypervisors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_get_update_&amp;lt;resource name&amp;gt; - If schema is same for create, get
&amp;amp; update API of any resource.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Note- Most of the schema names are defined as per above guidelines but
if there are some misleading names, those needs to be fixed.
For example - quota class set and quota set schemas are defined with same
name (quota_set) in quotas.py and quota_classes.py.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After above re arrangement it will be easy to maintain those schemas.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Keep things as they are which will keep schemas readability and maintenance
difficult.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Ghanshyam Mann&amp;lt;&lt;a class="reference external" href="mailto:ghanshyam.mann%40nectechnologies.in"&gt;ghanshyam&lt;span&gt;.&lt;/span&gt;mann&lt;span&gt;@&lt;/span&gt;nectechnologies&lt;span&gt;.&lt;/span&gt;in&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;p&gt;Target Milestone for completion:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;kilo-3&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Change schema as per proposed idea.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Import the changed schema according to their new path.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Work will be tracked in: &lt;a class="reference external" href="https://etherpad.openstack.org/p/rearrange-compute-response-schemas"&gt;https://etherpad.openstack.org/p/rearrange-compute-response-schemas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Tempest Client for Scenario Tests</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/tempest-client-scenarios.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/tempest-client-scenarios"&gt;https://blueprints.launchpad.net/tempest/+spec/tempest-client-scenarios&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tempest currently has tests using 2 different OpenStack clients. The
first is a client written in Tempest for testability and
debugability. The second is the various native clients. This adds debt
to the Tempest code that we should remove.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;As Tempest grew up we grew tests that included poking directly at the
raw API with our own client, as well as through the various native
clients for the projects. As the volume of tests have grown, and some
of the complexities in Tempest (like tenant isolation) have shown up,
the 2 client strategy has become problematic.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;It means that various abstractions need to be built above the
clients to do things like waiting for resources to be created,
handling tenant isolation, and doing safe cleanup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The debugging output is radically different depending on the client
that has failed. We can fix and react to a debuability issue in the
Tempest client in tree. Addressing something as simple as reduction
of extraneous token messages needs to be landed in 10 trees before
it’s fixed in a tempest run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It’s demotivating to work on the code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;We do a wholesale cut over of the openstack clients to the Tempest
client in all the scenario tests.&lt;/p&gt;
&lt;p&gt;We remove the abstractions that were built just for these
clients.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Keep things as they are. This however has begun to be a top issue
impacting gate debugability.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Masayuki Igawa &amp;lt;&lt;a class="reference external" href="mailto:igawa%40mxs.nes.nec.co.jp"&gt;igawa&lt;span&gt;@&lt;/span&gt;mxs&lt;span&gt;.&lt;/span&gt;nes&lt;span&gt;.&lt;/span&gt;nec&lt;span&gt;.&lt;/span&gt;co&lt;span&gt;.&lt;/span&gt;jp&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Andrea Frittoli &amp;lt;&lt;a class="reference external" href="mailto:andrea.frittoli%40hp.com"&gt;andrea&lt;span&gt;.&lt;/span&gt;frittoli&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Daisuke Morita &amp;lt;&lt;a class="reference external" href="mailto:morita.daisuke%40lab.ntt.co.jp"&gt;morita&lt;span&gt;.&lt;/span&gt;daisuke&lt;span&gt;@&lt;/span&gt;lab&lt;span&gt;.&lt;/span&gt;ntt&lt;span&gt;.&lt;/span&gt;co&lt;span&gt;.&lt;/span&gt;jp&lt;/a&gt;&amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;replace official clients in tempest/scenario with tempest clients&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add hacking rule to provide use of official clients&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;remove tenant isolation abstraction&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Will be tracked in:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/tempest-client-scenarios"&gt;https://etherpad.openstack.org/p/tempest-client-scenarios&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="referenences"&gt;
&lt;h2&gt;Referenences&lt;/h2&gt;
&lt;p&gt;Mailing list discussion - &lt;a class="reference external" href="http://lists.openstack.org/pipermail/openstack-dev/2014-July/039879.html"&gt;http://lists.openstack.org/pipermail/openstack-dev/2014-July/039879.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Test accounts</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/test-accounts.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt; &lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="test-accounts"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/test-accounts"&gt;https://blueprints.launchpad.net/tempest/+spec/test-accounts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tempest test accounts management&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Tempest relies on tenant isolation for parallel test executions. Test accounts
are provisioned on the fly for each test class to ensure isolation.
This approach requires an identity admin account being available for the
provisioning.
The aim of this blueprint is to provide an alternative solution,
specifically pre-provisioned accounts, and to solve the problems related to
this approach: how test accounts are allocated to different test processes
spawned by testr, including alt user and other test accounts, and how we can
support both tenant isolation and this new implementation in tempest, and
easily switch between the two.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Abstract the existing tenant isolation mechanism to a credentials provider
meta-class with two different implementations:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A configured credentials provider, which uses credentials statically
configured in tempest.conf. This can be used to avoid including admin
credentials in the configuration at test run-time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A dynamic credentials provider, which uses the existing tenant isolation
logic to generate credentials on the fly using identity admin credentials&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Move the logic that selects test accounts out of test and test base classes
into a separate &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;credentials_factory&lt;/span&gt;&lt;/code&gt; class, which provides the correct
implementation of tenant isolation to tests based on configuration.
The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;credentials_factory&lt;/span&gt;&lt;/code&gt; is the sole responsible for reading configuration
related to test accounts, and the existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get_credentials&lt;/span&gt;&lt;/code&gt; methods from
auth.py should be dropped, and the corresponding logic implemented in the
configured credentials provider.&lt;/p&gt;
&lt;p&gt;Change from something like this repeated in various slightly different flavours:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compute&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allow_tenant_isolation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isolated_creds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_primary_creds&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compute&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allow_tenant_isolation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isolated_creds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_alt_creds&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os_alt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AltManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To a code where tenant isolation is hidden to tests:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# Provides the right implementation based on the configuration&lt;/span&gt;
&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isolated_creds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;credentials_factory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_isolated_credentials&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# This may raise an AccountNotAvailable&lt;/span&gt;
&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isolated_creds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_primary_creds&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;os_alt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clients&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;cls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isolated_creds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_alt_creds&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Preserve the tenant_isolation flag, but move it out of compute to a
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;common&lt;/span&gt;&lt;/code&gt; configuration group. Remove the current user account
settings from the identity section, and create lists of settings in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;common&lt;/span&gt;&lt;/code&gt; configuration group instead, for users, tenants, passwords and
domains.&lt;/p&gt;
&lt;p&gt;As an indication users expects a list of values = CONCURRENCY x 2.
Tenant, password and domain will expect a list of values either the same
length as users, or with just 1 element, which represents the default value
for all users.&lt;/p&gt;
&lt;p&gt;Once a test is completed it releases the accounts it requested, and
they are available for the next test to use.
This should highlight issues with resource cleanup in tests, such as
resource leaks and non-blocking deletes.&lt;/p&gt;
&lt;p&gt;The configured credentials provider implements the logic to provide accounts
to tests from the pre-configured ones, ensuring that one account is only used
by one test only at any time. We use a file based reservation mechanism,
which addresses the following issues:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;avoid the initial race where parallel test processes all want to allocate a
test account at once&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ensure that file(s) used for reservation are cleanup up when testing is done,
even though each process alone does not have the knowledge about when test
overall is completed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How many accounts will tests require may vary depending on which tests
are executed. At the moment two per process is typically enough, if we
exclude identity tests, which we can do because they mostly require admin
credentials anyways, so they would not run without admin credentials
configured. Still it may happen that no account is available when test request
it. In this case we the test will fail with AccountNotAvailable.&lt;/p&gt;
&lt;section id="assumptions"&gt;
&lt;h3&gt;Assumptions&lt;/h3&gt;
&lt;p&gt;All non-admin test accounts have the same roles associated.
All resources associated to an account that require admin credentials
for creation are pre-created.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Implement static allocation of accounts to test processes to avoid the
reservation system. That requires either naming conventions for test accounts,
or each test process to be aware of it’s own ID, so that a selection can be
made based on hashing.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Andrea Frittoli &amp;lt;&lt;a class="reference external" href="mailto:andrea.frittoli%40hp.com"&gt;andrea&lt;span&gt;.&lt;/span&gt;frittoli&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Juno-final&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Expose the tenant isolation interface into a metaclass&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move the existing tenant isolation to the dynamic accounts provider&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the static accounts provider and reservation mechanism, including
the modified configuration options&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement a credentials_factory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adapt tests and test base classes (in multiple steps)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item><item><title>Test accounts Continued</title><link>https://specs.openstack.org/openstack/qa-specs/specs/tempest/implemented/test-accounts-continued.html</link><description>&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;licensed&lt;/span&gt; &lt;span class="n"&gt;under&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Creative&lt;/span&gt; &lt;span class="n"&gt;Commons&lt;/span&gt; &lt;span class="n"&gt;Attribution&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="n"&gt;Unported&lt;/span&gt; &lt;span class="n"&gt;License&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;creativecommons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;licenses&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;legalcode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="test-accounts-continued"&gt;

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/tempest/+spec/test-accounts-continued"&gt;https://blueprints.launchpad.net/tempest/+spec/test-accounts-continued&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tempest test accounts management&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The “Test accounts” spec provided support for preprovisioned accounts,
as well as for those accounts to be configured in YAML format.
There are a few limitations to the existing limitations:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;all accounts must belong to the same network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;all accounts must be of the same type, so we have a combination of
accounts configured in tempest.conf and in accounts.yaml&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Extend the format of the accounts YAML file to support specifying the
name and type of resources pre-provisioned for an account. Such resources
are intended to be reused by tests, and shall not be cleaned-up.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'user_1'&lt;/span&gt;
      &lt;span class="n"&gt;tenant_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'test_tenant_1'&lt;/span&gt;
      &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'test_password'&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'my_network'&lt;/span&gt;
      &lt;span class="n"&gt;subnet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'my_subnet'&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'user_2'&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Extend the format of the accounts YAML file to support specifying the
account type of an account. We may have an account type identifier,
or alternatively a list of roles.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'admin'&lt;/span&gt;
      &lt;span class="n"&gt;tenant_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'admin_tenant'&lt;/span&gt;
      &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'admin_password'&lt;/span&gt;
  &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'admin'&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'swift_admin'&lt;/span&gt;
      &lt;span class="n"&gt;tenant_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'admin_tenant'&lt;/span&gt;
      &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'admin_password'&lt;/span&gt;
  &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;reseller&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Adapt the credentials providers to be able to handle credentials
requests based on specific roles as well as account type (available
today via dedicated methods).&lt;/p&gt;
&lt;p&gt;The abstract implementation would be something like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nd"&gt;@abc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abstractmethod&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_creds_by_roles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_creds_by_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;get_primary_creds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Adapt the non pre-provisioned account scenario to also read accounts
from the accounts YAML file, and deprecate any account information
in tempest.conf beyond the name of account file.&lt;/p&gt;
&lt;p&gt;Provide a tool to be consumed by devstack to generate the
pre-provisioned accounts and the corresponding YAML file. Work on
this is already started here &lt;a class="reference external" href="https://review.openstack.org/#/c/107758/"&gt;https://review.openstack.org/#/c/107758/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Integrate with the post-run clean-up tool, to avoid deleting
pre-provisioned resources specified in the YAML file.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The current implementation is functional but incomplete, so the only
alternative is not to use it, or suffer its limitation.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Andrea Frittoli &amp;lt;&lt;a class="reference external" href="mailto:andrea.frittoli%40hp.com"&gt;andrea&lt;span&gt;.&lt;/span&gt;frittoli&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="milestones"&gt;
&lt;h3&gt;Milestones&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Target Milestone for completion:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Kilo-final&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Extend the YAML file parser&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the non-cleanup of configure resources&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deprecate account configuration options&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read account info from YAML, with fallback to deprecated
configuration options&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement provisioning tool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch devstack and job definition to use the accounts YAML file in
case of tenant isolation as well as pre-provisioned accounts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure check/gate to run a combination of tenant isolation and
pre-provisioned accounts&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Jul 2015 00:00:00 </pubDate></item></channel></rss>