Skip to content

Commit

Permalink
Merge "Introduce in-tree Rally specs"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Mar 9, 2015
2 parents 59766a5 + c3b27c6 commit 52b7252
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 1 deletion.
14 changes: 14 additions & 0 deletions doc/specs/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Rally Specs
===========

Specs are detailed description of proposed changes in project. Usually they
answer on what, why, how to change in project and who is going to work on
change.

This directory contains 2 subdirectories:

- in-progress - These specs are approved, but they are not implemented yet
- implemented - Implemented specs archive

If you are looking for full rally road map overview go `here <https://docs.google.com/a/mirantis.com/spreadsheets/d/16DXpfbqvlzMFaqaXAcJsBzzpowb_XpymaK2aFY2gA2g/edit#gid=0>`_.

10 changes: 10 additions & 0 deletions doc/specs/implemented/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Rally Specs
===========

Specs are detailed description of proposed changes in project. Usually they
answer on what, why, how to change in project and who is going to work on
change.

This directory contains files with implemented specs, 1 file is 1 spec.

If you are looking for full rally road map overview go `here <https://docs.google.com/a/mirantis.com/spreadsheets/d/16DXpfbqvlzMFaqaXAcJsBzzpowb_XpymaK2aFY2gA2g/edit#gid=0>`_.
12 changes: 12 additions & 0 deletions doc/specs/in-progress/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Rally Specs
===========

Specs are detailed description of proposed changes in project. Usually they
answer on what, why, how to change in project and who is going to work on
change.


This directory contains files with accepted by not implemented specs,
1 file is 1 spec.

If you are looking for full rally road map overview go `here <https://docs.google.com/a/mirantis.com/spreadsheets/d/16DXpfbqvlzMFaqaXAcJsBzzpowb_XpymaK2aFY2gA2g/edit#gid=0>`_.
89 changes: 89 additions & 0 deletions doc/specs/template.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode

..
This template should be in ReSTructured text. The filename in the git
repository should match the launchpad URL, for example a URL of
https://blueprints.launchpad.net/heat/+spec/awesome-thing should be named
awesome-thing.rst . Please do not delete any of the sections in this
template. If you have nothing to say for a whole section, just write: None
For help with syntax, see http://sphinx-doc.org/rest.html
To test out your formatting, see http://www.tele3.cz/jbar/rest/rest.html
=======================
The title of your Spec
=======================

Rally Road map:

https://docs.google.com/a/mirantis.com/spreadsheets/d/16DXpfbqvlzMFaqaXAcJsBzzpowb_XpymaK2aFY2gA2g/edit#gid=0


Introduction paragraph -- why are we doing anything?

Problem description
===================

A detailed description of the problem.

Proposed change
===============

Here is where you cover the change you propose to make in detail. How do you
propose to solve this problem?

If this is one part of a larger effort make it clear where this piece ends. In
other words, what's the scope of this effort?

Include where in the heat tree hierarchy this will reside.

Alternatives
------------

This is an optional section, where it does apply we'd just like a demonstration
that some thought has been put into why the proposed approach is the best one.

Implementation
==============

Assignee(s)
-----------

Who is leading the writing of the code? Or is this a blueprint where you're
throwing it out there to see who picks it up?

If more than one person is working on the implementation, please designate the
primary author and contact.

Primary assignee:
<launchpad-id or None>

Can optionally can list additional ids if they intend on doing
substantial implementation work on this blueprint.

Milestones
----------

Target Milestone for completion:
Juno-1

Work Items
----------

Work items or tasks -- break the feature up into the things that need to be
done to implement it. Those parts might end up being done by different people,
but we're mostly trying to understand the timeline for implementation.


Dependencies
============

- Include specific references to specs and/or blueprints in heat, or in other
projects, that this one either depends on or is related to.

- Does this feature require any new library dependencies or code otherwise not
included in OpenStack? Or does it depend on a specific version of library?

119 changes: 119 additions & 0 deletions tests/unit/doc/test_specs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import glob
import os
import re

import docutils.core

from tests.unit import test


class TitlesTestCase(test.TestCase):

specs_path = os.path.join(
os.path.dirname(__file__),
os.pardir, os.pardir, os.pardir,
"doc", "specs")

def _get_title(self, section_tree):
section = {"subtitles": []}
for node in section_tree:
if node.tagname == "title":
section["name"] = node.rawsource
elif node.tagname == "section":
subsection = self._get_title(node)
section["subtitles"].append(subsection["name"])
return section

def _get_titles(self, spec):
titles = {}
for node in spec:
if node.tagname == "section":
# Note subsection subtitles are thrown away
section = self._get_title(node)
titles[section["name"]] = section["subtitles"]
return titles

def _check_titles(self, filename, expect, actual):
missing_sections = [x for x in expect.keys() if x not in actual.keys()]
extra_sections = [x for x in actual.keys() if x not in expect.keys()]

msgs = []
if len(missing_sections) > 0:
msgs.append("Missing sections: %s" % missing_sections)
if len(extra_sections) > 0:
msgs.append("Extra sections: %s" % extra_sections)

for section in expect.keys():
missing_subsections = [x for x in expect[section]
if x not in actual.get(section, {})]
# extra subsections are allowed
if len(missing_subsections) > 0:
msgs.append("Section '%s' is missing subsections: %s"
% (section, missing_subsections))

if len(msgs) > 0:
self.fail("While checking '%s':\n %s"
% (filename, "\n ".join(msgs)))

def _check_lines_wrapping(self, tpl, raw):
for i, line in enumerate(raw.split("\n")):
if "http://" in line or "https://" in line:
continue
self.assertTrue(
len(line) < 80,
msg="%s:%d: Line limited to a maximum of 79 characters." %
(tpl, i+1))

def _check_no_cr(self, tpl, raw):
matches = re.findall("\r", raw)
self.assertEqual(
len(matches), 0,
"Found %s literal carriage returns in file %s" %
(len(matches), tpl))

def _check_trailing_spaces(self, tpl, raw):
for i, line in enumerate(raw.split("\n")):
trailing_spaces = re.findall(" +$", line)
self.assertEqual(
len(trailing_spaces), 0,
"Found trailing spaces on line %s of %s" % (i+1, tpl))

def test_template(self):
with open(os.path.join(self.specs_path, "template.rst")) as f:
template = f.read()

spec = docutils.core.publish_doctree(template)
template_titles = self._get_titles(spec)

for d in ["implemented", "in-progress"]:
spec_dir = "%s/%s" % (self.specs_path, d)

self.assertTrue(os.path.isdir(spec_dir),
"%s is not a directory" % spec_dir)
for filename in glob.glob(spec_dir + "/*"):
if filename.endswith("README.rst"):
continue

self.assertTrue(
filename.endswith(".rst"),
"spec's file must have .rst ext. Found: %s" % filename)
with open(filename) as f:
data = f.read()

titles = self._get_titles(docutils.core.publish_doctree(data))
self._check_titles(filename, template_titles, titles)
self._check_lines_wrapping(filename, data)
self._check_no_cr(filename, data)
self._check_trailing_spaces(filename, data)
3 changes: 2 additions & 1 deletion tests/unit/doc/test_task_samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ def test_task_config_pair_existance(self):
inexistent_paths.append(json_path)

if inexistent_paths:
self.fail("Sample task configs are missing:\n%r" % inexistent_paths)
self.fail("Sample task configs are missing:\n%r"
% inexistent_paths)

def test_task_config_pairs_equality(self):
for dirname, dirnames, filenames in os.walk(self.samples_path):
Expand Down

0 comments on commit 52b7252

Please sign in to comment.