testcloud 0.10.0__tar.gz → 0.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {testcloud-0.10.0/testcloud.egg-info → testcloud-0.11.0}/PKG-INFO +1 -1
- {testcloud-0.10.0 → testcloud-0.11.0}/docs/source/conf.py +64 -72
- testcloud-0.11.0/pyproject.toml +2 -0
- testcloud-0.11.0/setup.py +72 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/test/test_config.py +20 -20
- testcloud-0.11.0/test/test_image.py +144 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/test/test_instance.py +10 -9
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/__init__.py +1 -2
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/cli.py +307 -223
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/config.py +56 -57
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/distro_utils/alma.py +5 -4
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/distro_utils/centos.py +12 -7
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/distro_utils/debian.py +13 -6
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/distro_utils/fedora.py +22 -18
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/distro_utils/misc.py +6 -4
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/distro_utils/oracle.py +4 -3
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/distro_utils/rocky.py +5 -4
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/distro_utils/ubuntu.py +7 -6
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/domain_configuration.py +94 -54
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/exceptions.py +7 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/image.py +52 -86
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/instance.py +177 -144
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/sql.py +2 -1
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/util.py +37 -34
- testcloud-0.11.0/testcloud/workarounds.py +88 -0
- {testcloud-0.10.0 → testcloud-0.11.0/testcloud.egg-info}/PKG-INFO +1 -1
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud.egg-info/SOURCES.txt +1 -0
- testcloud-0.10.0/setup.py +0 -61
- testcloud-0.10.0/test/test_image.py +0 -145
- testcloud-0.10.0/testcloud/workarounds.py +0 -75
- {testcloud-0.10.0 → testcloud-0.11.0}/.gitignore +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/LICENSE +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/README.md +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/conf/99-testcloud-nonroot-libvirt-access.rules +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/conf/settings-example.py +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/conf/testcloud +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/docs/LICENSE +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/docs/Makefile +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/docs/source/api.rst +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/docs/source/indepth.rst +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/docs/source/index.rst +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/manpages/testcloud.1 +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/requirements.txt +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/run_testcloud.py +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/setup.cfg +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/test/__init__.py +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/test/test_cli.py +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud/distro_utils/__init__.py +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud.egg-info/dependency_links.txt +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud.egg-info/entry_points.txt +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud.egg-info/requires.txt +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/testcloud.egg-info/top_level.txt +0 -0
- {testcloud-0.10.0 → testcloud-0.11.0}/tox.ini +0 -0
|
@@ -18,56 +18,56 @@ import os
|
|
|
18
18
|
# If extensions (or modules to document with autodoc) are in another directory,
|
|
19
19
|
# add these directories to sys.path here. If the directory is relative to the
|
|
20
20
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
21
|
-
sys.path.insert(0, os.path.abspath(
|
|
21
|
+
sys.path.insert(0, os.path.abspath("../../"))
|
|
22
22
|
|
|
23
23
|
# -- General configuration ------------------------------------------------
|
|
24
24
|
|
|
25
25
|
# If your documentation needs a minimal Sphinx version, state it here.
|
|
26
|
-
#needs_sphinx = '1.0'
|
|
26
|
+
# needs_sphinx = '1.0'
|
|
27
27
|
|
|
28
28
|
# Add any Sphinx extension module names here, as strings. They can be
|
|
29
29
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
30
30
|
# ones.
|
|
31
31
|
extensions = [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
"sphinx.ext.autodoc",
|
|
33
|
+
"sphinx.ext.todo",
|
|
34
|
+
"sphinx.ext.viewcode",
|
|
35
35
|
]
|
|
36
36
|
|
|
37
37
|
# Add any paths that contain templates here, relative to this directory.
|
|
38
|
-
templates_path = [
|
|
38
|
+
templates_path = ["_templates"]
|
|
39
39
|
|
|
40
40
|
# The suffix of source filenames.
|
|
41
|
-
source_suffix =
|
|
41
|
+
source_suffix = ".rst"
|
|
42
42
|
|
|
43
43
|
# The encoding of source files.
|
|
44
|
-
#source_encoding = 'utf-8-sig'
|
|
44
|
+
# source_encoding = 'utf-8-sig'
|
|
45
45
|
|
|
46
46
|
# The master toctree document.
|
|
47
|
-
master_doc =
|
|
47
|
+
master_doc = "index"
|
|
48
48
|
|
|
49
49
|
# General information about the project.
|
|
50
|
-
project =
|
|
51
|
-
copyright =
|
|
50
|
+
project = "testCloud"
|
|
51
|
+
copyright = "2016-2024, testCloud devs"
|
|
52
52
|
|
|
53
53
|
# The version info for the project you're documenting, acts as replacement for
|
|
54
54
|
# |version| and |release|, also used in various other places throughout the
|
|
55
55
|
# built documents.
|
|
56
56
|
#
|
|
57
57
|
# The short X.Y version.
|
|
58
|
-
version =
|
|
58
|
+
version = "0.11.0"
|
|
59
59
|
# The full version, including alpha/beta/rc tags.
|
|
60
60
|
release = version
|
|
61
61
|
|
|
62
62
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
|
63
63
|
# for a list of supported languages.
|
|
64
|
-
#language = None
|
|
64
|
+
# language = None
|
|
65
65
|
|
|
66
66
|
# There are two options for replacing |today|: either, you set today to some
|
|
67
67
|
# non-false value, then it is used:
|
|
68
|
-
#today = ''
|
|
68
|
+
# today = ''
|
|
69
69
|
# Else, today_fmt is used as the format for a strftime call.
|
|
70
|
-
#today_fmt = '%B %d, %Y'
|
|
70
|
+
# today_fmt = '%B %d, %Y'
|
|
71
71
|
|
|
72
72
|
# List of patterns, relative to source directory, that match files and
|
|
73
73
|
# directories to ignore when looking for source files.
|
|
@@ -75,167 +75,161 @@ exclude_patterns = []
|
|
|
75
75
|
|
|
76
76
|
# The reST default role (used for this markup: `text`) to use for all
|
|
77
77
|
# documents.
|
|
78
|
-
#default_role = None
|
|
78
|
+
# default_role = None
|
|
79
79
|
|
|
80
80
|
# If true, '()' will be appended to :func: etc. cross-reference text.
|
|
81
|
-
#add_function_parentheses = True
|
|
81
|
+
# add_function_parentheses = True
|
|
82
82
|
|
|
83
83
|
# If true, the current module name will be prepended to all description
|
|
84
84
|
# unit titles (such as .. function::).
|
|
85
|
-
#add_module_names = True
|
|
85
|
+
# add_module_names = True
|
|
86
86
|
|
|
87
87
|
# If true, sectionauthor and moduleauthor directives will be shown in the
|
|
88
88
|
# output. They are ignored by default.
|
|
89
|
-
#show_authors = False
|
|
89
|
+
# show_authors = False
|
|
90
90
|
|
|
91
91
|
# The name of the Pygments (syntax highlighting) style to use.
|
|
92
|
-
pygments_style =
|
|
92
|
+
pygments_style = "sphinx"
|
|
93
93
|
|
|
94
94
|
# A list of ignored prefixes for module index sorting.
|
|
95
|
-
#modindex_common_prefix = []
|
|
95
|
+
# modindex_common_prefix = []
|
|
96
96
|
|
|
97
97
|
# If true, keep warnings as "system message" paragraphs in the built documents.
|
|
98
|
-
#keep_warnings = False
|
|
98
|
+
# keep_warnings = False
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
# -- Options for HTML output ----------------------------------------------
|
|
102
102
|
|
|
103
103
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
104
104
|
# a list of builtin themes.
|
|
105
|
-
html_theme =
|
|
105
|
+
html_theme = "nature"
|
|
106
106
|
|
|
107
107
|
# Theme options are theme-specific and customize the look and feel of a theme
|
|
108
108
|
# further. For a list of options available for each theme, see the
|
|
109
109
|
# documentation.
|
|
110
|
-
#html_theme_options = {}
|
|
110
|
+
# html_theme_options = {}
|
|
111
111
|
|
|
112
112
|
# Add any paths that contain custom themes here, relative to this directory.
|
|
113
|
-
#html_theme_path = []
|
|
113
|
+
# html_theme_path = []
|
|
114
114
|
|
|
115
115
|
# The name for this set of Sphinx documents. If None, it defaults to
|
|
116
116
|
# "<project> v<release> documentation".
|
|
117
|
-
#html_title = None
|
|
117
|
+
# html_title = None
|
|
118
118
|
|
|
119
119
|
# A shorter title for the navigation bar. Default is the same as html_title.
|
|
120
|
-
#html_short_title = None
|
|
120
|
+
# html_short_title = None
|
|
121
121
|
|
|
122
122
|
# The name of an image file (relative to this directory) to place at the top
|
|
123
123
|
# of the sidebar.
|
|
124
|
-
#html_logo = None
|
|
124
|
+
# html_logo = None
|
|
125
125
|
|
|
126
126
|
# The name of an image file (within the static path) to use as favicon of the
|
|
127
127
|
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
|
128
128
|
# pixels large.
|
|
129
|
-
#html_favicon = None
|
|
129
|
+
# html_favicon = None
|
|
130
130
|
|
|
131
131
|
# Add any paths that contain custom static files (such as style sheets) here,
|
|
132
132
|
# relative to this directory. They are copied after the builtin static files,
|
|
133
133
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
134
|
-
#html_static_path = ['_static']
|
|
134
|
+
# html_static_path = ['_static']
|
|
135
135
|
|
|
136
136
|
# Add any extra paths that contain custom files (such as robots.txt or
|
|
137
137
|
# .htaccess) here, relative to this directory. These files are copied
|
|
138
138
|
# directly to the root of the documentation.
|
|
139
|
-
#html_extra_path = []
|
|
139
|
+
# html_extra_path = []
|
|
140
140
|
|
|
141
141
|
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
|
142
142
|
# using the given strftime format.
|
|
143
|
-
#html_last_updated_fmt = '%b %d, %Y'
|
|
143
|
+
# html_last_updated_fmt = '%b %d, %Y'
|
|
144
144
|
|
|
145
145
|
# If true, SmartyPants will be used to convert quotes and dashes to
|
|
146
146
|
# typographically correct entities.
|
|
147
|
-
#html_use_smartypants = True
|
|
147
|
+
# html_use_smartypants = True
|
|
148
148
|
|
|
149
149
|
# Custom sidebar templates, maps document names to template names.
|
|
150
|
-
#html_sidebars = {}
|
|
150
|
+
# html_sidebars = {}
|
|
151
151
|
|
|
152
152
|
# Additional templates that should be rendered to pages, maps page names to
|
|
153
153
|
# template names.
|
|
154
|
-
#html_additional_pages = {}
|
|
154
|
+
# html_additional_pages = {}
|
|
155
155
|
|
|
156
156
|
# If false, no module index is generated.
|
|
157
|
-
#html_domain_indices = True
|
|
157
|
+
# html_domain_indices = True
|
|
158
158
|
|
|
159
159
|
# If false, no index is generated.
|
|
160
|
-
#html_use_index = True
|
|
160
|
+
# html_use_index = True
|
|
161
161
|
|
|
162
162
|
# If true, the index is split into individual pages for each letter.
|
|
163
|
-
#html_split_index = False
|
|
163
|
+
# html_split_index = False
|
|
164
164
|
|
|
165
165
|
# If true, links to the reST sources are added to the pages.
|
|
166
|
-
#html_show_sourcelink = True
|
|
166
|
+
# html_show_sourcelink = True
|
|
167
167
|
|
|
168
168
|
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
|
169
|
-
#html_show_sphinx = True
|
|
169
|
+
# html_show_sphinx = True
|
|
170
170
|
|
|
171
171
|
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
|
172
|
-
#html_show_copyright = True
|
|
172
|
+
# html_show_copyright = True
|
|
173
173
|
|
|
174
174
|
# If true, an OpenSearch description file will be output, and all pages will
|
|
175
175
|
# contain a <link> tag referring to it. The value of this option must be the
|
|
176
176
|
# base URL from which the finished HTML is served.
|
|
177
|
-
#html_use_opensearch = ''
|
|
177
|
+
# html_use_opensearch = ''
|
|
178
178
|
|
|
179
179
|
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
|
180
|
-
#html_file_suffix = None
|
|
180
|
+
# html_file_suffix = None
|
|
181
181
|
|
|
182
182
|
# Output file base name for HTML help builder.
|
|
183
|
-
htmlhelp_basename =
|
|
183
|
+
htmlhelp_basename = "testClouddoc"
|
|
184
184
|
|
|
185
185
|
|
|
186
186
|
# -- Options for LaTeX output ---------------------------------------------
|
|
187
187
|
|
|
188
188
|
latex_elements = {
|
|
189
|
-
# The paper size ('letterpaper' or 'a4paper').
|
|
190
|
-
#'papersize': 'letterpaper',
|
|
191
|
-
|
|
192
|
-
#
|
|
193
|
-
#
|
|
194
|
-
|
|
195
|
-
# Additional stuff for the LaTeX preamble.
|
|
196
|
-
#'preamble': '',
|
|
189
|
+
# The paper size ('letterpaper' or 'a4paper').
|
|
190
|
+
#'papersize': 'letterpaper',
|
|
191
|
+
# The font size ('10pt', '11pt' or '12pt').
|
|
192
|
+
#'pointsize': '10pt',
|
|
193
|
+
# Additional stuff for the LaTeX preamble.
|
|
194
|
+
#'preamble': '',
|
|
197
195
|
}
|
|
198
196
|
|
|
199
197
|
# Grouping the document tree into LaTeX files. List of tuples
|
|
200
198
|
# (source start file, target name, title,
|
|
201
199
|
# author, documentclass [howto, manual, or own class]).
|
|
202
200
|
latex_documents = [
|
|
203
|
-
|
|
204
|
-
u'testCloud devs', 'manual'),
|
|
201
|
+
("index", "testCloud.tex", "testCloud Documentation", "testCloud devs", "manual"),
|
|
205
202
|
]
|
|
206
203
|
|
|
207
204
|
# The name of an image file (relative to this directory) to place at the top of
|
|
208
205
|
# the title page.
|
|
209
|
-
#latex_logo = None
|
|
206
|
+
# latex_logo = None
|
|
210
207
|
|
|
211
208
|
# For "manual" documents, if this is true, then toplevel headings are parts,
|
|
212
209
|
# not chapters.
|
|
213
|
-
#latex_use_parts = False
|
|
210
|
+
# latex_use_parts = False
|
|
214
211
|
|
|
215
212
|
# If true, show page references after internal links.
|
|
216
|
-
#latex_show_pagerefs = False
|
|
213
|
+
# latex_show_pagerefs = False
|
|
217
214
|
|
|
218
215
|
# If true, show URL addresses after external links.
|
|
219
|
-
#latex_show_urls = False
|
|
216
|
+
# latex_show_urls = False
|
|
220
217
|
|
|
221
218
|
# Documents to append as an appendix to all manuals.
|
|
222
|
-
#latex_appendices = []
|
|
219
|
+
# latex_appendices = []
|
|
223
220
|
|
|
224
221
|
# If false, no module index is generated.
|
|
225
|
-
#latex_domain_indices = True
|
|
222
|
+
# latex_domain_indices = True
|
|
226
223
|
|
|
227
224
|
|
|
228
225
|
# -- Options for manual page output ---------------------------------------
|
|
229
226
|
|
|
230
227
|
# One entry per manual page. List of tuples
|
|
231
228
|
# (source start file, name, description, authors, manual section).
|
|
232
|
-
man_pages = [
|
|
233
|
-
('index', 'testcloud', u'testCloud Documentation',
|
|
234
|
-
[u'testCloud devs'], 1)
|
|
235
|
-
]
|
|
229
|
+
man_pages = [("index", "testcloud", "testCloud Documentation", ["testCloud devs"], 1)]
|
|
236
230
|
|
|
237
231
|
# If true, show URL addresses after external links.
|
|
238
|
-
#man_show_urls = False
|
|
232
|
+
# man_show_urls = False
|
|
239
233
|
|
|
240
234
|
|
|
241
235
|
# -- Options for Texinfo output -------------------------------------------
|
|
@@ -244,19 +238,17 @@ man_pages = [
|
|
|
244
238
|
# (source start file, target name, title, author,
|
|
245
239
|
# dir menu entry, description, category)
|
|
246
240
|
texinfo_documents = [
|
|
247
|
-
|
|
248
|
-
u'testCloud devs', 'testCloud', 'One line description of project.',
|
|
249
|
-
'Miscellaneous'),
|
|
241
|
+
("index", "testCloud", "testCloud Documentation", "testCloud devs", "testCloud", "One line description of project.", "Miscellaneous"),
|
|
250
242
|
]
|
|
251
243
|
|
|
252
244
|
# Documents to append as an appendix to all manuals.
|
|
253
|
-
#texinfo_appendices = []
|
|
245
|
+
# texinfo_appendices = []
|
|
254
246
|
|
|
255
247
|
# If false, no module index is generated.
|
|
256
|
-
#texinfo_domain_indices = True
|
|
248
|
+
# texinfo_domain_indices = True
|
|
257
249
|
|
|
258
250
|
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
|
259
|
-
#texinfo_show_urls = 'footnote'
|
|
251
|
+
# texinfo_show_urls = 'footnote'
|
|
260
252
|
|
|
261
253
|
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
|
262
|
-
#texinfo_no_detailmenu = False
|
|
254
|
+
# texinfo_no_detailmenu = False
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import codecs
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
from setuptools import Command, setup
|
|
6
|
+
|
|
7
|
+
here = os.path.abspath(os.path.dirname(__file__))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def read(*parts):
|
|
11
|
+
return codecs.open(os.path.join(here, *parts), "r").read()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def find_version(*file_paths):
|
|
15
|
+
version_file = read(*file_paths)
|
|
16
|
+
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M)
|
|
17
|
+
if version_match:
|
|
18
|
+
return version_match.group(1)
|
|
19
|
+
raise RuntimeError("Unable to find version string.")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PyTest(Command):
|
|
23
|
+
user_options = []
|
|
24
|
+
|
|
25
|
+
def initialize_options(self):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
def finalize_options(self):
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
def run(self):
|
|
32
|
+
import subprocess
|
|
33
|
+
|
|
34
|
+
errno = subprocess.call(["pytest-3"])
|
|
35
|
+
raise SystemExit(errno)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
with open("README.md") as f:
|
|
39
|
+
long_description_readme = f.read()
|
|
40
|
+
|
|
41
|
+
setup(
|
|
42
|
+
name="testcloud",
|
|
43
|
+
version=find_version("testcloud", "__init__.py"),
|
|
44
|
+
description="A tool to download and boot cloud images locally, with an easy to use API.",
|
|
45
|
+
long_description=long_description_readme,
|
|
46
|
+
long_description_content_type="text/markdown",
|
|
47
|
+
author="Mike Ruckman",
|
|
48
|
+
author_email="roshi@fedoraproject.org",
|
|
49
|
+
license="GPLv2+",
|
|
50
|
+
url="https://pagure.io/testcloud",
|
|
51
|
+
packages=["testcloud", "testcloud.distro_utils"],
|
|
52
|
+
package_dir={"testcloud": "testcloud"},
|
|
53
|
+
include_package_data=True,
|
|
54
|
+
cmdclass={"test": PyTest},
|
|
55
|
+
entry_points=dict(
|
|
56
|
+
console_scripts=[
|
|
57
|
+
"testcloud=testcloud.cli:main",
|
|
58
|
+
"t7d=testcloud.cli:main",
|
|
59
|
+
]
|
|
60
|
+
),
|
|
61
|
+
data_files=[
|
|
62
|
+
("share/man/man1", ["manpages/testcloud.1"]),
|
|
63
|
+
("share/bash-completion/completions", ["conf/testcloud"]),
|
|
64
|
+
],
|
|
65
|
+
install_requires=[
|
|
66
|
+
"libvirt-python",
|
|
67
|
+
"peewee",
|
|
68
|
+
"requests",
|
|
69
|
+
"packaging",
|
|
70
|
+
],
|
|
71
|
+
extras_require={"image_resolve_caching": ["requests_cache>=1.2"]},
|
|
72
|
+
)
|
|
@@ -18,11 +18,11 @@ class TestConfig(object):
|
|
|
18
18
|
config._config = None
|
|
19
19
|
|
|
20
20
|
def test_get_config_object(self, monkeypatch):
|
|
21
|
-
|
|
21
|
+
"""Simple test to grab a config object, will return default config
|
|
22
22
|
values.
|
|
23
|
-
|
|
23
|
+
"""
|
|
24
24
|
|
|
25
|
-
monkeypatch.setattr(config,
|
|
25
|
+
monkeypatch.setattr(config, "CONF_DIRS", [])
|
|
26
26
|
ref_conf = config.ConfigData()
|
|
27
27
|
|
|
28
28
|
test_conf = config.get_config()
|
|
@@ -30,8 +30,8 @@ class TestConfig(object):
|
|
|
30
30
|
assert ref_conf.META_DATA == test_conf.META_DATA
|
|
31
31
|
|
|
32
32
|
def test_missing_config_file(self, monkeypatch):
|
|
33
|
-
|
|
34
|
-
monkeypatch.setattr(config,
|
|
33
|
+
"""Make sure that None is returned if no config files are found"""
|
|
34
|
+
monkeypatch.setattr(config, "CONF_DIRS", [])
|
|
35
35
|
|
|
36
36
|
test_config_filename = config._find_config_file()
|
|
37
37
|
assert test_config_filename is None
|
|
@@ -40,11 +40,11 @@ class TestConfig(object):
|
|
|
40
40
|
# leaving them here as we have no differentiation between unit and
|
|
41
41
|
# functional tests at the moment
|
|
42
42
|
def test_load_config_object(self, tmpdir):
|
|
43
|
-
|
|
43
|
+
"""load config object from file, make sure it's loaded properly"""
|
|
44
44
|
|
|
45
|
-
refdir = tmpdir.mkdir(
|
|
46
|
-
ref_conf_filename =
|
|
47
|
-
with open(ref_conf_filename,
|
|
45
|
+
refdir = tmpdir.mkdir("conf")
|
|
46
|
+
ref_conf_filename = "{}/{}".format(refdir, config.CONF_FILE)
|
|
47
|
+
with open(ref_conf_filename, "w+") as ref_conffile:
|
|
48
48
|
ref_conffile.write(REF_CONF_CONTENTS)
|
|
49
49
|
|
|
50
50
|
test_config = config._load_config(ref_conf_filename)
|
|
@@ -52,13 +52,13 @@ class TestConfig(object):
|
|
|
52
52
|
assert test_config.DATA_DIR == REF_DATA_DIR
|
|
53
53
|
|
|
54
54
|
def test_merge_config_file(self, tmpdir):
|
|
55
|
-
|
|
55
|
+
"""merge loaded config object with defaults, make sure that the defaults
|
|
56
56
|
are overridden.
|
|
57
|
-
|
|
57
|
+
"""
|
|
58
58
|
|
|
59
|
-
refdir = tmpdir.mkdir(
|
|
60
|
-
ref_conf_filename =
|
|
61
|
-
with open(ref_conf_filename,
|
|
59
|
+
refdir = tmpdir.mkdir("conf")
|
|
60
|
+
ref_conf_filename = "{}/{}".format(refdir, config.CONF_FILE)
|
|
61
|
+
with open(ref_conf_filename, "w+") as ref_conffile:
|
|
62
62
|
ref_conffile.write(REF_CONF_CONTENTS)
|
|
63
63
|
|
|
64
64
|
test_config_obj = config._load_config(ref_conf_filename)
|
|
@@ -70,16 +70,16 @@ class TestConfig(object):
|
|
|
70
70
|
assert test_config.DATA_DIR == REF_DATA_DIR
|
|
71
71
|
|
|
72
72
|
def test_load_merge_config_file(self, tmpdir, monkeypatch):
|
|
73
|
-
|
|
73
|
+
"""get config, making sure that an addional config file is found. make
|
|
74
74
|
sure that default values are properly overridden.
|
|
75
|
-
|
|
75
|
+
"""
|
|
76
76
|
|
|
77
|
-
refdir = tmpdir.mkdir(
|
|
78
|
-
ref_conf_filename =
|
|
79
|
-
with open(ref_conf_filename,
|
|
77
|
+
refdir = tmpdir.mkdir("conf")
|
|
78
|
+
ref_conf_filename = "{}/{}".format(refdir, config.CONF_FILE)
|
|
79
|
+
with open(ref_conf_filename, "w+") as ref_conffile:
|
|
80
80
|
ref_conffile.write(REF_CONF_CONTENTS)
|
|
81
81
|
|
|
82
|
-
monkeypatch.setattr(config,
|
|
82
|
+
monkeypatch.setattr(config, "CONF_DIRS", [str(refdir)])
|
|
83
83
|
test_config = config.get_config()
|
|
84
84
|
|
|
85
85
|
assert test_config.DATA_DIR == REF_DATA_DIR
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright 2015, Red Hat, Inc.
|
|
3
|
+
# License: GPL-2.0+ <http://spdx.org/licenses/GPL-2.0+>
|
|
4
|
+
# See the LICENSE file for more details on Licensing
|
|
5
|
+
|
|
6
|
+
""" This module is for testing the behaviour of the Image class."""
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from testcloud import image
|
|
11
|
+
from testcloud import exceptions
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TestImage:
|
|
15
|
+
|
|
16
|
+
def test_image_download_path(self):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
def test_image_name(self):
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
def test_download(self):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# def test_save_pristine(self):
|
|
27
|
+
# pass
|
|
28
|
+
#
|
|
29
|
+
# def test_load_pristine(self):
|
|
30
|
+
# pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TestImageUriProcess(object):
|
|
34
|
+
"""The basic idea of what these tests do is to make sure that uris are
|
|
35
|
+
parsed properly. http, https and file are OK and supported. ftp is an
|
|
36
|
+
an example of a type which is not currently supported and should raise an
|
|
37
|
+
exception."""
|
|
38
|
+
|
|
39
|
+
def setup_method(self, method):
|
|
40
|
+
self.image_name = "image.img"
|
|
41
|
+
self.len_data = 3
|
|
42
|
+
|
|
43
|
+
def test_http_ur1(self):
|
|
44
|
+
ref_type = "http"
|
|
45
|
+
ref_path = "localhost/images/{}".format(self.image_name)
|
|
46
|
+
ref_uri = "{}://{}".format(ref_type, ref_path)
|
|
47
|
+
|
|
48
|
+
test_image = image.Image(ref_uri)
|
|
49
|
+
test_data = test_image._process_uri(ref_uri)
|
|
50
|
+
|
|
51
|
+
assert len(test_data) == self.len_data
|
|
52
|
+
assert test_data["type"] == ref_type
|
|
53
|
+
assert test_data["name"] == self.image_name
|
|
54
|
+
assert test_data["path"] == ref_path
|
|
55
|
+
|
|
56
|
+
# def test_http_ur1_params(self):
|
|
57
|
+
# ref_type = 'http'
|
|
58
|
+
# ref_path = 'localhost/images/{}'.format(self.image_name)
|
|
59
|
+
# ref_uri = '{}://{}?url_param=value'.format(ref_type, ref_path)
|
|
60
|
+
#
|
|
61
|
+
# test_image = image.Image(ref_uri)
|
|
62
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
63
|
+
#
|
|
64
|
+
# assert test_data['type'] == ref_type
|
|
65
|
+
# assert test_data['name'] == self.image_name
|
|
66
|
+
# assert test_data['path'] == ref_path
|
|
67
|
+
#
|
|
68
|
+
# def test_http_ur1_anchor(self):
|
|
69
|
+
# ref_type = 'http'
|
|
70
|
+
# ref_path = 'localhost/images/{}'.format(self.image_name)
|
|
71
|
+
# ref_uri = '{}://{}#anchor'.format(ref_type, ref_path)
|
|
72
|
+
#
|
|
73
|
+
# test_image = image.Image(ref_uri)
|
|
74
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
75
|
+
#
|
|
76
|
+
# assert test_data['type'] == ref_type
|
|
77
|
+
# assert test_data['name'] == self.image_name
|
|
78
|
+
# assert test_data['path'] == ref_path
|
|
79
|
+
#
|
|
80
|
+
#
|
|
81
|
+
# def test_http_ur1_url_quoted(self):
|
|
82
|
+
# ref_type = 'http'
|
|
83
|
+
# ref_path = 'localhost/images/image%20name.img'
|
|
84
|
+
# ref_uri = '{}://{}'.format(ref_type, ref_path)
|
|
85
|
+
#
|
|
86
|
+
# test_image = image.Image(ref_uri)
|
|
87
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
88
|
+
#
|
|
89
|
+
# assert test_data['type'] == ref_type
|
|
90
|
+
# assert test_data['name'] == "image name.img"
|
|
91
|
+
# assert test_data['path'] == ref_path
|
|
92
|
+
|
|
93
|
+
def test_https_uri(self):
|
|
94
|
+
ref_type = "https"
|
|
95
|
+
ref_path = "localhost/images/{}".format(self.image_name)
|
|
96
|
+
ref_uri = "{}://{}".format(ref_type, ref_path)
|
|
97
|
+
|
|
98
|
+
test_image = image.Image(ref_uri)
|
|
99
|
+
test_data = test_image._process_uri(ref_uri)
|
|
100
|
+
|
|
101
|
+
assert len(test_data) == self.len_data
|
|
102
|
+
assert test_data["type"] == ref_type
|
|
103
|
+
assert test_data["name"] == self.image_name
|
|
104
|
+
assert test_data["path"] == ref_path
|
|
105
|
+
|
|
106
|
+
def test_file_uri(self):
|
|
107
|
+
ref_type = "file"
|
|
108
|
+
ref_path = "/srv/images/{}".format(self.image_name)
|
|
109
|
+
ref_uri = "{}://{}".format(ref_type, ref_path)
|
|
110
|
+
|
|
111
|
+
test_image = image.Image(ref_uri)
|
|
112
|
+
test_data = test_image._process_uri(ref_uri)
|
|
113
|
+
|
|
114
|
+
assert len(test_data) == self.len_data
|
|
115
|
+
assert test_data["type"] == ref_type
|
|
116
|
+
assert test_data["name"] == self.image_name
|
|
117
|
+
assert test_data["path"] == ref_path
|
|
118
|
+
|
|
119
|
+
# def test_box(self):
|
|
120
|
+
# ref_uri = "http://local.host/file.box"
|
|
121
|
+
# test_image = image.Image(ref_uri)
|
|
122
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
123
|
+
# assert test_data['name'] == "file.qcow2"
|
|
124
|
+
#
|
|
125
|
+
#
|
|
126
|
+
# def test_xz(self):
|
|
127
|
+
# ref_uri = "http://local.host/file.iso.xz"
|
|
128
|
+
# test_image = image.Image(ref_uri)
|
|
129
|
+
# test_data = test_image._process_uri(ref_uri)
|
|
130
|
+
# assert test_data['name'] == "file.iso"
|
|
131
|
+
|
|
132
|
+
def test_invalid_uri_type(self):
|
|
133
|
+
ref_type = "ftp"
|
|
134
|
+
ref_path = "/localhost/images/{}".format(self.image_name)
|
|
135
|
+
ref_uri = "{}://{}".format(ref_type, ref_path)
|
|
136
|
+
|
|
137
|
+
with pytest.raises(exceptions.TestcloudImageError):
|
|
138
|
+
image.Image(ref_uri)
|
|
139
|
+
|
|
140
|
+
def test_invalid_uri(self):
|
|
141
|
+
ref_uri = "leprechaunhandywork"
|
|
142
|
+
|
|
143
|
+
with pytest.raises(exceptions.TestcloudImageError):
|
|
144
|
+
image.Image(ref_uri)
|
|
@@ -11,6 +11,7 @@ from unittest import mock
|
|
|
11
11
|
|
|
12
12
|
from testcloud import instance, image, config, domain_configuration
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
class dotdict(dict):
|
|
15
16
|
# https://stackoverflow.com/a/23689767
|
|
16
17
|
"""dot.notation access to dictionary attributes"""
|
|
@@ -18,6 +19,7 @@ class dotdict(dict):
|
|
|
18
19
|
__setattr__ = dict.__setitem__
|
|
19
20
|
__delattr__ = dict.__delitem__
|
|
20
21
|
|
|
22
|
+
|
|
21
23
|
class TestInstance:
|
|
22
24
|
|
|
23
25
|
def test_expand_qcow(self):
|
|
@@ -45,30 +47,29 @@ class TestFindInstance(object):
|
|
|
45
47
|
self.conf = config.ConfigData()
|
|
46
48
|
|
|
47
49
|
def test_non_existant_instance(self, monkeypatch):
|
|
48
|
-
ref_name =
|
|
49
|
-
ref_image = image.Image(
|
|
50
|
+
ref_name = "test-123"
|
|
51
|
+
ref_image = image.Image("file:///someimage.qcow2")
|
|
50
52
|
|
|
51
53
|
stub_listdir = mock.Mock()
|
|
52
54
|
stub_listdir.return_value = []
|
|
53
|
-
monkeypatch.setattr(os,
|
|
55
|
+
monkeypatch.setattr(os, "listdir", stub_listdir)
|
|
54
56
|
|
|
55
57
|
test_instance = instance.find_instance(ref_name, ref_image)
|
|
56
58
|
|
|
57
59
|
assert test_instance is None
|
|
58
60
|
|
|
59
61
|
def test_find_exist_instance(self, monkeypatch):
|
|
60
|
-
ref_name =
|
|
61
|
-
ref_image = image.Image(
|
|
62
|
-
ref_path = os.path.join(self.conf.DATA_DIR,
|
|
63
|
-
'instances/{}'.format(ref_name))
|
|
62
|
+
ref_name = "test-123"
|
|
63
|
+
ref_image = image.Image("file:///someimage.qcow2")
|
|
64
|
+
ref_path = os.path.join(self.conf.DATA_DIR, "instances/{}".format(ref_name))
|
|
64
65
|
|
|
65
66
|
stub_listdir = mock.Mock()
|
|
66
67
|
stub_listdir.return_value = [ref_name]
|
|
67
|
-
monkeypatch.setattr(os,
|
|
68
|
+
monkeypatch.setattr(os, "listdir", stub_listdir)
|
|
68
69
|
|
|
69
70
|
stub_data_dir = mock.Mock()
|
|
70
71
|
stub_data_dir.return_value = dotdict({"DATA_DIR": self.conf.DATA_DIR})
|
|
71
|
-
monkeypatch.setattr(config,
|
|
72
|
+
monkeypatch.setattr(config, "get_config", stub_data_dir)
|
|
72
73
|
|
|
73
74
|
test_instance = instance.find_instance(ref_name, ref_image)
|
|
74
75
|
|