Retire dox repository
This change removes all content from the repository and adds the usual README file to point out that the repository is retired following the process from https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project Depends-On: https://review.opendev.org/701446 Change-Id: I49ddca0f6c4a5d0e546e22a5515d405f0e869eab
This commit is contained in:
parent
3087d31254
commit
06e67f317d
@ -1,7 +0,0 @@
|
||||
[run]
|
||||
branch = True
|
||||
source = dox
|
||||
omit = dox/tests/*,dox/openstack/*
|
||||
|
||||
[report]
|
||||
ignore_errors = True
|
55
.gitignore
vendored
55
.gitignore
vendored
@ -1,55 +0,0 @@
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
lib
|
||||
lib64
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
.testrepository
|
||||
cover
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# Complexity
|
||||
output/*.html
|
||||
output/*/index.html
|
||||
|
||||
# Sphinx
|
||||
doc/build
|
||||
|
||||
# pbr generates these
|
||||
AUTHORS
|
||||
ChangeLog
|
||||
|
||||
# Editors
|
||||
*~
|
||||
.*.swp
|
||||
|
||||
# Autogenerated by ourseleves when testing the dox.yml
|
||||
.dox
|
3
.mailmap
3
.mailmap
@ -1,3 +0,0 @@
|
||||
# Format is:
|
||||
# <preferred e-mail> <other e-mail 1>
|
||||
# <preferred e-mail> <other e-mail 2>
|
@ -1,7 +0,0 @@
|
||||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
@ -1,16 +0,0 @@
|
||||
If you would like to contribute to the development of OpenStack,
|
||||
you must follow the steps in this page:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html
|
||||
|
||||
Once those steps have been completed, changes to OpenStack
|
||||
should be submitted for review via the Gerrit tool, following
|
||||
the workflow documented at:
|
||||
|
||||
http://docs.openstack.org/infra/manual/developers.html#development-workflow
|
||||
|
||||
Pull requests submitted through GitHub will be ignored.
|
||||
|
||||
Bugs should be filed on Storyboard, not GitHub:
|
||||
|
||||
https://storyboard.openstack.org
|
@ -1,4 +0,0 @@
|
||||
dox Style Commandments
|
||||
===============================================
|
||||
|
||||
Read the OpenStack Style Commandments http://docs.openstack.org/developer/hacking/
|
175
LICENSE
175
LICENSE
@ -1,175 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
@ -1,6 +0,0 @@
|
||||
include AUTHORS
|
||||
include ChangeLog
|
||||
exclude .gitignore
|
||||
exclude .gitreview
|
||||
|
||||
global-exclude *.pyc
|
155
README.rst
155
README.rst
@ -1,149 +1,10 @@
|
||||
===
|
||||
dox
|
||||
===
|
||||
This project is no longer maintained.
|
||||
|
||||
dox is a tool for using docker containers to run local tests, inspired by
|
||||
tox and virtualenv for python. There are two elements to its configuration:
|
||||
The contents of this repository are still available in the Git
|
||||
source code management system. To see the contents of this
|
||||
repository before it reached its end of life, please check out the
|
||||
previous commit with "git checkout HEAD^1".
|
||||
|
||||
* What commands should be run?
|
||||
|
||||
* In what image should they be run?
|
||||
|
||||
If there is a dox.yml file, you're set. You want to specify what image to
|
||||
use and what commands to run. You win::
|
||||
|
||||
image: ubuntu:trusty
|
||||
commands: |
|
||||
pip install . -r test-requirements.txt
|
||||
python setup.py test
|
||||
|
||||
You might either not be willing to commit to dox as a way of life yet, or you
|
||||
may want to use dox in a project that similarly has not done so.
|
||||
|
||||
What commands should be run
|
||||
---------------------------
|
||||
|
||||
dox.yml wins.
|
||||
|
||||
If there is a tox.ini file, the commands specified in the base [testenv]
|
||||
will be used.
|
||||
|
||||
If there is a .travis.yml file, the script section will be used.
|
||||
|
||||
If there are none of those things, dox will do its best to infer what
|
||||
should be done. Examining the directory can often provide hints if you
|
||||
haven't been too clever. For instance, if you have a Gruntfile, you probably
|
||||
want to run grunt. If you have a Makefile, then make && make test is probably
|
||||
your bag. If you have a Makefile.am, you probably want to run autotools first.
|
||||
If you have a setup.py file, python setup.py test is a likely choice (although
|
||||
in that case, you probably haven't done it right because setuptools support
|
||||
for this is quite awful.)
|
||||
|
||||
After all of that, if we still can't figure out what you want - it's probably
|
||||
easiest to just edit a file called dox.yml and put in a section telling us
|
||||
what to do.
|
||||
|
||||
In what image should they be run
|
||||
--------------------------------
|
||||
|
||||
Again, dox.yml wins, and thanks for making things easy!
|
||||
|
||||
If there is a tox.ini file, and it contains a [docker] section, the value in
|
||||
"image" will be used::
|
||||
|
||||
[docker]
|
||||
image=ubuntu:trusty
|
||||
|
||||
If there is not an image key in the docker section or an image key in the
|
||||
dox.yml but there is a Dockerfile in the repo, an new image will be built
|
||||
using the Dockerfile and the test commands will be run inside of the image.
|
||||
|
||||
If all of that fails, tests are going to run in a bare ubuntu image. Good luck!
|
||||
|
||||
Image Caching
|
||||
-------------
|
||||
|
||||
Every run actually has two images associated with it: The `base` image and
|
||||
the `test` image.
|
||||
|
||||
The image referenced above is the `base` image. When you execute `dox`,
|
||||
it will search docker for the named image. If it exists, it will do nothing.
|
||||
If it does not, it will either pull it, or, it will build it from the
|
||||
Dockerfile. In the case of building from a Dockerfile, dox will make an image
|
||||
named for the source directory. So if you're in ~/src/openstack/nova, it'll
|
||||
make an image called "dox/nova/base".
|
||||
|
||||
The `test` image is an image made by dox for the test run. Similar to the
|
||||
base run, it'll have a generated name, such as "dox/nova/test", and similar
|
||||
to the base image, it will get generated once and then left alone.
|
||||
|
||||
If you want to regenerate the `test` image, you can run dox with the `-r`
|
||||
option. If you want to regenerate/repull everything, you can run it with the
|
||||
`--rebuild-all` option.
|
||||
|
||||
The reasoning behind this is that the base image should really be the
|
||||
substrata which doesn't have a lot to do with the repo itself ... it shouldn't
|
||||
really expect to change much based on day to day changes in the repo. The
|
||||
test image on the other hand is built a bit more based on the repo itself.
|
||||
So, for instance, in the base image you might want to do things like::
|
||||
|
||||
apt-get install libxml-dev
|
||||
|
||||
and in the test image, you'd want things like::
|
||||
|
||||
pip install -U requirements.txt
|
||||
|
||||
Neither change frequently, but the second it more likely to change day to day
|
||||
than the first.
|
||||
|
||||
Additional information
|
||||
----------------------
|
||||
|
||||
Regardless, dox will mount the current source dir as a volume at `/src` in
|
||||
the container and will run commands in that context.
|
||||
|
||||
dox will attempt to reuse containers. Since the source is bind-mounted into
|
||||
the container, things that might be expensive like copying source dirs or
|
||||
re-installing the source into the system can be minimized.
|
||||
|
||||
Boot2Docker support
|
||||
-------------------
|
||||
|
||||
To get support for non Linux OSes that doesn't support natively docker
|
||||
there is a tool called `boot2docker <http://boot2docker.io/>`_ which
|
||||
allows you to run a remote docker server in a VirtualBox VM and the
|
||||
client running on the non Linux desktop.
|
||||
|
||||
Volume support started to be supported by `boot2docker` since docker version
|
||||
1.3. You will need to be at least on that version to have volume mount support.
|
||||
|
||||
If you username id is different from the docker username on the `boot2docker` vm,
|
||||
you will need to specify it on the command line, like this::
|
||||
|
||||
dox --user-map=docker:1000:10
|
||||
|
||||
If you use VirtualBox guest additions to mount your osx onto the `boot2docker` vm,
|
||||
example /Users/your_name/openstack/oslo-incubator as /home/your_name/openstack/oslo-incubator,
|
||||
then you can add the following mapping::
|
||||
|
||||
dos --path-map=/Users/your_name:/home/your_name
|
||||
|
||||
|
||||
Advanced
|
||||
--------
|
||||
It is possible to specify multiple images to be used in a dox run.
|
||||
Images can be provided on the command line, via the dox.yml file, or the
|
||||
tox.ini file.
|
||||
|
||||
For the command line, images should be provided via the --images option,
|
||||
in a comma-separated list.
|
||||
|
||||
The tox.ini file should also use a comma-separated list.
|
||||
|
||||
The dox.yml file should list images in an array.
|
||||
|
||||
The same prep and command instructions will be executed on each image sequentially.
|
||||
|
||||
dox does not currently allow for multiple images executing different tasks
|
||||
at this time. However, it is a goal to allow for such test scenarios in
|
||||
the future.
|
||||
For any further questions, please email
|
||||
openstack-discuss@lists.openstack.org or join #openstack-dev on
|
||||
Freenode.
|
||||
|
@ -1,6 +0,0 @@
|
||||
# This is a cross-platform list tracking distribution packages needed by tests;
|
||||
# see http://docs.openstack.org/infra/bindep/ for additional information.
|
||||
|
||||
docker.io [platform:dpkg test]
|
||||
python-dev [platform:dpkg test]
|
||||
python-devel [platform:rpm test]
|
@ -1,74 +0,0 @@
|
||||
# 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 os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
# -- General configuration ----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
#'sphinx.ext.intersphinx',
|
||||
'oslo.sphinx'
|
||||
]
|
||||
|
||||
# autodoc generation is a bit aggressive and a nuisance when doing heavy
|
||||
# text edit cycles.
|
||||
# execute "export SPHINX_DEBUG=1" in your terminal to disable
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'dox'
|
||||
copyright = u'2013, OpenStack Foundation'
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
add_module_names = True
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
# html_theme_path = ["."]
|
||||
# html_theme = '_theme'
|
||||
# html_static_path = ['static']
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = '%sdoc' % project
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass
|
||||
# [howto/manual]).
|
||||
latex_documents = [
|
||||
('index',
|
||||
'%s.tex' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation', 'manual'),
|
||||
]
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
#intersphinx_mapping = {'http://docs.python.org/': None}
|
@ -1 +0,0 @@
|
||||
.. include:: ../../CONTRIBUTING.rst
|
@ -1,37 +0,0 @@
|
||||
.. dox documentation master file, created by
|
||||
sphinx-quickstart on Tue Jul 9 22:26:36 2013.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to dox's documentation!
|
||||
========================================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
readme
|
||||
installation
|
||||
usage
|
||||
contributing
|
||||
|
||||
|
||||
Release Notes
|
||||
==============
|
||||
|
||||
0.2.0
|
||||
-----
|
||||
|
||||
dffe391 Don't prefix the cached image with `_`
|
||||
ea141b9 Don't run useradd for root
|
||||
d3971df Add Centos 7 Dockerfile
|
||||
d0d15f9 More informative error when command fails
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
@ -1,12 +0,0 @@
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
At the command line::
|
||||
|
||||
$ pip install dox
|
||||
|
||||
Or, if you have virtualenvwrapper installed::
|
||||
|
||||
$ mkvirtualenv dox
|
||||
$ pip install dox
|
@ -1 +0,0 @@
|
||||
.. include:: ../README.rst
|
@ -1,7 +0,0 @@
|
||||
========
|
||||
Usage
|
||||
========
|
||||
|
||||
To use dox in a project::
|
||||
|
||||
import dox
|
@ -1,9 +0,0 @@
|
||||
FROM centos:7
|
||||
MAINTAINER OpenStack <openstack-dev@lists.openstack.org>
|
||||
|
||||
RUN yum -y update
|
||||
RUN yum -y groupinstall 'Development Tools'
|
||||
RUN yum -y install wget git python
|
||||
|
||||
RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && rm get-pip.py
|
||||
RUN pip install -U setuptools
|
@ -1,9 +0,0 @@
|
||||
FROM fedora:20
|
||||
MAINTAINER OpenStack <openstack-dev@lists.openstack.org>
|
||||
|
||||
RUN yum -y update
|
||||
RUN yum -y groupinstall 'Development Tools'
|
||||
RUN yum -y install wget git python
|
||||
|
||||
RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && rm get-pip.py
|
||||
RUN pip install -U setuptools
|
@ -1,8 +0,0 @@
|
||||
FROM ubuntu:trusty
|
||||
MAINTAINER OpenStack <openstack-dev@lists.openstack.org>
|
||||
|
||||
RUN apt-get update --fix-missing
|
||||
RUN apt-get install -y build-essential wget git python python-dev
|
||||
|
||||
RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && rm get-pip.py
|
||||
RUN pip install -U setuptools
|
@ -1,8 +0,0 @@
|
||||
FROM ubuntu:xenial
|
||||
MAINTAINER OpenStack <openstack-dev@lists.openstack.org>
|
||||
|
||||
RUN apt-get update --fix-missing
|
||||
RUN apt-get install -y build-essential wget git python python-dev
|
||||
|
||||
RUN wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && rm get-pip.py
|
||||
RUN pip install -U setuptools
|
19
dox.yml
19
dox.yml
@ -1,19 +0,0 @@
|
||||
testing:
|
||||
images:
|
||||
- infra/trusty
|
||||
add:
|
||||
- requirements.txt
|
||||
- test-requirements.txt
|
||||
prep:
|
||||
- pip install -U -r requirements.txt -r test-requirements.txt
|
||||
commands:
|
||||
- export PYTHONHASHSEED=$RANDOM
|
||||
- python setup.py testr --slowest
|
||||
|
||||
testing:pep8:
|
||||
commands:
|
||||
- flake8
|
||||
|
||||
testing:cover:
|
||||
commands:
|
||||
- /bin/echo "hello"
|
@ -1,16 +0,0 @@
|
||||
# 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 pbr.version
|
||||
|
||||
|
||||
__version__ = pbr.version.VersionInfo('dox').version_string()
|
140
dox/cmd.py
140
dox/cmd.py
@ -1,140 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 argparse
|
||||
import functools
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
import dox.commands
|
||||
import dox.config.cmdline
|
||||
import dox.images
|
||||
import dox.runner
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_log_level(args):
|
||||
if args.debug:
|
||||
return logging.DEBUG
|
||||
if args.quiet:
|
||||
return logging.WARN
|
||||
return logging.INFO
|
||||
|
||||
|
||||
def setup_logging(level):
|
||||
handler = logging.StreamHandler()
|
||||
formatter = logging.Formatter('%(levelname)s|%(name)s|%(message)s')
|
||||
handler.setFormatter(formatter)
|
||||
logger = logging.getLogger('dox')
|
||||
logger.setLevel(level)
|
||||
logger.addHandler(handler)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='Run tests in docker.')
|
||||
parser.add_argument(dest='extra_args', nargs='*',
|
||||
help='args to append to command, or command to run'
|
||||
' if -c is given')
|
||||
parser.add_argument('-i', '--images', dest='images',
|
||||
help='Base images to use')
|
||||
parser.add_argument('-e', '--environment', dest='environment',
|
||||
default=None,
|
||||
help='Run target environment.')
|
||||
parser.add_argument('-c', '--command', dest='command', default=False,
|
||||
action='store_true',
|
||||
help='Treat arguments as the entire command to run')
|
||||
parser.add_argument('-r', '--rebuild', dest='rebuild', default=False,
|
||||
action='store_true',
|
||||
help='Rebuild the test image')
|
||||
parser.add_argument('--rebuild-all', dest='rebuild_all', default=False,
|
||||
action='store_true', help='Rebuild all images')
|
||||
parser.add_argument('-d', '--debug', dest='debug', default=False,
|
||||
action='store_true', help='Debug mode')
|
||||
parser.add_argument('-q', '--quiet', dest='quiet', default=False,
|
||||
action='store_true', help='Quiet output')
|
||||
parser.add_argument('-n', '--noop', dest='noop', default=False,
|
||||
action='store_true',
|
||||
help="Don't actually execute commands")
|
||||
parser.add_argument('--user-map', default=os.environ.get("DOX_USER_MAP"),
|
||||
help='User to run the container to '
|
||||
'format is user:uid:gid, with boot2docker use '
|
||||
'docker:1000:10 (default to your current user)')
|
||||
parser.add_argument('--path-map', default=os.environ.get("DOX_PATH_MAP"),
|
||||
help='with boot2docker, specify how osx path maps to '
|
||||
'linux path. example --path-map /Users:/home, '
|
||||
'means /Users is available as /home on docker '
|
||||
'container')
|
||||
parser.add_argument('-k', '--keep', dest='keep_image', default=False,
|
||||
action='store_true',
|
||||
help="Keep test container after command finishes")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
setup_logging(get_log_level(args))
|
||||
|
||||
return runner(args)
|
||||
|
||||
|
||||
def run_dox(args, images, command, image_name):
|
||||
# Run
|
||||
try:
|
||||
run = functools.partial(dox.runner.Runner(args, image_name).run,
|
||||
command=command)
|
||||
map(run, images)
|
||||
except Exception as e:
|
||||
logger.error("Operation failed, aborting dox.", exc_info=e)
|
||||
return 1
|
||||
|
||||
|
||||
def runner(args):
|
||||
options = {}
|
||||
args_images = None
|
||||
|
||||
if not dox.runner.Runner(args).is_docker_installed():
|
||||
sys.exit(1)
|
||||
|
||||
# Get Image
|
||||
if args.images:
|
||||
args_images = [x.strip() for x in args.images.split(',')]
|
||||
|
||||
if args.command:
|
||||
command = dox.config.cmdline.CommandLine(args.extra_args)
|
||||
logger.debug("Command source is the command line")
|
||||
return run_dox(args, args_images, command, image_name="commandline")
|
||||
|
||||
if args.environment:
|
||||
sections = args.environment.split(',')
|
||||
else:
|
||||
sections = ['_default']
|
||||
|
||||
for section in sections:
|
||||
options['section'] = section
|
||||
|
||||
if args_images:
|
||||
images = args_images
|
||||
else:
|
||||
images = dox.images.get_images(options)
|
||||
|
||||
command = dox.commands.Commands(args.extra_args, options)
|
||||
logger.debug("Command source is %s, section %s" % (
|
||||
command.source.source_name(), section))
|
||||
|
||||
# TODO(chmouel): add to section a proper image_name that include the
|
||||
# type of backend i.e: dox_yaml/tox_init
|
||||
run_dox(args, images, command, image_name=section)
|
@ -1,96 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
__all__ = [
|
||||
'get_commands',
|
||||
'Commands',
|
||||
]
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
import dox.config.dox_yaml
|
||||
import dox.config.tox_ini
|
||||
import dox.config.travis_yaml
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_commands(options):
|
||||
'''Examine the local environment and figure out what we should run.'''
|
||||
|
||||
dox_yaml = dox.config.dox_yaml.get_dox_yaml(options)
|
||||
tox_ini = dox.config.tox_ini.get_tox_ini(options)
|
||||
travis_yaml = dox.config.travis_yaml.get_travis_yaml(options)
|
||||
|
||||
for source in (dox_yaml, tox_ini, travis_yaml):
|
||||
if source.exists():
|
||||
return source
|
||||
raise Exception("dox cannot figure out what command to run")
|
||||
|
||||
|
||||
class Commands(object):
|
||||
|
||||
def __init__(self, extra_args=[], options=None):
|
||||
self.options = options or {}
|
||||
self.source = get_commands(options)
|
||||
self.args = []
|
||||
self.extra_args = extra_args
|
||||
|
||||
def _test_command_as_script(self, commands, shell='/bin/sh'):
|
||||
"""Combine test commands into a master script file.
|
||||
|
||||
The script, using the given shell, will be created in the .dox
|
||||
subdirectory of the current directory.
|
||||
|
||||
:param commands: A list of commands to execute.
|
||||
:param shell: Path to the OS shell to run the commands.
|
||||
"""
|
||||
dox_dir = '.dox'
|
||||
master_script = os.path.join(dox_dir, 'master_script.sh')
|
||||
|
||||
if not os.path.exists(dox_dir):
|
||||
os.mkdir(dox_dir, 0o755)
|
||||
|
||||
with open(master_script, "w") as f:
|
||||
f.write("#!" + shell + "\n")
|
||||
f.write("\n".join(commands))
|
||||
f.write("\n")
|
||||
|
||||
os.chmod(master_script, 0o700)
|
||||
return master_script
|
||||
|
||||
def test_command(self):
|
||||
"""Return the command to execute in the container.
|
||||
|
||||
If there is more than one command, we combine them into a master
|
||||
script to execute. Otherwise, we just issue the command normally
|
||||
on the docker command line.
|
||||
"""
|
||||
commands = self.source.get_commands(self.extra_args)
|
||||
if len(commands) > 1:
|
||||
return self._test_command_as_script(commands)
|
||||
|
||||
ret = commands[0] + ' ' + ' '.join(self.args)
|
||||
return ret.strip()
|
||||
|
||||
def prep_commands(self):
|
||||
return self.source.get_prep_commands()
|
||||
|
||||
def get_add_files(self):
|
||||
return self.source.get_add_files()
|
||||
|
||||
def append(self, args):
|
||||
self.args = args
|
@ -1,81 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 abc
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class ConfigBase(object):
|
||||
"""Configuration file reader base class."""
|
||||
|
||||
def __init__(self, options):
|
||||
self.options = options
|
||||
|
||||
@abc.abstractmethod
|
||||
def exists(self):
|
||||
"""Check if the configuration file is present.
|
||||
|
||||
:returns: True if the file is present.
|
||||
:returns: False if the file is not present.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_images(self):
|
||||
"""Get list of docker source images used to build the test image.
|
||||
|
||||
:returns: List of image names in <user>/<repo>[:<tag>] format.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_commands(self):
|
||||
"""Get list of commands to execute with the final test image.
|
||||
|
||||
These commands will be executed via the 'docker run' command
|
||||
with the final test image.
|
||||
|
||||
:returns: List of executable commands.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_prep_commands(self):
|
||||
"""Get list of commands to run while building the test image.
|
||||
|
||||
These commands will be executed while building the test image,
|
||||
thus allowing for any software installation, configuration, etc.
|
||||
to be built into the test image.
|
||||
|
||||
:returns: List of executable commands.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_add_files(self):
|
||||
"""Get list of files to add to the test image.
|
||||
|
||||
The named files will be placed in the working directory of the
|
||||
built test image.
|
||||
|
||||
:returns: List of file names.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def source_name(self):
|
||||
"""The source of the configuration.
|
||||
|
||||
This identifies the source of the configuration values. E.g.,
|
||||
a file name, or other descriptive text.
|
||||
|
||||
:returns: String describing the source.
|
||||
"""
|
@ -1,33 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
__all__ = [
|
||||
'CommandLine',
|
||||
]
|
||||
|
||||
|
||||
class CommandLine(object):
|
||||
|
||||
def __init__(self, args):
|
||||
self.args = args
|
||||
|
||||
def test_command(self):
|
||||
return " ".join(self.args)
|
||||
|
||||
def prep_commands(self):
|
||||
return ""
|
||||
|
||||
def get_add_files(self):
|
||||
return []
|
@ -1,35 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
__all__ = [
|
||||
'get_dockerfile',
|
||||
]
|
||||
|
||||
import os
|
||||
|
||||
_dockerfile = None
|
||||
|
||||
|
||||
def get_dockerfile():
|
||||
global _dockerfile
|
||||
if _dockerfile is None:
|
||||
_dockerfile = Dockerfile()
|
||||
return _dockerfile
|
||||
|
||||
|
||||
class Dockerfile(object):
|
||||
|
||||
def exists(self):
|
||||
return os.path.exists('Dockerfile')
|
@ -1,107 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 os
|
||||
|
||||
import yaml
|
||||
|
||||
import dox.config.base as base
|
||||
|
||||
|
||||
__all__ = [
|
||||
'get_dox_yaml',
|
||||
]
|
||||
|
||||
_dox_yaml = None
|
||||
|
||||
|
||||
class DoxYamlSectionNotFound(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def get_dox_yaml(options):
|
||||
global _dox_yaml
|
||||
if _dox_yaml is None:
|
||||
_dox_yaml = DoxYaml(options)
|
||||
return _dox_yaml
|
||||
|
||||
|
||||
class DoxYaml(base.ConfigBase):
|
||||
|
||||
_yaml = None
|
||||
dox_file = 'dox.yml'
|
||||
default_section = 'testing'
|
||||
default_keys_of_section = ['images', 'commands', 'add', 'prep']
|
||||
|
||||
def _parse_parent_child_section(self, section, _yaml):
|
||||
ret = {}
|
||||
if ':' not in section:
|
||||
return _yaml
|
||||
|
||||
parent, child = section.split(':')
|
||||
|
||||
if parent in self._yaml.keys():
|
||||
ret = self._yaml.get(parent)
|
||||
ret.update(_yaml)
|
||||
else:
|
||||
raise DoxYamlSectionNotFound("Parent %s was not found" % parent)
|
||||
return ret
|
||||
|
||||
def get_section(self, _yaml, section):
|
||||
if section == '_default':
|
||||
section = self.default_section
|
||||
|
||||
# NOTE(chmou): This is for compatibility mode with dox.yml with no
|
||||
# sections, probably need to be removed in the future
|
||||
if (section is None and
|
||||
(all(i in _yaml.keys() for i in self.default_keys_of_section)
|
||||
or all(i in self.default_keys_of_section
|
||||
for i in _yaml.keys()))):
|
||||
return _yaml
|
||||
elif not section:
|
||||
if self.default_section in _yaml.keys():
|
||||
return self._parse_parent_child_section(
|
||||
self.default_section, _yaml.get(self.default_section))
|
||||
raise DoxYamlSectionNotFound("You need to specify a section.")
|
||||
elif section not in _yaml.keys():
|
||||
raise DoxYamlSectionNotFound(section)
|
||||
|
||||
return self._parse_parent_child_section(section,
|
||||
_yaml.get(section))
|
||||
|
||||
def _open_dox_yaml(self):
|
||||
if self._yaml is None:
|
||||
with open(self.dox_file, 'r') as f:
|
||||
self._yaml = yaml.load(f)
|
||||
return self.get_section(self._yaml,
|
||||
self.options.get('section'))
|
||||
|
||||
def source_name(self):
|
||||
return self.dox_file
|
||||
|
||||
def exists(self):
|
||||
return os.path.exists(self.dox_file)
|
||||
|
||||
def get_images(self):
|
||||
return self._open_dox_yaml().get('images', [])
|
||||
|
||||
def get_commands(self, extra_args):
|
||||
return self._open_dox_yaml().get('commands', [])
|
||||
|
||||
def get_prep_commands(self):
|
||||
return self._open_dox_yaml().get('prep', [])
|
||||
|
||||
def get_add_files(self):
|
||||
return self._open_dox_yaml().get('add', [])
|
@ -1,101 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 os
|
||||
|
||||
from six.moves.configparser import ConfigParser
|
||||
|
||||
import dox.config.base as base
|
||||
|
||||
|
||||
__all__ = [
|
||||
'get_tox_ini',
|
||||
]
|
||||
|
||||
_tox_ini = None
|
||||
|
||||
|
||||
def get_tox_ini(options):
|
||||
global _tox_ini
|
||||
if _tox_ini is None:
|
||||
_tox_ini = ToxIni(options)
|
||||
return _tox_ini
|
||||
|
||||
|
||||
class ToxIni(base.ConfigBase):
|
||||
|
||||
_ini = None
|
||||
tox_ini_file = 'tox.ini'
|
||||
default_section = 'testenv'
|
||||
|
||||
def _open_tox_ini(self):
|
||||
if self._ini is None:
|
||||
self._ini = ConfigParser()
|
||||
self._ini.read(self.tox_ini_file)
|
||||
return self._ini
|
||||
|
||||
def source_name(self):
|
||||
return self.tox_ini_file
|
||||
|
||||
def exists(self):
|
||||
return os.path.exists(self.tox_ini_file)
|
||||
|
||||
def get_images(self):
|
||||
ini = self._open_tox_ini()
|
||||
if ini.has_option('docker', 'images'):
|
||||
return ini.get('docker', 'images').split(',')
|
||||
|
||||
def get_commands(self, extra_args):
|
||||
"""Get commands to run from the config file.
|
||||
|
||||
If any of the commands contain the string '{posargs}', then this
|
||||
is replaced with the extra_args value.
|
||||
"""
|
||||
section = self.options.get('section',
|
||||
self.default_section)
|
||||
|
||||
if section == '_default':
|
||||
section = self.default_section
|
||||
|
||||
ini = self._open_tox_ini()
|
||||
commands = ini.get(section, 'commands').split("\n")
|
||||
extra_args = " ".join(extra_args)
|
||||
|
||||
scrubbed = []
|
||||
for cmd in commands:
|
||||
if '{posargs}' in cmd:
|
||||
scrubbed.append(cmd.replace('{posargs}', extra_args))
|
||||
else:
|
||||
scrubbed.append(cmd)
|
||||
return scrubbed
|
||||
|
||||
def get_prep_commands(self):
|
||||
ini = self._open_tox_ini()
|
||||
deps = ""
|
||||
if ini.has_option('testenv', 'deps'):
|
||||
deps = ini.get('testenv', 'deps')
|
||||
deps = deps.replace('{toxinidir}', '/dox').replace('\n', ' ')
|
||||
if deps.strip() == '':
|
||||
return []
|
||||
install_command = "pip install -U"
|
||||
if ini.has_option('testenv', 'install_command'):
|
||||
install_command = ini.get('testenv', 'install_command')
|
||||
install_command = install_command.replace('{opts}', '')
|
||||
install_command = install_command.replace('{packages}', deps)
|
||||
return [install_command]
|
||||
|
||||
def get_add_files(self):
|
||||
return [d for d in os.listdir('.') if d.endswith('requirements.txt')]
|
@ -1,75 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 os
|
||||
import yaml
|
||||
|
||||
import dox.config.base as base
|
||||
|
||||
|
||||
__all__ = [
|
||||
'get_travis_yaml',
|
||||
]
|
||||
|
||||
_travis_yaml = None
|
||||
|
||||
|
||||
def get_travis_yaml(options):
|
||||
global _travis_yaml
|
||||
if _travis_yaml is None:
|
||||
_travis_yaml = TravisYaml(options)
|
||||
return _travis_yaml
|
||||
|
||||
|
||||
class TravisYaml(base.ConfigBase):
|
||||
|
||||
_yaml = None
|
||||
_travis_file = 'travis.yml'
|
||||
|
||||
def _open_travis_yaml(self):
|
||||
if self._yaml is None:
|
||||
with open('travis.yml', 'r') as f:
|
||||
self._yaml = yaml.load(f)
|
||||
return self._yaml
|
||||
|
||||
def source_name(self):
|
||||
return self._travis_file
|
||||
|
||||
def exists(self):
|
||||
return os.path.exists(self._travis_file)
|
||||
|
||||
def get_commands(self, command):
|
||||
return self._open_travis_yaml().get('script', command)
|
||||
|
||||
def get_prep_commands(self):
|
||||
travis_yaml = self._open_travis_yaml()
|
||||
prep = []
|
||||
|
||||
for key in ('before_install', 'install', 'before_script'):
|
||||
if key in travis_yaml:
|
||||
val = travis_yaml[key]
|
||||
if hasattr(val, 'append'):
|
||||
prep.extend(val)
|
||||
else:
|
||||
prep.append(val)
|
||||
return []
|
||||
|
||||
# TODO(Shrews): Implement this
|
||||
def get_add_files(self):
|
||||
return []
|
||||
|
||||
# TODO(Shrews): Implement this
|
||||
def get_images(self):
|
||||
return []
|
@ -1,45 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
__all__ = [
|
||||
'get_images',
|
||||
]
|
||||
|
||||
import dox.config.dockerfile
|
||||
import dox.config.dox_yaml
|
||||
import dox.config.tox_ini
|
||||
|
||||
|
||||
def get_images(options):
|
||||
'''Examine the local environment and figure out where we should run.'''
|
||||
|
||||
dockerfile = dox.config.dockerfile.get_dockerfile()
|
||||
dox_yaml = dox.config.dox_yaml.get_dox_yaml(options)
|
||||
tox_ini = dox.config.tox_ini.get_tox_ini(options)
|
||||
|
||||
if dockerfile.exists():
|
||||
default_images = []
|
||||
else:
|
||||
# NOTE(flaper87): We should probably raise
|
||||
# `RuntimeError` if no image was specified
|
||||
default_images = ['ubuntu']
|
||||
|
||||
images = []
|
||||
if dox_yaml.exists():
|
||||
images = dox_yaml.get_images()
|
||||
elif tox_ini.exists():
|
||||
images = tox_ini.get_images()
|
||||
|
||||
return images or default_images
|
211
dox/runner.py
211
dox/runner.py
@ -1,211 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
__all__ = [
|
||||
'Runner',
|
||||
]
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pwd
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Runner(object):
|
||||
|
||||
def __init__(self, args, image_name=None):
|
||||
image_name = image_name and "_" + image_name or ""
|
||||
self.args = args
|
||||
self.project = os.path.basename(os.path.abspath('.'))
|
||||
self.base_image_name = 'dox/%s%s_base' % (self.project,
|
||||
image_name)
|
||||
self.test_image_name = 'dox/%s%s_test' % (self.project,
|
||||
image_name)
|
||||
self.user_map = self._get_user_mapping()
|
||||
self.path_map = self._get_path_mapping()
|
||||
|
||||
def _get_user_mapping(self):
|
||||
"""Get user mapping from command line or current user."""
|
||||
if self.args.user_map:
|
||||
username, uid, gid = self.args.user_map.split(':')
|
||||
else:
|
||||
username, uid, gid = (pwd.getpwuid(os.getuid())[0],
|
||||
os.getuid(),
|
||||
os.getgid())
|
||||
return {'username': username, 'uid': int(uid), 'gid': int(gid)}
|
||||
|
||||
def _get_path_mapping(self):
|
||||
"""Get path mapping from command line."""
|
||||
if not self.args.path_map:
|
||||
return None
|
||||
local, remote = self.args.path_map.split(':', 1)
|
||||
return {'local': local, 'remote': remote}
|
||||
|
||||
def is_docker_installed(self):
|
||||
try:
|
||||
self._docker_cmd("version")
|
||||
except OSError as e:
|
||||
msg = 'docker does not seem installed'
|
||||
if e.errno == 2 and not self.args.debug:
|
||||
logger.error(msg)
|
||||
else:
|
||||
logger.exception(msg)
|
||||
return False
|
||||
return True
|
||||
|
||||
def _docker_build(self, image, image_dir='.'):
|
||||
logger.info('Building image %s' % image)
|
||||
self._docker_cmd('build', '-t', image, image_dir)
|
||||
|
||||
def _docker_run(self, *args):
|
||||
logger.info('Running docker')
|
||||
self._docker_cmd('run', *args)
|
||||
|
||||
def _docker_cmd(self, *args):
|
||||
base_docker = ['docker']
|
||||
try:
|
||||
self._run_shell_command(base_docker + list(args))
|
||||
except Exception as e:
|
||||
logger.error("docker failed")
|
||||
logger.info(e)
|
||||
raise
|
||||
|
||||
def _run_shell_command(self, cmd):
|
||||
|
||||
logger.debug('shell: ' + ' '.join(cmd))
|
||||
if self.args.noop:
|
||||
return
|
||||
|
||||
process = subprocess.Popen(
|
||||
cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
while True:
|
||||
output = process.stdout.read(1)
|
||||
|
||||
if output == '' and process.poll() is not None:
|
||||
break
|
||||
|
||||
if output != '' and not self.args.quiet:
|
||||
sys.stdout.write(output)
|
||||
sys.stdout.flush()
|
||||
|
||||
if process.returncode:
|
||||
raise Exception(
|
||||
"%s returned %d" % (cmd, process.returncode))
|
||||
|
||||
def _indent(self, text):
|
||||
wrapper = textwrap.TextWrapper(
|
||||
initial_indent=' ', subsequent_indent=' ')
|
||||
return '\n'.join([wrapper.fill(line) for line in text.split('\n')])
|
||||
|
||||
def _get_image_list(self):
|
||||
|
||||
process = subprocess.Popen(
|
||||
shlex.split('docker images'),
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
stdout, _ = process.communicate()
|
||||
out_text = stdout.strip().decode('utf-8') if stdout else ""
|
||||
return dict([f.split()[:2] for f in out_text.split('\n')])
|
||||
|
||||
def have_test_image(self):
|
||||
if self.args.rebuild or self.args.rebuild_all:
|
||||
return False
|
||||
if self.test_image_name in self._get_image_list():
|
||||
return True
|
||||
return False
|
||||
|
||||
def build_test_image(self, image, commands):
|
||||
logger.debug(
|
||||
"Want test image %(image)s with %(prep_commands)s" % dict(
|
||||
image=self.test_image_name,
|
||||
prep_commands=commands.prep_commands()))
|
||||
if self.have_test_image():
|
||||
return
|
||||
|
||||
dockerfile = []
|
||||
dockerfile.append("FROM %s" % image)
|
||||
try:
|
||||
tempd = tempfile.mkdtemp()
|
||||
if not self.user_map['username'] == 'root':
|
||||
dockerfile.append(
|
||||
"RUN useradd -M -U -d /src -u %(uid)s %(user)s" % dict(
|
||||
uid=self.user_map['uid'],
|
||||
gid=self.user_map['gid'],
|
||||
user=self.user_map['username']))
|
||||
|
||||
for add_file in commands.get_add_files():
|
||||
shutil.copy(add_file, os.path.join(tempd, add_file))
|
||||
dockerfile.append("ADD %s /dox/" % add_file)
|
||||
dockerfile.append("WORKDIR /dox")
|
||||
for command in commands.prep_commands():
|
||||
dockerfile.append("RUN %s\n" % command)
|
||||
dockerfile = '\n'.join(dockerfile)
|
||||
with open(os.path.join(tempd, 'Dockerfile'), 'w') as f:
|
||||
f.write(dockerfile)
|
||||
logger.debug("Dockerfile:\n" + self._indent(dockerfile))
|
||||
self._docker_build(self.test_image_name, tempd)
|
||||
finally:
|
||||
shutil.rmtree(tempd)
|
||||
|
||||
def run_commands(self, command):
|
||||
path = os.path.abspath('.')
|
||||
if self.path_map:
|
||||
path = path.replace(self.path_map['local'],
|
||||
self.path_map['remote'])
|
||||
docker_args = ['--privileged=true',
|
||||
'--user=%s' % self.user_map['username'],
|
||||
'-v', "%s:/src" % path,
|
||||
'-w', '/src']
|
||||
if not self.args.keep_image:
|
||||
docker_args.append('--rm')
|
||||
docker_args.append(self.test_image_name)
|
||||
for c in command:
|
||||
docker_args.append(c)
|
||||
self._docker_run(*docker_args)
|
||||
|
||||
def have_base_image(self):
|
||||
if self.args.rebuild_all:
|
||||
return False
|
||||
if self.base_image_name in self._get_image_list():
|
||||
return True
|
||||
return False
|
||||
|
||||
def build_base_image(self):
|
||||
|
||||
logger.debug("Want base image")
|
||||
if self.have_base_image():
|
||||
return
|
||||
self._docker_build(self.base_image_name)
|
||||
|
||||
def run(self, image, command):
|
||||
logger.debug(
|
||||
"Going to run %(command)s in %(image)s" % dict(
|
||||
command=command.test_command(), image=image))
|
||||
if self.args.rebuild:
|
||||
logger.debug("Need to rebuild")
|
||||
|
||||
if image is None:
|
||||
self.build_base_image()
|
||||
self.build_test_image(image, command)
|
||||
|
||||
self.run_commands(shlex.split(command.test_command()))
|
@ -1,69 +0,0 @@
|
||||
# Copyright 2010-2011 OpenStack Foundation
|
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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 os
|
||||
|
||||
import fixtures
|
||||
import testtools
|
||||
|
||||
_TRUE_VALUES = ('true', '1', 'yes')
|
||||
|
||||
TESTDIR = os.path.dirname(os.path.abspath(__file__))
|
||||
SAMPLEDIR = os.path.join(TESTDIR, 'samples')
|
||||
|
||||
|
||||
class TestCase(testtools.TestCase):
|
||||
|
||||
"""Test case base class for all unit tests."""
|
||||
|
||||
def setUp(self):
|
||||
"""Run before each test method to initialize test environment."""
|
||||
|
||||
super(TestCase, self).setUp()
|
||||
test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0)
|
||||
try:
|
||||
test_timeout = int(test_timeout)
|
||||
except ValueError:
|
||||
# If timeout value is invalid do not set a timeout.
|
||||
test_timeout = 0
|
||||
if test_timeout > 0:
|
||||
self.useFixture(fixtures.Timeout(test_timeout, gentle=True))
|
||||
|
||||
self.useFixture(fixtures.NestedTempfile())
|
||||
self.useFixture(fixtures.TempHomeDir())
|
||||
|
||||
if os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES:
|
||||
stdout = self.useFixture(fixtures.StringStream('stdout')).stream
|
||||
self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
|
||||
if os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES:
|
||||
stderr = self.useFixture(fixtures.StringStream('stderr')).stream
|
||||
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
|
||||
|
||||
self.log_fixture = self.useFixture(fixtures.FakeLogger())
|
||||
|
||||
|
||||
def fake_does_exist(self):
|
||||
return True
|
||||
|
||||
|
||||
def fake_does_not_exist(self):
|
||||
return False
|
||||
|
||||
|
||||
def bool_to_fake(val):
|
||||
if val:
|
||||
return fake_does_exist
|
||||
else:
|
||||
return fake_does_not_exist
|
@ -1,84 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
test_commands
|
||||
----------------------------------
|
||||
|
||||
Tests for `dox.commands` module.
|
||||
"""
|
||||
|
||||
import fixtures
|
||||
import testscenarios
|
||||
|
||||
from dox import commands
|
||||
from dox.tests import base
|
||||
|
||||
|
||||
def get_fake_command(value):
|
||||
def fake_value(self, args):
|
||||
return value
|
||||
return fake_value
|
||||
|
||||
|
||||
class TestCommands(base.TestCase):
|
||||
|
||||
scenarios = [
|
||||
('dox_yaml', dict(
|
||||
dox_yaml=True, tox_ini=False, travis_yaml=False,
|
||||
dox_value=["testr run"], tox_value=None, travis_value=None,
|
||||
commands="testr run")),
|
||||
('dox_yaml_ignore_others', dict(
|
||||
dox_yaml=True, tox_ini=True, travis_yaml=True,
|
||||
dox_value=["testr run"], tox_value=["setup.py test"],
|
||||
travis_value=["gem test"],
|
||||
commands="testr run")),
|
||||
('tox_ini', dict(
|
||||
dox_yaml=False, tox_ini=True, travis_yaml=False,
|
||||
dox_value=None, tox_value=["setup.py test"], travis_value=None,
|
||||
commands="setup.py test")),
|
||||
('travis_yaml', dict(
|
||||
dox_yaml=False, tox_ini=False, travis_yaml=True,
|
||||
dox_value=["testr run"], tox_value=None, travis_value=["ruby"],
|
||||
commands="ruby")),
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(TestCommands, self).setUp()
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.dox_yaml.DoxYaml.exists',
|
||||
base.bool_to_fake(self.dox_yaml)))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.tox_ini.ToxIni.exists',
|
||||
base.bool_to_fake(self.tox_ini)))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.travis_yaml.TravisYaml.exists',
|
||||
base.bool_to_fake(self.travis_yaml)))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.dox_yaml.DoxYaml.get_commands',
|
||||
get_fake_command(self.dox_value)))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.tox_ini.ToxIni.get_commands',
|
||||
get_fake_command(self.tox_value)))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.travis_yaml.TravisYaml.get_commands',
|
||||
get_fake_command(self.travis_value)))
|
||||
|
||||
def test_commands(self):
|
||||
p = commands.Commands()
|
||||
self.assertEqual(p.test_command(), self.commands)
|
||||
|
||||
|
||||
def load_tests(loader, in_tests, pattern):
|
||||
return testscenarios.load_tests_apply_scenarios(loader, in_tests, pattern)
|
@ -1,62 +0,0 @@
|
||||
# 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 os
|
||||
|
||||
import dox.config.base as cfg_base
|
||||
|
||||
from dox.config import dox_yaml
|
||||
from dox.tests import base
|
||||
|
||||
|
||||
class TestDoxYaml(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestDoxYaml, self).setUp()
|
||||
self.doxyaml = dox_yaml.DoxYaml({})
|
||||
self.doxyaml.dox_file = os.path.join(base.SAMPLEDIR,
|
||||
'dox.yaml')
|
||||
|
||||
def test_base_class(self):
|
||||
self.assertIsInstance(self.doxyaml, cfg_base.ConfigBase)
|
||||
|
||||
def test_dox_yaml_old_parsing(self):
|
||||
self.doxyaml = dox_yaml.DoxYaml({})
|
||||
self.doxyaml.dox_file = os.path.join(base.SAMPLEDIR,
|
||||
'dox-old.yaml')
|
||||
for key in self.doxyaml.default_keys_of_section:
|
||||
self.assertIn(
|
||||
key, self.doxyaml._open_dox_yaml().keys())
|
||||
|
||||
def test_dox_yaml_not_finding_section(self):
|
||||
self.doxyaml = dox_yaml.DoxYaml({'section': 'foobar'})
|
||||
self.doxyaml.dox_file = os.path.join(base.SAMPLEDIR,
|
||||
'dox.yaml')
|
||||
self.assertRaises(
|
||||
dox_yaml.DoxYamlSectionNotFound,
|
||||
self.doxyaml._open_dox_yaml)
|
||||
|
||||
def test_dox_yaml_with_default_session(self):
|
||||
self.doxyaml = dox_yaml.DoxYaml({})
|
||||
self.doxyaml.dox_file = os.path.join(base.SAMPLEDIR,
|
||||
'dox.yaml')
|
||||
|
||||
for key in self.doxyaml.default_keys_of_section:
|
||||
self.assertIn(
|
||||
key, self.doxyaml._open_dox_yaml().keys())
|
||||
|
||||
def test_dox_yaml_new_parsing(self):
|
||||
for key in self.doxyaml.default_keys_of_section:
|
||||
self.assertIn(
|
||||
key, self.doxyaml._open_dox_yaml().keys())
|
||||
|
||||
# TOOD(chmou): Finish tests of dox_yaml.py
|
@ -1,65 +0,0 @@
|
||||
# Author: Chmouel Boudjnah <chmouel@enovance.com>
|
||||
#
|
||||
# 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 mock
|
||||
import os
|
||||
|
||||
import dox.config.base as cfg_base
|
||||
|
||||
from dox.config import tox_ini
|
||||
from dox.tests import base
|
||||
|
||||
|
||||
class TestToxIni(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestToxIni, self).setUp()
|
||||
|
||||
self.toxini = tox_ini.ToxIni({})
|
||||
self.toxini.tox_ini_file = os.path.join(base.SAMPLEDIR,
|
||||
'tox.ini')
|
||||
|
||||
def test_get_tox_ini(self):
|
||||
tox_ini_new = tox_ini.ToxIni({})
|
||||
with mock.patch.object(tox_ini, '_tox_ini', tox_ini_new):
|
||||
self.assertEqual(tox_ini.get_tox_ini({}),
|
||||
tox_ini_new)
|
||||
|
||||
def test_base_class(self):
|
||||
self.assertIsInstance(self.toxini, cfg_base.ConfigBase)
|
||||
|
||||
def test_exists_ini_file(self):
|
||||
self.assertTrue(self.toxini.exists())
|
||||
|
||||
def test_open_tox_ini(self):
|
||||
self.assertIn('tox', self.toxini._open_tox_ini().sections())
|
||||
|
||||
def test_get_images(self):
|
||||
self.assertEqual(['foo', 'bar'],
|
||||
self.toxini.get_images())
|
||||
|
||||
def test_get_commands(self):
|
||||
self.toxini = tox_ini.ToxIni({'section': 'testenv2'})
|
||||
self.toxini.tox_ini_file = os.path.join(base.SAMPLEDIR,
|
||||
'tox.ini')
|
||||
self.assertEqual(['foobar -c blah'],
|
||||
self.toxini.get_commands(
|
||||
['-c']))
|
||||
|
||||
def test_get_prep_commands(self):
|
||||
cmd = ['pip install -U -r/dox/requirements.txt '
|
||||
'-r/dox/test-requirements.txt']
|
||||
self.assertEqual(
|
||||
self.toxini.get_prep_commands(),
|
||||
cmd)
|
@ -1,26 +0,0 @@
|
||||
# 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 dox.config.base as cfg_base
|
||||
|
||||
from dox.config import travis_yaml
|
||||
from dox.tests import base
|
||||
|
||||
|
||||
class TestTravisYaml(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestTravisYaml, self).setUp()
|
||||
self.travisyaml = travis_yaml.TravisYaml({})
|
||||
|
||||
def test_base_class(self):
|
||||
self.assertIsInstance(self.travisyaml, cfg_base.ConfigBase)
|
@ -1,9 +0,0 @@
|
||||
images:
|
||||
- infra/trusty
|
||||
add:
|
||||
- requirements.txt
|
||||
- test-requirements.txt
|
||||
prep:
|
||||
- pip install -U -r requirements.txt -r test-requirements.txt
|
||||
commands:
|
||||
- python setup.py testr --slowest
|
@ -1,21 +0,0 @@
|
||||
testing:
|
||||
images:
|
||||
- infra/trusty
|
||||
add:
|
||||
- requirements.txt
|
||||
- test-requirements.txt
|
||||
prep:
|
||||
- pip install -U -r requirements.txt -r test-requirements.txt
|
||||
commands:
|
||||
- python setup.py testr --slowest
|
||||
|
||||
pep8:
|
||||
images:
|
||||
- infra/trusty
|
||||
add:
|
||||
- requirements.txt
|
||||
- test-requirements.txt
|
||||
prep:
|
||||
- pip install -U -r requirements.txt -r test-requirements.txt
|
||||
commands:
|
||||
- pep8
|
@ -1,14 +0,0 @@
|
||||
[tox]
|
||||
minversion = 1.6
|
||||
|
||||
[docker]
|
||||
images = foo,bar
|
||||
|
||||
[testenv]
|
||||
commands = foobar
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
install_command = pip install -U {opts} {packages}
|
||||
|
||||
[testenv2]
|
||||
commands = foobar {posargs} blah
|
@ -1,79 +0,0 @@
|
||||
# Author: Chmouel Boudjnah <chmouel@chmouel.com>
|
||||
#
|
||||
# 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 argparse
|
||||
|
||||
import mock
|
||||
|
||||
import dox.cmd
|
||||
from dox.tests import base
|
||||
|
||||
default_argp = argparse.Namespace(user_map=None, command=None,
|
||||
environment=None, extra_args=None,
|
||||
debug=None, noop=True,
|
||||
images=None, path_map=None)
|
||||
|
||||
|
||||
class TestCmd(base.TestCase):
|
||||
|
||||
@mock.patch('dox.runner.Runner.is_docker_installed',
|
||||
return_value=False)
|
||||
def test_runner(self, installed_mock):
|
||||
self.assertRaises(SystemExit, dox.cmd.runner, default_argp)
|
||||
|
||||
@mock.patch('dox.cmd.run_dox')
|
||||
@mock.patch('dox.config.cmdline.CommandLine')
|
||||
def test_multiple_images_one_command(self, m_cmdline, m_run_dox):
|
||||
argp = default_argp
|
||||
argp.images = 'foo, bar'
|
||||
argp.command = '/bin/true'
|
||||
dox.cmd.runner(argp)
|
||||
|
||||
self.assertTrue(m_cmdline.called)
|
||||
# silly but i'm not sure how to test that in a proper way
|
||||
self.assertEqual(['foo', 'bar'],
|
||||
m_run_dox.call_args_list[0][0][1])
|
||||
|
||||
@mock.patch('dox.cmd.run_dox')
|
||||
@mock.patch('dox.images.get_images')
|
||||
def test_multiple_environments(self, m_get_images, m_run_dox):
|
||||
argp = default_argp
|
||||
argp.environment = 'env1, env2'
|
||||
dox.cmd.runner(argp)
|
||||
|
||||
self.assertEqual(2, m_get_images.call_count)
|
||||
self.assertEqual(2, m_run_dox.call_count)
|
||||
|
||||
@mock.patch('dox.cmd.run_dox')
|
||||
@mock.patch('dox.images.get_images')
|
||||
def test_multiple_environments_images(self, m_get_images, m_run_dox):
|
||||
argp = default_argp
|
||||
argp.images = 'foo, bar'
|
||||
argp.environment = 'env1, env2'
|
||||
dox.cmd.runner(argp)
|
||||
|
||||
self.assertEqual(0, m_get_images.call_count)
|
||||
self.assertEqual(2, m_run_dox.call_count)
|
||||
|
||||
@mock.patch('dox.cmd.run_dox')
|
||||
@mock.patch('dox.images.get_images')
|
||||
def test_default(self, m_get_images, m_run_dox):
|
||||
dox.cmd.runner(default_argp)
|
||||
|
||||
self.assertEqual('_default',
|
||||
m_get_images.call_args_list[0][0][0].get('section'))
|
||||
|
||||
@mock.patch('dox.runner.Runner')
|
||||
def test_run_dox(self, m_runner):
|
||||
dox.cmd.run_dox(default_argp, ['1', '2', '3'], '/bin/echo', "name")
|
||||
self.assertEqual(1, m_runner.call_count)
|
@ -1,26 +0,0 @@
|
||||
# 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.
|
||||
|
||||
"""
|
||||
test_dox
|
||||
----------------------------------
|
||||
|
||||
Tests for `dox` module.
|
||||
"""
|
||||
|
||||
from dox.tests import base
|
||||
|
||||
|
||||
class TestDox(base.TestCase):
|
||||
|
||||
def test_something(self):
|
||||
pass
|
@ -1,102 +0,0 @@
|
||||
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
test_images
|
||||
--------------
|
||||
|
||||
Tests for `dox.images` module.
|
||||
"""
|
||||
|
||||
import fixtures
|
||||
import testscenarios
|
||||
|
||||
from dox import images
|
||||
from dox.tests import base
|
||||
|
||||
|
||||
def get_fake_image(value):
|
||||
if value is not None:
|
||||
def fake_value(self):
|
||||
return value
|
||||
else:
|
||||
def fake_value(self):
|
||||
return ['ubuntu']
|
||||
return fake_value
|
||||
|
||||
|
||||
class TestImages(base.TestCase):
|
||||
|
||||
scenarios = [
|
||||
('have_dockerfile', dict(
|
||||
dockerfile=True, tox_ini=False, dox_yaml=False,
|
||||
tox_value=[], dox_value=[], images=[])),
|
||||
('no_dockerfile', dict(
|
||||
dockerfile=False, tox_ini=False, dox_yaml=False,
|
||||
tox_value=[], dox_value=[], images=['ubuntu'])),
|
||||
('tox_no_docker', dict(
|
||||
dockerfile=False, tox_ini=True, dox_yaml=False,
|
||||
tox_value=[], dox_value=[], images=['ubuntu'])),
|
||||
('tox_docker', dict(
|
||||
dockerfile=False, tox_ini=True, dox_yaml=False,
|
||||
tox_value=['tox_docker'], dox_value=[], images=['tox_docker'])),
|
||||
('dox_image', dict(
|
||||
dockerfile=False, tox_ini=False, dox_yaml=True,
|
||||
tox_value=[], dox_value=[], images=['ubuntu'])),
|
||||
('dox_no_image', dict(
|
||||
dockerfile=False, tox_ini=False, dox_yaml=True,
|
||||
tox_value=[], dox_value=['dox_value'], images=['dox_value'])),
|
||||
('both_dox_wins', dict(
|
||||
dockerfile=False, tox_ini=True, dox_yaml=True,
|
||||
tox_value=['tox_wins'], dox_value=['dox_wins'],
|
||||
images=['dox_wins'])),
|
||||
('both_no_dox', dict(
|
||||
dockerfile=False, tox_ini=True, dox_yaml=True,
|
||||
tox_value=['tox_wins'], dox_value=[], images=['ubuntu'])),
|
||||
('both_dockerfile_passthru', dict(
|
||||
dockerfile=True, tox_ini=True, dox_yaml=True,
|
||||
tox_value=[], dox_value=[], images=[])),
|
||||
('all_dockerfile_dox_override', dict(
|
||||
dockerfile=True, tox_ini=True, dox_yaml=True,
|
||||
tox_value=[], dox_value=['dox_wins'], images=['dox_wins'])),
|
||||
('all_dockerfile_tox_loses', dict(
|
||||
dockerfile=True, tox_ini=True, dox_yaml=True,
|
||||
tox_value=['tox_wins'], dox_value=[], images=[])),
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(TestImages, self).setUp()
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.dockerfile.Dockerfile.exists',
|
||||
base.bool_to_fake(self.dockerfile)))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.dox_yaml.DoxYaml.exists',
|
||||
base.bool_to_fake(self.dox_yaml)))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.tox_ini.ToxIni.exists',
|
||||
base.bool_to_fake(self.tox_ini)))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.dox_yaml.DoxYaml.get_images',
|
||||
get_fake_image(self.dox_value)))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'dox.config.tox_ini.ToxIni.get_images',
|
||||
get_fake_image(self.tox_value)))
|
||||
|
||||
def test_images(self):
|
||||
image = images.get_images({})
|
||||
self.assertEqual(image, self.images)
|
||||
|
||||
|
||||
def load_tests(loader, in_tests, pattern):
|
||||
return testscenarios.load_tests_apply_scenarios(loader, in_tests, pattern)
|
@ -1,232 +0,0 @@
|
||||
# Author: Chmouel Boudjnah <chmouel@enovance.com>
|
||||
#
|
||||
# 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 argparse
|
||||
import os
|
||||
import shutil # noqa
|
||||
import tempfile
|
||||
|
||||
import mock
|
||||
|
||||
import dox.runner as doxrunner
|
||||
from dox.tests import base
|
||||
|
||||
|
||||
class FakeCommands(object):
|
||||
def __init__(self, commands=None, files_to_add=None):
|
||||
self.commands = commands or ["command1", "command2"]
|
||||
self.files_to_add = files_to_add or ["file1"]
|
||||
|
||||
def prep_commands(self):
|
||||
return self.commands
|
||||
|
||||
def get_add_files(self):
|
||||
return self.files_to_add
|
||||
|
||||
|
||||
class TestRunner(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRunner, self).setUp()
|
||||
|
||||
def test_user_mapping(self):
|
||||
dr = doxrunner.Runner(argparse.Namespace(user_map='foo:100:10',
|
||||
path_map=None))
|
||||
self.assertEqual('foo', dr.user_map['username'])
|
||||
self.assertEqual(100, dr.user_map['uid'])
|
||||
self.assertEqual(10, dr.user_map['gid'])
|
||||
|
||||
@mock.patch('os.getuid', return_value=12345)
|
||||
@mock.patch('os.getgid', return_value=67890)
|
||||
@mock.patch('pwd.getpwuid', return_value=['toto'])
|
||||
def test_user_mapping_default(self, os_uid, os_gid, os_username):
|
||||
dr = doxrunner.Runner(argparse.Namespace(user_map=None,
|
||||
path_map=None))
|
||||
self.assertEqual('toto', dr.user_map['username'])
|
||||
self.assertEqual(12345, dr.user_map['uid'])
|
||||
self.assertEqual(67890, dr.user_map['gid'])
|
||||
|
||||
def test_path_mapping(self):
|
||||
dr = doxrunner.Runner(argparse.Namespace(path_map='/Users:/home',
|
||||
user_map=None))
|
||||
self.assertEqual('/Users', dr.path_map['local'])
|
||||
self.assertEqual('/home', dr.path_map['remote'])
|
||||
|
||||
def test_path_mapping_extra_colon(self):
|
||||
dr = doxrunner.Runner(argparse.Namespace(path_map='/Users:/home:foo',
|
||||
user_map=None))
|
||||
self.assertEqual('/Users', dr.path_map['local'])
|
||||
self.assertEqual('/home:foo', dr.path_map['remote'])
|
||||
|
||||
def test_path_mapping_default(self):
|
||||
dr = doxrunner.Runner(argparse.Namespace(path_map=None,
|
||||
user_map=None))
|
||||
self.assertIsNone(dr.path_map)
|
||||
|
||||
def test_is_docker_installed(self):
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
|
||||
def mydocker_cmd(dr, *args):
|
||||
raise OSError
|
||||
dr._docker_cmd = mydocker_cmd
|
||||
self.assertFalse(dr.is_docker_installed())
|
||||
|
||||
def mydocker_cmd(dr, *args):
|
||||
return True
|
||||
dr._docker_cmd = mydocker_cmd
|
||||
self.assertTrue(dr.is_docker_installed())
|
||||
|
||||
def test_docker_cmd(self):
|
||||
dr = doxrunner.Runner(argparse.Namespace(user_map=None,
|
||||
path_map=None,
|
||||
debug=False))
|
||||
dr._run_shell_command = mock.MagicMock()
|
||||
dr._docker_cmd("version")
|
||||
dr._run_shell_command.assert_called_with(
|
||||
['docker', 'version']
|
||||
)
|
||||
|
||||
dr = doxrunner.Runner(argparse.Namespace(user_map=None,
|
||||
path_map=None,
|
||||
debug=True))
|
||||
dr._run_shell_command = mock.MagicMock()
|
||||
dr._docker_cmd("version")
|
||||
dr._run_shell_command.assert_called_with(
|
||||
['docker', 'version']
|
||||
)
|
||||
|
||||
dr = doxrunner.Runner(argparse.Namespace(user_map=None,
|
||||
path_map=None,
|
||||
debug=True))
|
||||
dr._run_shell_command = mock.Mock()
|
||||
dr._run_shell_command.side_effect = OSError("Boom")
|
||||
self.assertRaises(OSError, dr._docker_cmd, "version")
|
||||
|
||||
def test_build_images_pass(self):
|
||||
dr = doxrunner.Runner(argparse.Namespace(path_map=None,
|
||||
user_map=None))
|
||||
dr.have_test_image = mock.Mock()
|
||||
dr.return_value = True
|
||||
self.assertIsNone(dr.build_test_image("image", FakeCommands()))
|
||||
|
||||
@mock.patch.multiple("shutil", rmtree=mock.DEFAULT,
|
||||
copy=mock.DEFAULT)
|
||||
def test_build_images(self, rmtree, copy):
|
||||
my_temp_file = tempfile.mkdtemp()
|
||||
docker_written = os.path.join(my_temp_file, "Dockerfile")
|
||||
fk = FakeCommands(["toto1", "toto2"],
|
||||
["blah3", "blah4"])
|
||||
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
quiet=False, noop=False,
|
||||
rebuild=True, debug=True,
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
m_docker_build = dr._docker_build = mock.Mock()
|
||||
with mock.patch.object(tempfile, "mkdtemp", return_value=my_temp_file):
|
||||
dr.build_test_image("myimage", fk)
|
||||
|
||||
m_docker_build.assert_called_once_with(
|
||||
dr.test_image_name, my_temp_file)
|
||||
|
||||
# Only the last one
|
||||
copy.assert_called_with('blah4',
|
||||
os.path.join(my_temp_file, "blah4"))
|
||||
self.assertTrue(copy.called)
|
||||
self.assertTrue(rmtree.called)
|
||||
self.assertTrue(os.path.exists(docker_written))
|
||||
um = dr.user_map
|
||||
|
||||
expected = """FROM %s
|
||||
RUN useradd -M -U -d /src -u %s %s
|
||||
ADD blah3 /dox/
|
||||
ADD blah4 /dox/
|
||||
WORKDIR /dox
|
||||
RUN toto1
|
||||
|
||||
RUN toto2
|
||||
""""" % ("myimage", um['uid'], um['username'])
|
||||
|
||||
self.assertEqual(expected, open(docker_written, 'r').read())
|
||||
|
||||
def test_have_base_image(self):
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
rebuild=True,
|
||||
rebuild_all=False,
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
dr._get_image_list = mock.MagicMock()
|
||||
self.assertFalse(dr.have_base_image())
|
||||
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
rebuild=False,
|
||||
rebuild_all=True,
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
dr._get_image_list = mock.MagicMock()
|
||||
self.assertFalse(dr.have_base_image())
|
||||
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
rebuild=False,
|
||||
rebuild_all=False,
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
dr._get_image_list = mock.MagicMock()
|
||||
dr._get_image_list.return_value = [dr.base_image_name]
|
||||
self.assertTrue(dr.have_base_image())
|
||||
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
rebuild=False,
|
||||
rebuild_all=False,
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
dr._get_image_list = mock.MagicMock()
|
||||
dr._get_image_list.return_value = []
|
||||
self.assertFalse(dr.have_base_image())
|
||||
|
||||
def test_have_test_image(self):
|
||||
# NOTE(chmou): this probably would need some refactoring with
|
||||
# have_base_image
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
rebuild=True,
|
||||
rebuild_all=False,
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
self.assertFalse(dr.have_test_image())
|
||||
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
rebuild=False,
|
||||
rebuild_all=True,
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
self.assertFalse(dr.have_test_image())
|
||||
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
rebuild=False,
|
||||
rebuild_all=False,
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
dr._get_image_list = mock.MagicMock()
|
||||
dr._get_image_list.return_value = [dr.test_image_name]
|
||||
self.assertTrue(dr.have_test_image())
|
||||
|
||||
dr = doxrunner.Runner(argparse.Namespace(
|
||||
rebuild=False,
|
||||
rebuild_all=False,
|
||||
path_map=None,
|
||||
user_map=None))
|
||||
dr._get_image_list = mock.MagicMock()
|
||||
dr._get_image_list.return_value = []
|
||||
self.assertFalse(dr.have_test_image())
|
@ -1,4 +0,0 @@
|
||||
pbr>=0.5.21,<1.0
|
||||
|
||||
PyYAML
|
||||
six
|
46
setup.cfg
46
setup.cfg
@ -1,46 +0,0 @@
|
||||
[metadata]
|
||||
name = dox
|
||||
summary = dox runs tox descriptions in docker containers
|
||||
description-file =
|
||||
README.rst
|
||||
author = OpenStack
|
||||
author-email = openstack-dev@lists.openstack.org
|
||||
home-page = http://www.openstack.org/
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Information Technology
|
||||
Intended Audience :: System Administrators
|
||||
License :: OSI Approved :: Apache Software License
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 2.6
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.3
|
||||
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
dox = dox.cmd:main
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
build-dir = doc/build
|
||||
all_files = 1
|
||||
|
||||
[upload_sphinx]
|
||||
upload-dir = doc/build/html
|
||||
|
||||
[compile_catalog]
|
||||
directory = dox/locale
|
||||
domain = dox
|
||||
|
||||
[update_catalog]
|
||||
domain = dox
|
||||
output_dir = dox/locale
|
||||
input_file = dox/locale/dox.pot
|
||||
|
||||
[extract_messages]
|
||||
keywords = _ gettext ngettext l_ lazy_gettext
|
||||
mapping_file = babel.cfg
|
||||
output_file = dox/locale/dox.pot
|
22
setup.py
22
setup.py
@ -1,22 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr'],
|
||||
pbr=True)
|
@ -1,12 +0,0 @@
|
||||
hacking>=0.5.6,<0.8
|
||||
|
||||
coverage>=3.6
|
||||
discover
|
||||
fixtures>=0.3.14
|
||||
python-subunit
|
||||
sphinx>=1.1.2
|
||||
oslo.sphinx
|
||||
testrepository>=0.0.17
|
||||
testscenarios>=0.4,<0.5
|
||||
testtools>=0.9.32
|
||||
mock
|
@ -1,38 +0,0 @@
|
||||
#!/bin/bash -ex
|
||||
# Copyright 2017 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
GROUP=docker
|
||||
if [ $(id -gn) != ${GROUP} ]; then
|
||||
exec sg ${GROUP} "$0 $*"
|
||||
fi
|
||||
|
||||
### Build image with docker
|
||||
IMAGES="infra/centos7 infra/trusty infra/xenial"
|
||||
for IMAGE in $IMAGES; do
|
||||
docker build dockerfiles/$IMAGE -t $IMAGE
|
||||
done
|
||||
|
||||
docker images
|
||||
|
||||
# NOTE(pabelanger): Make sure we hash by ZUUL_COMMIT, so we know which tarball
|
||||
# to download from secure worker.
|
||||
DIST=$WORKSPACE/dist/$ZUUL_COMMIT
|
||||
mkdir -p $DIST
|
||||
|
||||
### Save docker image for upload to tarballs.o.o
|
||||
FILENAME=images.tar.gz
|
||||
docker save $IMAGES | gzip -9 > $DIST/$FILENAME
|
||||
shasum $DIST/$FILENAME > $DIST/$FILENAME.sha256
|
@ -1,18 +0,0 @@
|
||||
#!/bin/bash -ex
|
||||
# Copyright 2017 Red Hat, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
sudo gpasswd -a ${USER} docker
|
||||
sudo service docker restart
|
33
tox.ini
33
tox.ini
@ -1,33 +0,0 @@
|
||||
[tox]
|
||||
minversion = 1.6
|
||||
envlist = py27,py33,pep8
|
||||
skipsdist = True
|
||||
|
||||
[testenv]
|
||||
usedevelop = True
|
||||
install_command = pip install -U {opts} {packages}
|
||||
setenv =
|
||||
VIRTUAL_ENV={envdir}
|
||||
LANG=en_US.UTF-8
|
||||
LANGUAGE=en_US:en
|
||||
LC_ALL=C
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
commands = python setup.py testr --slowest --testr-args='{posargs}'
|
||||
|
||||
[testenv:pep8]
|
||||
commands = flake8
|
||||
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
||||
|
||||
[testenv:cover]
|
||||
commands = python setup.py testr --coverage --testr-args='{posargs}'
|
||||
|
||||
[flake8]
|
||||
show-source = True
|
||||
builtins = _
|
||||
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
|
||||
|
||||
[docker]
|
||||
images = infra/trusty
|
Loading…
x
Reference in New Issue
Block a user