Compare commits

...

60 Commits

Author SHA1 Message Date
7c641961d3 better validation with parent + deepconfig 2019-08-28 15:55:10 +02:00
4321bde399 prefix metaconfig_prefix with current name 2019-08-26 17:04:46 +02:00
c15dac8093 unrestraint in subconfig 2019-08-24 08:14:54 +02:00
82a91db16e prefix metaconfig_prefix with current name 2019-08-21 16:24:50 +02:00
5ff47ac5c9 rc 11 2019-08-19 14:13:56 +02:00
a9ca9fdb6a add multi parents tests 2019-08-07 08:40:23 +02:00
b6ec77aa23 better way to manage follower in MetaConfig 2019-08-07 08:38:32 +02:00
2d7d237e19 Config could have multiple parents 2019-08-05 22:31:56 +02:00
113b7a3410 todict works with Metaconfig 2019-08-03 21:03:23 +02:00
1691e38db5 separate Cache from values and settings 2019-08-01 18:22:18 +02:00
c5ce9be699 doc + description + can updates with dict 2019-07-29 22:13:04 +02:00
613ae47573 update tests ans version number 2019-07-26 10:13:45 +02:00
fd18af62ca update Changelog and translation 2019-07-26 09:45:19 +02:00
34d71901d0 to_dict improvment and add display_name parameter to change impl_get_display_name function 2019-07-26 08:55:20 +02:00
35ef218c9c better message error 2019-07-26 08:52:01 +02:00
a33c7ed41e follower option with consistency 2019-07-16 08:03:33 +02:00
73d45f54cf follower option with consistency 2019-07-14 10:35:46 +02:00
69384a5e69 update translations 2019-07-06 11:39:06 +02:00
e73f3d1e47 we have to access to option without restriction 2019-07-06 08:36:13 +02:00
d3eef77c03 works with test/auto tests 2019-07-06 07:18:32 +02:00
fb1286e50e better hidden/display support 2019-07-04 20:43:47 +02:00
83f05197fb update todict support and tests 2019-06-21 23:04:04 +02:00
55da00f131 3.0 rc 8 2019-06-21 09:14:09 +02:00
516a5a7219 copy default properties when copy config or create a config in a metaconfig 2019-06-20 15:24:21 +02:00
620e8bbf2e optimize 2019-06-12 08:45:56 +02:00
4df36a5548 3.0 rc7 2019-06-05 15:03:17 +02:00
aa11e3b79c can retrieve metaconfig/mixconfig/config in a metaconfig/mixconfig 2019-06-05 14:37:58 +02:00
07e6ea5eb2 can add new config with mixconfig type 2019-06-05 12:33:00 +02:00
e7cbd7849a add test for config's deepcopy 2019-05-28 07:19:26 +02:00
b9e9e98270 reindent 2019-05-27 16:21:43 +02:00
a774378732 local must not be None 2019-05-27 16:18:57 +02:00
5498a12b2b copy/deepcopy groupconfig 2019-05-27 16:11:41 +02:00
552cd3740d todict: better support for callback 2019-05-09 20:32:43 +02:00
5ea35bf84e simplify tiramisu dict format 2019-04-22 10:51:44 +02:00
6d0d233d9b demoting_error_warning is not more mandatory in option.dict()
RequirementError returns proptype
better submulti support for valid_mandatory
2019-04-17 19:13:40 +02:00
829247e79f better symlink support for option.dict() 2019-04-17 19:13:17 +02:00
63094f7e54 better error messages with list 2019-04-13 22:04:49 +02:00
1aec891408 import tiramisu-json in tiramisu repository 2019-04-08 20:34:05 +02:00
48b3b7e8a4 flit 2019-04-07 20:51:53 +02:00
4dbb82ed3f Python Packaging Autority recommandations 2019-04-05 22:39:24 +02:00
97b75660c5 do not change Config contexts properties when reload in MetaConfig (fixes #7) 2019-04-05 22:11:54 +02:00
06f501ad05 test for property in persistent storage 2019-04-05 21:17:36 +02:00
2b45955886 add/remove config in mixconfig or metaconfig (fixes #6) 2019-04-05 21:00:25 +02:00
0e02ae3182 changelog 2019-03-24 20:27:26 +01:00
ac42fd509c remove documentation (now in a separate project) 2019-03-24 20:26:51 +01:00
4709ac5f01 corrections in debug logger 2019-03-23 08:26:39 +01:00
cab8dae15a requirement can have callback 2019-03-13 08:49:18 +01:00
05abe76932 add generic calc_value function 2019-03-09 13:28:15 +01:00
33c1666cc9 add cidr notation to domainnameoption if allow_ip is True (fixes #5) 2019-03-08 07:11:56 +01:00
2a6df8c8d8 safer option.type() (ref #4) 2019-03-06 21:50:28 +01:00
cc44cabf56 update translation 2019-03-05 20:46:04 +01:00
35ee424810 add test_leadership_requires_transitive 2019-03-03 08:02:57 +01:00
5c0ac75c52 multiple option call (fixes #1) 2019-03-02 21:31:21 +01:00
7873910322 doesn't check follower requirement with an other follower or a leader if idx is None (fixes #3) 2019-03-02 19:43:58 +01:00
d25edd7dd7 update test_auto (fixes #2) 2019-03-02 19:32:55 +01:00
e786b4068d update french translation 2019-02-25 20:32:14 +01:00
da015d3af0 coverage 2019-02-25 20:30:20 +01:00
a248e114de simplify netmaskoption 2019-02-25 19:29:00 +01:00
74d367c731 simplify netmaskoption 2019-02-25 19:18:52 +01:00
0e20318a9b simplify netmaskoption 2019-02-25 19:10:20 +01:00
299 changed files with 16420 additions and 9575 deletions

1
.gitignore vendored
View File

@ -3,5 +3,4 @@
*.pyc
*.mo
*.swp
version.in
build/

View File

@ -1,4 +1,59 @@
Sat Sep 8 22:54:12 2018 +0200 Emmanuel Garette <egarette@cadoles.com>
Wed Aug 28 15:50:30 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc14
* correction in metaconfig_prefix
* correction in validation with parent
Mon Aug 21 14:24:42 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc12
* prefix metaconfig_prefix with current name
Mon Aug 19 08:02:27 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc11
* Config could have multiple parents
* todict works with Metaconfig
* separate Cache from values and settings
Fri Jul 26 09:43:03 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc9 and rc10
* better todict support (especially for leadership
* can add display_name method to Config init to change the name a
option in errors
Mon Jun 5 14:49:27 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc7
* retrieve metaconfig/mixconfig/config by name in a metaconfig/mixconfig
* add new config with mixconfig type
Mon Apr 8 08:40:10 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc6
* import tiramisu-json in tiramisu repository
Fri Apr 5 20:57:05 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc4 and rc5
* change filename/directory name with Python Packaging Autority
recommendations
* do not change Config contexts properties when reload in MetaConfig
(fixes #7)
* add/remove config in mixconfig or metaconfig (fixes #6)
Sun Mar 24 20:24:34 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc3
* corrections in debug logger
* requirement can have callback
* version 3.0 rc2
* add cidr notation to domainnameoption if allow_ip is True (fixes #5)
* safer option.type() (ref #4)
Tue Mar 5 08:22:12 2018 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc2
* simplifying netmaskoption
* multiple option call (fixes #1)
* doesn't check follower requirement with an other follower or a leader if idx is None (fixes #3)
Mon Feb 25 10:12:35 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc1
Sat Sep 8 22:54:12 2019 +0200 Emmanuel Garette <egarette@cadoles.com>
* propose a new API to access to Tiramisu Option
This new API is totally incompatible with older's one

8
MANIFEST.in Normal file
View File

@ -0,0 +1,8 @@
# Include the README
include *.rst
# Include the license file
include LICENSE.txt
# Include the data files
recursive-include tiramisu *.py *.mo

View File

@ -10,7 +10,7 @@ INSTALL_DATA := install -m 644
INSTALL_PROGRAM := install -m 755
INSTALL_DIR := install -m 755 -d
TRADUC_DIR = translations
TRADUC_DIR = tiramisu/locale
TRADUC_DEST = $(DESTDIR)/usr/share/locale
PYTHON_OPTS =
@ -26,7 +26,7 @@ define gettext
else \
P="pygettext.py" ; \
fi ; \
$$P -p translations/ -o $(PACKAGE).pot `find $(PACKAGE)/ -name "*.py"`
$$P -p $(TRADUC_DIR)/ -o $(PACKAGE).pot `find $(PACKAGE)/ -name "*.py"`
endef
# Build translation files
@ -69,12 +69,12 @@ build-pot:
build-lang:
$(call build_translation, $(TRADUC_DIR))
install-lang:
$(INSTALL_DIR) $(TRADUC_DEST)
$(call install_translation, $(TRADUC_DIR))
# install-lang:
# $(INSTALL_DIR) $(TRADUC_DEST)
# $(call install_translation, $(TRADUC_DIR))
install: install-lang
python setup.py install --no-compile $(PYTHON_OPTS)
install: # install-lang
python3 setup.py install --no-compile $(PYTHON_OPTS)
dist:
git archive --format=tar --prefix $(PACKAGE)-$(VERSION)/ HEAD | gzip -9 > $(PACKAGE)-$(VERSION).tar.gz

View File

View File

@ -1 +0,0 @@
master

View File

@ -1,153 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/tiramisu.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/tiramisu.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/tiramisu"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/tiramisu"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

View File

@ -1,6 +0,0 @@
{{ fullname }}
{{ underline }}
.. automodule:: {{ fullname }}
:members:
:noindex:

View File

@ -1,15 +0,0 @@
Auto generated library's API
================================
.. autosummary::
:toctree: api
:template: module.rst
tiramisu.option
tiramisu.setting
tiramisu.config
tiramisu.value
tiramisu.autolib
tiramisu.error
tiramisu.storage

View File

@ -1,6 +0,0 @@
tiramisu.autolib
================
.. automodule:: tiramisu.autolib
:members:
:noindex:

View File

@ -1,6 +0,0 @@
tiramisu.config
===============
.. automodule:: tiramisu.config
:members:
:noindex:

View File

@ -1,6 +0,0 @@
tiramisu.error
==============
.. automodule:: tiramisu.error
:members:
:noindex:

View File

@ -1,6 +0,0 @@
tiramisu.option
===============
.. automodule:: tiramisu.option
:members:
:noindex:

View File

@ -1,5 +0,0 @@
tiramisu.setting
================
.. automodule:: tiramisu.setting
:members:

View File

@ -1,6 +0,0 @@
tiramisu.storage
================
.. automodule:: tiramisu.storage
:members:
:noindex:

View File

@ -1,5 +0,0 @@
tiramisu.value
==============
.. automodule:: tiramisu.value
:members:

View File

@ -1,295 +0,0 @@
# -*- coding: utf-8 -*-
#
# tiramisu documentation build configuration file, created by
# sphinx-quickstart on Tue Nov 20 14:29:31 2012.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# 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.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode', 'sphinx.ext.autosummary', 'sphinx.ext.extlinks']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.txt'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'tiramisu'
copyright = u'2013, tiramisu team'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1'
# The full version, including alpha/beta/rc tags.
release = '1.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# 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
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'traditional'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'tiramisudoc'
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'tiramisu.tex', u'tiramisu Documentation',
u'gwen', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'tiramisu', u'tiramisu Documentation',
[u'gwen'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'tiramisu', u'tiramisu Documentation',
u'gwen', 'tiramisu', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# -- Options for Epub output ---------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = u'tiramisu'
epub_author = u'gwen'
epub_publisher = u'gwen'
epub_copyright = u'2012, gwen'
# The language of the text. It defaults to the language option
# or en if the language is not set.
#epub_language = ''
# The scheme of the identifier. Typical schemes are ISBN or URL.
#epub_scheme = ''
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#epub_identifier = ''
# A unique identification for the text.
#epub_uid = ''
# A tuple containing the cover image and cover page html template filenames.
#epub_cover = ()
# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_pre_files = []
# HTML files shat should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#epub_post_files = []
# A list of files that should not be packed into the epub file.
#epub_exclude_files = []
# The depth of the table of contents in toc.ncx.
#epub_tocdepth = 3
# Allow duplicate toc entries.
#epub_tocdup = True
todo_include_todos = True
extlinks = {'api': ('./api/tiramisu.%s', ""),
'test': ('./api/test.%s', "")}
autosummary_generate = True

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,257 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="400"
height="200"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="test.svg"
inkscape:export-filename="/home/gnunux/git/tiramisu/doc/storage.png"
inkscape:export-xdpi="135"
inkscape:export-ydpi="135">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3827" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="73.881208"
inkscape:cy="154.11692"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="841"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-852.36218)">
<g
id="g4206"
transform="translate(32.34835,646.56497)">
<text
sodipodi:linespacing="686.00001%"
id="text2985"
y="368.36218"
x="98"
style="font-size:10px;font-style:normal;font-weight:normal;line-height:686.00001335%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="368.36218"
x="98"
id="tspan2987"
sodipodi:role="line">Config</tspan></text>
<rect
y="351.36218"
x="81"
height="30"
width="63"
id="rect3757"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
</g>
<g
id="g4211"
transform="translate(-21.922096,643.64303)">
<rect
y="312.36218"
x="189.5"
height="30"
width="63"
id="rect3757-2"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text3777"
y="325.76599"
x="220.51762"
style="font-size:10px;font-style:normal;font-weight:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="325.76599"
x="220.51762"
id="tspan3779"
sodipodi:role="line">Option</tspan><tspan
y="335.76599"
x="220.51762"
sodipodi:role="line"
id="tspan3022">Description</tspan></text>
</g>
<g
id="g4201"
transform="translate(11,622)">
<rect
y="293.42468"
x="81"
height="30"
width="63"
id="rect3757-5"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text4190"
y="309.42468"
x="110.27588"
style="font-size:10px;font-style:normal;font-weight:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan4194"
y="309.42468"
x="110.27588"
sodipodi:role="line">Option</tspan></text>
</g>
<g
id="g4201-9"
transform="translate(85.749784,621.95117)">
<rect
y="293.42468"
x="81"
height="30"
width="63"
id="rect3757-5-1"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text4190-0"
y="309.42468"
x="110.27588"
style="font-size:10px;font-style:normal;font-weight:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan4194-2"
y="309.42468"
x="110.27588"
sodipodi:role="line">Option</tspan></text>
</g>
<g
id="g4211-4"
transform="translate(52.525433,602.85429)">
<rect
y="312.36218"
x="189.5"
height="30"
width="63"
id="rect3757-2-3"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text3777-0"
y="325.76599"
x="220.51762"
style="font-size:10px;font-style:normal;font-weight:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="325.76599"
x="220.51762"
id="tspan3779-1"
sodipodi:role="line">Option</tspan><tspan
y="335.76599"
x="220.51762"
sodipodi:role="line"
id="tspan3022-7">Description</tspan></text>
</g>
<g
id="g4201-1"
transform="translate(123.6527,582.89051)">
<rect
y="293.42468"
x="81"
height="30"
width="63"
id="rect3757-5-7"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text4190-2"
y="309.42468"
x="110.27588"
style="font-size:10px;font-style:normal;font-weight:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan4194-8"
y="309.42468"
x="110.27588"
sodipodi:role="line">Option</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 151.43627,945.42468 19.70537,10.58053"
id="path3110"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4201"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4211"
inkscape:connection-end-point="d4" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 198.77217,956.00521 -0.21665,-10.62936"
id="path3112"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4211"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4201-9"
inkscape:connection-end-point="d4" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 226.45587,956.00521 19.69159,-10.78874"
id="path3114"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4211"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4211-4"
inkscape:connection-end-point="d4" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 259.11483,915.21647 -8.55152,-8.90128"
id="path3116"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4211-4"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4201-1"
inkscape:connection-end-point="d4" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 164.25211,997.92715 15.42203,-11.92194"
id="path3118"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4206"
inkscape:connection-start-point="d4"
inkscape:connection-end="#g4211"
inkscape:connection-end-point="d4" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -1,570 +0,0 @@
.. default-role:: literal
===============================
Options handling basics
===============================
Tiramisu is made of almost three main objects :
- :class:`tiramisu.option.Option` stands for the option types
- :class:`tiramisu.option.OptionDescription` is the shema, the option's structure
- :class:`tiramisu.config.Config` which is the whole configuration entry point
Accessing the `Option`'s
-------------------------
The :class:`~tiramisu.config.Config` object attribute access notation stands for
the value of the configuration's :class:`~tiramisu.option.Option`.
:class:`~tiramisu.config.Config`'s object attribute is the name of the option,
and the value is the value accessed by the `__getattr__` attribute access
mechanism.
If the attribute of the `Config` called by `__getattr__` has not been set before
(by the classic `__setattr__` mechanism), the default value of the `Option`
object is returned, and if no `Option` has been declared in the
`OptionDescription` (that is the schema of the configuration), an
`AttributeError` is raised.
::
>>> from tiramisu.config import Config
>>> from tiramisu.option import BoolOption, OptionDescription
>>>
>>> gcdummy = BoolOption('dummy', 'dummy', default=False)
>>> gcdummy.impl_getdefault()
False
>>> cfg.dummy
False
>>> descr = OptionDescription('tiramisu', '', [gcdummy])
>>> cfg = Config(descr)
>>> cfg.dummy = True
>>> cfg.dummy
True
>>> cfg.idontexist
AttributeError: 'OptionDescription' object has no attribute 'idontexist'
The `Option` objects (in this case the :class:`~tiramisu.option.BoolOption`),
are organized into a tree into nested
:class:`~tiramisu.option.OptionDescription` objects.
.. image:: config.png
Every option has a name, as does every option group. The parts
of the full name of the option are separated by dots: e.g.
``cfg.optgroup.optname``.
Let's make the protocol of accessing a `Config`'s attribute explicit
(because explicit is better than implicit):
1. If the option has not been declared, an `AttributeError` is raised,
2. If an option is declared, but neither a value nor a default value has
been set, the returned value is `None`,
3. If an option is declared and a default value has been set, but no value
has been set, the returned value is the default value of the option,
4. If an option is declared, and a value has been set, the returned value is
the value of the option.
But there are special exceptions. We will see later on that an option can be a
:term:`mandatory option`. A mandatory option is an option that must have a value
defined.
Setting the value of an option
------------------------------
An important part of the setting's configuration consists of setting the
value's option. There are different ways of setting values,
the first one is of course the `__setattr__` method
::
cfg.name = value
And if you wanna come back to a default value, use the builtin `del()` function::
del(cfg.name)
.. module:: tiramisu.config
.. _`tree`:
The handling of options
~~~~~~~~~~~~~~~~~~~~~~~~~~
The handling of options is split into two parts: the description of
which options are available, what their possible values and defaults are
and how they are organized into a tree. A specific choice of options is
bundled into a configuration object which has a reference to its option
description (and therefore makes sure that the configuration values
adhere to the option description).
Common manipulations
------------------------
Let's perform some common manipulation on some options
>>> from tiramisu.config import Config
>>> from tiramisu.option import UnicodeOption, OptionDescription
>>> #
>>> var1 = UnicodeOption('var1', 'first variable')
>>> var2 = UnicodeOption('var2', '', u'value')
>>> #
>>> od1 = OptionDescription('od1', 'first OD', [var1, var2])
>>> rootod = OptionDescription('rootod', '', [od1])
let's set somme access rules on the main namespace
>>> c = Config(rootod)
>>> c.read_write()
let's travel the namespaces
>>> print c
[od1]
>>> print c.od1
var1 = None
var2 = value
>>> print c.od1.var1
None
>>> print c.od1.var2
value
let's modify a value (be careful to the value's type...)
>>> c.od1.var1 = 'value'
Traceback (most recent call last):
ValueError: invalid value value for option var1
>>> c.od1.var1 = u'value'
>>> print c.od1.var1
value
>>> c.od1.var2 = u'value2'
>>> print c.od1.var2
value2
let's come back to the default value
>>> del(c.od1.var2)
>>> print c.od1.var2
value
The value is saved in a :class:`~tiramisu.value.Value` object. It is on this
object that we have to trigger the `reset`, which take the option itself
(`var2`) as a parameter.
On the other side, in the `read_only` mode, it is not possible to modify the value
>>> c.read_only()
>>> c.od1.var2 = u'value2'
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: cannot change the value for option var2 this option is frozen
let's retrieve the option `var1` description
>>> var1.impl_get_information('doc')
'first variable'
And if the option has been lost, it is possible to retrieve it again:
>>> c.unwrap_from_path('od1.var1').impl_get_information('doc')
'first variable'
Searching for an option
~~~~~~~~~~~~~~~~~~~~~~~~~~
In an application, knowing the path of an option is not always feasible.
That's why a tree of options can easily be searched. First, let's build such a tree::
>>> var1 = UnicodeOption('var1', '')
>>> var2 = UnicodeOption('var2', '')
>>> var3 = UnicodeOption('var3', '')
>>> od1 = OptionDescription('od1', '', [var1, var2, var3])
>>> var4 = UnicodeOption('var4', '')
>>> var5 = UnicodeOption('var5', '')
>>> var6 = UnicodeOption('var6', '')
>>> var7 = UnicodeOption('var1', '', u'value')
>>> od2 = OptionDescription('od2', '', [var4, var5, var6, var7])
>>> rootod = OptionDescription('rootod', '', [od1, od2])
>>> c = Config(rootod)
>>> c.read_write()
Second, let's find an option by it's name::
>>> print c.find(byname='var1')
[<tiramisu.option.UnicodeOption object at 0x7ff1bf7d6ef0>,
<tiramisu.option.UnicodeOption object at 0x7ff1b90c7290>]
If the option name is unique, the search can be stopped once one matched option
has been found:
>>> print c.find_first(byname='var1')
<tiramisu.option.UnicodeOption object at 0x7ff1bf7d6ef0>
Instead of the option's object, the value or path can be retrieved:
>>> print c.find(byname='var1', type_='value')
[None, u'value']
>>> print c.find(byname='var1', type_='path')
['od1.var1', 'od2.var1']
Finaly, a search can be performed on the values, the type or even a combination
of all these criteria:
>>> print c.find(byvalue=u'value', type_='path')
['od2.var1']
>>> print c.find(bytype=UnicodeOption, type_='path')
['od1.var1', 'od1.var2', 'od1.var3', 'od2.var4', 'od2.var5', 'od2.var6', 'od2.var1']
>>> print c.find(byvalue=u'value', byname='var1', bytype=UnicodeOption, type_='path')
['od2.var1']
The search can be performed in a subtree:
>>> print c.od1.find(byname='var1', type_='path')
['od1.var1']
In a root tree or in a subtree, all option can be retrieved in a dict container:
>>> print c.make_dict()
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None, 'od2.var1': u'value',
'od1.var1': None, 'od1.var3': None, 'od1.var2': None}
If the organisation in a tree is not important,
:meth:`~config.SubConfig.make_dict()` results can be flattened
>>> print c.make_dict(flatten=True)
{'var5': None, 'var4': None, 'var6': None, 'var1': u'value', 'var3': None,
'var2': None}
.. note:: be carefull with this `flatten` parameter, here we have just lost
two options named `var1`
One can export only interesting parts of a tree of options into a dict, for
example the options that are in the same group that a given `var1` option::
>>> print c.make_dict(withoption='var1')
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None, 'od2.var1': u'value',
'od1.var1': None, 'od1.var3': None, 'od1.var2': None}
>>> print c.make_dict(withoption='var1', withvalue=u'value')
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None, 'od2.var1': u'value'}
and of course, :meth:`~config.SubConfig.make_dict()` can be called in a subtree:
>>> print c.od1.make_dict(withoption='var1')
{'var1': None, 'var3': None, 'var2': None}
The owners
~~~~~~~~~~~
.. glossary::
owner
When a value is set on an option, an owner is set too, that's why one can know
at any time if a value is a default value or not. Let's create a tree::
>>> var1 = UnicodeOption('var1', '', u'oui')
>>> od1 = OptionDescription('od1', '', [var1])
>>> rootod = OptionDescription('rootod', '', [od1])
>>> c = Config(rootod)
>>> c.read_write()
Then let's retrieve the owner associated to an option::
>>> print c.getowner(var1)
default
>>> c.od1.var1 = u'no'
>>> print c.getowner(var1)
user
>>> del(c.var1)
>>> print c.getowner(var1)
default
You can create your own owner, for example to distinguish modification made by
one user to an other one's.
>>> from tiramisu.setting import owners
>>> owners.addowner('toto')
>>> c.cfgimpl_get_settings().setowner(owners.toto)
>>> print c.getowner(var1)
default
>>> c.od1.var1 = u'no'
>>> print c.getowner(var1)
toto
The properties
~~~~~~~~~~~~~~
A property is an information on an option's state.
Let's create options with properties::
>>> var1 = UnicodeOption('var1', '', u'value', properties=('hidden',))
>>> var2 = UnicodeOption('var2', '', properties=('mandatory',))
>>> var3 = UnicodeOption('var3', '', u'value', properties=('frozen', 'unknown'))
>>> var4 = UnicodeOption('var4', '', u'value')
>>> od1 = OptionDescription('od1', '', [var1, var2, var3])
>>> od2 = OptionDescription('od2', '', [var4], properties=('hidden',))
>>> rootod = OptionDescription('rootod', '', [od1, od2])
>>> c = Config(rootod)
>>> c.read_write()
A hidden value is a value that cannot be accessed in read/write mode. This
option cannot be modified any more. Let's try to access to an option's value
with a hidden option::
>>> print c.od1.var1
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: trying to access to an option named: var1
with properties ['hidden']
>>> c.read_only()
>>> print c.od1.var1
value
A mandatory option is an option with a value that shall not be `None`. The
value has to be defined. Accessing to such an option is easy in read/write
mode. But in read only mode, an error is raised if no value has been defined::
>>> c.read_write()
>>> print c.od1.var2
None
>>> c.read_only()
>>> print c.od1.var2
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: trying to access to an option named: var2
with properties ['mandatory']
>>> c.read_write()
>>> c.od1.var2 = u'value'
>>> c.read_only()
>>> print c.od1.var2
value
A frozen option, is an option that cannot be modified by a user.
Let's try to modify a frozen option::
>>> c.read_write()
>>> print c.od1.var3
value
>>> c.od1.var3 = u'value2'
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: cannot change the value for option var3 this option is frozen
>>> c.read_only()
>>> print c.od1.var3
value
Tiramisu allows us to use user defined properties. Let's define and use one in
read/write or read only mode::
>>> c.cfgimpl_get_settings().append('unknown')
>>> print c.od1.var3
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: trying to access to an option named:
var3 with properties ['unknown']
>>> c.cfgimpl_get_settings().remove('unknown')
>>> print c.od1.var3
value
Many properties can be defined at the same time on an option::
>>> c.cfgimpl_get_settings().extend(['unknown1', 'unknown2'])
Properties can also be defined on an option group (that is, on an
:term:`option description`) let's hide a group and try to access to it::
>>> c.read_write()
>>> print c.od2.var4
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: trying to access to an option named: od2
with properties ['hidden']
>>> c.read_only()
>>> print c.od2.var4
value
Furthermore, let's retrieve the properties, delete and add the `hidden` property::
>>> c.read_write()
>>> c.cfgimpl_get_settings()[rootod.od1.var1]
['hidden']
>>> print c.od1.var1
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: trying to access to an option named:
var1 with properties ['hidden']
>>> c.cfgimpl_get_settings()[rootod.od1.var1].remove('hidden')
>>> c.cfgimpl_get_settings()[rootod.od1.var1]
[]
>>> print c.od1.var1
value
>>> c.cfgimpl_get_settings()[rootod.od1.var1].append('hidden')
>>> c.cfgimpl_get_settings()[rootod.od1.var1]
['hidden']
>>> print c.od1.var1
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: trying to access to an option named:
var1 with properties ['hidden']
.. _multi-option:
The multi-options
~~~~~~~~~~~~~~~~~~~~~
.. glossary::
multi-option
Multi-options are normal options that have list of values (multiple values)
instead of values::
>>> var1 = UnicodeOption('var1', '', [u'val1', u'val2'], multi=True)
>>> od1 = OptionDescription('od1', '', [var1])
>>> rootod = OptionDescription('rootod', '', [od1])
>>> c = Config(rootod)
>>> c.read_write()
A multi-option's value can be manipulated like a list::
>>> print c.od1.var1
[u'val1', u'val2']
>>> c.od1.var1 = [u'var1']
>>> print c.od1.var1
[u'var1']
>>> c.od1.var1.append(u'val3')
>>> print c.od1.var1
[u'var1', u'val3']
>>> c.od1.var1.pop(1)
u'val3'
>>> print c.od1.var1
[u'var1']
But it is not possible to set a value to a multi-option which is not a list::
>>> c.od1.var1 = u'error'
Traceback (most recent call last):
ValueError: invalid value error for option var1 which must be a list
The master/slave groups
~~~~~~~~~~~~~~~~~~~~~~~~~
.. glossary::
master/slave
A master/slave group is an :class:`~tiramisu.option.OptionDescription` and the
options that lives inside.
Inside this group, a special option, named master option, has the same name as
the group. The group (the option description) is set to type `master`.
All options in a master group is a multi-option (see :ref:`multi-option`).
The slave options have a `default_multi` attribute set to `True`::
>>> from tiramisu.setting import groups
>>> from tiramisu.config import Config
>>> from tiramisu.option import UnicodeOption, OptionDescription
>>>
>>> var1 = UnicodeOption('master', '', multi=True)
>>> var2 = UnicodeOption('slave1', '', multi=True)
>>> var3 = UnicodeOption('slave2', '', multi=True, default_multi=u"default")
>>>
>>> od1 = OptionDescription('master', '', [var1, var2, var3])
>>> od1.impl_set_group_type(groups.master)
>>>
>>> rootod = OptionDescription('rootod', '', [od1])
>>> c = Config(rootod)
>>> c.read_write()
The length of the lists can be modified::
>>> print c.master
master = []
slave1 = []
slave2 = []
>>> c.master.master.append(u'oui')
>>> print c.master
master = [u'oui']
slave1 = [None]
slave2 = [u'default']
>>> c.master.master = [u'non']
>>> print c.master
master = [u'non']
slave1 = [None]
slave2 = [u'default']
>>>
>>> c.master.master = [u'oui', u'non']
>>> print c.master
master = [u'oui', u'non']
slave1 = [None, None]
slave2 = [u'default', u'default']
But it is forbidden to change the lenght of a slave::
>>> c.master.slave1[0] = u'super'
>>> print c.master
master = [u'oui', u'non']
slave1 = [u'super', None]
slave2 = [u'default', u'default']
>>> c.master.slave1 = [u'new1', u'new2']
>>> print c.master
master = [u'oui', u'non']
slave1 = [u'new1', u'new2']
slave2 = [u'default', u'default']
>>> c.master.slave1 = [u'new1']
Traceback (most recent call last):
tiramisu.error.SlaveError: invalid len for the slave: slave1 which has master.master as master
>>> c.master.slave1 = [u'new1', u'new2', u'new3']
tiramisu.error.SlaveError: invalid len for the slave: slave1 which has master.master as master
you have to call the `pop` function on the master::
>>> c.master.master = [u'oui']
Traceback (most recent call last):
tiramisu.error.SlaveError: invalid len for the master: master which has slave1 as slave with greater len
>>> c.master.master.pop(0)
u'oui'
>>> print c.master
master = [u'non']
slave1 = [u'new2']
slave2 = [u'default']
Configuration's interesting methods
------------------------------------------
A `Config` object is informed by an `option.OptionDescription`
instance. The attributes of the ``Config`` objects are the names of the
children of the ``OptionDescription``.
Here are the (useful) methods on ``Config`` (or `SubConfig`).
.. currentmodule:: tiramisu.config
.. class:: Config
.. autoclass:: SubConfig
:members: find, find_first, __iter__, iter_groups, iter_all, make_dict
.. automethod:: __init__
.. rubric:: Summary
.. autosummary::
find
find_first
__iter__
iter_groups
iter_all
make_dict
.. rubric:: Methods
A :class:`~config.CommonConfig` is a abstract base class. A
:class:`~config.SubConfig` is an just in time created objects that wraps an
::class:`~option.OptionDescription`. A SubConfig differs from a Config in the
fact that a config is a root object and has an environnement, a context which
defines the different properties, access rules, vs... There is generally only
one Config, and many SubConfigs.

View File

@ -1,306 +0,0 @@
.. default-role:: literal
.. currentmodule:: tiramisu
The global consistency
===========================
Identical option names
----------------------
If an :class:`~option.Option()` happens to be defined twice in the
:term:`schema` (e.g. the :class:`~option.OptionDescription()`),
that is the two options actually have the same name, an exception is raised.
The calculation is currently carried out in the samespace, for example
if `config.gc.name` is defined, another option in `gc` with the name
`name` is **not** allowed, whereas `config.whateverelse.name` is still
allowed.
Option's values type validation
--------------------------------
When a value is set to the option, the value is validated by the
option's :class:`option.Option()` validator's type.
Notice that if the option is `multi`, that is the `multi` attribute is set to
`True`, then the validation of the option value accepts a list of values
of the same type.
For example, an :class:`option.IntOption` validator waits for an `int` object of
course, an :class:`option.StrOption` validator waits for an `str`, vs...
Where are located the values
-------------------------------
The entry point of the acces to the values is the :class:`setting.Setting()` of
the root configuration object, but the values are actually located in the
:class:`value.Values()` object, in order to be delegated in some kind of a
`tiramisu.storage`, which can be a in-memory storage, or a persistent (for the
time being, a sqlite3) storage.
:class:`value.Values()` is also responsible of the owners and the calculation
of the options that have callbacks.
Requirements
------------
Configuration options can specify requirements as parameters at the init
time, the specification of some links between options or groups allows
to carry out a dependencies calculation. For example, an option can ben
hidden if another option has been set with some expected value. This is
just an example, the possibilities are hudge.
A requirement is a list of dictionaries that have fairly this form::
[{'option': a, 'expected': False, 'action': 'disabled', 'inverse': True,
'transitive':True, 'same_action': True}]
Actually a transformation is made to this dictionary during the validation of
this requires at the :class:`~option.Option()`'s init. The dictionary becomes
a tuple, wich is passed to the :meth:`~setting.Settings.apply_requires()`
method. Take a look at the code to fully understand the exact meaning of the
requirements:
.. automethod:: tiramisu.setting.Settings.apply_requires
The path of the option is required, the second element is the value wich is
expected to trigger the callback, it is required too, and the third one is the
callback's action name (`hide`, `show`...), wich is a
:class:`~setting.Property()`. Requirements are validated in
:class:`setting.Setting`.
Let's create an option wich has requirements::
>>> from tiramisu.option import *
>>> from tiramisu.config import *
>>> var2 = UnicodeOption('var2', '', u'oui')
>>> var1 = UnicodeOption('var1', '', u'value', requires=[{'option':var2, 'expected':u'non', 'action':'hidden'}])
>>> var3 = UnicodeOption('var3', '', u'value', requires=[{'option':var2, 'expected':u'non', 'action':'hidden'}, {'option':var2, 'expected':u'non', 'action':'disabled'}])
>>> var4 = UnicodeOption('var4', '', u'oui')
>>> od1 = OptionDescription('od1', '', [var1, var2, var3])
>>> od2 = OptionDescription('od2', '', [var4], requires=[{'option':od1.var2, 'expected':u'oui', 'action':'hidden', 'inverse':True}])
>>> rootod = OptionDescription('rootod', '', [od1, od2])
>>> c = Config(rootod)
>>> c.read_write()
The requirement here is the dict `{'option':var2, 'expected':u'non',
'action':'hidden'}` wich means that is the option `'od1.var2'` is set to
`'non'`, the option `'od1.var1'` is gonna be hidden. On the other hand, if the
option `'od1.var2'` is different from `'non'`, the option `'od1.var1'` is not
hidden any more::
>>> print c.cfgimpl_get_settings()[rootod.od1.var1]
[]
>>> print c.od1.var1
value
>>> print c.od1.var2
oui
>>> c.od1.var2 = u'non'
>>> print c.cfgimpl_get_settings()[rootod.od1.var1]
['hidden']
>>> print c.od1.var1
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: trying to access to an option named:
var1 with properties ['hidden']
>>> c.od1.var2 = u'oui'
>>> print c.cfgimpl_get_settings()[rootod.od1.var1]
[]
>>> print c.od1.var1
value
The requirement on `od2` is `{'option':od1.var2, 'expected':u'oui',
'action':'hidden', 'inverse':True}`, which means that if the option `od1.var2`
is set to `oui`, the option is not hidden (because of the `True` at the end of
the tuple wich means 'inverted', take a look at the :doc:`consistency`
document.)::
>>> print c.od2.var4
oui
>>> c.od1.var2 = u'non'
>>> print c.od2.var4
Traceback (most recent call last):
tiramisu.error.PropertiesOptionError: trying to access to an option named: od2 with properties ['hidden']
>>> c.od1.var2 = u'oui'
>>> print c.od2.var4
oui
Requirements can be accumulated
>>> print c.cfgimpl_get_settings()[rootod.od1.var3]
[]
>>> c.od1.var2 = u'non'
>>> print c.cfgimpl_get_settings()[rootod.od1.var3]
['disabled', 'hidden']
>>> c.od1.var2 = u'oui'
>>> print c.cfgimpl_get_settings()[rootod.od1.var3]
[]
Requirements can be accumulated for different or identical properties (inverted
or not)::
>>> a = UnicodeOption('var3', '', u'value', requires=[{'option':od1.var2,
... 'expected':'non', 'action':'hidden'}, {'option':od1.var1, 'expected':'oui',
... 'action':'hidden'}])
>>> a = UnicodeOption('var3', '', u'value', requires=[{'option':od1.var2,
... 'expected':'non', 'action':'hidden'}, {'option':od1.var1, 'excepted':'oui',
... 'action':'disabled', 'inverse':True}])
But it is not possible to have inverted requirements on the same property.
Here is an impossible situation::
>>> a = UnicodeOption('var3', '', u'value', requires=[{'option':od1.var2,
... 'expected':'non', 'action':'hidden'}, {'option':od1.var1, 'expected':'oui',
... 'hidden', True}])
Traceback (most recent call last):
ValueError: inconsistency in action types for option: var3 action: hidden
Validation upon a whole configuration object
----------------------------------------------
An option's integrity can be validated towards a whole configuration.
This type of validation is very open. Let's take a use case : an option
has a certain value, and the value of this option can change the owner
of another option or option group... Everything is possible.
.. currentmodule:: tiramisu.option
Other hooks are availables to validate upon a whole configuration at any time,
for example the consistency between two options (typically, an
:class:`IPOption` and a :class:`NetworkOption`).
Let's define validator (wich is a normal python function)::
>>> def valid_a(value, letter=''):
... return value.startswith(letter)
Here is an option wich uses this validator::
>>> var1 = UnicodeOption('var1', '', u'oui', validator=valid_a, validator_args={'letter': 'o'})
>>> od1 = OptionDescription('od1', '', [var1])
>>> rootod = OptionDescription('rootod', '', [od1])
>>> c = Config(rootod)
>>> c.read_write()
The validation is applied at the modification time::
>>> c.od1.var1 = u'non'
Traceback (most recent call last):
ValueError: invalid value non for option var1
>>> c.od1.var1 = u'oh non'
You can disabled this validation::
>>> c.cfgimpl_get_settings().remove('validator')
>>> c.od1.var1 = u'non'
Values that are calculated
--------------------------------
An option that have a callback is considered to have a value that is to be
calculated.
An option's property with a `force_store_value` attribute is considered to be
modified at the first calculation.
.. automodule:: tiramisu.autolib
:members:
This is the typically protocol for accessing a option's for a calculated value,
but some twisted ways are also possible, take a look at the `force_store_value`
attribute.
.. glossary::
force store value
A calculated value (that is, an option that has a callback) with the
attribute `force_store_value` enabled is considered to be modified at
the first calculation
Let's create four calculation functions::
def return_calc():
#return an unicode value
return u'calc'
def return_value(value):
return value
def return_value_param(param=u''):
return param
def return_no_value_if_non(value):
#if value is not u'non' return value
if value == u'non':
return None
else:
return value
Then we create four options using theses functions::
>>> var1 = UnicodeOption('var1', '', callback=return_calc)
>>> var2 = UnicodeOption('var2', '', callback=return_value, callback_params={'': (u'value',)})
>>> var3 = UnicodeOption('var3', '', callback=return_value_param, callback_params={'param': (u'value_param',)})
>>> var4 = UnicodeOption('var4', '', callback=return_no_value_if_non, callback_params={'': (('od1.var5', False),)})
>>> var5 = UnicodeOption('var5', '', u'oui')
>>> od1 = OptionDescription('od1', '', [var1, var2, var3, var4, var5])
>>> rootod = OptionDescription('rootod', '', [od1])
>>> c = Config(rootod)
>>> c.read_write()
The first option `var1` returns the result of the `return_calc` function, wich
is `u'calc'`::
>>> print c.od1.var1
calc
The second option `var2` returns the result of the `return_value` fucntion,
wich is `value`. The parameter `u'value'` is passed to this function::
>>> print c.od1.var2
value
The third option `var3` returns the result of the function `return_value_param`
with the named parameter `param` and the value `u'value_param'`::
>>> print c.od1.var3
value_param
The fourth option `var4` returns the reslut of the function `return_no_value_if_non`
that is the value of `od1.var5` exceptif the value is u`non`::
>>> print c.od1.var4
oui
>>> c.od1.var5 = u'new'
>>> print c.od1.var4
new
>>> c.od1.var5 = u'non'
>>> print c.od1.var4
None
The calculation replaces the default value.
If we modify the value, the calculation is not carried out any more::
>>> print c.od1.var1
calc
>>> c.od1.var1 = u'new_value'
>>> print c.od1.var1
new_value
To force the calculation to be carried out in some cases, one must add the
`frozen` and the `force_default_on_freeze` properties::
>>> c.cfgimpl_get_settings()[rootod.od1.var1].append('frozen')
>>> c.cfgimpl_get_settings()[rootod.od1.var1].append('force_default_on_freeze')
>>> print c.od1.var1
calc
>>> c.cfgimpl_get_settings()[rootod.od1.var1].remove('frozen')
>>> c.cfgimpl_get_settings()[rootod.od1.var1].remove('force_default_on_freeze')
>>> print c.od1.var1
new_value

View File

@ -1,92 +0,0 @@
Test framework
==================
Have a look at the :file:`test` subdirectory of the project.
We are using py.test_
.. _py.test: http://pytest.org/latest/
config APIs
-----------------
.. automodule:: test.test_config
:members:
option APIs
---------------
.. automodule:: test.test_option
:members:
others
----------
.. automodule:: test.test_mandatory
:members:
.. automodule:: test.test_config_big_example
:members:
.. automodule:: test.test_option_default
:members:
.. automodule:: test.test_option_consistency
:members:
.. automodule:: test.test_cache
:members:
.. automodule:: test.test_option_setting
:members:
.. automodule:: test.test_freeze
:members:
.. automodule:: test.test_config_ip
:members:
.. automodule:: test.test_slots
:members:
.. automodule:: test.test_reverse_from_path
:members:
.. automodule:: test.test_requires
:members:
.. automodule:: test.test_option_owner
:members:
.. automodule:: test.test_permissive
:members:
.. automodule:: test.test_option_type
:members:
.. automodule:: test.test_dereference
:members:
.. automodule:: test.test_storage
:members:
.. automodule:: test.test_option_calculation
:members:
.. automodule:: test.test_option_with_special_name
:members:
.. automodule:: test.test_config_domain
:members:
.. automodule:: test.test_symlink
:members:
.. automodule:: test.test_metaconfig
:members:
.. automodule:: test.test_parsing_group
:members:

View File

@ -1,12 +0,0 @@
SRC=$(wildcard *.tex)
OBJ=$(subst .tex,.pdf,$(SRC))
pdf: $(OBJ)
%.pdf: %.tex
pdflatex $<
clean:
rm -f $(OBJ)
rm -f *.aux *.log *.toc *.snm *.out *.nav

View File

@ -1,69 +0,0 @@
\begin{frame}
\frametitle{Comparaison entre le noyau de Créole et Tiramisu}
\begin{itemize}
\item \emph{Tiramisu} a pour objectif de
\begin{itemize}
\item remplacer le noyau \emph{Creole} (\texttt{EoleDict}) de manière transparente ;
\item résoudre les problèmes inhérents à \texttt{CreoleServ} ;
\end{itemize}
\item au niveau du code, il y a enfin une vraie séparation du c\oe ur et du fonctionnel ;
\item valide le type \emph{et la structure}, l'ajout de types est aisé.
\item \emph{Creole} : \texttt{EoleDict, EoleVars} $ \Leftrightarrow $ \texttt{Config, Option}\\
cf \texttt{tiramisu/doc/build/pydoc/index.html}
\item intégré à \texttt{gen\_config}, \texttt{cheetah}, \texttt{DTD Creole}, syntaxe \texttt{Creole} \dots
\item \texttt{eole-report/D02CoherenceVariables.pdf}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{Gestionnaire de configuration existants}
\begin{itemize}
\item Le gestionnaire de conf de Victor Stinner $\Rightarrow$ \emph{NuFw};
\item puppet, cfgengine... $\Rightarrow$ intéressant, de nombreux comportements peuvent être repris, mais tel quel difficilement compatible avec \emph{Creole};
\item \emph{Creole} $\Leftrightarrow$ \texttt{tiramisu/doc/build/glossary.html}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{Un "vrai" serveur de config}
\begin{itemize}
\item un serveur de données de configuration ;
\item $1^{ere}$ méthode : exportation (snapshot) d'un état de la config $ \Rightarrow $ Créole ;
\item $2^{eme}$ méthode : JIT (just in time) calculation, une modification
de l'état de la configuration est possible \emph{pendant} la manipulation et l'utilisation de la conf $ \Rightarrow $ Tiramisu.
\item \texttt{doc/getting-started.html}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{Qu'est-ce qu'un gestionnaire de conf moderne ?}
\begin{itemize}
\item c'est une organisation arborescente des données (les données sont imbriquées) ;
\item c'est un accès facile aux données (typiquement une interface de type \emph{dictionnaire}) ;
\item clefs-valeurs, mais quelles valeurs exactement ? $ \Rightarrow $ calcul JIT (just in time) ;
\item \texttt{eole-report/D01AccesVariables.pdf}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{Définition d'un gestionnaire de configuration}
\begin{itemize}
\item les families, groups, master \dots~ ce sont des \emph{schémas} de données (\texttt{OptionDescription}) ;
\item c'est la configuration (\texttt{Config}) qui est responsable de l'accès aux valeurs ;
\item la configuration est aisément manipulable, et a un point d'entrée unique ;
\item l'accès aux valeurs des \texttt{Options} de configuration ne peut se faire \emph{que} depuis la conf racine.
\item \texttt{eole-report/D01AccesVariables.pdf}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{Organisation en espace de nommage}
\begin{itemize}
\item dans \emph{tiramisu} l'accent est mis sur l'organisation arborescente des données ;
\item la validation des options de configuration se fait par l'appartenance aux groupes (families, master/slaves \dots) ;
\item l'organisation en groupes est unifiée par l'espace de nommage ;
\item \texttt{eole-report/D03ReglesEtats.pdf}
\item lisibilité d'une config : \texttt{tiramisu/report/build/index.html} rapport html d'une config
\end{itemize}
\end{frame}

View File

@ -1,61 +0,0 @@
\begin{frame}
\frametitle{Etats ("status") de la configuration}
\begin{itemize}
\item système d'états de la configuration par \emph{droits d'accès} ;
\item \texttt{read write}, \texttt{read only} ;
\item correspond à \texttt{freeze}, \texttt{hidden}, \texttt{disabled} \dots ;
\item \texttt{doc/status.html} ;
\item \texttt{eole-report/D03ReglesEtats.pdf} ;
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{hidden if in, hidden if not in}
\begin{itemize}
\item les hidden if in, disabled if, \dots sont généralisés
\item dans tiramisu, ce sont des pré-requis sur une (des) variables
\item \texttt{eole-report/D03ReglesEtats.pdf}
\item \texttt{doc/consistency.html}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{un peu de mathématiques : prévenir les deadlocks}
\begin{itemize}
\item sûreté : prévention des deadlocks ;
\item dans tiramisu, le modèle est suffisamment abstrait pour que son exploitation mathématique soit
réalisable par les techniques de \emph{Model Checking} ;
\item soit on a besoin de ne connaître que l'ensemble des états, pas leurs liens $\Rightarrow$ espace d'états ;
\item soit on a besoin de connaître toutes les relations $\Rightarrow$ graphe d'accessibilité ;
\item la configuration est modélisable en une structure de \emph{Kripe} ;
\item déjà le parsing de la conf est facile, la preuve : \texttt{tiramisu/report/build/index.html}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{un peu de mathématiques (suite) CreoleLint}
\begin{itemize}
\item exemple : $ P = 3 \wedge Q = 1 \triangleleft \langle P = 1 \hookleftarrow Q = 0 \rangle$
\item la propriété \og dans aucun état on a $P = 3$ et $Q = 1$ \fg~ est-elle vraie ?
Pour vérifier cette propriété, on a besoin de connaître l'espace d'états ;
\item la propriété \og chaque chemin débutant dans un état accessible $P=1$ passe par un état où $Q=3$ et $P=2$ \fg~
est-elle vraie ? Cela demande de connaître le graphe d'accessibilité ;
\item les structures de \emph{Kripe} sont des machines à états étiquetées par les valuations de toutes les variables propositionnelles ;
\item une compliation statique devient possible dans \emph{CreoleLint} \dots
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{compatibilité Créole : ce qui reste à faire}
\begin{itemize}
\item les options spéciales sont implémentées (auto, fill, obligatoire, \dots) reste la librairie des fonctions pour les variables automatiques \texttt{eosfunc} ;
\item tous les états sont implémentés (hidden, disabled, mode (normal/expert), \dots), il faut fixer les comportement \texttt{read write} ;
\item les "valprec" (valeur précédentes) et une mémoire de \emph{tous} les états antérieurs ;
\item fixer les comportement des hides (sous-groupes récursifs, \dots) ;
\item validations master/slaves, validations globales au regard de la configuration entière puisque c'est possible maintenant.
\end{itemize}
\end{frame}

View File

@ -1,36 +0,0 @@
%%presentation
\documentclass{beamer}
\usepackage{beamerthemetree}
%%impression
%\documentclass[a4paper,9pt]{extarticle}
%\usepackage{beamerarticle}
%%
% class FR
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[frenchb]{babel}
% image
%% \usepackage{graphicx}
\usepackage{alltt}
\usecolortheme{crane}
\beamertemplatetransparentcovered
%\logo{\includegraphics[height=1cm]{ban.png}}
\title{Tiramisu}
\subtitle{gestionnaire de configuration}
\author{Gwen}
\institute{\texttt{git clone git://git.labs.libre-entreprise.org/tiramisu.git} \\
\texttt{firefox tiramisu/doc/build/index.html}}
\date{\today}
\begin{document}
\frame{\titlepage}
\include{definition}
\include{statut}
\end{document}

View File

@ -1,19 +0,0 @@
Errors that may be encountered
==================================
Three builtins exceptions are used :
-----------------------------------------
- **ValueError** : Validation error, parameters error, a list instead
of a Multi, or if the value does not make sense
- **TypeError** : type error in a parameter
- **AttributeError** : wrong path or unknownd option or optiondescription
And five other exceptions :
------------------------------
.. automodule:: tiramisu.error
:members:

View File

@ -1,86 +0,0 @@
==================================
Getting started
==================================
What is options handling ?
=================================
Due to more and more available options required to set up an operating system,
compiler options or whatever, it became quite annoying to hand the necessary
options to where they are actually used and even more annoying to add new
options. To circumvent these problems the configuration control was
introduced...
What is Tiramisu ?
===================
Tiramisu is an options handler and an options controller, which aims at
producing flexible and fast options access. The main advantages are its access
rules and the fact that the whole consistency is preserved at any time, see
:doc:`consistency`. There is of course type and structure validations, but also
validations towards the whole options. Furthermore, options can be reached and
changed according to the access rules from nearly everywhere in your appliance.
Just the facts
==============
.. _gettingtiramisu:
`tiramisu`\ 's home page is here_
.. _here: https://forge.cadoles.com/Cadoles/tiramisu
Download
---------
To obtain a copy of the sources, check it out from the repository using `git`.
We suggest using `git` if one wants to access to the current developments.
::
git clone https://forge.cadoles.com/Cadoles/tiramisu.git
This will get you a fresh checkout of the code repository in a local directory
named ``tiramisu``.
Getting started
-------------------
Option objects can be created in different ways. Let's perform very basic
:class:`~tiramisu.option.Option` and :class:`~tiramisu.config.Config` object
manipulations:
::
>>> from tiramisu.config import Config
>>> from tiramisu.option import OptionDescription, BoolOption
>>> # let's create a group of options... with only one option inside
>>> descr = OptionDescription("optgroup", "", [
... BoolOption("bool", "", default=False)])
>>> # c is a namespace as well as a container for the options
>>> c = Config(descr)
>>> c.bool
False
>>> c.bool = True
>>> c.bool
True
So by now, we have:
- a namespace (which is `c` here)
- the access of an option's value by the
attribute access way (here `bool`, which is a boolean option
:class:`~tiramisu.option.BoolOption()`.
So, option objects are produced at the entry point `c` and then handed down to
where they are actually used when `c.bool` is triggered. This keeps options
local but available at any timer and consistent.
Once the namespace is created, we can set a
:meth:`~config.CommonConfig.read_write()` access to the options::
>>> c.read_write()
which enables us to set a bunch of access rules that we wil explain later in
:doc:`status`.

View File

@ -1,86 +0,0 @@
.. default-role:: literal
Glossary
==========
.. glossary::
configuration
Global configuration object, wich contains the whole configuration
options *and* their descriptions (option types and group)
schema
option description
see :class:`tiramisu.option.OptionDescription`
The schema of a configuration :
- the option types
- how they are organised in groups or even subgroups, that's why we
call them **groups** too.
configuration option
An option object wich has a name and a value and can be accessed
from the configuration object
access rules
Global access rules are : :meth:`~config.CommonConfig.read_write()` or
:meth:`~config.Config.read_only()`, see :doc:`status`
default value
Default value of a configuration option. The default value can be
set at instanciation time, or even at any moment. Remember that if
you reset the default value, the owner reset to `default`
freeze
A whole configuration can be frozen (used in read only access). See
:ref:`frozen` for details.
A single option can be frozen too.
value owner
When an option is modified, including at the instanciation, we
always know who has modified it. It's the owner of the option, see
:doc:`status` for more details.
option with properties
an option wich has property like 'hidden' or 'disabled' is an option
wich has restricted acces rules
hidden option
a hidden option has a different behaviour on regards to the access
of the value in the configuration, see :doc:`status` for more details.
disabled option
a disabled option has a different behaviour on regards to the access
of the value in the configuration, see :doc:`status` for more details.
mandatory option
A mandatory option is a configuration option wich value has to be
set, that is the default value cannot be `None`.
consistency
Preserving the consistency in a whole configuration is a tricky thing,
tiramisu takes care of it for you, see :doc:`consistency` for details.
context
The context is a :class:`tiramisu.setting.Setting()` object in the
configuration that enables us to access to the global properties
for example the `read_write` or `read_only` :term:`access rules`

View File

@ -1,62 +0,0 @@
.. default-role:: literal
.. meta::
:description: configuration management
:keywords: config, configuration
.. title:: tiramisu
The tasting of `Tiramisu`
=========================
.. image:: logo.png
:height: 150px
`Tiramisu`
is a cool, refreshing Italian dessert,
it is also an `options controller tool`_.
.. _`options controller tool`: http://en.wikipedia.org/wiki/Configuration_management#Overview
It's a pretty small, local (that is, straight on the operating system) options
handler and controller.
controlling options explanations
--------------------------------------
.. toctree::
:maxdepth: 1
getting-started
config
option
storage
status
consistency
error
glossary
api
doctest
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
.. note:: The tiramisu code is licensed under the `LGPL licence`_
and this documentation is licensed under the `Creative Commons
Attribution-ShareAlike 3.0 Unported License`_\ .
.. _`Creative Commons Attribution-ShareAlike 3.0 Unported License`: http://creativecommons.org/licenses/by-sa/3.0/deed.en_US
.. _`LGPL licence`: http://www.gnu.org/licenses/lgpl.html
.. todolist::

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,125 +0,0 @@
.. default-role:: literal
.. module:: tiramisu.option
The options types
===================
Description of Options
----------------------
All the constructors take a ``name`` and a ``doc`` argument as first
arguments to give to the option or option description a name and a description document.
Most constructors take a ``default`` argument that specifies the default
value of the option. If this argument is not supplied the default value
is assumed to be ``None``.
The `Option` base class
-------------------------
It's the abstract base class for almost all options (except the symlink).
.. _optioninit:
.. autoclass:: Option
:special-members:
:members:
All option types
------------------
BoolOption
~~~~~~~~~~
.. autoclass:: BoolOption
:private-members:
IntOption
~~~~~~~~~
.. autoclass:: IntOption
:private-members:
FloatOption
~~~~~~~~~~~
.. autoclass:: FloatOption
:private-members:
StrOption
~~~~~~~~~
.. autoclass:: StrOption
:private-members:
UnicodeOption
~~~~~~~~~~~~~
.. autoclass:: UnicodeOption
:private-members:
SymLinkOption
~~~~~~~~~~~~~
.. autoclass:: SymLinkOption
:private-members:
``SymLinkOption`` redirects to another configuration option in the
configuration, that is :
- retrieves the value of the target,
- can set the value of the target too
IPOption
~~~~~~~~
.. autoclass:: IPOption
:private-members:
PortOption
~~~~~~~~~~
.. autoclass:: PortOption
:private-members:
NetmaskOption
~~~~~~~~~~~~~
.. autoclass:: NetmaskOption
:private-members:
NetworkOption
~~~~~~~~~~~~~
.. autoclass:: NetworkOption
:private-members:
DomainnameOption
~~~~~~~~~~~~~~~~
.. autoclass:: DomainnameOption
:private-members:
ChoiceOption
~~~~~~~~~~~~
.. autoclass:: ChoiceOption
:private-members:
.. _optdescr:
The `OptionDescription` class
-------------------------------
.. autoclass:: OptionDescription
:special-members:
:members:
If you need to access to an option object, you can do it with the
OptionDescription object. Not only the value of the option by attribute access,
but the option object itself that lives behind the scene. It can always be
accessed internally. The option objects are in the `_children`
`OptionDescription`'s attribute.

View File

@ -1,155 +0,0 @@
.. default-role:: literal
Local statuses and global settings
=====================================
Available configuration statuses
----------------------------------
.. currentmodule:: tiramisu
The configuration's status lives in an :class:`setting.Setting()` object.
This configuration status corresponds to specific attributes or bunch of
attributes that can be accessed together with some `setting.Setting`
method:
**read write status**
The configuration can be accessed by `__get__` and `__set__`
properties, except for the `hidden` configuration options but, yes, it is
possible to modify a disabled option.
To enable read-write status, call
:class:`~config.CommonConfig.read_write()` on the config.
**read only status**
The whole configuration is `frozen`, that is modifiying a value is
forbidden. We can access to a configuration option only with the
`__getattr__` property.
The configuration has not an access to the hidden options
but can read the disabled options.
To enable read only status, call :class:`~config.SubConfig.read_only()` on
the config.
.. csv-table:: **Configuration's statuses summary**
:header: " ", "Hidden", "Disabled", "Mandatory"
"read only status", `False`, `True`, `True`
"read-write status", `True`, `False`, `False`
.. _`frozen`:
Freezing a configuration
---------------------------
At the configuration level, :class:`~setting.Setting()` enables us to freeze the
whole configuration, wich means that the frozen :class:`~option.Option()`'s
values cannot be modified.
It is possible to *freeze* a single :class:`~option.Option()` object with
:meth:`~config.SubConfig.cfgimpl_get_settings()`. If you try to modify a frozen
option, it raises a `TypeError: trying to change a frozen option object`.
To find out if an option `myoption` is frozen, just make an assertion on the
settings like that::
'frozen' in cfg.cfgimpl_get_settings()[myoption]
Moreover, frozen option can return their default values if
:meth:`~option.Option.force_default()` is called on this option.
.. glossary::
force default on freeze
A single option is frozen and we want the option to return something
else than his value, typically it is his default value.
In the option's values, an attribute can be set
:attr:`force_default_on_freeze`, that forces this behavior.
Restricted access to an `Option()`
-----------------------------------
.. autoclass:: tiramisu.setting.Property
The `properties` attribute is in charge of the access rules' option's value.
Configuration options access statuses are defined at configuration level
that corresponds to the `option.Option()`'s `properties` attribute,
for example: hidden, disabled.
Use the pythonic way to know if a property is there::
'hidden' in c.cfgimpl_get_settings()
'frozen' in c.cfgimpl_get_settings()[opt]
To access to the global settings::
cfg.cfgimpl_get_settings()
cfg.cfgimpl_get_settings()[option1]
to add, or suppress a global property::
cfg.cfgimpl_get_settings()[option1].append('hidden')
cfg.cfgimpl_get_settings()[option1].remove('hidden')
to activate, deactivate properties::
cfg.cfgimpl_get_settings().append('hidden')
cfg.cfgimpl_get_settings().remove('hidden')
The global properties are living in e :class:`~setting.Setting` object. A
`Setting` object also takes care of the way to access option values and the
storage in the cache.
Value owners
-------------
Every configuration option has a **owner**. When the option is instanciated,
the owner is :obj:`setting.owners.default` because a default value has been set
(including `None`, wich means that no value has been set yet).
.. method:: config.CommonConfig.getowner()
This method can retrieve an Option's owner.
- At the instance of the `Config` object, the value owner is
:obj:`setting.owners.default` because
the default values are set at the instance of the configuration option
object,
- at the modification of an option, the owner is `owners.default`, (which is
:obj:`owners.user`)
Special behaviors for an option
---------------------------------
**mandatory**
A mandatory option shall return a value. If a value, or a default value
has not been set, a error is raised.
**has a callback**
This means that it is a calculated value and therefore automatically
protected it cannot be modified by attribute access.
**force_store_value**
if the configuration option has a default value, the default is
returned, otherwise the value is calculated.
Its inner state is represented by `option.Option.force_default()`
Configuration options have default values that are stored in the
`Option()` object itself. Default values, the `default`, can be set in
various ways.
If a default value is modified by overriding it, not only the value of
the option resets to the default that is proposed, but the owner is
modified too, it is reseted to `owners.default`.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,265 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="400"
height="200"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="test.svg"
inkscape:export-filename="/home/gnunux/git/tiramisu/doc/storage.png"
inkscape:export-xdpi="135"
inkscape:export-ydpi="135">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3827" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="106.95445"
inkscape:cy="208.15932"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="841"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-852.36218)">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 235.5,78.588237 306,109"
id="path4403"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4211"
inkscape:connection-start-point="d4"
transform="translate(0,852.36218)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 235.5,131.08416 305,107"
id="path4405"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#g4216"
inkscape:connection-start-point="d4"
transform="translate(0,852.36218)" />
<g
id="g4206"
transform="translate(-17,590)">
<text
sodipodi:linespacing="686.00001%"
id="text2985"
y="368.36218"
x="98"
style="font-size:10px;font-style:normal;font-weight:normal;line-height:686.00001335%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="368.36218"
x="98"
id="tspan2987"
sodipodi:role="line">Config</tspan></text>
<rect
y="351.36218"
x="81"
height="30"
width="63"
id="rect3757"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
</g>
<g
id="g4211"
transform="translate(-17,590)">
<rect
y="312.36218"
x="189.5"
height="30"
width="63"
id="rect3757-2"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
<text
sodipodi:linespacing="686.00001%"
id="text3777"
y="330.36218"
x="206"
style="font-size:10px;font-style:normal;font-weight:normal;line-height:686.00001335%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="330.36218"
x="206"
id="tspan3779"
sodipodi:role="line">Values</tspan></text>
</g>
<g
id="g4216"
transform="translate(-17,590)">
<rect
y="389.36218"
x="189.5"
height="30"
width="63"
id="rect3757-4"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
<text
sodipodi:linespacing="686.00001%"
id="text3799"
y="407.36218"
x="200"
style="font-size:10px;font-style:normal;font-weight:normal;line-height:686.00001335%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
y="407.36218"
x="200"
id="tspan3801"
sodipodi:role="line">Settings</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 127,967.39444 45.5,15.93548"
id="path4028"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 127,945.0396 45.5,-16.35484"
id="path4030"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none"
id="rect4161"
width="55.5"
height="26"
x="277.5"
y="946.36218" />
<path
sodipodi:type="arc"
style="fill:none;stroke:#000000;stroke-width:1.96347165;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3843"
sodipodi:cx="401"
sodipodi:cy="334.86218"
sodipodi:rx="38"
sodipodi:ry="10.5"
d="m 439,334.86218 a 38,10.5 0 1 1 -76,0 38,10.5 0 1 1 76,0 z"
transform="matrix(0.71325325,0,0,0.57998971,18.66254,749.17042)" />
<path
transform="matrix(0.71325325,0,0,0.57998971,18.57337,775.05247)"
sodipodi:type="arc"
style="fill:none;stroke:#000000;stroke-width:1.96347165;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3843-3"
sodipodi:cx="401"
sodipodi:cy="334.86218"
sodipodi:rx="38"
sodipodi:ry="10.5"
d="m 439,334.86218 a 38,10.5 0 1 1 -76,0 38,10.5 0 1 1 76,0 z" />
<path
transform="matrix(0.71325325,0,0,0.57998971,18.52879,762.07519)"
sodipodi:type="arc"
style="fill:none;stroke:#000000;stroke-width:1.96347165;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3843-3-0"
sodipodi:cx="401"
sodipodi:cy="334.86218"
sodipodi:rx="38"
sodipodi:ry="10.5"
d="m 439,334.86218 a 38,10.5 0 1 1 -76,0 38,10.5 0 1 1 76,0 z" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none"
id="rect3883"
width="62.989182"
height="6.7061315"
x="274.72043"
y="949.91193" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none"
id="rect3883-3"
width="58.087975"
height="6.4161367"
x="277.34818"
y="962.78046" />
<path
style="fill:none;stroke:#000000;stroke-width:1.26286423;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
d="m 277.52869,943.35095 -0.0442,26.02673"
id="path3917"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.26286423;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
d="m 331.64698,969.26909 0.13377,-26.17203"
id="path3921"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-weight:normal;line-height:686.00001335%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
x="286.33643"
y="958.32324"
id="text3821"
sodipodi:linespacing="686.00001%"><tspan
sodipodi:role="line"
id="tspan3823"
x="286.33643"
y="958.32324">Storage</tspan></text>
<g
id="g4201"
transform="translate(-17,590)">
<rect
y="293.42468"
x="81"
height="30"
width="63"
id="rect3757-5"
style="fill:none;stroke:#000000;stroke-linejoin:round;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text4190"
y="309.42468"
x="110.27588"
style="font-size:10px;font-style:normal;font-weight:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
xml:space="preserve"><tspan
id="tspan4194"
y="309.42468"
x="110.27588"
sodipodi:role="line">Option</tspan></text>
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 95.5,913.42468 0,27.9375"
id="path4199"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -1,52 +0,0 @@
Storage
=======
.. automodule:: tiramisu.storage
.. automethod:: tiramisu.storage.set_storage
.. image:: storage.png
Dictionary
~~~~~~~~~~
.. automodule:: tiramisu.storage.dictionary
Dictionary settings:
.. automethod:: tiramisu.storage.dictionary.storage.Setting
Sqlite3
~~~~~~~
.. automodule:: tiramisu.storage.sqlite3
Sqlite3 settings:
.. automethod:: tiramisu.storage.sqlite3.storage.Setting
Example
~~~~~~~
>>> from tiramisu.option import StrOption, OptionDescription
>>> from tiramisu.config import Config
>>> from tiramisu.storage import set_storage
>>> set_storage('sqlite3', dir_database='/tmp/tiramisu')
>>> s = StrOption('str', '')
>>> o = OptionDescription('od', '', [s])
>>> c1 = Config(o, persistent=True, session_id='xxxx')
>>> c1.str
>>> c1.str = 'yes'
>>> c1.str
'yes'
>>> del(c1)
>>> c2 = Config(o, persistent=True, session_id='xxxx')
>>> c2.str
'yes'
>>> del(c2)
>>> list_sessions()
['xxxx']
>>> delete_session('xxxx')
>>> c3 = Config(o, persistent=True, session_id='xxxx')
>>> c3.str

View File

@ -1,57 +1,27 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from distutils.core import setup
from os.path import dirname, abspath, join, normpath, isdir
from os import listdir
from setuptools import setup, find_packages
import os
from tiramisu import __version__
package_name = os.environ.get('PACKAGE_DST', 'tiramisu')
def fetch_version():
"""Get version from version.in"""
return open('VERSION', 'r').readline().strip()
def return_files(component):
here = dirname(abspath(__file__))
path = normpath(join(here, 'tiramisu', component))
dir_content = [content for content in listdir(path)
if not content == '__pycache__']
paths = filter(isdir, [join(path, content)
for content in dir_content])
lst = ['.'.join(path.split('/')[-3:]) for path in paths]
#lst = [package_name + '.' + '.'.join(path.split('/')[-2:]) for path in paths]
return lst
packages = [package_name, package_name + '.storage', package_name + '.option']
packages.extend(return_files('storage'))
packages.extend(return_files('option'))
if package_name != 'tiramisu':
package_dir = {package_name: 'tiramisu'}
else:
package_dir = {}
PACKAGE_NAME = os.environ.get('PACKAGE_DST', 'tiramisu')
setup(
version=__version__,
author="Tiramisu's team",
author_email='contact@cadoles.com',
name=package_name,
version=fetch_version(),
author_email='gnunux@gnunux.info',
name=PACKAGE_NAME,
description='an options controller tool',
url='http://tiramisu.labs.libre-entreprise.org/',
url='https://framagit.org/tiramisu/tiramisu',
license='GNU Library or Lesser General Public License (LGPL)',
provides=['tiramisu_api'],
classifiers=[
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3",
"Development Status :: 4 - Beta",
"Environment :: Other Environment",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
"Operating System :: OS Independent",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Text Processing :: Linguistic"
"Natural Language :: English",
"Natural Language :: French",
],
long_description="""\
An options controller tool
@ -67,8 +37,8 @@ Tiramisu is an options handler and an options controller, wich aims at
producing flexible and fast options access.
This version requires Python 2.6 or later.
This version requires Python 3.5 or later.
""",
packages=packages,
package_dir=package_dir
include_package_data=True,
packages=find_packages(include=['tiramisu'])
)

View File

@ -1,1196 +0,0 @@
from .autopath import do_autopath
do_autopath()
from py.test import raises
from tiramisu import Config
from tiramisu.config import KernelConfig
from tiramisu.setting import groups, owners
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription, SymLinkOption, IPOption, NetmaskOption, Leadership, \
undefined, Params, ParamOption, ParamValue, ParamContext
from tiramisu.api import TIRAMISU_VERSION
from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
from tiramisu.i18n import _
from tiramisu.storage import list_sessions
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def return_val():
return 'val'
def return_concat(*args):
return '.'.join(list(args))
def return_list(value=None):
return ['val', 'val']
def return_list2(*args):
l = []
for arg in args:
if isinstance(arg, list):
l.extend(arg)
else:
l.append(arg)
return l
def return_value(value=None):
return value
def return_value2(*args, **kwargs):
value = list(args)
value.extend(kwargs.values())
return value
def return_value3(value=None, index=None):
if index is not None and isinstance(value, list):
if len(value) > index:
return value[index]
return None
return value
def return_index(val1, val2=None, index=None, self=None):
if index is None:
return [val1, val2]
if index == 0:
return val1
if index == 1:
return val2
def return_calc(i, j, k):
return i + j + k
def is_config(config, **kwargs):
if isinstance(config, KernelConfig):
return 'yes'
else:
return 'no'
def ret_from_config(config):
api = Config(config)
return api.option('val1').value.get()
def return_raise(*arg):
raise Exception('test')
def return_valueerror(*arg):
raise ValueError('test')
def make_description_duplicates():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
## dummy 1
gcdummy = BoolOption('dummy', 'dummy', default=False)
objspaceoption = ChoiceOption('objspace', 'Object space',
('std', 'thunk'), 'std')
booloption = BoolOption('bool', 'Test boolean option', default=True)
intoption = IntOption('int', 'Test int option', default=0)
floatoption = FloatOption('float', 'Test float option', default=2.3)
stroption = StrOption('str', 'Test string option', default="abc")
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
wantref_option = BoolOption('wantref', 'Test requires', default=False,
requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
wantframework_option = BoolOption('wantframework', 'Test requires',
default=False,
requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
# dummy2 (same path)
gcdummy2 = BoolOption('dummy', 'dummy2', default=True)
# dummy3 (same name)
gcdummy3 = BoolOption('dummy', 'dummy2', default=True)
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, gcdummy2, floatoption])
descr = OptionDescription('constraints', '', [gcgroup, booloption, objspaceoption,
wantref_option, stroption,
wantframework_option,
intoption, boolop, gcdummy3])
return descr
def test_identical_paths():
"""If in the schema (the option description) there is something that
have the same name, an exection is raised
"""
raises(ConflictError, "make_description_duplicates()")
def test_hidden_if_in():
intoption = IntOption('int', 'Test int option', default=0)
stroption = StrOption('str', 'Test string option', default="abc",
requires=({'option': intoption, 'expected': 1, 'action': 'hidden'},))
descr = OptionDescription('constraints', '', [stroption, intoption])
api = Config(descr)
api.property.read_write()
assert not 'hidden' in api.option('str').property.get()
api.option('int').value.set(1)
raises(PropertiesOptionError, "api.option('str').value.get()")
raises(PropertiesOptionError, "api.option('str').value.set('uvw')")
assert 'hidden' in api.unrestraint.option('str').property.get()
def test_hidden_if_in_with_group():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False)
floatoption = FloatOption('float', 'Test float option', default=2.3)
objspaceoption = ChoiceOption('objspace', 'Object space',
('std', 'thunk'), 'std')
booloption = BoolOption('bool', 'Test boolean option', default=True)
intoption = IntOption('int', 'Test int option', default=0)
stroption = StrOption('str', 'Test string option', default="abc")
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption],
requires=({'option': intoption, 'expected': 1, 'action': 'hidden'},))
descr = OptionDescription('constraints', '', [gcgroup, booloption,
objspaceoption, stroption, intoption])
api = Config(descr)
api.property.read_write()
assert not 'hidden' in api.option('str').property.get()
api.option('int').value.set(1)
raises(PropertiesOptionError, "api.option('gc.name').value.get()")
def test_disabled_with_group():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False)
floatoption = FloatOption('float', 'Test float option', default=2.3)
objspaceoption = ChoiceOption('objspace', 'Object space',
('std', 'thunk'), 'std')
booloption = BoolOption('bool', 'Test boolean option', default=True)
intoption = IntOption('int', 'Test int option', default=0)
stroption = StrOption('str', 'Test string option', default="abc")
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption],
requires=({'option': intoption, 'expected': 1, 'action': 'disabled'},))
descr = OptionDescription('constraints', '', [gcgroup, booloption,
objspaceoption, stroption, intoption])
api = Config(descr)
api.property.read_write()
assert api.option('gc.name').value.get()
api.option('int').value.set(1)
raises(PropertiesOptionError, "api.option('gc.name').value.get()")
#____________________________________________________________
def make_description_callback():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
gcdummy = BoolOption('dummy', 'dummy')
objspaceoption = ChoiceOption('objspace', 'Object space',
('std', 'thunk'), 'std')
booloption = BoolOption('bool', 'Test boolean option', default=True)
intoption = IntOption('int', 'Test int option', default=0)
floatoption = FloatOption('float', 'Test float option', default=2.3)
stroption = StrOption('str', 'Test string option', default="abc")
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
wantref_option = BoolOption('wantref', 'Test requires', default=False,
requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
wantframework_option = BoolOption('wantframework', 'Test requires',
default=False,
requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
descr = OptionDescription('constraints', '', [gcgroup, booloption, objspaceoption,
wantref_option, stroption,
wantframework_option,
intoption, boolop])
return descr
def test_has_callback():
descr = make_description_callback()
# here the owner is 'default'
api = Config(descr)
api.property.read_write()
api.option('bool').value.set(False)
# because dummy has a callback
api.property.add('freeze')
api.option('gc.dummy').property.add('frozen')
raises(PropertiesOptionError, "api.option('gc.dummy').value.set(True)")
def test_freeze_and_has_callback():
descr = make_description_callback()
api = Config(descr)
api.property.read_write()
api.option('bool').value.set(False)
api.property.add('freeze')
api.option('gc.dummy').property.add('frozen')
raises(PropertiesOptionError, "api.option('gc.dummy').value.set(True)")
def test_callback():
val1 = StrOption('val1', "", callback=return_val)
val2 = StrOption('val2', "")
maconfig = OptionDescription('rootconfig', '', [val1, val2])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1').option.callbacks() != (None, None)
assert api.option('val2').option.callbacks() == (None, None)
assert api.option('val1').value.get() == 'val'
api.option('val1').value.set('new-val')
assert api.option('val1').value.get() == 'new-val'
api.option('val1').value.reset()
assert api.option('val1').value.get() == 'val'
def test_callback_params_without_callback():
raises(ValueError, "StrOption('val2', '', callback_params=Params(ParamValue('yes')))")
def test_params():
raises(ValueError, "Params([ParamContext()])")
raises(ValueError, "Params('str')")
raises(ValueError, "Params(('str',))")
raises(ValueError, "Params(kwargs=[ParamContext()])")
raises(ValueError, "Params(kwargs={'a': 'str'})")
def test_param_option():
val1 = StrOption('val1', "")
raises(ValueError, "ParamOption('str')")
raises(ValueError, "ParamOption(val1, 'str')")
def test_callback_invalid():
raises(AssertionError, 'val1 = StrOption("val1", "", callback="string")')
raises(AssertionError, 'val1 = StrOption("val1", "", callback=return_val, callback_params="string")')
val1 = StrOption('val1', "", 'val')
val1
raises(AssertionError, "StrOption('val2', '', callback=return_value, callback_params={'': 'string'})")
raises(AssertionError, "StrOption('val4', '', callback=return_value, callback_params={'value': (('string', False),)})")
raises(AssertionError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1, 'string'),)})")
raises(AssertionError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1, False, 'unknown'),)})")
raises(AssertionError, "StrOption('val4', '', callback=return_value, callback_params={'value': ((val1,),)})")
def test_callback_with_context():
context = ParamContext()
value = ParamValue('string')
params = Params((context,), {'value': value})
val1 = StrOption("val1", "", callback=is_config, callback_params=params)
maconfig = OptionDescription('rootconfig', '', [val1])
api = Config(maconfig)
assert api.option('val1').value.get() == 'yes'
def test_callback_with_context_named():
context = ParamContext()
params = Params(kwargs={'config': context})
val1 = StrOption("val1", "", callback=is_config, callback_params=params)
maconfig = OptionDescription('rootconfig', '', [val1])
api = Config(maconfig)
assert api.option('val1').value.get() == 'yes'
def test_callback_with_error():
val1 = StrOption("val1", "", callback=is_config, callback_params=Params(ParamValue('string'), kwargs={'value': ParamValue('string')}))
maconfig = OptionDescription('rootconfig', '', [val1])
api = Config(maconfig)
assert api.option('val1').value.get() == 'no'
def test_callback_with_context_value():
context = ParamContext()
params = Params((context,))
val1 = StrOption("val1", "")
val2 = StrOption("val2", "", callback=ret_from_config, callback_params=params)
maconfig = OptionDescription('rootconfig', '', [val1, val2])
api = Config(maconfig)
api.option('val1').value.set('yes')
assert api.option('val1').value.get() == 'yes'
assert api.option('val2').value.get() == 'yes'
api.option('val1').value.set('no')
assert api.option('val1').value.get() == 'no'
assert api.option('val2').value.get() == 'no'
def test_callback_value():
val1 = StrOption('val1', "", 'val')
val2 = StrOption('val2', "", callback=return_value, callback_params=Params(ParamOption(val1)))
val3 = StrOption('val3', "", callback=return_value, callback_params=Params(ParamValue('yes')))
val4 = StrOption('val4', "", callback=return_value, callback_params=Params(kwargs={'value': ParamOption(val1)}))
val5 = StrOption('val5', "", callback=return_value, callback_params=Params(ParamValue('yes')))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4, val5])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1').value.get() == 'val'
assert api.option('val2').value.get() == 'val'
assert api.option('val4').value.get() == 'val'
api.option('val1').value.set('new-val')
assert api.option('val1').value.get() == 'new-val'
assert api.option('val2').value.get() == 'new-val'
assert api.option('val4').value.get() == 'new-val'
api.option('val1').value.reset()
assert api.option('val1').value.get() == 'val'
assert api.option('val2').value.get() == 'val'
assert api.option('val3').value.get() == 'yes'
assert api.option('val4').value.get() == 'val'
assert api.option('val5').value.get() == 'yes'
def test_callback_value_tuple():
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2')
val3 = StrOption('val3', "", callback=return_concat, callback_params=Params((ParamOption(val1), ParamOption(val2))))
val4 = StrOption('val4', "", callback=return_concat, callback_params=Params((ParamValue('yes'), ParamValue('no'))))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1').value.get() == 'val1'
assert api.option('val2').value.get() == 'val2'
assert api.option('val3').value.get() == 'val1.val2'
assert api.option('val4').value.get() == 'yes.no'
api.option('val1').value.set('new-val')
assert api.option('val3').value.get() == 'new-val.val2'
api.option('val1').value.reset()
assert api.option('val3').value.get() == 'val1.val2'
def test_callback_value_force_permissive():
val1 = StrOption('val1', "", 'val', properties=('disabled',))
val2 = StrOption('val2', "", callback=return_value, callback_params=Params(ParamOption(val1)))
val3 = StrOption('val3', "", callback=return_value, callback_params=Params(ParamOption(val1, True)))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
api = Config(maconfig)
api.property.read_only()
raises(ConfigError, "api.option('val2').value.get()")
api.option('val3').value.get() is None
def test_callback_value_force_permissive_kwargs():
val1 = StrOption('val1', "", 'val', properties=('disabled',))
val2 = StrOption('val2', "", callback=return_value, callback_params=Params(value=ParamOption(val1)))
val3 = StrOption('val3', "", callback=return_value, callback_params=Params(value=ParamOption(val1, True)))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
api = Config(maconfig)
api.property.read_only()
raises(ConfigError, "api.option('val2').value.get()")
api.option('val3').value.get() is None
def test_callback_symlink():
val1 = StrOption('val1', "", 'val')
val2 = SymLinkOption('val2', val1)
val3 = StrOption('val3', "", callback=return_value, callback_params=Params(ParamOption(val2)))
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1').value.get() == 'val'
assert api.option('val2').value.get() == 'val'
assert api.option('val3').value.get() == 'val'
api.option('val1').value.set('new-val')
assert api.option('val1').value.get() == 'new-val'
assert api.option('val3').value.get() == 'new-val'
api.option('val1').value.reset()
assert api.option('val1').value.get() == 'val'
assert api.option('val3').value.get() == 'val'
def test_callback_list():
val1 = StrOption('val1', "", callback=return_list)
maconfig = OptionDescription('rootconfig', '', [val1])
api = Config(maconfig)
api.property.read_write()
raises(ValueError, "api.option('val1').value.get()")
def test_callback_list2():
val1 = StrOption('val1', "", callback=return_list)
#val2 = StrOption('val2', "", callback=return_value, callback_params=Params(ParamOption(val1)))
val2 = StrOption('val2', "", callback=return_value, callback_params=Params(ParamOption(val1))) # , 'forcepermissive': False}]})
maconfig = OptionDescription('rootconfig', '', [val1, val2])
api = Config(maconfig)
api.property.read_write()
raises(ValueError, "api.option('val1').value.get()")
#cfg.val2
raises(ValueError, "api.option('val2').value.get()")
def test_callback_multi():
val1 = StrOption('val1', "", callback=return_val, multi=True)
maconfig = OptionDescription('rootconfig', '', [val1])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1').value.get() == ['val']
api.option('val1').value.set(['new-val'])
assert api.option('val1').value.get() == ['new-val']
api.option('val1').value.set(['new-val', 'new-val2'])
assert api.option('val1').value.get() == ['new-val', 'new-val2']
api.option('val1').value.reset()
assert api.option('val1').value.get() == ['val']
def test_callback_multi_value():
val1 = StrOption('val1', "", ['val'], multi=True)
#val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)))
#val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamValue('yes')))
#val4 = StrOption('val4', "", multi=True, callback=return_list2, callback_params={'': ((val1, False), 'yes')})
option = ParamOption(val1)
params1 = Params((option,))
value = ParamValue('yes')
params2 = Params((value,))
params3 = Params((option, value))
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params=params1)
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=params2)
val4 = StrOption('val4', "", multi=True, callback=return_list2, callback_params=params3)
maconfig = OptionDescription('rootconfig', '', [val1, val2, val3, val4])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1').value.get() == ['val']
assert api.option('val2').value.get() == ['val']
assert api.option('val4').value.get() == ['val', 'yes']
api.option('val1').value.set(['new-val'])
assert api.option('val1').value.get() == ['new-val']
assert api.option('val2').value.get() == ['new-val']
assert api.option('val4').value.get() == ['new-val', 'yes']
api.option('val1').value.set(['new-val', 'new-val2'])
assert api.option('val1').value.get() == ['new-val', 'new-val2']
assert api.option('val2').value.get() == ['new-val', 'new-val2']
assert api.option('val4').value.get() == ['new-val', 'new-val2', 'yes']
api.option('val1').value.reset()
assert api.option('val1').value.get() == ['val']
assert api.option('val2').value.get() == ['val']
assert api.option('val3').value.get() == ['yes']
assert api.option('val4').value.get() == ['val', 'yes']
api.option('val2').value.set(['val', 'new'])
assert api.option('val1').value.get() == ['val']
assert api.option('val2').value.get() == ['val', 'new']
def test_callback_multi_list():
val1 = StrOption('val1', "", callback=return_list, multi=True)
maconfig = OptionDescription('rootconfig', '', [val1])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1').value.get() == ['val', 'val']
api.option('val1').value.set(['new-val'])
assert api.option('val1').value.get() == ['new-val']
api.option('val1').value.set(['new-val', 'new-val2'])
assert api.option('val1').value.get() == ['new-val', 'new-val2']
api.option('val1').value.reset()
assert api.option('val1').value.get() == ['val', 'val']
def test_callback_multi_list_extend():
val1 = StrOption('val1', "", callback=return_list2, callback_params=Params((ParamValue(['1', '2', '3']), ParamValue(['4', '5']))), multi=True)
maconfig = OptionDescription('rootconfig', '', [val1])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1').value.get() == ['1', '2', '3', '4', '5']
def test_callback_multi_callback():
val1 = StrOption('val1', "", multi=True, callback=return_val)
interface1 = OptionDescription('val1', '', [val1])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1.val1').value.get() == ['val']
api.option('val1.val1').value.set(['val1', undefined])
assert api.option('val1.val1').value.get() == ['val1', 'val']
def test_callback_leader_and_followers_leader():
val1 = StrOption('val1', "", multi=True, callback=return_val)
val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1.val1').value.get() == ['val']
api.option('val1.val1').value.set([undefined, undefined])
assert api.option('val1.val1').value.get() == ['val', 'val']
assert api.option('val1.val2', 0).value.get() == None
assert api.option('val1.val2', 1).value.get() == None
def test_callback_follower():
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_value3, callback_params=Params(ParamValue(['string', 'new'])))
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
api.option('val1.val1').value.set(['val'])
assert api.option('val1.val2', 0).value.get() == 'string'
api.option('val1.val1').value.set(['val', 'val1'])
assert api.option('val1.val2', 0).value.get() == 'string'
assert api.option('val1.val2', 1).value.get() == 'new'
api.option('val1.val1').value.set(['val', 'val1', 'val2'])
assert api.option('val1.val2', 0).value.get() == 'string'
assert api.option('val1.val2', 1).value.get() == 'new'
assert api.option('val1.val2', 2).value.get() == None
api.option('val1.val1').value.set(['val', 'val1', 'val2', 'val3'])
assert api.option('val1.val2', 0).value.get() == 'string'
assert api.option('val1.val2', 1).value.get() == 'new'
assert api.option('val1.val2', 2).value.get() == None
assert api.option('val1.val2', 3).value.get() == None
def test_callback_leader_and_followers_leader2():
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, default_multi='val2')
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val2)))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val3)))
interface1 = Leadership('val1', '', [val1, val2, val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
api.option('val1.val1').value.set(['val'])
assert api.option('val1.val4', 0).value.get() == 'val2'
assert api.option('val1.val3', 0).value.get() == 'val2'
assert api.option('val1.val2', 0).value.get() == 'val2'
def test_callback_leader_and_followers_leader_mandatory():
val = StrOption('val', "", default='val')
val1 = StrOption('val1', "", multi=True, callback=return_value2, callback_params=Params(ParamOption(val)), properties=('mandatory',))
val3 = StrOption('val3', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
val4 = StrOption('val4', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
interface1 = Leadership('val1', '', [val1, val3, val4])
maconfig = OptionDescription('rootconfig', '', [val, interface1])
api = Config(maconfig)
api.property.read_only()
assert api.option('val1.val3', 0).value.get() == 'val'
assert api.option('val1.val4', 0).value.get() == 'val'
assert api.option('val1.val1').value.get() == ['val']
api.property.read_write()
api.option('val1.val1').value.set([undefined, 'val3'])
api.property.read_only()
assert api.option('val1.val1').value.get() == ['val', 'val3']
assert api.option('val1.val3', 0).value.get() == 'val'
raises(PropertiesOptionError, "api.option('val1.val3', 1).value.get()")
raises(PropertiesOptionError, "api.option('val1.val4', 1).value.get()")
def test_callback_leader_and_followers_leader_mandatory2():
val = StrOption('val', "", default='val')
val_ = StrOption('val_', "", default='val_')
val1 = StrOption('val1', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val), {'val2': ParamOption(val_)}), properties=('mandatory',))
val3 = StrOption('val3', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val1), {'val2': ParamOption(val_)}), properties=('mandatory',))
val4 = StrOption('val4', "", multi=True, callback=return_index, callback_params=Params(ParamOption(val1), {'val2': ParamOption(val_)}), properties=('mandatory',))
interface1 = Leadership('val1', '', [val1, val3, val4])
maconfig = OptionDescription('rootconfig', '', [val, val_, interface1])
api = Config(maconfig)
api.property.read_only()
assert api.option('val1.val3', 0).value.get() == 'val'
assert api.option('val1.val3', 1).value.get() == 'val_'
assert api.option('val1.val4', 0).value.get() == 'val'
assert api.option('val1.val4', 1).value.get() == 'val_'
assert api.option('val1.val1').value.get() == ['val', 'val_']
api.property.read_write()
api.option('val1.val1').value.set(['val', 'val_', 'val3'])
assert api.option('val1.val1').value.get() == ['val', 'val_', 'val3']
api.property.read_only()
assert api.option('val1.val3', 0).value.get() == 'val'
assert api.option('val1.val3', 1).value.get() == 'val_'
assert api.option('val1.val4', 0).value.get() == 'val'
assert api.option('val1.val4', 1).value.get() == 'val_'
raises(PropertiesOptionError, "api.option('val1.val3', 2).value.get()")
raises(PropertiesOptionError, "api.option('val1.val4', 2).value.get()")
assert api.option('val1.val1').value.get() == ['val', 'val_', 'val3']
def test_callback_leader_and_followers_leader_mandatory3():
val = StrOption('val', "", default='val')
val_ = StrOption('val_', "", default='val_')
val1 = StrOption('val1', "", multi=True, callback=return_value2, callback_params=Params(ParamOption(val), {'val': ParamOption(val_)}), properties=('mandatory',))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
interface1 = Leadership('val1', '', [val1, val3, val4])
maconfig = OptionDescription('rootconfig', '', [val, val_, interface1])
api = Config(maconfig)
api.property.read_only()
assert api.option('val1.val3', 0).value.get() == 'val'
assert api.option('val1.val3', 1).value.get() == 'val_'
assert api.option('val1.val4', 0).value.get() == 'val'
assert api.option('val1.val4', 1).value.get() == 'val_'
assert api.option('val1.val1').value.get() == ['val', 'val_']
api.property.read_write()
api.option('val1.val1').value.set(['val', 'val_', 'val3'])
api.property.read_only()
assert api.option('val1.val3', 0).value.get() == 'val'
assert api.option('val1.val3', 1).value.get() == 'val_'
assert api.option('val1.val3', 2).value.get() == 'val3'
assert api.option('val1.val4', 0).value.get() == 'val'
assert api.option('val1.val4', 1).value.get() == 'val_'
assert api.option('val1.val4', 2).value.get() == 'val3'
assert api.option('val1.val1').value.get() == ['val', 'val_', 'val3']
def test_callback_leader_and_followers_leader_mandatory4():
val = StrOption('val', "", default='val')
val1 = StrOption('val1', "", multi=True, callback=return_value2, callback_params=Params(ParamOption(val)), properties=('mandatory',))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)), properties=('mandatory',))
interface1 = Leadership('val1', '', [val1, val3, val4])
maconfig = OptionDescription('rootconfig', '', [val, interface1])
api = Config(maconfig)
api.property.read_only()
#raises(IndexError, "api.option('val1.val3').value.get()")
assert api.option('val1.val3', 0).value.get() == 'val'
assert api.option('val1.val4', 0).value.get() == 'val'
assert api.option('val1.val1').value.get() == ['val']
api.property.read_write()
api.option('val1.val1').value.set(['val', 'val3'])
api.property.read_only()
assert api.option('val1.val1').value.get() == ['val', 'val3']
assert api.option('val1.val3', 0).value.get() == 'val'
assert api.option('val1.val3', 1).value.get() == 'val3'
assert api.option('val1.val4', 0).value.get() == 'val'
assert api.option('val1.val4', 1).value.get() == 'val3'
def test_callback_leader_and_followers_leader3():
val1 = StrOption('val1', "", multi=True, properties=('mandatory', 'empty'))
val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert',))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val2)))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val3)))
interface1 = Leadership('val1', '', [val1, val2, val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
assert list(api.value.mandatory()) == ['val1.val1']
def test_callback_leader_and_followers_leader4():
val1 = StrOption('val1', "", ['val1'], multi=True, properties=('mandatory',))
val2 = StrOption('val2', "", multi=True, default_multi='val2', properties=('expert', 'mandatory'))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val2)))
val4 = StrOption('val4', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val3)))
interface1 = Leadership('val1', '', [val1, val2, val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
api.property.add('expert')
api.permissive.set(frozenset(['expert']))
assert list(api.value.mandatory()) == []
def test_consistency_leader_and_followers_leader_mandatory_transitive():
#default value
val1 = IPOption('val1', "", ['192.168.0.1'], multi=True, properties=('mandatory',))
val2 = NetmaskOption('val2', "", multi=True, default_multi='255.255.255.0', properties=('disabled', 'mandatory'))
val2.impl_add_consistency('ip_netmask', val1)
#no value
val3 = IPOption('val3', "", multi=True, properties=('mandatory',))
val4 = NetmaskOption('val4', "", multi=True, default_multi='255.255.255.0', properties=('disabled', 'mandatory'))
val4.impl_add_consistency('ip_netmask', val3)
interface1 = Leadership('val1', '', [val1, val2])
interface2 = Leadership('val3', '', [val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1, interface2])
api = Config(maconfig)
api.property.read_write()
try:
api.option('val1.val1').value.get()
except PropertiesOptionError as error:
assert str(error) == str(_('cannot access to {0} "{1}" because "{2}" has {3} {4}').format('option', 'val1', 'val2', 'property', '"disabled"'))
else:
raise Exception('must raises')
raises(PropertiesOptionError, "api.option('val3.val3').value.get()")
assert list(api.value.mandatory()) == []
def test_consistency_leader_and_followers_leader_mandatory_non_transitive():
#no value
val1 = IPOption('val1', "", multi=True, properties=('mandatory',))
val2 = NetmaskOption('val2', "", multi=True, default_multi='255.255.255.0', properties=('disabled', 'mandatory'))
val2.impl_add_consistency('ip_netmask', val1, transitive=False)
#default value
val3 = IPOption('val3', "", ['192.168.0.1'], multi=True, properties=('mandatory',))
val4 = NetmaskOption('val4', "", multi=True, default_multi='255.255.255.0', properties=('disabled', 'mandatory'))
val4.impl_add_consistency('ip_netmask', val3, transitive=False)
interface1 = Leadership('val1', '', [val1, val2])
interface2 = Leadership('val3', '', [val3, val4])
maconfig = OptionDescription('rootconfig', '', [interface1, interface2])
api = Config(maconfig)
api.property.read_write()
if TIRAMISU_VERSION == 2:
assert list(api.value.mandatory()) == ["val1.val1", "val1.val2"]
else:
assert list(api.value.mandatory()) == ["val1.val1"]
def test_callback_leader_and_followers_leader_list():
val1 = StrOption('val1', "", multi=True, callback=return_list)
val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1.val1').value.get() == ['val', 'val']
assert api.option('val1.val2', 0).value.get() == None
assert api.option('val1.val2', 1).value.get() == None
api.option('val1.val1').value.set(['val', 'val', undefined])
assert api.option('val1.val1').value.get() == ['val', 'val', None]
assert api.option('val1.val2', 0).value.get() == None
assert api.option('val1.val2', 1).value.get() == None
assert api.option('val1.val2', 1).value.get() == None
api.option('val1.val1').value.reset()
assert api.option('val1.val1').value.get() == ['val', 'val']
assert api.option('val1.val2', 0).value.get() == None
assert api.option('val1.val2', 1).value.get() == None
api.option('val1.val1').value.pop(1)
assert api.option('val1.val1').value.get() == ['val']
assert api.option('val1.val2', 0).value.get() == None
def test_callback_leader_and_followers_leader_follower_list():
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_list)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1.val1').value.get() == []
api.option('val1.val1').value.set(['val1'])
raises(LeadershipError, "api.option('val1.val2', 0).value.get()")
def test_callback_leader_and_followers_follower():
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_val)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1.val1').value.get() == []
#
api.option('val1.val1').value.set(['val1'])
assert api.option('val1.val1').value.get() == ['val1']
assert api.option('val1.val2', 0).value.get() == 'val'
#
api.option('val1.val1').value.set(['val1', 'val2'])
assert api.option('val1.val1').value.get() == ['val1', 'val2']
assert api.option('val1.val2', 0).value.get() == 'val'
assert api.option('val1.val2', 1).value.get() == 'val'
#
api.option('val1.val1').value.set(['val1', 'val2', 'val3'])
assert api.option('val1.val1').value.get() == ['val1', 'val2', 'val3']
assert api.option('val1.val2', 0).value.get() == 'val'
assert api.option('val1.val2', 1).value.get() == 'val'
assert api.option('val1.val2', 2).value.get() == 'val'
#
api.option('val1.val1').value.pop(2)
assert api.option('val1.val1').value.get() == ['val1', 'val2']
assert api.option('val1.val2', 0).value.get() == 'val'
assert api.option('val1.val2', 1).value.get() == 'val'
#
api.option('val1.val2', 0).value.set('val2')
api.option('val1.val2', 1).value.set('val2')
assert api.option('val1.val2', 0).value.get() == 'val2'
assert api.option('val1.val2', 1).value.get() == 'val2'
#
api.option('val1.val1').value.set(['val1', 'val2', 'val3'])
assert api.option('val1.val2', 0).value.get() == 'val2'
assert api.option('val1.val2', 1).value.get() == 'val2'
assert api.option('val1.val2', 2).value.get() == 'val'
def test_callback_leader_and_followers():
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_val)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
def test_callback_leader_and_followers_follower_cal():
val3 = StrOption('val3', "", multi=True)
val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val3)))
val2 = StrOption('val2', "", multi=True, callback=return_val)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1, val3])
api = Config(maconfig)
api.property.read_write()
#
assert api.option('val3').value.get() == []
assert api.option('val1.val1').value.get() == []
#
api.option('val1.val1').value.set(['val1'])
api.option('val3').value.set(['val1'])
assert api.option('val1.val1').value.get() == ['val1']
assert api.option('val1.val2', 0).value.get() == 'val'
#
api.option('val1.val1').value.reset()
api.option('val1.val2', 0).value.set('val')
#
api.option('val3').value.set(['val1', 'val2'])
assert api.option('val1.val2', 0).value.get() == 'val'
assert api.option('val1.val2', 1).value.get() == 'val'
assert api.option('val1.val1').value.get() == ['val1', 'val2']
# len of follower is higher than leader's one
api.option('val1.val2', 0).value.set('val1')
api.option('val1.val2', 1).value.set('val2')
api.option('val3').value.set(['val1'])
assert api.option('val1.val1').value.get() == ['val1']
raises(LeadershipError, "api.option('val1.val2', 0).value.get()")
#
api.option('val3').value.set(['val1', 'val2', 'val3'])
assert api.option('val1.val2', 0).value.get() == 'val1'
assert api.option('val1.val2', 1).value.get() == 'val2'
assert api.option('val1.val2', 2).value.get() == 'val'
def test_callback_leader_and_followers_leader_disabled():
#properties must be transitive
val1 = StrOption('val1', "", ['val1'], multi=True, properties=('disabled',))
val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
raises(PropertiesOptionError, "api.option('val1.val1').value.get()")
raises(PropertiesOptionError, "api.option('val1.val1').value.set(['yes'])")
raises(PropertiesOptionError, "api.option('val1.val2', 0).value.get()")
def test_callback_leader_and_followers_leader_callback_disabled():
val0 = StrOption('val0', "", multi=True, properties=('disabled',))
val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val0)))
val2 = StrOption('val2', "", multi=True)
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1, val0])
api = Config(maconfig)
api.property.read_write()
raises(ConfigError, "api.option('val1.val1').value.get()")
raises(ConfigError, "api.option('val1.val2').value.get()")
api.property.pop('disabled')
api.option('val1.val1').value.set([])
api.property.add('disabled')
assert api.option('val1.val1').value.get() == []
def test_callback_leader_and_followers_follower_disabled():
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, properties=('disabled',))
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1.val1').value.get() == []
#raises(PropertiesOptionError, "api.option('val1.val2').value.get()")
api.option('val1.val1').value.set(['yes'])
assert api.option('val1.val1').value.get() == ['yes']
api.property.pop('disabled')
assert api.option('val1.val2', 0).value.get() == None
api.option('val1.val2', 0).value.set('no')
api.option('val1.val1').value.set(['yes', 'yes2', 'yes3'])
api.option('val1.val2', 2).value.set('no1')
assert api.option('val1.val2', 0).value.get() == 'no'
assert api.option('val1.val2', 1).value.get() == None
assert api.option('val1.val2', 2).value.get() == 'no1'
api.property.add('disabled')
api.option('val1.val1').value.pop(0)
assert api.option('val1.val1').value.get() == ['yes2', 'yes3']
api.property.pop('disabled')
assert api.option('val1.val2', 0).value.get() == None
assert api.option('val1.val2', 1).value.get() == 'no1'
def test_callback_leader_and_followers_follower_callback_disabled():
val0 = StrOption('val0', "", multi=True, properties=('disabled',))
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val0)))
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1, val0])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1.val1').value.get() == []
api.option('val1.val1').value.set(['yes'])
assert api.option('val1.val1').value.get() == ['yes']
api.property.pop('disabled')
api.option('val1.val2', 0).value.set('no')
api.option('val1.val1').value.set(['yes', 'yes1'])
assert api.option('val1.val2', 0).value.get() == 'no'
api.property.add('disabled')
api.option('val1.val1').value.pop(1)
def test_callback_leader_and_followers_value():
val4 = StrOption('val4', '', multi=True, default=['val10', 'val11'])
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val1)))
val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params=Params(ParamValue('yes')))
val5 = StrOption('val5', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val4)))
val6 = StrOption('val6', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val5)))
interface1 = Leadership('val1', '', [val1, val2, val3, val5, val6])
maconfig = OptionDescription('rootconfig', '', [interface1, val4])
api = Config(maconfig)
api.property.read_write()
api.option('val4').value.get() == ['val10', 'val11']
assert api.option('val1.val1').value.get() == []
#raises(LeadershipError, "cfg.val1.val1")
#raises(LeadershipError, "cfg.val1.val2")
#raises(LeadershipError, "cfg.val1.val3")
#raises(LeadershipError, "cfg.val1.val5")
#raises(LeadershipError, "cfg.val1.val6")
#
#default calculation has greater length
#raises(LeadershipError, "api.option('val1.val1').value.set(['val1']")
#
api.option('val1.val1').value.set(['val1', 'val2'])
assert api.option('val1.val1').value.get() == ['val1', 'val2']
assert api.option('val1.val2', 0).value.get() == 'val1'
assert api.option('val1.val2', 1).value.get() == 'val2'
assert api.option('val1.val3', 0).value.get() == 'yes'
assert api.option('val1.val3', 1).value.get() == 'yes'
raises(LeadershipError, "api.option('val1.val5', 0).value.get()")
raises(LeadershipError, "api.option('val1.val5', 1).value.get()")
raises(LeadershipError, "api.option('val1.val6', 0).value.get()")
raises(LeadershipError, "api.option('val1.val6', 1).value.get()")
#
api.option('val1.val1').value.set(['val1', 'val2', 'val3'])
assert api.option('val1.val1').value.get() == ['val1', 'val2', 'val3']
assert api.option('val1.val2', 0).value.get() == 'val1'
assert api.option('val1.val2', 1).value.get() == 'val2'
assert api.option('val1.val2', 2).value.get() == 'val3'
assert api.option('val1.val3', 0).value.get() == 'yes'
assert api.option('val1.val3', 1).value.get() == 'yes'
assert api.option('val1.val3', 2).value.get() == 'yes'
raises(LeadershipError, "api.option('val1.val5', 2).value.get()")
raises(LeadershipError, "api.option('val1.val6', 2).value.get()")
#
api.option('val1.val1').value.pop(2)
assert api.option('val1.val1').value.get() == ['val1', 'val2']
assert api.option('val1.val2', 0).value.get() == 'val1'
assert api.option('val1.val2', 1).value.get() == 'val2'
assert api.option('val1.val3', 0).value.get() == 'yes'
assert api.option('val1.val3', 1).value.get() == 'yes'
#
api.option('val1.val2', 0).value.set('val2')
api.option('val1.val2', 1).value.set('val2')
api.option('val1.val3', 0).value.set('val2')
api.option('val1.val3', 1).value.set('val2')
api.option('val1.val5', 0).value.set('val2')
api.option('val1.val5', 1).value.set('val2')
assert api.option('val1.val2', 0).value.get() == 'val2'
assert api.option('val1.val2', 1).value.get() == 'val2'
assert api.option('val1.val3', 0).value.get() == 'val2'
assert api.option('val1.val3', 1).value.get() == 'val2'
assert api.option('val1.val5', 0).value.get() == 'val2'
assert api.option('val1.val5', 1).value.get() == 'val2'
assert api.option('val1.val6', 0).value.get() == 'val2'
assert api.option('val1.val6', 1).value.get() == 'val2'
#
api.option('val1.val1').value.set(['val1', 'val2', 'val3'])
assert api.option('val1.val2', 2).value.get() == 'val3'
assert api.option('val1.val3', 2).value.get() == 'yes'
def test_callback_leader():
val2 = StrOption('val2', "", multi=True, callback=return_value)
val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val2)))
raises(ValueError, "Leadership('val1', '', [val1, val2])")
def test_callback_different_type():
val = IntOption('val', "", default=2)
val_ = IntOption('val_', "", default=3)
val1 = IntOption('val1', "", multi=True)
val2 = IntOption('val2', "", multi=True, callback=return_calc, callback_params=Params((ParamOption(val), ParamOption(val1)), {'k': ParamOption(val_)}))
interface1 = Leadership('val1', '', [val1, val2])
maconfig = OptionDescription('rootconfig', '', [interface1, val, val_])
api = Config(maconfig)
api.property.read_write()
assert api.option('val1.val1').value.get() == []
api.option('val1.val1').value.set([1])
assert api.option('val1.val1').value.get() == [1]
assert api.option('val1.val2', 0).value.get() == 6
api.option('val1.val1').value.set([1, 3])
assert api.option('val1.val1').value.get() == [1, 3]
assert api.option('val1.val2', 0).value.get() == 6
assert api.option('val1.val2', 1).value.get() == 8
api.option('val1.val1').value.set([1, 3, 5])
assert api.option('val1.val1').value.get() == [1, 3, 5]
assert api.option('val1.val2', 0).value.get() == 6
assert api.option('val1.val2', 1).value.get() == 8
assert api.option('val1.val2', 2).value.get() == 10
def test_callback_hidden():
opt1 = BoolOption('opt1', '')
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)))
od1 = OptionDescription('od1', '', [opt1], properties=('hidden',))
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_write()
raises(PropertiesOptionError, "api.option('od1.opt1').value.get()")
# do not raise, forcepermissive
api.option('od2.opt2').value.get()
def test_callback_hidden_permissive():
opt1 = BoolOption('opt1', '')
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)))
od1 = OptionDescription('od1', '', [opt1], properties=('hidden',))
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.permissive.set(frozenset(['hidden']))
api.property.read_write()
raises(PropertiesOptionError, "api.option('od1.opt1').value.get()")
api.option('od2.opt2').value.get()
def test_callback_hidden_permissive_callback():
opt1 = BoolOption('opt1', '')
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1, True)))
od1 = OptionDescription('od1', '', [opt1], properties=('hidden',))
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_write()
raises(PropertiesOptionError, "api.option('od1.opt1').value.get()")
api.option('od2.opt2').value.get()
def test_callback_two_disabled():
opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('disabled',))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_write()
raises(PropertiesOptionError, "api.option('od2.opt2').value.get()")
def test_callback_two_disabled2():
opt1 = BoolOption('opt1', '', properties=('hidden',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('hidden',))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_write()
api.permissive.set(frozenset(['hidden']))
raises(PropertiesOptionError, "api.option('od2.opt2').value.get()")
assert api.forcepermissive.option('od2.opt2').owner.isdefault()
def test_callback_calculating_invalid():
opt1 = IntOption('opt1', '', 1)
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_write()
raises(ValueError, "api.option('od2.opt2').value.get()")
api.unrestraint.option('od2.opt2').property.add('disabled')
raises(PropertiesOptionError, "api.option('od2.opt2').value.get()")
def test_callback_calculating_disabled():
opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_write()
raises(ConfigError, "api.option('od2.opt2').value.get()")
def test_callback_calculating_mandatory():
opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('mandatory',))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_only()
raises(ConfigError, "api.option('od2.opt2').value.get()")
def test_callback_calculating_mandatory_multi():
opt1 = BoolOption('opt1', '', multi=True, properties=('disabled',))
opt2 = BoolOption('opt2', '', multi=True, callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('mandatory',))
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_only()
raises(ConfigError, "api.option('od2.opt2').value.get()")
def test_callback_two_disabled_multi():
opt1 = BoolOption('opt1', '', properties=('disabled',))
opt2 = BoolOption('opt2', '', callback=return_value, callback_params=Params(ParamOption(opt1)), properties=('disabled',), multi=True)
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_write()
raises(PropertiesOptionError, "api.option('od2.opt2').value.get()")
def test_callback_multi_list_params():
val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
val2 = StrOption('val2', "", multi=True, callback=return_list, callback_params=Params(ParamOption(val1)))
oval2 = OptionDescription('val2', '', [val2])
maconfig = OptionDescription('rootconfig', '', [val1, oval2])
api = Config(maconfig)
api.property.read_write()
assert api.option('val2.val2').value.get() == ['val', 'val']
def test_callback_multi_list_params_key():
val1 = StrOption('val1', "", multi=True, default=['val1', 'val2'])
val2 = StrOption('val2', "", multi=True, callback=return_list, callback_params=Params(kwargs={'value': ParamOption(val1)}))
oval2 = OptionDescription('val2', '', [val2])
maconfig = OptionDescription('rootconfig', '', [val1, oval2])
api = Config(maconfig)
api.property.read_write()
assert api.option('val2.val2').value.get() == ['val', 'val']
def test_leadership_callback_description():
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True, callback=return_value, callback_params=Params(ParamOption(st1)))
stm = Leadership('st1', '', [st1, st2])
st = OptionDescription('st', '', [stm])
od = OptionDescription('od', '', [st])
od2 = OptionDescription('od', '', [od])
api = Config(od2)
owner = api.owner.get()
assert api.option('od.st.st1.st1').value.get() == []
assert api.option('od.st.st1.st1').owner.isdefault()
##
api.option('od.st.st1.st1').value.set(['yes'])
api.option('od.st.st1.st2', 0).value.set('yes')
assert api.option('od.st.st1.st1').owner.get() == owner
assert api.option('od.st.st1.st2', 0).owner.get() == owner
def test_callback_raise():
opt1 = BoolOption('opt1', 'Option 1', callback=return_raise)
opt2 = BoolOption('opt2', 'Option 2', callback=return_valueerror)
od1 = OptionDescription('od1', '', [opt1])
od2 = OptionDescription('od2', '', [opt2])
maconfig = OptionDescription('rootconfig', '', [od1, od2])
api = Config(maconfig)
api.property.read_write()
try:
api.option('od1.opt1').value.get()
except ConfigError as err:
assert '"Option 1"' in str(err)
try:
api.option('od2.opt2').value.get()
except ConfigError as err:
assert '"Option 2"' in str(err)

View File

@ -1,216 +0,0 @@
"test all types of option default values for options, add new option in a descr"
from .autopath import do_autopath
do_autopath()
from py.test import raises
from tiramisu.setting import owners
from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu import IntOption, FloatOption, StrOption, ChoiceOption, \
BoolOption, OptionDescription, Leadership, Config, undefined
from tiramisu.storage import list_sessions
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description():
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False)
objspaceoption = ChoiceOption('objspace', 'Object space',
['std', 'thunk'], 'std')
booloption = BoolOption('bool', 'Test boolean option', default=True)
intoption = IntOption('int', 'Test int option', default=0)
floatoption = FloatOption('float', 'Test float option', default=2.3)
stroption = StrOption('str', 'Test string option', default="abc")
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
wantref_option = BoolOption('wantref', 'Test requires', default=False,
requires=['boolop'])
wantframework_option = BoolOption('wantframework', 'Test requires',
default=False,
requires=['boolop'])
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
descr = OptionDescription('tiramisu', '', [gcgroup, booloption, objspaceoption,
wantref_option, stroption,
wantframework_option,
intoption, boolop])
return descr
#____________________________________________________________
# default values
def test_default_is_none():
"""
Most constructors take a ``default`` argument that specifies the default
value of the option. If this argument is not supplied the default value is
assumed to be ``None``.
"""
dummy1 = BoolOption('dummy1', 'doc dummy')
dummy2 = BoolOption('dummy2', 'doc dummy')
group = OptionDescription('group', '', [dummy1, dummy2])
api = Config(group)
# so when the default value is not set, there is actually a default value
assert api.option('dummy1').value.get() is None
assert api.option('dummy2').value.get() is None
def test_set_defaut_value_from_option_object():
"""Options have an available default setting and can give it back"""
b = BoolOption("boolean", "", default=False)
assert b.impl_getdefault() is False
def test_force_default_on_freeze():
"a frozen option wich is forced returns his default"
dummy1 = BoolOption('dummy1', 'doc dummy', default=False, properties=('force_default_on_freeze',))
dummy2 = BoolOption('dummy2', 'doc dummy', default=True)
group = OptionDescription('group', '', [dummy1, dummy2])
api = Config(group)
api.property.read_write()
owner = api.owner.get()
api.option('dummy1').value.set(True)
api.option('dummy2').value.set(False)
assert api.option('dummy1').owner.get() == owner
assert api.option('dummy2').owner.get() == owner
api.option('dummy1').property.add('frozen')
api.option('dummy2').property.add('frozen')
assert api.option('dummy1').value.get() is False
assert api.option('dummy2').value.get() is False
assert api.option('dummy1').owner.isdefault()
assert api.option('dummy2').owner.get() == owner
raises(PropertiesOptionError, "api.option('dummy2').owner.set('frozen')")
raises(PropertiesOptionError, "api.option('dummy1').value.reset()")
api.option('dummy1').property.pop('frozen')
api.option('dummy1').value.reset()
api.option('dummy1').property.add('frozen')
raises(PropertiesOptionError, "api.option('dummy2').owner.set('frozen')")
def test_force_default_on_freeze_multi():
dummy1 = BoolOption('dummy1', 'doc dummy', default=[False], properties=('force_default_on_freeze',), multi=True)
dummy2 = BoolOption('dummy2', 'doc dummy', default=[True], multi=True)
group = OptionDescription('group', '', [dummy1, dummy2])
api = Config(group)
api.property.read_write()
api.option('dummy1').value.set([undefined, True])
api.option('dummy2').value.set([undefined, False])
owner = api.owner.get()
assert api.option('dummy1').owner.get() == owner
assert api.option('dummy2').owner.get() == owner
api.option('dummy1').property.add('frozen')
api.option('dummy2').property.add('frozen')
assert api.option('dummy1').value.get() == [False]
assert api.option('dummy2').value.get() == [True, False]
assert api.option('dummy1').owner.isdefault()
assert api.option('dummy2').owner.get() == owner
raises(PropertiesOptionError, "api.option('dummy2').owner.set('owner')")
raises(PropertiesOptionError, "api.option('dummy2').value.reset()")
api.option('dummy1').property.pop('frozen')
api.option('dummy1').value.reset()
api.option('dummy1').property.add('frozen')
def test_force_default_on_freeze_leader():
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_default_on_freeze',))
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr])
raises(ConfigError, "Config(descr)")
def test_force_metaconfig_on_freeze_leader():
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_metaconfig_on_freeze',))
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr])
raises(ConfigError, "Config(descr)")
def test_force_default_on_freeze_leader_frozen():
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_default_on_freeze', 'frozen'))
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr])
api = Config(descr)
raises(ConfigError, "api.option('dummy1.dummy1').property.pop('frozen')")
def test_force_metaconfig_on_freeze_leader_frozen():
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_metaconfig_on_freeze', 'frozen'))
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr])
api = Config(descr)
raises(ConfigError, "api.option('dummy1.dummy1').property.pop('frozen')")
def test_force_default_on_freeze_follower():
dummy1 = BoolOption('dummy1', 'Test int option', multi=True)
dummy2 = BoolOption('dummy2', 'Test string option', multi=True, properties=('force_default_on_freeze',))
descr = Leadership("dummy1", "", [dummy1, dummy2])
descr = OptionDescription("root", "", [descr])
api = Config(descr)
api.property.read_write()
owners.addowner("frozenmultifollower2")
api.option('dummy1.dummy1').value.set([True])
api.option('dummy1.dummy2', 0).value.set(False)
assert api.option('dummy1.dummy1').value.get() == [True]
assert api.option('dummy1.dummy2', 0).value.get() == False
assert api.option('dummy1.dummy1').owner.get() == 'user'
assert api.option('dummy1.dummy2', 0).owner.get() == 'user'
#
api.option('dummy1.dummy2').property.add('frozen')
assert api.option('dummy1.dummy1').value.get() == [True]
assert api.option('dummy1.dummy2', 0).value.get() == None
assert api.option('dummy1.dummy1').owner.get() == 'user'
assert api.option('dummy1.dummy2', 0).owner.isdefault()
raises(PropertiesOptionError, "api.option('dummy1.dummy2', 0).owner.set('frozenmultifollower2')")
#
api.option('dummy1.dummy2').property.pop('frozen')
api.option('dummy1.dummy1').value.set([True, True])
api.option('dummy1.dummy2', 1).value.set(False)
assert api.option('dummy1.dummy1').value.get() == [True, True]
assert api.option('dummy1.dummy2', 0).value.get() == False
assert api.option('dummy1.dummy2', 1).value.get() == False
#
api.option('dummy1.dummy2').property.add('frozen')
assert api.option('dummy1.dummy1').value.get() == [True, True]
assert api.option('dummy1.dummy2', 0).value.get() == None
assert api.option('dummy1.dummy2', 1).value.get() == None
#
api.option('dummy1.dummy1').value.pop(1)
assert api.option('dummy1.dummy1').value.get() == [True]
assert api.option('dummy1.dummy2', 0).value.get() == None
#
api.option('dummy1.dummy2').property.pop('frozen')
assert api.option('dummy1.dummy1').value.get() == [True]
assert api.option('dummy1.dummy2', 0).value.get() == False
#
api.option('dummy1.dummy1').value.set([True, True])
assert api.option('dummy1.dummy2', 0).value.get() == False
assert api.option('dummy1.dummy2', 1).value.get() == None
def test_overrides_changes_option_value():
"with config.override(), the default is changed and the value is changed"
descr = OptionDescription("test", "", [
BoolOption("b", "", default=False)])
api = Config(descr)
api.option('b').value.set(True)
def test_choice_with_no_default():
descr = OptionDescription("test", "", [
ChoiceOption("backend", "", ("c", "cli"))])
api = Config(descr)
assert api.option('backend').value.get() is None
api.option('backend').value.set('c')
def test_choice_with_default():
descr = OptionDescription("test", "", [
ChoiceOption("backend", "", ("c", "cli"), default="cli")])
api = Config(descr)
assert api.option('backend').value.get() == 'cli'

View File

@ -1,184 +0,0 @@
from .autopath import do_autopath
do_autopath()
from py.test import raises
from tiramisu.setting import owners, groups
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription, SymLinkOption, Leadership, Config
from tiramisu.error import ConfigError, ConstError, PropertiesOptionError, APIError
from tiramisu.storage import list_sessions
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description():
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False)
objspaceoption = ChoiceOption('objspace', 'Object space',
['std', 'thunk'], 'std')
booloption = BoolOption('bool', 'Test boolean option', default=True)
intoption = IntOption('int', 'Test int option', default=0)
floatoption = FloatOption('float', 'Test float option', default=2.3)
stroption = StrOption('str', 'Test string option', default="abc")
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
wantref_option = BoolOption('wantref', 'Test requires', default=False)
wantframework_option = BoolOption('wantframework', 'Test requires',
default=False)
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
descr = OptionDescription('tiram', '', [gcgroup, booloption, objspaceoption,
wantref_option, stroption,
wantframework_option,
intoption, boolop])
return descr
def test_default_owner():
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
api.option('dummy').value.set(True)
owner = api.owner.get()
assert api.option('dummy').owner.get() == owner
def test_hidden_owner():
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=('hidden',))
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
api.property.read_write()
#raises(PropertiesOptionError, "api.forcepermissive.option('dummy').owner.get()")
#raises(PropertiesOptionError, "api.option('dummy').owner.isdefault()")
#raises(PropertiesOptionError, "api.forcepermissive.option('dummy').owner.isdefault()")
api.permissive.set(frozenset(['hidden']))
api.forcepermissive.option('dummy').value.get()
api.forcepermissive.option('dummy').owner.isdefault()
def test_addowner():
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
assert api.option('dummy').owner.isdefault()
api.owner.set('gen_config')
api.option('dummy').value.set(True)
assert api.option('dummy').owner.get() == owners.gen_config
assert not api.option('dummy').owner.isdefault()
def test_addowner_multiple_time():
owners.addowner("testowner2")
raises(ConstError, 'owners.addowner("testowner2")')
def test_delete_owner():
owners.addowner('deleted2')
raises(ConstError, 'del(owners.deleted2)')
def test_owner_is_not_a_string():
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == owners.default
assert api.option('dummy').owner.get() == 'default'
assert isinstance(api.option('dummy').owner.get(), owners.Owner)
api.option('dummy').value.set(True)
assert api.option('dummy').owner.get() == 'user'
def test_setowner_without_valid_owner():
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
def test_setowner_for_value():
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
owners.addowner("new2")
raises(ConfigError, "api.option('dummy').owner.set('new2')")
api.option('dummy').value.set(False)
assert api.option('dummy').owner.get() == owners.user
api.option('dummy').owner.set('new2')
assert api.option('dummy').owner.get() == owners.new2
def test_setowner_forbidden():
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
raises(ValueError, "api.owner.set('default')")
api.option('dummy').value.set(False)
raises(ValueError, "api.option('dummy').owner.set('default')")
def test_setowner_read_only():
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
api = Config(descr)
api.property.read_write()
assert api.option('dummy').value.get() is False
assert api.option('dummy').owner.get() == 'default'
owners.addowner("readonly2")
api.option('dummy').value.set(False)
assert api.option('dummy').owner.get() == owners.user
api.property.read_only()
raises(PropertiesOptionError,
"api.option('dummy').owner.set('readonly2')")
assert api.option('dummy').owner.get() == owners.user
def test_setowner_optiondescription():
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr1 = OptionDescription('tiramisu', '', [gcdummy])
descr = OptionDescription('tiramisu', '', [descr1])
api = Config(descr)
raises(APIError, "api.option('tiramisu').owner.get()")
raises(APIError, "api.option('tiramisu').owner.set('user')")
def test_setowner_symlinkoption():
gcdummy = BoolOption('dummy', 'dummy', default=False)
s = SymLinkOption('symdummy', gcdummy)
descr1 = OptionDescription('tiramisu', '', [gcdummy, s])
descr = OptionDescription('tiramisu', '', [descr1])
api = Config(descr)
assert api.option('tiramisu.symdummy').owner.isdefault()
api.option('tiramisu.dummy').value.set(True)
assert not api.option('tiramisu.symdummy').owner.isdefault()
raises(ConfigError, "api.option('tiramisu.symdummy').owner.set('user')")
def test_owner_leadership():
b = IntOption('int', 'Test int option', default=[0], multi=True)
c = StrOption('str', 'Test string option', multi=True)
descr = Leadership("int", "", [b, c])
od = OptionDescription('od', '', [descr])
api = Config(od)
raises(ConfigError, "api.option('int.str', 0).owner.set('user')")
api.option('int.int').value.set([0, 1])
api.option('int.str', 0).value.set('yes')
assert not api.option('int.str', 0).owner.isdefault()
assert api.option('int.str', 1).owner.isdefault()
api.option('int.str', 0).owner.set('user')
assert api.option('int.str', 0).owner.get() == owners.user
assert api.option('int.str', 1).owner.isdefault()
assert api.option('int.str', 0).value.get() == 'yes'
assert api.option('int.str', 1).value.get() == None

View File

@ -1,139 +0,0 @@
# coding: utf-8
"frozen and hidden values"
from .autopath import do_autopath
do_autopath()
from py.test import raises
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
PasswordOption, StrOption, DateOption, OptionDescription, Config
from tiramisu.error import PropertiesOptionError
from tiramisu.storage import list_sessions
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=(('hidden'),))
objspaceoption = ChoiceOption('objspace', 'Object space',
('std', 'thunk'), ['std'], multi=True)
booloption = BoolOption('bool', 'Test boolean option', default=True)
intoption = IntOption('int', 'Test int option', default=0)
floatoption = FloatOption('float', 'Test float option', default=2.3)
stroption = StrOption('str', 'Test string option', default="abc")
wantref_option = BoolOption('wantref', 'Test requires', default=False,
requires=({'option': gcoption, 'expected': 'ref', 'action': 'hidden'},))
wantframework_option = BoolOption('wantframework', 'Test requires',
default=False,
requires=({'option': gcoption, 'expected': 'framework', 'action': 'hidden'},))
# ____________________________________________________________
booloptiontwo = BoolOption('booltwo', 'Test boolean option two', default=False)
subgroup = OptionDescription('subgroup', '', [booloptiontwo])
# ____________________________________________________________
gcgroup = OptionDescription('gc', '', [subgroup, gcoption, gcdummy, floatoption])
descr = OptionDescription('trs', '', [gcgroup, booloption, objspaceoption,
wantref_option, stroption,
wantframework_option,
intoption])
return descr
# ____________________________________________________________
def test_is_hidden():
descr = make_description()
api = Config(descr)
api.property.read_write()
assert not 'frozen' in api.forcepermissive.option('gc.dummy').property.get()
# setattr
raises(PropertiesOptionError, "api.option('gc.dummy').value.get() == False")
# getattr
raises(PropertiesOptionError, "api.option('gc.dummy').value.get()")
def test_group_is_hidden():
descr = make_description()
api = Config(descr)
api.property.read_write()
api.option('gc').property.add('hidden')
raises(PropertiesOptionError, "api.option('gc.dummy').value.get()")
assert 'hidden' in api.forcepermissive.option('gc').property.get()
raises(PropertiesOptionError, "api.option('gc.float').value.get()")
# manually set the subconfigs to "show"
api.forcepermissive.option('gc').property.pop('hidden')
assert not 'hidden' in api.option('gc').property.get()
assert api.option('gc.float').value.get() == 2.3
#dummy est en hide
prop = []
try:
api.option('gc.dummy').value.set(False)
except PropertiesOptionError as err:
prop = err.proptype
assert 'hidden' in prop
def test_group_is_hidden_multi():
descr = make_description()
api = Config(descr)
api.property.read_write()
api.option('objspace').property.add('hidden')
raises(PropertiesOptionError, "api.option('objspace').value.get()")
assert 'hidden' in api.forcepermissive.option('objspace').property.get()
prop = []
try:
api.option('objspace').value.set(['std'])
except PropertiesOptionError as err:
prop = err.proptype
assert 'hidden' in prop
api.forcepermissive.option('objspace').property.pop('hidden')
assert not 'hidden' in api.option('objspace').property.get()
api.option('objspace').value.set(['std', 'std'])
def test_global_show():
descr = make_description()
api = Config(descr)
api.property.read_write()
api.forcepermissive.option('gc.dummy').property.add('hidden')
assert 'hidden' in api.forcepermissive.option('gc.dummy').property.get()
raises(PropertiesOptionError, "api.option('gc.dummy').value.get() == False")
def test_with_many_subgroups():
descr = make_description()
api = Config(descr)
#booltwo = config.unwrap_from_path('gc.subgroup.booltwo')
#setting = config.cfgimpl_get_settings()
assert not 'hidden' in api.option('gc.subgroup.booltwo').property.get()
assert api.option('gc.subgroup.booltwo').value.get() is False
api.option('gc.subgroup.booltwo').property.add('hidden')
def test_password_option():
o = PasswordOption('o', '')
d = OptionDescription('d', '', [o])
api = Config(d)
api.option('o').value.set('a_valid_password')
raises(ValueError, "api.option('o').value.set(1)")
def test_date_option():
o = DateOption('o', '')
d = OptionDescription('d', '', [o])
api = Config(d)
api.option('o').value.set('2017-02-04')
api.option('o').value.set('2017-2-4')
raises(ValueError, "api.option('o').value.set(1)")
raises(ValueError, "api.option('o').value.set('2017-13-20')")
raises(ValueError, "api.option('o').value.set('2017-11-31')")
raises(ValueError, "api.option('o').value.set('2017-12-32')")
raises(ValueError, "api.option('o').value.set('2017-2-29')")
raises(ValueError, "api.option('o').value.set('2-2-2017')")
raises(ValueError, "api.option('o').value.set('2017/2/2')")

View File

@ -1,379 +0,0 @@
# coding: utf-8
from .autopath import do_autopath
do_autopath()
from py.test import raises
from tiramisu import IntOption, UnicodeOption, OptionDescription, Config
from tiramisu.error import PropertiesOptionError, ConfigError
from tiramisu.api import TIRAMISU_VERSION
from tiramisu.storage import list_sessions, delete_session
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def make_description():
u1 = IntOption('u1', '', properties=('frozen', 'mandatory', 'disabled', ))
u2 = IntOption('u2', '', properties=('frozen', 'mandatory', 'disabled', ))
return OptionDescription('od1', '', [u1, u2])
def test_permissive():
descr = make_description()
api = Config(descr)
api.property.read_write()
api.property.read_write()
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.unrestraint.permissive.set(frozenset(['disabled']))
assert api.unrestraint.permissive.get() == frozenset(['disabled'])
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.property.add('permissive')
api.option('u1').value.get()
api.property.pop('permissive')
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
def test_permissive_add():
descr = make_description()
api = Config(descr)
api.property.read_write()
api.property.read_write()
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.unrestraint.permissive.add('disabled')
assert api.unrestraint.permissive.get() == frozenset(['hidden', 'disabled'])
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.property.add('permissive')
api.option('u1').value.get()
api.property.pop('permissive')
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
def test_permissive_pop():
descr = make_description()
api = Config(descr)
api.property.read_write()
api.property.read_write()
props = frozenset()
try:
api.forcepermissive.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.unrestraint.permissive.add('disabled')
assert api.unrestraint.permissive.get() == frozenset(['hidden', 'disabled'])
api.forcepermissive.option('u1').value.get()
api.unrestraint.permissive.pop('disabled')
props = frozenset()
try:
api.forcepermissive.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
def test_permissive_reset():
descr = make_description()
api = Config(descr)
api.property.read_write()
assert api.unrestraint.permissive.get() == frozenset(['hidden'])
#
api.unrestraint.permissive.set(frozenset(['disabled']))
assert api.unrestraint.permissive.get() == frozenset(['disabled'])
#
api.unrestraint.permissive.reset()
assert api.unrestraint.permissive.get() == frozenset()
def test_permissive_mandatory():
descr = make_description()
api = Config(descr)
api.property.read_only()
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
if TIRAMISU_VERSION == 2:
assert frozenset(props) == frozenset(['disabled', 'mandatory'])
else:
assert frozenset(props) == frozenset(['disabled'])
api.unrestraint.permissive.set(frozenset(['mandatory', 'disabled']))
assert api.unrestraint.permissive.get() == frozenset(['mandatory', 'disabled'])
api.property.add('permissive')
api.option('u1').value.get()
api.property.pop('permissive')
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
if TIRAMISU_VERSION == 2:
assert frozenset(props) == frozenset(['disabled', 'mandatory'])
else:
assert frozenset(props) == frozenset(['disabled'])
def test_permissive_frozen():
descr = make_description()
api = Config(descr)
api.property.read_write()
api.unrestraint.permissive.set(frozenset(['frozen', 'disabled']))
assert api.unrestraint.permissive.get() == frozenset(['frozen', 'disabled'])
assert api.permissive.get() == frozenset(['frozen', 'disabled'])
try:
api.option('u1').value.set(1)
except PropertiesOptionError as err:
props = err.proptype
if TIRAMISU_VERSION == 2:
assert frozenset(props) == frozenset(['disabled', 'frozen'])
else:
assert frozenset(props) == frozenset(['disabled'])
api.property.add('permissive')
api.option('u1').value.set(1)
assert api.option('u1').value.get() == 1
api.property.pop('permissive')
try:
api.option('u1').value.set(1)
except PropertiesOptionError as err:
props = err.proptype
if TIRAMISU_VERSION == 2:
assert frozenset(props) == frozenset(['disabled', 'frozen'])
else:
assert frozenset(props) == frozenset(['disabled'])
def test_invalid_permissive():
descr = make_description()
api = Config(descr)
api.property.read_write()
raises(TypeError, "api.unrestraint.permissive.set(['frozen', 'disabled'])")
def test_forbidden_permissive():
descr = make_description()
api = Config(descr)
api.property.read_write()
raises(ConfigError, "api.permissive.set(frozenset(['force_default_on_freeze']))")
raises(ConfigError, "api.permissive.set(frozenset(['force_metaconfig_on_freeze']))")
def test_permissive_option():
descr = make_description()
api = Config(descr)
api.property.read_write()
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
props = frozenset()
try:
api.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.unrestraint.option('u1').permissive.set(frozenset(['disabled']))
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset()
props = frozenset()
try:
api.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.property.add('permissive')
api.option('u1').value.get()
props = frozenset()
try:
api.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.property.pop('permissive')
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset()
props = frozenset()
try:
api.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
def test_permissive_option_cache():
descr = make_description()
api = Config(descr)
api.property.read_write()
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
props = frozenset()
try:
api.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.unrestraint.option('u1').permissive.set(frozenset(['disabled']))
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset()
props = frozenset()
try:
api.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.property.add('permissive')
api.option('u1').value.get()
props = frozenset()
try:
api.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
api.property.pop('permissive')
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset()
props = frozenset()
try:
api.option('u2').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled'}
def test_permissive_option_mandatory():
descr = make_description()
api = Config(descr)
api.property.read_only()
props = frozenset()
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
if TIRAMISU_VERSION == 2:
assert frozenset(props) == frozenset(['disabled', 'mandatory'])
else:
assert frozenset(props) == frozenset(['disabled'])
api.unrestraint.option('u1').permissive.set(frozenset(['mandatory', 'disabled']))
assert api.unrestraint.option('u1').permissive.get() == frozenset(['mandatory', 'disabled'])
api.property.add('permissive')
api.option('u1').value.get()
api.property.pop('permissive')
try:
api.option('u1').value.get()
except PropertiesOptionError as err:
props = err.proptype
if TIRAMISU_VERSION == 2:
assert frozenset(props) == frozenset(['disabled', 'mandatory'])
else:
assert frozenset(props) == frozenset(['disabled'])
def test_permissive_option_frozen():
descr = make_description()
api = Config(descr)
api.property.read_write()
api.unrestraint.option('u1').permissive.set(frozenset(['frozen', 'disabled']))
api.option('u1').value.set(1)
assert api.option('u1').value.get() == 1
api.property.add('permissive')
assert api.option('u1').value.get() == 1
api.property.pop('permissive')
assert api.option('u1').value.get() == 1
if TIRAMISU_VERSION == 3:
def test_invalid_option_permissive():
descr = make_description()
api = Config(descr)
api.property.read_write()
raises(TypeError, "api.unrestraint.option('u1').permissive.set(['frozen', 'disabled'])")
def test_remove_option_permissive():
var1 = UnicodeOption('var1', '', u'value', properties=('hidden',))
od1 = OptionDescription('od1', '', [var1])
rootod = OptionDescription('rootod', '', [od1])
api = Config(rootod)
api.property.read_write()
raises(PropertiesOptionError, "api.option('od1.var1').value.get()")
api.forcepermissive.option('od1.var1').permissive.set(frozenset(['hidden']))
assert api.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden'])
assert api.option('od1.var1').value.get() == 'value'
api.forcepermissive.option('od1.var1').permissive.set(frozenset())
assert api.forcepermissive.option('od1.var1').permissive.get() == frozenset()
raises(PropertiesOptionError, "api.option('od1.var1').value.get()")
def test_reset_option_permissive():
var1 = UnicodeOption('var1', '', u'value', properties=('hidden',))
od1 = OptionDescription('od1', '', [var1])
rootod = OptionDescription('rootod', '', [od1])
api = Config(rootod)
api.property.read_write()
raises(PropertiesOptionError, "api.option('od1.var1').value.get()")
api.forcepermissive.option('od1.var1').permissive.set(frozenset(['hidden']))
assert api.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden'])
assert api.option('od1.var1').value.get() == 'value'
api.forcepermissive.option('od1.var1').permissive.reset()
assert api.forcepermissive.option('od1.var1').permissive.get() == frozenset()
raises(PropertiesOptionError, "api.option('od1.var1').value.get()")

View File

@ -1,1125 +0,0 @@
# coding: utf-8
from .autopath import do_autopath
do_autopath()
from copy import copy
from tiramisu.i18n import _
from tiramisu.setting import groups
from tiramisu import setting
setting.expires_time = 1
from tiramisu import IPOption, OptionDescription, BoolOption, IntOption, StrOption, \
Leadership, Config
from tiramisu.error import PropertiesOptionError, RequirementError
from py.test import raises
from tiramisu.storage import list_sessions, delete_session
def teardown_function(function):
assert list_sessions() == [], 'session list is not empty when leaving "{}"'.format(function.__name__)
def test_properties():
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '', properties=('disabled',))
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.unrestraint.option('ip_address_service').property.pop('disabled')
api.option('ip_address_service').value.get()
api.unrestraint.option('ip_address_service').property.add('disabled')
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
# pop twice
api.unrestraint.option('ip_address_service').property.pop('disabled')
api.unrestraint.option('ip_address_service').property.pop('disabled')
def test_requires():
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
assert not api.option('activate_service').option.requires()
assert api.option('ip_address_service').option.requires()
api.option('ip_address_service').value.get()
api.option('activate_service').value.set(False)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(True)
api.option('ip_address_service').value.get()
def test_requires_inverse():
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled', 'inverse': True}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(False)
api.option('ip_address_service').value.get()
api.option('activate_service').value.set(True)
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_self():
a = StrOption('ip_address_service', '',
requires=[{'option': 'self', 'expected': 'b', 'action': 'disabled'}])
od = OptionDescription('service', '', [a])
api = Config(od)
api.property.read_write()
assert api.option('ip_address_service').value.get() == None
api.option('ip_address_service').value.set('a')
assert api.option('ip_address_service').value.get() == 'a'
api.option('ip_address_service').value.set('b')
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_with_requires():
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
api.option('ip_address_service').property.add('test')
api.option('ip_address_service').value.get()
api.option('activate_service').value.set(False)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(True)
api.option('ip_address_service').value.get()
def test_requires_invalid():
a = BoolOption('activate_service', '', True)
a
raises(ValueError, "IPOption('ip_address_service', '', requires='string')")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False, 'action': 'disabled', 'unknown': True}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'action': 'disabled'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'expected': False, 'action': 'disabled'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False, 'action': 'disabled', 'inverse': 'string'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False, 'action': 'disabled', 'transitive': 'string'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False, 'action': 'disabled', 'same_action': 'string'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': 'string', 'expected': False, 'action': 'disabled'}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': 'string', 'action': 'disabled'}])")
def test_requires_same_action():
activate_service = BoolOption('activate_service', '', True)
activate_service_web = BoolOption('activate_service_web', '', True,
requires=[{'option': activate_service, 'expected': False,
'action': 'new'}])
ip_address_service_web = IPOption('ip_address_service_web', '',
requires=[{'option': activate_service_web, 'expected': False,
'action': 'disabled', 'inverse': False,
'transitive': True, 'same_action': False}])
od1 = OptionDescription('service', '', [activate_service, activate_service_web, ip_address_service_web])
api = Config(od1)
api.property.read_write()
api.property.add('new')
api.option('activate_service').value.get()
api.option('activate_service_web').value.get()
api.option('ip_address_service_web').value.get()
api.option('activate_service').value.set(False)
#
props = []
try:
api.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['new'])
#
props = []
try:
api.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
submsg = '"disabled" (' + _('the value of "{0}" is {1}').format('activate_service', '"False"') + ')'
assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', 'property', submsg))
#access to cache
assert str(err) == str(_('cannot access to {0} "{1}" because has {2} {3}').format('option', 'ip_address_service_web', 'property', submsg))
assert frozenset(props) == frozenset(['disabled'])
def test_multiple_requires():
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled'},
{'option': a, 'expected': 'ok', 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
api.option('ip_address_service').value.get()
api.option('activate_service').value.set('yes')
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set('ok')
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set('no')
api.option('ip_address_service').value.get()
def test_multiple_requires_cumulative():
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled'},
{'option': a, 'expected': 'yes', 'action': 'hidden'}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
api.option('ip_address_service').value.get()
api.option('activate_service').value.set('yes')
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == set(['hidden', 'disabled'])
api.option('activate_service').value.set('ok')
api.option('ip_address_service').value.get()
api.option('activate_service').value.set('no')
api.option('ip_address_service').value.get()
def test_multiple_requires_cumulative_inverse():
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled', 'inverse': True},
{'option': a, 'expected': 'yes', 'action': 'hidden', 'inverse': True}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == set(['hidden', 'disabled'])
api.option('activate_service').value.set('yes')
api.option('ip_address_service').value.get()
api.option('activate_service').value.set('ok')
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == set(['hidden', 'disabled'])
api.option('activate_service').value.set('no')
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == set(['hidden', 'disabled'])
def test_multiple_requires_inverse():
a = StrOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': 'yes', 'action': 'disabled', 'inverse': True},
{'option': a, 'expected': 'ok', 'action': 'disabled', 'inverse': True}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set('yes')
api.option('ip_address_service').value.get()
api.option('activate_service').value.set('ok')
api.option('ip_address_service').value.get()
api.option('activate_service').value.set('no')
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
api = Config(od)
api.property.read_write()
api.option('activate_service').value.get()
api.option('activate_service_web').value.get()
api.option('ip_address_service_web').value.get()
api.option('activate_service').value.set(False)
#
props = []
try:
api.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
#
props = []
try:
api.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_unrestraint():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
api = Config(od)
api.property.read_write()
api.option('activate_service').value.get()
api.option('activate_service_web').value.get()
api.option('ip_address_service_web').value.get()
api.option('activate_service').value.set(False)
#
assert api.unrestraint.option('activate_service_web').property.get() == {'disabled'}
assert api.unrestraint.option('ip_address_service_web').property.get() == {'disabled'}
def test_requires_transitive_owner():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
api = Config(od)
api.property.read_write()
api.option('activate_service').value.get()
api.option('activate_service_web').value.get()
api.option('ip_address_service_web').value.get()
#no more default value
api.option('ip_address_service_web').value.set('1.1.1.1')
api.option('activate_service').value.set(False)
props = []
try:
api.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_bis():
a = BoolOption('activate_service', '', True)
abis = BoolOption('activate_service_bis', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': True, 'action': 'disabled', 'inverse': True}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
od = OptionDescription('service', '', [a, abis, b, d])
api = Config(od)
api.property.read_write()
#
api.option('activate_service_web').value.get()
api.option('ip_address_service_web').value.get()
api.option('activate_service').value.set(False)
#
props = []
try:
api.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
#
props = []
try:
api.option('ip_address_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_transitive_hidden_permissive():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'hidden'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
api = Config(od)
api.property.read_write()
api.option('activate_service').value.get()
api.option('ip_address_service_web').value.get()
api.option('ip_address_service_web').value.get()
api.option('activate_service').value.set(False)
#
api.option('ip_address_service_web').value.get()
def test_requires_transitive_hidden_disabled():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'hidden'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, d])
api = Config(od)
api.property.read_write()
api.option('activate_service').value.get()
api.option('activate_service_web').value.get()
api.option('ip_address_service_web').value.get()
api.option('activate_service').value.set(False)
#
props = []
try:
api.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['hidden'])
api.option('ip_address_service_web').value.get()
def test_requires_transitive_hidden_disabled_multiple():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'hidden'},
{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False, 'action': 'mandatory'}])
od = OptionDescription('service', '', [a, b, d])
api = Config(od)
api.property.read_write()
api.option('activate_service').value.get()
api.option('activate_service_web').value.get()
api.option('ip_address_service_web').value.get()
api.option('activate_service').value.set(False)
#
props = []
try:
api.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert set(props) == {'disabled', 'hidden'}
del props
#
req = None
try:
api.option('ip_address_service_web').value.get()
except RequirementError as err:
req = err
assert req, "ip_address_service_web should raise RequirementError"
assert str(req) == str(_('cannot access to option "{}" because required option "{}" has {} {}').format('ip_address_service_web', 'activate_service_web', 'property', '"disabled"'))
del req
#
api.permissive.set(frozenset())
try:
api.option('ip_address_service_web').value.get()
except RequirementError as err:
req = err
assert req, "ip_address_service_web should raise RequirementError"
assert str(req) == str(_('cannot access to option "{}" because required option "{}" has {} {}').format('ip_address_service_web', 'activate_service_web', 'properties', '"disabled" and "hidden"'))
del req
def test_requires_not_transitive():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False,
'action': 'disabled', 'transitive': False}])
od = OptionDescription('service', '', [a, b, d])
api = Config(od)
api.property.read_write()
api.option('activate_service').value.get()
api.option('activate_service_web').value.get()
api.option('ip_address_service_web').value.get()
api.option('activate_service').value.set(False)
#
props = []
try:
api.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
#
api.option('ip_address_service_web').value.get()
def test_requires_not_transitive_not_same_action():
a = BoolOption('activate_service', '', True)
b = BoolOption('activate_service_web', '', True,
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
d = IPOption('ip_address_service_web', '',
requires=[{'option': b, 'expected': False,
'action': 'hidden', 'transitive': False}])
od = OptionDescription('service', '', [a, b, d])
api = Config(od)
api.property.read_write()
api.option('activate_service').value.get()
api.option('activate_service_web').value.get()
api.option('ip_address_service_web').value.get()
api.option('activate_service').value.set(False)
#
props = []
try:
api.option('activate_service_web').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
#
raises(RequirementError, "api.option('ip_address_service_web').value.get()")
def test_requires_None():
a = BoolOption('activate_service', '')
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': None, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(False)
api.option('ip_address_service').value.get()
def test_requires_multi_disabled():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': True, 'action': 'disabled'},
{'option': b, 'expected': 1, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, c])
api = Config(od)
api.property.read_write()
api.option('ip_address_service').value.get()
api.option('activate_service').value.set(True)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(False)
api.option('ip_address_service').value.get()
api.option('num_service').value.set(1)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(True)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled_new_format():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': True}, {'option': b, 'value': 1}], 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b, c])
api = Config(od)
api.property.read_write()
api.option('ip_address_service').value.get()
api.option('activate_service').value.set(True)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(False)
api.option('ip_address_service').value.get()
api.option('num_service').value.set(1)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(True)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_unknown_operator():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
raises(ValueError, """IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': True}, {'option': b, 'value': 1}],
'action': 'disabled', 'operator': 'unknown'}])""")
def test_requires_keys():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
raises(ValueError, """IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value2': True}, {'option': b, 'value': 1}],
'action': 'disabled', 'operator': 'and'}])""")
def test_requires_unvalid():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
raises(ValueError, """IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': 'unvalid'}, {'option': b, 'value': 1}],
'action': 'disabled', 'operator': 'and'}])""")
def test_requires_multi_disabled_new_format_and():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': True}, {'option': b, 'value': 1}], 'action': 'disabled', 'operator': 'and'}])
od = OptionDescription('service', '', [a, b, c])
api = Config(od)
api.property.read_write()
api.option('ip_address_service').value.get()
api.option('activate_service').value.set(True)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert props == []
api.option('activate_service').value.set(False)
api.option('ip_address_service').value.get()
api.option('num_service').value.set(1)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert props == []
api.option('activate_service').value.set(True)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled_new_format_and_2():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'expected': [{'option': a, 'value': True}, {'option': b, 'value': 1}], 'action': 'disabled', 'operator': 'and'},
{'expected': [{'option': a, 'value': False}, {'option': b, 'value': 1}], 'action': 'expert'}])
od = OptionDescription('service', '', [a, b, c])
api = Config(od)
api.property.add('expert')
api.property.read_write()
api.option('ip_address_service').value.get()
api.option('activate_service').value.set(True)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert props == []
api.option('activate_service').value.set(False)
api.option('num_service').value.set(1)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['expert'])
api.option('activate_service').value.set(True)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled', 'expert'])
def test_requires_multi_disabled_inverse():
a = BoolOption('activate_service', '')
b = IntOption('num_service', '')
c = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': True,
'action': 'disabled', 'inverse': True},
{'option': b, 'expected': 1,
'action': 'disabled', 'inverse': True}])
od = OptionDescription('service', '', [a, b, c])
api = Config(od)
api.property.read_write()
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(True)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(False)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('num_service').value.set(1)
props = []
try:
api.option('ip_address_service').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
api.option('activate_service').value.set(True)
api.option('ip_address_service').value.get()
def test_requires_multi_disabled_2():
a = BoolOption('a', '')
b = BoolOption('b', '')
c = BoolOption('c', '')
d = BoolOption('d', '')
e = BoolOption('e', '')
f = BoolOption('f', '')
g = BoolOption('g', '')
h = BoolOption('h', '')
i = BoolOption('i', '')
j = BoolOption('j', '')
k = BoolOption('k', '')
l = BoolOption('l', '')
m = BoolOption('m', '')
list_bools = [a, b, c, d, e, f, g, h, i, j, k, l, m]
requires = []
for boo in list_bools:
requires.append({'option': boo, 'expected': True, 'action': 'disabled'})
z = IPOption('z', '', requires=requires)
y = copy(list_bools)
y.append(z)
od = OptionDescription('service', '', y)
api = Config(od)
api.property.read_write()
api.option('z').value.get()
for boo in list_bools:
api.option(boo.impl_getname()).value.set(True)
props = []
try:
api.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
for boo in list_bools:
api.option(boo.impl_getname()).value.set(False)
if boo == m:
api.option('z').value.get()
else:
props = []
try:
api.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_multi_disabled_inverse_2():
a = BoolOption('a', '')
b = BoolOption('b', '')
c = BoolOption('c', '')
d = BoolOption('d', '')
e = BoolOption('e', '')
f = BoolOption('f', '')
g = BoolOption('g', '')
h = BoolOption('h', '')
i = BoolOption('i', '')
j = BoolOption('j', '')
k = BoolOption('k', '')
l = BoolOption('l', '')
m = BoolOption('m', '')
list_bools = [a, b, c, d, e, f, g, h, i, j, k, l, m]
requires = []
for boo in list_bools:
requires.append({'option': boo, 'expected': True, 'action': 'disabled',
'inverse': True})
z = IPOption('z', '', requires=requires)
y = copy(list_bools)
y.append(z)
od = OptionDescription('service', '', y)
api = Config(od)
api.property.read_write()
props = []
try:
api.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
for boo in list_bools:
api.option(boo.impl_getname()).value.set(True)
if boo == m:
api.option('z').value.get()
else:
props = []
try:
api.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
for boo in list_bools:
api.option(boo.impl_getname()).value.set(False)
props = []
try:
api.option('z').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert frozenset(props) == frozenset(['disabled'])
def test_requires_requirement_append():
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
api.property.get()
api.option('ip_address_service').property.get()
raises(ValueError, "api.option('ip_address_service').property.add('disabled')")
api.option('activate_service').value.set(False)
# disabled is now set, test to remove disabled before store in storage
api.unrestraint.option('ip_address_service').property.add("test")
def test_requires_different_inverse():
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '', requires=[
{'option': a, 'expected': True, 'action': 'disabled', 'inverse': True},
{'option': a, 'expected': True, 'action': 'disabled', 'inverse': False}])
od = OptionDescription('service', '', [a, b])
api = Config(od)
api.property.read_write()
raises(PropertiesOptionError, "api.option('ip_address_service').value.get()")
api.option('activate_service').value.set(False)
raises(PropertiesOptionError, "api.option('ip_address_service').value.get()")
def test_requires_different_inverse_unicode():
a = BoolOption('activate_service', '', True)
d = StrOption('activate_other_service', '', 'val2')
b = IPOption('ip_address_service', '', requires=[
{'option': a, 'expected': True, 'action': 'disabled', 'inverse': True},
{'option': d, 'expected': 'val1', 'action': 'disabled', 'inverse': False}])
od = OptionDescription('service', '', [a, d, b])
api = Config(od)
api.property.read_write()
assert api.option('ip_address_service').value.get() == None
api.option('activate_service').value.set(False)
raises(PropertiesOptionError, "api.option('ip_address_service').value.get()")
api.option('activate_service').value.set(True)
assert api.option('ip_address_service').value.get() == None
api.option('activate_other_service').value.set('val1')
raises(PropertiesOptionError, "api.option('ip_address_service').value.get()")
api.option('activate_service').value.set(False)
raises(PropertiesOptionError, "api.option('ip_address_service').value.get()")
def test_requires_recursive_path():
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '',
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od1 = OptionDescription('service', '', [a, b], requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
od = OptionDescription('base', '', [od1])
api = Config(od)
api.property.read_write()
raises(RequirementError, "api.option('service.a').value.get()")
def test_optiondescription_requires():
a = BoolOption('activate_service', '', True)
b = BoolOption('ip_address_service', '', multi=True)
a, b
OptionDescription('service', '', [b], requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
def test_optiondescription_requires_multi():
a = BoolOption('activate_service', '', True)
b = IPOption('ip_address_service', '', multi=True)
a, b
raises(ValueError, "OptionDescription('service', '', [a], requires=[{'option': b, 'expected': False, 'action': 'disabled'}])")
def test_properties_conflict():
a = BoolOption('activate_service', '', True)
a
raises(ValueError, "IPOption('ip_address_service', '', properties=('disabled',), requires=[{'option': a, 'expected': False, 'action': 'disabled'}])")
raises(ValueError, "od1 = OptionDescription('service', '', [a], properties=('disabled',), requires=[{'option': a, 'expected': False, 'action': 'disabled'}])")
def test_leadership_requires():
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'option': ip_admin_eth0, 'expected': '192.168.1.1', 'action': 'disabled'}])
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [interface1])
api = Config(maconfig)
api.property.read_write()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
#
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1'])
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
#
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.2'])
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() is None
api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('255.255.255.255')
assert api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == '255.255.255.255'
assert api.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.2'],
'ip_admin_eth0.netmask_admin_eth0': [None, '255.255.255.255']}
#
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1'])
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
ret = api.value.dict()
assert set(ret.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert ret['ip_admin_eth0.ip_admin_eth0'] == ['192.168.1.2', '192.168.1.1']
assert len(ret['ip_admin_eth0.netmask_admin_eth0']) == 2
assert ret['ip_admin_eth0.netmask_admin_eth0'][0] is None
assert isinstance(ret['ip_admin_eth0.netmask_admin_eth0'][1], PropertiesOptionError)
del ret['ip_admin_eth0.netmask_admin_eth0'][1]
del ret['ip_admin_eth0.netmask_admin_eth0'][0]
del ret['ip_admin_eth0.netmask_admin_eth0']
#
api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.255')
ret = api.value.dict()
assert set(ret.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
assert ret['ip_admin_eth0.ip_admin_eth0'] == ['192.168.1.2', '192.168.1.1']
assert len(ret['ip_admin_eth0.netmask_admin_eth0']) == 2
assert ret['ip_admin_eth0.netmask_admin_eth0'][0] == '255.255.255.255'
assert isinstance(ret['ip_admin_eth0.netmask_admin_eth0'][1], PropertiesOptionError)
del ret['ip_admin_eth0.netmask_admin_eth0'][1]
del ret['ip_admin_eth0.netmask_admin_eth0'][0]
del ret['ip_admin_eth0.netmask_admin_eth0']
def test_leadership_requires_both():
ip_admin = StrOption('ip_admin_eth0', "ip réseau autorisé")
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True,
requires=[{'option': ip_admin, 'expected': '192.168.1.1', 'action': 'disabled'}])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
raises(RequirementError, "Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], requires=[{'option': ip_admin, 'expected': '192.168.1.1', 'action': 'disabled'}])")
def test_leadership_requires_properties_invalid():
ip_admin = StrOption('ip_admin', "ip réseau autorisé")
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'option': ip_admin_eth0, 'expected': '192.168.1.1', 'action': 'disabled'}])
raises(ValueError, "Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], properties=('disabled',), requires=[{'option': ip_admin, 'expected': '192.168.1.1', 'action': 'disabled'}])")
def test_leadership_requires_properties_invalid_2():
ip_admin = StrOption('ip_admin', "ip réseau autorisé")
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True,
requires=[{'option': ip_admin, 'expected': '192.168.1.1', 'action': 'disabled'}])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'option': ip_admin_eth0, 'expected': '192.168.1.1', 'action': 'disabled'}])
raises(ValueError, "Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], properties=('disabled',))")
def test_leadership_requires_properties():
ip_admin = StrOption('ip_admin', "ip réseau autorisé")
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'option': ip_admin_eth0, 'expected': '192.168.1.1', 'action': 'disabled'}])
Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0], properties=('hidden',),
requires=[{'option': ip_admin, 'expected': '192.168.1.1', 'action': 'disabled'}])
def test_leadership_requires_leader():
activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True,
requires=[{'option': activate, 'expected': False, 'action': 'disabled'}])
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [activate, interface1])
api = Config(maconfig)
api.property.read_write()
#
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
#
api.option('activate').value.set(False)
raises(PropertiesOptionError, "api.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
#
api.option('activate').value.set(True)
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
#
api.option('activate').value.set(False)
raises(PropertiesOptionError, "api.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
assert api.value.dict() == {'activate': False}
def test_leadership_requires_leadership():
activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0],
requires=[{'option': activate, 'expected': False, 'action': 'disabled'}])
maconfig = OptionDescription('toto', '', [activate, interface1])
api = Config(maconfig)
api.property.read_write()
#
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
#
api.option('activate').value.set(False)
raises(PropertiesOptionError, "api.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
#
api.option('activate').value.set(True)
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
#
api.option('activate').value.set(False)
raises(PropertiesOptionError, "api.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
assert api.value.dict() == {'activate': False}
def test_leadership_requires_no_leader():
activate = BoolOption('activate', "Activer l'accès au réseau", True)
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
requires=[{'option': activate, 'expected': False, 'action': 'disabled'}])
interface1 = Leadership('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
maconfig = OptionDescription('toto', '', [activate, interface1])
api = Config(maconfig)
api.property.read_write()
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == []
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2'])
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2']
api.option('activate').value.set(False)
api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1'])
assert api.option('ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.1.2', '192.168.1.1']
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
api.option('activate').value.set(True)
assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None
assert api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() is None
api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('255.255.255.255')
assert api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == '255.255.255.255'
api.option('activate').value.set(False)
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
assert api.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.1'], 'activate': False}

View File

@ -83,30 +83,34 @@ def _autocheck_default_value(cfg, path, conf, **kwargs):
# test default value (should be empty)
# cannot test for follower (we cannot get all values for a follower)
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
with warnings.catch_warnings(record=True) as w:
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(path).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(path).value.get() == empty_value
assert cfg_.option(path).value.get() == empty_value
assert cfg_.forcepermissive.option(path).value.get() == empty_value
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(path).value.get()")
assert cfg.config(conf).forcepermissive.option(path).value.get() == empty_value
raises(PropertiesOptionError, "cfg_.option(path).value.get()")
assert cfg_.forcepermissive.option(path).value.get() == empty_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(path).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(path).value.get()")
raises(PropertiesOptionError, "cfg_.option(path).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(path).value.get()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(path, 0).value.get() == empty_value
assert cfg.config(conf).option(path, 1).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(path, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(path, 1).value.get() == empty_value
assert cfg_.option(path, 0).value.get() == empty_value
assert cfg_.option(path, 1).value.get() == empty_value
assert cfg_.forcepermissive.option(path, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(path, 1).value.get() == empty_value
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(path, 0).value.get()")
assert cfg.config(conf).forcepermissive.option(path, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(path, 1).value.get() == empty_value
raises(PropertiesOptionError, "cfg_.option(path, 0).value.get()")
assert cfg_.forcepermissive.option(path, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(path, 1).value.get() == empty_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(path, 0).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(path, 0).value.get()")
raises(PropertiesOptionError, "cfg_.option(path, 0).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(path, 0).value.get()")
def _set_value(cfg, pathwrite, conf, **kwargs):
@ -131,52 +135,56 @@ def _set_value(cfg, pathwrite, conf, **kwargs):
# for follower should have an index and good length
# for leader must append, not set
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
with warnings.catch_warnings(record=True) as w:
if isleader:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
raises(APIError, "cfg.config(conf).option(pathwrite, 0).value.set(first_value[0])")
raises(APIError, "cfg_.option(pathwrite, 0).value.set(first_value[0])")
if not set_permissive:
cfg.config(conf).option(pathwrite).value.set([first_value[0]])
cfg_.option(pathwrite).value.set([first_value[0]])
else:
cfg.config(conf).forcepermissive.option(pathwrite).value.set([first_value[0]])
cfg_.forcepermissive.option(pathwrite).value.set([first_value[0]])
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite).value.set([first_value[0]])")
raises(PropertiesOptionError, "cfg_.option(pathwrite).value.set([first_value[0]])")
if set_permissive:
cfg.config(conf).forcepermissive.option(pathwrite).value.set([first_value[0]])
cfg_.forcepermissive.option(pathwrite).value.set([first_value[0]])
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite).value.set([first_value[0]])")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathwrite).value.set([first_value[0]])")
raises(PropertiesOptionError, "cfg_.option(pathwrite).value.set([first_value[0]])")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathwrite).value.set([first_value[0]])")
if len(first_value) > 1:
raises(APIError, "cfg.config(conf).unrestraint.option(pathwrite).value.set(first_value[1])")
raises(APIError, "cfg_.unrestraint.option(pathwrite).value.set(first_value[1])")
elif isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
if not set_permissive:
cfg.config(conf).option(pathwrite, 1).value.set(second_value)
cfg_.option(pathwrite, 1).value.set(second_value)
else:
cfg.config(conf).forcepermissive.option(pathwrite, 1).value.set(second_value)
cfg_.forcepermissive.option(pathwrite, 1).value.set(second_value)
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite, 1).value.set(second_value)")
raises(PropertiesOptionError, "cfg_.option(pathwrite, 1).value.set(second_value)")
if set_permissive:
cfg.config(conf).forcepermissive.option(pathwrite, 1).value.set(second_value)
cfg_.forcepermissive.option(pathwrite, 1).value.set(second_value)
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite, 1).value.set(second_value)")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathwrite, 1).value.set(second_value)")
raises(APIError, "cfg.config(conf).unrestraint.option(pathwrite).value.set([second_value, second_value])")
raises(PropertiesOptionError, "cfg_.option(pathwrite, 1).value.set(second_value)")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathwrite, 1).value.set(second_value)")
raises(APIError, "cfg_.unrestraint.option(pathwrite).value.set([second_value, second_value])")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
if not set_permissive:
cfg.config(conf).option(pathwrite).value.set(first_value)
cfg_.option(pathwrite).value.set(first_value)
else:
cfg.config(conf).forcepermissive.option(pathwrite).value.set(first_value)
cfg_.forcepermissive.option(pathwrite).value.set(first_value)
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite).value.set(first_value)")
raises(PropertiesOptionError, "cfg_.option(pathwrite).value.set(first_value)")
if set_permissive:
cfg.config(conf).forcepermissive.option(pathwrite).value.set(first_value)
cfg_.forcepermissive.option(pathwrite).value.set(first_value)
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite).value.set(first_value)")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathwrite).value.set(first_value)")
#FIXME raises(APIError, "cfg.config(conf).unrestraint.option(pathwrite).value.set(first_value)")
raises(PropertiesOptionError, "cfg_.option(pathwrite).value.set(first_value)")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathwrite).value.set(first_value)")
#FIXME raises(APIError, "cfg_.unrestraint.option(pathwrite).value.set(first_value)")
def _getproperties(multi, isfollower, kwargs):
@ -195,37 +203,41 @@ def _getproperties(multi, isfollower, kwargs):
def _check_properties(cfg, mcfg, pathread, conf, kwargs, props_permissive, props):
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if not cfg.unrestraint.option(pathread).option.isfollower():
if not kwargs.get('permissive_od', False):
assert set(cfg.config(conf).option(pathread).property.get()) == set(props_permissive)
assert set(cfg.config(conf).option(pathread).property.get()) == set(props)
assert set(cfg_.option(pathread).property.get()) == set(props_permissive)
assert set(cfg_.option(pathread).property.get()) == set(props)
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).property.get()")
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).property.get()")
assert set(cfg.config(conf).forcepermissive.option(pathread).property.get()) == set(props_permissive)
assert set(cfg.config(conf).forcepermissive.option(pathread).property.get()) == set(props)
assert set(cfg.config(conf).unrestraint.option(pathread).property.get()) == set(props_permissive)
assert set(cfg.config(conf).unrestraint.option(pathread).property.get()) == set(props)
raises(PropertiesOptionError, "cfg_.option(pathread).property.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).property.get()")
assert set(cfg_.forcepermissive.option(pathread).property.get()) == set(props_permissive)
assert set(cfg_.forcepermissive.option(pathread).property.get()) == set(props)
assert set(cfg_.unrestraint.option(pathread).property.get()) == set(props_permissive)
assert set(cfg_.unrestraint.option(pathread).property.get()) == set(props)
else:
if not kwargs.get('permissive_od', False):
assert set(cfg.config(conf).option(pathread, 0).property.get()) == set(props_permissive)
assert set(cfg.config(conf).option(pathread, 0).property.get()) == set(props)
assert set(cfg_.option(pathread, 0).property.get()) == set(props_permissive)
assert set(cfg_.option(pathread, 0).property.get()) == set(props)
#
assert set(cfg.config(conf).option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg.config(conf).option(pathread, 1).property.get()) == set(props)
assert set(cfg_.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg_.option(pathread, 1).property.get()) == set(props)
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).property.get()")
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).property.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).property.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).property.get()")
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 1).property.get()")
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 1).property.get()")
assert set(cfg.config(conf).forcepermissive.option(pathread, 0).property.get()) == set(props_permissive)
assert set(cfg.config(conf).forcepermissive.option(pathread, 0).property.get()) == set(props)
raises(PropertiesOptionError, "cfg_.option(pathread, 1).property.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 1).property.get()")
assert set(cfg_.forcepermissive.option(pathread, 0).property.get()) == set(props_permissive)
assert set(cfg_.forcepermissive.option(pathread, 0).property.get()) == set(props)
#
assert set(cfg.config(conf).forcepermissive.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg.config(conf).forcepermissive.option(pathread, 1).property.get()) == set(props)
assert set(cfg.config(conf).unrestraint.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg.config(conf).unrestraint.option(pathread, 1).property.get()) == set(props)
assert set(cfg_.forcepermissive.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg_.forcepermissive.option(pathread, 1).property.get()) == set(props)
assert set(cfg_.unrestraint.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg_.unrestraint.option(pathread, 1).property.get()) == set(props)
def _property_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs):
@ -253,12 +265,16 @@ def _property_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
# set properties with permissive
for prop in properties:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg.config(confread).option(pathwrite).property.add(prop)
elif not kwargs.get('propertyerror', False):
cfg.config(confread).forcepermissive.option(pathwrite).property.add(prop)
if confread is not None:
cfg_ = cfg.config(confread)
else:
cfg.config(confread).unrestraint.option(pathwrite).property.add(prop)
cfg_ = cfg
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg_.option(pathwrite).property.add(prop)
elif not kwargs.get('propertyerror', False):
cfg_.forcepermissive.option(pathwrite).property.add(prop)
else:
cfg_.unrestraint.option(pathwrite).property.add(prop)
if confwrite == confread:
_check_properties(cfg, mcfg, pathread, confwrite, kwargs, properties, properties)
else:
@ -286,64 +302,72 @@ def _autocheck_get_value(cfg, pathread, conf, **kwargs):
second_value = SUBLIST_SECOND_VALUE[1]
# get value after set value without permissive
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
with warnings.catch_warnings(record=True) as w:
if isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).option(pathread, 1).value.get() == second_value
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == second_value
assert cfg_.option(pathread, 0).value.get() == empty_value
assert cfg_.option(pathread, 1).value.get() == second_value
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread, 1).value.get() == second_value
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
raises(PropertiesOptionError, "cfg_.option(pathread, 0).value.get()")
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
if set_permissive:
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == second_value
assert cfg_.forcepermissive.option(pathread, 1).value.get() == second_value
else:
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread, 1).value.get() == empty_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread, 0).value.get()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread).value.get() == first_value
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
assert cfg_.option(pathread).value.get() == first_value
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
if set_permissive:
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
else:
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread).value.get() == empty_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).value.get()")
def _check_owner(cfg, pathread, conf, kwargs, owner, permissive_owner):
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread).owner.get() == owner
assert cfg.config(conf).forcepermissive.option(pathread).owner.get() == owner
assert cfg_.option(pathread).owner.get() == owner
assert cfg_.forcepermissive.option(pathread).owner.get() == owner
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.get()")
assert cfg.config(conf).forcepermissive.option(pathread).owner.get() == permissive_owner
raises(PropertiesOptionError, "cfg_.option(pathread).owner.get()")
assert cfg_.forcepermissive.option(pathread).owner.get() == permissive_owner
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).owner.get()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).option(pathread, 1).owner.get() == owner
assert cfg.config(conf).forcepermissive.option(pathread, 1).owner.get() == owner
assert cfg_.option(pathread, 0).owner.get() == 'default'
assert cfg_.forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg_.option(pathread, 1).owner.get() == owner
assert cfg_.forcepermissive.option(pathread, 1).owner.get() == owner
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 1).owner.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).forcepermissive.option(pathread, 1).owner.get() == permissive_owner
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 1).owner.get()")
assert cfg_.forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg_.forcepermissive.option(pathread, 1).owner.get() == permissive_owner
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread, 0).owner.get()")
@autocheck
@ -373,49 +397,53 @@ def autocheck_default_owner(cfg, mcfg, pathread, pathwrite, confread, confwrite,
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
# check if owner is a string "default" and 'isdefault'
def do(conf):
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread).owner.get() == 'default'
assert cfg.config(conf).forcepermissive.option(pathread).owner.get() == 'default'
assert cfg_.option(pathread).owner.get() == 'default'
assert cfg_.forcepermissive.option(pathread).owner.get() == 'default'
#
assert cfg.config(conf).option(pathread).owner.isdefault()
assert cfg.config(conf).forcepermissive.option(pathread).owner.isdefault()
assert cfg_.option(pathread).owner.isdefault()
assert cfg_.forcepermissive.option(pathread).owner.isdefault()
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.get()")
assert cfg.config(conf).forcepermissive.option(pathread).owner.get() == 'default'
raises(PropertiesOptionError, "cfg_.option(pathread).owner.get()")
assert cfg_.forcepermissive.option(pathread).owner.get() == 'default'
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.isdefault()")
assert cfg.config(conf).forcepermissive.option(pathread).owner.isdefault()
raises(PropertiesOptionError, "cfg_.option(pathread).owner.isdefault()")
assert cfg_.forcepermissive.option(pathread).owner.isdefault()
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).owner.get()")
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.isdefault()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).owner.isdefault()")
raises(PropertiesOptionError, "cfg_.option(pathread).owner.isdefault()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).owner.isdefault()")
#
assert cfg.config(conf).unrestraint.option(pathread).owner.get() == 'default'
assert cfg.config(conf).unrestraint.option(pathread).owner.isdefault()
assert cfg_.unrestraint.option(pathread).owner.get() == 'default'
assert cfg_.unrestraint.option(pathread).owner.isdefault()
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg_.option(pathread, 0).owner.get() == 'default'
assert cfg_.forcepermissive.option(pathread, 0).owner.get() == 'default'
#
assert cfg.config(conf).option(pathread, 0).owner.isdefault()
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.isdefault()
assert cfg_.option(pathread, 0).owner.isdefault()
assert cfg_.forcepermissive.option(pathread, 0).owner.isdefault()
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.get() == 'default'
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.get()")
assert cfg_.forcepermissive.option(pathread, 0).owner.get() == 'default'
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.isdefault()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.isdefault()
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.isdefault()")
assert cfg_.forcepermissive.option(pathread, 0).owner.isdefault()
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread, 0).owner.get()")
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.isdefault()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread, 0).owner.isdefault()")
assert cfg.config(conf).unrestraint.option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).unrestraint.option(pathread, 0).owner.isdefault()
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.isdefault()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread, 0).owner.isdefault()")
assert cfg_.unrestraint.option(pathread, 0).owner.get() == 'default'
assert cfg_.unrestraint.option(pathread, 0).owner.isdefault()
do(confread)
if confread != confwrite:
do(confwrite)
@ -450,40 +478,44 @@ def autocheck_get_value_permissive(cfg, mcfg, pathread, pathwrite, confread, con
def do(conf):
# get value after set value without permissive
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg_.option(pathread, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
if submulti_:
assert cfg.config(conf).option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
assert cfg_.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
assert cfg_.forcepermissive.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
else:
assert cfg.config(conf).option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
assert cfg_.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
assert cfg_.forcepermissive.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "assert cfg.config(conf).option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg.config(conf).option(pathread, 1).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
raises(PropertiesOptionError, "assert cfg_.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg_.option(pathread, 1).value.get()")
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
if submulti_:
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
assert cfg_.forcepermissive.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
else:
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
assert cfg_.forcepermissive.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
else:
raises(PropertiesOptionError, "assert cfg.config(conf).option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg.config(conf).option(pathread, 1).value.get()")
raises(PropertiesOptionError, "assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get()")
raises(PropertiesOptionError, "assert cfg_.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg_.option(pathread, 1).value.get()")
raises(PropertiesOptionError, "assert cfg_.forcepermissive.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg_.forcepermissive.option(pathread, 1).value.get()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
with warnings.catch_warnings(record=True) as w:
assert cfg.config(conf).option(pathread).value.get() == first_value
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
assert cfg_.option(pathread).value.get() == first_value
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).value.get()")
with warnings.catch_warnings(record=True) as w:
do(confread)
if confread != confwrite:
@ -515,8 +547,12 @@ def autocheck_value_follower(cfg, mcfg, pathread, pathwrite, confread, confwrite
empty_value = kwargs['default']
def do(conf):
length = cfg.config(conf).option(pathread).value.len()
assert cfg.config(conf).forcepermissive.option(pathread).value.len() == length
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
length = cfg_.option(pathread).value.len()
assert cfg_.forcepermissive.option(pathread).value.len() == length
assert length == 2
do(confread)
if confread != confwrite:
@ -567,33 +603,41 @@ def autocheck_reset_value(cfg, mcfg, pathread, pathwrite, confread, confwrite, *
# reset value without permissive
with warnings.catch_warnings(record=True) as w:
if confwrite is not None:
cfg_ = cfg.config(confwrite)
else:
cfg_ = cfg
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg.config(confwrite).option(pathwrite).value.reset()
cfg_.option(pathwrite).value.reset()
#else:
#FIXME raises(PropertiesOptionError, "cfg.config(confwrite).option(pathwrite).value.reset()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg.config(confwrite).option(pathwrite, 0).value.reset()
cfg_.option(pathwrite, 0).value.reset()
#else:
#FIXME raises(PropertiesOptionError, "cfg.config(confwrite).option(pathwrite, 0).value.reset()")
# get value after reset value without permissive
def do(conf):
if confwrite is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).option(pathread, 1).value.get() == second_value[1]
assert cfg_.option(pathread, 0).value.get() == empty_value
assert cfg_.option(pathread, 1).value.get() == second_value[1]
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == second_value[1]
raises(PropertiesOptionError, "cfg_.option(pathread, 0).value.get()")
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread, 1).value.get() == second_value[1]
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread).value.get() == empty_value
assert cfg_.option(pathread).value.get() == empty_value
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
with warnings.catch_warnings(record=True) as w:
do(confread)
if confread != confwrite:
@ -606,16 +650,24 @@ def autocheck_append_value(cfg, mcfg, pathread, pathwrite, confread, confwrite,
submulti_ = cfg.unrestraint.option(pathread).option.issubmulti()
if not isleader:
return
if confread is not None:
cfg_ = cfg.config(confread)
else:
cfg_ = cfg
if confwrite is not None:
cfg2_ = cfg.config(confwrite)
else:
cfg2_ = cfg
with warnings.catch_warnings(record=True) as w:
if not kwargs.get('propertyerror', False):
leader_value = cfg.config(confread).forcepermissive.option(pathread).value.get()
leader_value = cfg_.forcepermissive.option(pathread).value.get()
len_value = len(leader_value)
leader_value.append(undefined)
assert len(cfg.config(confread).forcepermissive.option(pathread).value.get()) == len_value
assert len(cfg_.forcepermissive.option(pathread).value.get()) == len_value
with warnings.catch_warnings(record=True) as w:
cfg.forcepermissive.config(confwrite).option(pathread).value.set(leader_value)
new_leader_value = cfg.config(confread).forcepermissive.option(pathread).value.get()
cfg2_.forcepermissive.option(pathread).value.set(leader_value)
new_leader_value = cfg_.forcepermissive.option(pathread).value.get()
len_new = len(new_leader_value)
assert len_value + 1 == len_new
assert new_leader_value[-1] == kwargs['default_multi']
@ -625,16 +677,16 @@ def autocheck_append_value(cfg, mcfg, pathread, pathwrite, confread, confwrite,
else:
follower_path += '.third'
for idx in range(len_new):
assert cfg.config(confread).forcepermissive.option(follower_path, idx).value.get() == kwargs['default_multi']
assert cfg_.forcepermissive.option(follower_path, idx).value.get() == kwargs['default_multi']
#
if not submulti_:
value = 'value'
else:
value = ['value']
leader_value.append(value)
assert len(cfg.config(confread).forcepermissive.option(pathread).value.get()) == len(new_leader_value)
cfg.forcepermissive.config(confwrite).option(pathread).value.set(leader_value)
assert cfg.config(confread).forcepermissive.option(pathread).value.get()[-1] == value
assert len(cfg_.forcepermissive.option(pathread).value.get()) == len(new_leader_value)
cfg2_.forcepermissive.option(pathread).value.set(leader_value)
assert cfg_.forcepermissive.option(pathread).value.get()[-1] == value
@autocheck
@ -644,6 +696,14 @@ def autocheck_pop_value(cfg, mcfg, pathread, pathwrite, confread, confwrite, **k
if not isleader:
return
if confwrite is not None:
cfg_ = cfg.config(confwrite)
else:
cfg_ = cfg
if confread is not None:
cfg2_ = cfg.config(confread)
else:
cfg2_ = cfg
if not kwargs.get('propertyerror', False):
if not submulti_:
values = ['value1', 'value2', 'value3', 'value4']
@ -658,34 +718,34 @@ def autocheck_pop_value(cfg, mcfg, pathread, pathwrite, confread, confwrite, **k
else:
a_follower += '.third'
with warnings.catch_warnings(record=True) as w:
cfg.forcepermissive.config(confwrite).option(pathread).value.set(values)
cfg.forcepermissive.config(confwrite).option(a_follower, 1).value.set(follower_value)
cfg.config(confread).forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg.config(confread).forcepermissive.option(a_follower, 1).value.get() == follower_value
assert cfg.config(confread).forcepermissive.option(a_follower, 1).owner.isdefault() is False
cfg.config(confread).forcepermissive.option(a_follower, 2).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 2).owner.isdefault() is True
cfg.config(confread).forcepermissive.option(a_follower, 3).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 3).owner.isdefault() is True
cfg_.forcepermissive.option(pathread).value.set(values)
cfg_.forcepermissive.option(a_follower, 1).value.set(follower_value)
cfg2_.forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg2_.forcepermissive.option(a_follower, 1).value.get() == follower_value
assert cfg2_.forcepermissive.option(a_follower, 1).owner.isdefault() is False
cfg2_.forcepermissive.option(a_follower, 2).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 2).owner.isdefault() is True
cfg2_.forcepermissive.option(a_follower, 3).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 3).owner.isdefault() is True
#
cfg.forcepermissive.config(confwrite).option(pathread).value.pop(3)
cfg.config(confread).forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg.config(confread).forcepermissive.option(a_follower, 1).value.get() == follower_value
assert cfg.config(confread).forcepermissive.option(a_follower, 1).owner.isdefault() is False
cfg.config(confread).forcepermissive.option(a_follower, 2).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 2).owner.isdefault() is True
cfg_.forcepermissive.option(pathread).value.pop(3)
cfg2_.forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg2_.forcepermissive.option(a_follower, 1).value.get() == follower_value
assert cfg2_.forcepermissive.option(a_follower, 1).owner.isdefault() is False
cfg2_.forcepermissive.option(a_follower, 2).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 2).owner.isdefault() is True
#
cfg.forcepermissive.config(confwrite).option(pathread).value.pop(0)
cfg.config(confread).forcepermissive.option(a_follower, 0).value.get() == follower_value
assert cfg.config(confread).forcepermissive.option(a_follower, 0).owner.isdefault() is False
cfg.config(confread).forcepermissive.option(a_follower, 1).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 1).owner.isdefault() is True
cfg_.forcepermissive.option(pathread).value.pop(0)
cfg2_.forcepermissive.option(a_follower, 0).value.get() == follower_value
assert cfg2_.forcepermissive.option(a_follower, 0).owner.isdefault() is False
cfg2_.forcepermissive.option(a_follower, 1).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 1).owner.isdefault() is True
#
cfg.forcepermissive.config(confwrite).option(pathread).value.pop(0)
cfg.config(confread).forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg_.forcepermissive.option(pathread).value.pop(0)
cfg2_.forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 0).owner.isdefault() is True
@autocheck
@ -697,12 +757,20 @@ def autocheck_reset_value_permissive(cfg, mcfg, pathread, pathwrite, confread, c
with warnings.catch_warnings(record=True) as w:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
if not isfollower:
cfg.forcepermissive.config(confwrite).option(pathwrite).value.reset()
if confwrite is not None:
cfg_ = cfg.forcepermissive.config(confwrite)
else:
cfg_ = cfg.forcepermissive
cfg_.option(pathwrite).value.reset()
else:
cfg.forcepermissive.option(pathwrite, 1).value.reset()
elif kwargs.get('permissive', False):
if not isfollower:
cfg.forcepermissive.config(confwrite).option(pathwrite).value.reset()
if confwrite is not None:
cfg_ = cfg.forcepermissive.config(confwrite)
else:
cfg_ = cfg.forcepermissive
cfg_.option(pathwrite).value.reset()
else:
cfg.forcepermissive.option(pathwrite, 1).value.reset()
#FIXME else:
@ -723,13 +791,21 @@ def autocheck_display(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwa
return
make_dict = kwargs['make_dict']
make_dict_value = kwargs['make_dict_value']
assert cfg.config(confread).value.dict() == make_dict
if confread is not None:
cfg_ = cfg.config(confread)
else:
cfg_ = cfg
if confwrite is not None:
cfg2_ = cfg.config(confwrite)
else:
cfg2_ = cfg
assert cfg_.value.dict() == make_dict
if confread != confwrite:
assert(cfg.config(confwrite).value.dict()) == make_dict
assert(cfg2_.value.dict()) == make_dict
_set_value(cfg, pathwrite, confwrite, **kwargs)
assert cfg.config(confread).value.dict() == make_dict_value
assert cfg_.value.dict() == make_dict_value
if confread != confwrite:
assert(cfg.config(confwrite).value.dict()) == make_dict_value
assert(cfg2_.value.dict()) == make_dict_value
@autocheck
@ -749,7 +825,11 @@ def autocheck_property(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kw
# set properties without permissive
for prop in properties:
cfg.unrestraint.config(confwrite).option(pathwrite).property.add(prop)
if confwrite is not None:
cfg_ = cfg.unrestraint.config(confwrite)
else:
cfg_ = cfg.unrestraint
cfg_.option(pathwrite).property.add(prop)
if confread == confwrite:
_check_properties(cfg, mcfg, pathread, confread, kwargs, properties, properties)
else:
@ -774,7 +854,11 @@ def autocheck_reset_property(cfg, mcfg, pathread, pathwrite, confread, confwrite
_property_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs)
# reset properties without permissive
cfg.unrestraint.config(confwrite).option(pathwrite).property.reset()
if confwrite is not None:
cfg_ = cfg.unrestraint.config(confwrite)
else:
cfg_ = cfg.unrestraint
cfg_.option(pathwrite).property.reset()
if confread == confwrite:
_check_properties(cfg, mcfg, pathread, confread, kwargs, default_props, default_props)
@ -819,22 +903,28 @@ def autocheck_default_owner_with_value(cfg, mcfg, pathread, pathwrite, confread,
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
_set_value(cfg, pathwrite, confwrite, **kwargs)
if confwrite is not None:
cfg_ = cfg.config(confread)
cfg2_ = cfg.config(confwrite)
else:
cfg_ = cfg
cfg2_ = cfg
# test if is default owner without permissive
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(confwrite).option(pathread).owner.isdefault() is False
assert cfg_.option(pathread).owner.isdefault() is False
if confwrite != confread:
assert cfg.config(confread).option(pathread).owner.isdefault() is False
assert cfg2_.option(pathread).owner.isdefault() is False
#FIXME else:
# raises(PropertiesOptionError, "cfg.config(confwrite).option(pathread).owner.isdefault()")
# raises(PropertiesOptionError, "cfg.config(confread).option(pathread).owner.isdefault()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(confwrite).option(pathread, 0).owner.isdefault() is True
assert cfg.config(confwrite).option(pathread, 1).owner.isdefault() is False
assert cfg2_.option(pathread, 0).owner.isdefault() is True
assert cfg2_.option(pathread, 1).owner.isdefault() is False
if confwrite != confread:
assert cfg.config(confread).option(pathread, 0).owner.isdefault() is True
assert cfg.config(confread).option(pathread, 1).owner.isdefault() is False
assert cfg_.option(pathread, 0).owner.isdefault() is True
assert cfg_.option(pathread, 1).owner.isdefault() is False
#FIXME else:
# raises(PropertiesOptionError, "cfg.config(confwrite).option(pathread, 0).owner.isdefault()")
# raises(PropertiesOptionError, "cfg.config(confread).option(pathread, 0).owner.isdefault()")
@ -849,14 +939,16 @@ def autocheck_default_owner_with_value_permissive(cfg, mcfg, pathread, pathwrite
def do(conf):
# test if is default owner with permissive
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if not kwargs.get('propertyerror', False):
if not isfollower:
assert cfg.config(conf).forcepermissive.option(pathread).owner.isdefault() is False
assert cfg_.forcepermissive.option(pathread).owner.isdefault() is False
else:
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.isdefault() is True
assert cfg.config(conf).forcepermissive.option(pathread, 1).owner.isdefault() is False
#FIXME else:
# raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).owner.isdefault()")
assert cfg_.forcepermissive.option(pathread, 0).owner.isdefault() is True
assert cfg_.forcepermissive.option(pathread, 1).owner.isdefault() is False
do(confwrite)
if confwrite != confread:
do(confread)
@ -865,11 +957,15 @@ def autocheck_default_owner_with_value_permissive(cfg, mcfg, pathread, pathwrite
@autocheck
def autocheck_set_owner_no_value(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs):
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
if confwrite is not None:
cfg_ = cfg.forcepermissive.config(confwrite)
else:
cfg_ = cfg.forcepermissive
if not kwargs.get('propertyerror', False):
if not isfollower:
raises(ConfigError, "cfg.forcepermissive.config(confwrite).option(pathwrite).owner.set('new_user')")
raises(ConfigError, "cfg_.option(pathwrite).owner.set('new_user')")
else:
raises(ConfigError, "cfg.forcepermissive.option(pathwrite, 1).owner.set('new_user')")
raises(ConfigError, "cfg_.option(pathwrite, 1).owner.set('new_user')")
@autocheck
@ -878,13 +974,17 @@ def autocheck_set_owner(cfg, mcfg, pathread, pathwrite, confread, confwrite, **k
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
_set_value(cfg, pathwrite, confwrite, **kwargs)
if confwrite is not None:
cfg_ = cfg.config(confwrite)
else:
cfg_ = cfg
# set owner without permissive
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg.config(confwrite).option(pathwrite).owner.set('new_user')
raises(ValueError, "cfg.config(confwrite).option(pathwrite).owner.set('default')")
raises(ValueError, "cfg.config(confwrite).option(pathwrite).owner.set('forced')")
cfg_.option(pathwrite).owner.set('new_user')
raises(ValueError, "cfg_.option(pathwrite).owner.set('default')")
raises(ValueError, "cfg_.option(pathwrite).owner.set('forced')")
#FIXME else:
# raises(PropertiesOptionError, "cfg.config(confwrite).option(pathwrite).owner.set('new_user')")
else:
@ -903,11 +1003,15 @@ def autocheck_set_owner_permissive(cfg, mcfg, pathread, pathwrite, confread, con
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
_set_value(cfg, pathwrite, confwrite, **kwargs)
if confwrite is not None:
cfg_ = cfg.forcepermissive.config(confwrite)
else:
cfg_ = cfg.forcepermissive
# set owner with permissive
if not kwargs.get('propertyerror', False):
if not isfollower:
cfg.forcepermissive.config(confwrite).option(pathwrite).owner.set('new_user1')
cfg_.option(pathwrite).owner.set('new_user1')
else:
cfg.forcepermissive.option(pathwrite, 1).owner.set('new_user1')
#FIXME else:
@ -961,9 +1065,17 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
"""test permissive for hidden and disabled value
"""
# no permissive before
assert cfg.unrestraint.config(confwrite).option(pathread).permissive.get() == frozenset()
if confwrite is not None:
cfg_ = cfg.unrestraint.config(confwrite)
else:
cfg_ = cfg.unrestraint
if confread is not None:
cfg2_ = cfg.config(confread).unrestraint
else:
cfg2_ = cfg.unrestraint
assert cfg_.option(pathread).permissive.get() == frozenset()
if kwargs.get('permissive_od', False):
assert cfg.unrestraint.config(confwrite).option(pathread.rsplit('.', 1)[0]).permissive.get() == frozenset()
assert cfg_.option(pathread.rsplit('.', 1)[0]).permissive.get() == frozenset()
# cannot access to hidden value without forcepermissive
# and to disabled value (with forcepermissive too)
@ -972,17 +1084,17 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
_autocheck_default_value(cfg, pathread, confread, **kwargs)
# set permissive
cfg.unrestraint.config(confwrite).option(pathwrite).permissive.set(frozenset(['disabled']))
cfg_.option(pathwrite).permissive.set(frozenset(['disabled']))
callback = kwargs['callback']
if callback:
if pathread.endswith('val1') or pathread.endswith('val2'):
call_path = pathread[:-4] + 'call' + pathread[-4:]
else:
call_path = pathread + 'call'
cfg.unrestraint.config(confwrite).option(call_path).permissive.set(frozenset(['disabled']))
cfg_.option(call_path).permissive.set(frozenset(['disabled']))
# have permissive?
assert cfg.unrestraint.config(confwrite).option(pathread).permissive.get() == frozenset(['disabled'])
assert cfg_.option(pathread).permissive.get() == frozenset(['disabled'])
#if confwrite != confread:
# assert cfg.config(confread).unrestraint.option(pathread).permissive.get() == frozenset(['disabled'])
@ -991,9 +1103,9 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
ckwargs['propertyerror'] = False
_autocheck_default_value(cfg, pathread, confwrite, **ckwargs)
cfg.config(confread).unrestraint.option(pathwrite).permissive.set(frozenset(['disabled', 'hidden']))
cfg2_.option(pathwrite).permissive.set(frozenset(['disabled', 'hidden']))
if kwargs['callback']:
cfg.config(confread).unrestraint.option(call_path).permissive.set(frozenset(['disabled', 'hidden']))
cfg2_.option(call_path).permissive.set(frozenset(['disabled', 'hidden']))
# can access to all value except when optiondescript have hidden
if not ckwargs.get('permissive_od', False):
@ -1002,7 +1114,7 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
if ckwargs.get('permissive_od', False):
# set permissive to OptionDescription
cfg.config(confread).unrestraint.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset(['disabled',
cfg2_.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset(['disabled',
'hidden']))
ckwargs['permissive'] = False
_autocheck_default_value(cfg, pathread, confread, **ckwargs)
@ -1010,23 +1122,23 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
# _autocheck_default_value(cfg, pathread, confwrite, **ckwargs)
# only hidden
cfg.config(confread).unrestraint.option(pathwrite).permissive.set(frozenset(['hidden']))
cfg2_.option(pathwrite).permissive.set(frozenset(['hidden']))
if callback:
cfg.config(confread).unrestraint.option(call_path).permissive.set(frozenset(['hidden']))
cfg2_.option(call_path).permissive.set(frozenset(['hidden']))
if ckwargs.get('permissive_od', False):
_autocheck_default_value(cfg, pathread, confread, **ckwargs)
cfg.config(confread).unrestraint.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset(['hidden']))
cfg2_.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset(['hidden']))
ckwargs = copy(kwargs)
ckwargs['permissive'] = False
_autocheck_default_value(cfg, pathread, confread, **ckwargs)
# no permissive
cfg.config(confread).unrestraint.option(pathwrite).permissive.set(frozenset())
cfg2_.option(pathwrite).permissive.set(frozenset())
if callback:
cfg.config(confread).unrestraint.option(call_path).permissive.set(frozenset())
cfg2_.option(call_path).permissive.set(frozenset())
if ckwargs.get('permissive_od', False):
_autocheck_default_value(cfg, pathread, confread, **ckwargs)
cfg.config(confread).unrestraint.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset())
cfg2_.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset())
_autocheck_default_value(cfg, pathread, confread, **kwargs)
@ -1060,17 +1172,21 @@ def autocheck_find(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs
option = _getoption(cfg.unrestraint.option(pathread))
def do(conf):
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert option == _getoption(cfg.config(conf).option.find(name, first=True))
assert option == _getoption(cfg.config(conf).forcepermissive.option.find(name, first=True))
elif kwargs.get('permissive', False):
raises(AttributeError, "cfg.config(conf).option.find(name, first=True)")
assert option == _getoption(cfg.config(conf).forcepermissive.option.find(name, first=True))
if conf is not None:
cfg_ = cfg.config(conf)
else:
raises(AttributeError, "cfg.config(conf).option.find(name, first=True)")
raises(AttributeError, "cfg.config(conf).forcepermissive.option.find(name, first=True)")
assert option == _getoption(cfg.config(conf).unrestraint.option.find(name, first=True))
assert [option] == _getoptions(cfg.config(conf).unrestraint.option.find(name))
cfg_ = cfg
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert option == _getoption(cfg_.option.find(name, first=True))
assert option == _getoption(cfg_.forcepermissive.option.find(name, first=True))
elif kwargs.get('permissive', False):
raises(AttributeError, "cfg_.option.find(name, first=True)")
assert option == _getoption(cfg_.forcepermissive.option.find(name, first=True))
else:
raises(AttributeError, "cfg_.option.find(name, first=True)")
raises(AttributeError, "cfg_.forcepermissive.option.find(name, first=True)")
assert option == _getoption(cfg_.unrestraint.option.find(name, first=True))
assert [option] == _getoptions(cfg_.unrestraint.option.find(name))
do(confread)
if confread != confwrite:
do(confwrite)

42
tests/config.py Normal file
View File

@ -0,0 +1,42 @@
# from json import dumps, loads
try:
from tiramisu_api import Config
class TestConfig(Config):
def __init__(self,
config):
self.test_option = config.option
json = self.test_option.dict()
# assert json == loads(dumps(json))
super().__init__(json)
def send_data(self,
updates):
return self.updates_data(self.test_option.updates(updates))
PARAMS = ['tiramisu', 'tiramisu-api']
except:
PARAMS = ['tiramisu']
import pytest
def get_config(config, type, error=False):
if type == 'tiramisu':
return config
if error:
config.property.add('demoting_error_warning')
return TestConfig(config)
def value_list(values):
if values[0] == '':
del values[0]
return tuple(values)
def global_owner(config, config_type):
return config.owner.get()
@pytest.fixture(params=PARAMS)
def config_type(request):
return request.param

0
tests/dict/__init__.py Normal file
View File

View File

View File

@ -0,0 +1,43 @@
{
"schema": {
"options": {
"properties": {
"options.boolean": {
"type": "boolean",
"title": "Boolean 1"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.boolean": {
"clearable": true
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,12 @@
"""just an boolean option
"""
from tiramisu.option import BoolOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = BoolOption('boolean', "Boolean 1")
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("boolean1", "Simple boolean", [descr1])
return descr

View File

@ -0,0 +1,47 @@
{
"schema": {
"options": {
"properties": {
"options.boolean": {
"type": "boolean",
"title": "Boolean 1 frozen"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {
"options.boolean": {
"readOnly": true
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.boolean": {
"clearable": true
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,12 @@
"""just an boolean option
"""
from tiramisu.option import BoolOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = BoolOption('boolean', "Boolean 1 frozen", properties=('frozen',))
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("boolean1_frozen", "Simple boolean", [descr1])
return descr

View File

@ -0,0 +1,49 @@
{
"schema": {
"options": {
"properties": {
"options.choice": {
"type": "choice",
"enum": [
"",
"choice 1",
"choice 2"
],
"title": "Choice description"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.choice": {
"clearable": true,
"type": "choice"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,10 @@
from tiramisu.option import ChoiceOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = ChoiceOption('choice', "Choice description", ("choice 1", "choice 2"))
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("choice1", "Simple choice", [descr1])
return descr

View File

@ -0,0 +1,53 @@
{
"schema": {
"options": {
"properties": {
"options.choice": {
"type": "choice",
"enum": [
"",
"choice 1",
"choice 2"
],
"title": "Choice description frozen"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {
"options.choice": {
"readOnly": true
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.choice": {
"clearable": true,
"type": "choice"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,10 @@
from tiramisu.option import ChoiceOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = ChoiceOption('choice', "Choice description frozen", ("choice 1", "choice 2"), properties=('frozen',))
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("choice1_frozen", "Simple choice", [descr1])
return descr

View File

@ -0,0 +1,101 @@
{
"schema": {
"options": {
"properties": {
"options.choice1": {
"properties": {
"options.choice1.choice1": {
"type": "choice",
"isMulti": true,
"enum": [
"choice 1",
"choice 2"
],
"title": "Choice description leader"
},
"options.choice1.choice2": {
"type": "choice",
"isMulti": true,
"enum": [
"",
"choice 3",
"choice 4"
],
"title": "Choice description follower 1"
},
"options.choice1.choice3": {
"type": "choice",
"isMulti": true,
"enum": [
"",
"choice 5",
"choice 6"
],
"title": "Choice description follower 2"
},
"options.choice1.choice4": {
"type": "choice",
"isMulti": true,
"enum": [
"",
"choice 7",
"choice 8"
],
"title": "Choice description follower 3"
}
},
"type": "array",
"title": "Common configuration 1"
}
},
"type": "object",
"title": "Common configuration 2"
}
},
"model": {
"options.choice1.choice1": {
"required": true
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.choice1.choice1": {
"clearable": true,
"type": "choice"
},
"options.choice1.choice2": {
"clearable": true,
"type": "choice"
},
"options.choice1.choice3": {
"clearable": true,
"type": "choice"
},
"options.choice1.choice4": {
"clearable": true,
"type": "choice"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,16 @@
from tiramisu.option import ChoiceOption, OptionDescription
from tiramisu import Leadership
def get_description():
"""generate description for this test
"""
option = ChoiceOption('choice1', "Choice description leader", ("choice 1", "choice 2"), multi=True)
option1 = ChoiceOption('choice2', "Choice description follower 1", ("choice 3", "choice 4"), multi=True)
option2 = ChoiceOption('choice3', "Choice description follower 2", ("choice 5", "choice 6"), multi=True)
option3 = ChoiceOption('choice4', "Choice description follower 3", ("choice 7", "choice 8"), multi=True)
descr1 = Leadership("choice1", "Common configuration 1",
[option, option1, option2, option3])
descr = OptionDescription("options", "Common configuration 2", [descr1])
descr = OptionDescription("choice1_leadership", "Leader followers with choice", [descr])
return descr

View File

@ -0,0 +1,106 @@
{
"schema": {
"options": {
"properties": {
"options.choice1": {
"properties": {
"options.choice1.choice1": {
"type": "choice",
"isMulti": true,
"enum": [
"choice 1",
"choice 2"
],
"title": "Choice description leader"
},
"options.choice1.choice2": {
"type": "choice",
"isMulti": true,
"enum": [
"",
"choice 3",
"choice 4"
],
"title": "Choice description follower 1"
},
"options.choice1.choice3": {
"type": "choice",
"isMulti": true,
"enum": [
"",
"choice 5",
"choice 6"
],
"title": "Choice description follower 2 hidden"
},
"options.choice1.choice4": {
"type": "choice",
"isMulti": true,
"enum": [
"",
"choice 7",
"choice 8"
],
"title": "Choice description follower 3"
}
},
"type": "array",
"title": "Slave 2 is hidden"
}
},
"type": "object",
"title": "Common configuration 2"
}
},
"model": {
"options.choice1.choice1": {
"required": true
},
"options.choice1.choice3": {
"null": {
"display": false
}
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.choice1.choice1": {
"clearable": true,
"type": "choice"
},
"options.choice1.choice2": {
"clearable": true,
"type": "choice"
},
"options.choice1.choice3": {
"clearable": true,
"type": "choice"
},
"options.choice1.choice4": {
"clearable": true,
"type": "choice"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,16 @@
from tiramisu.option import ChoiceOption, OptionDescription
from tiramisu import Leadership
from tiramisu.setting import groups
def get_description():
"""generate description for this test
"""
option = ChoiceOption('choice1', "Choice description leader", ("choice 1", "choice 2"), multi=True)
option1 = ChoiceOption('choice2', "Choice description follower 1", ("choice 3", "choice 4"), multi=True)
option2 = ChoiceOption('choice3', "Choice description follower 2 hidden", ("choice 5", "choice 6"), multi=True, properties=('hidden',))
option3 = ChoiceOption('choice4', "Choice description follower 3", ("choice 7", "choice 8"), multi=True)
descr1 = Leadership("choice1", "Slave 2 is hidden",
[option, option1, option2, option3])
descr = OptionDescription("options", "Common configuration 2", [descr1])
descr = OptionDescription("choice1_leadership_hidden", "Leader follower with choice, one is hidden", [descr])
return descr

View File

@ -0,0 +1,111 @@
{
"schema": {
"options": {
"properties": {
"options.choice1": {
"properties": {
"options.choice1.choice1": {
"type": "choice",
"isMulti": true,
"enum": [
"choice 1",
"choice 2"
],
"title": "Choice leader"
},
"options.choice1.choice2": {
"type": "choice",
"isMulti": true,
"enum": [
"",
"choice 3",
"choice 4"
],
"title": "Choice follower 1"
},
"options.choice1.choice3": {
"type": "choice",
"isMulti": true,
"enum": [
"",
"choice 5",
"choice 6"
],
"title": "Choice follower 2"
},
"options.choice1.choice4": {
"type": "choice",
"isMulti": true,
"enum": [
"",
"choice 7",
"choice 8"
],
"title": "Choice follower 3"
}
},
"type": "array",
"title": "Common configuration 1"
}
},
"type": "object",
"title": "Common configuration 2"
}
},
"model": {
"options.choice1.choice1": {
"required": true,
"value": [
"choice 2"
],
"owner": "user"
},
"options.choice1.choice2": {
"0": {
"value": "choice 4",
"owner": "user"
}
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.choice1.choice1": {
"clearable": true,
"type": "choice"
},
"options.choice1.choice2": {
"clearable": true,
"type": "choice"
},
"options.choice1.choice3": {
"clearable": true,
"type": "choice"
},
"options.choice1.choice4": {
"clearable": true,
"type": "choice"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,25 @@
from tiramisu.option import ChoiceOption, OptionDescription
from tiramisu import Leadership
def get_description():
"""generate description for this test
"""
option = ChoiceOption('choice1', "Choice leader", ("choice 1", "choice 2"), multi=True)
option1 = ChoiceOption('choice2', "Choice follower 1", ("choice 3", "choice 4"), multi=True)
option2 = ChoiceOption('choice3', "Choice follower 2", ("choice 5", "choice 6"), multi=True)
option3 = ChoiceOption('choice4', "Choice follower 3", ("choice 7", "choice 8"), multi=True)
descr1 = Leadership("choice1", "Common configuration 1",
[option, option1, option2, option3])
descr = OptionDescription("options", "Common configuration 2", [descr1])
descr = OptionDescription("choice1_leadership_value", "Leader followers with choices, leader is 'choice 2' and follower 1 is 'choice 4'", [descr])
return descr
def get_values(api, allpath=False):
if allpath:
root = 'choice1_leadership_value.'
else:
root = ''
api.option(root + 'options.choice1.choice1').value.set(['choice 2'])
api.option(root + 'options.choice1.choice2', 0).value.set('choice 4')

View File

@ -0,0 +1,53 @@
{
"schema": {
"options": {
"properties": {
"options.choice": {
"type": "choice",
"isMulti": true,
"enum": [
"choice 1",
"choice 2"
],
"title": "Choice description"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {
"options.choice": {
"required": true
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.choice": {
"clearable": true,
"type": "choice"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,10 @@
from tiramisu.option import ChoiceOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = ChoiceOption('choice', "Choice description", ("choice 1", "choice 2"), multi=True)
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("choice1_multi", "Multi choice", [descr1])
return descr

View File

@ -0,0 +1,53 @@
{
"schema": {
"options": {
"properties": {
"options.choice": {
"type": "choice",
"enum": [
"",
"choice 1",
"choice 2"
],
"title": "Choice description"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.choice": {
"clearable": true,
"type": "choice",
"displayed": {
"choice 1": "renamed 1",
"choice 2": "renamed 2"
}
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,20 @@
from tiramisu.option import ChoiceOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = ChoiceOption('choice', "Choice description", ("choice 1", "choice 2"))
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("choice1_rename", "Rename displayed value", [descr1])
return descr
def get_form(allpath=False):
key = 'options.choice'
if allpath:
key = 'choice1_rename.' + key
return [{'key': key,
'displayed': {'choice 1': 'renamed 1',
'choice 2': 'renamed 2'}
}]

View File

@ -0,0 +1,85 @@
{
"schema": {
"options": {
"properties": {
"options.choice": {
"type": "choice",
"enum": [
"hide",
"show"
],
"value": "hide",
"title": "Choice description"
},
"options.unicode2": {
"type": "string",
"title": "Unicode 2"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {
"options.choice": {
"required": true,
"value": "hide"
},
"options.unicode2": {
"display": false,
"hidden": true
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.choice": {
"clearable": true,
"type": "choice",
"dependencies": {
"default": {
"show": [
"options.unicode2"
]
},
"expected": {
"show": {
"show": [
"options.unicode2"
]
},
"hide": {
"hide": [
"options.unicode2"
]
}
}
}
},
"options.unicode2": {
"clearable": true,
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,12 @@
from tiramisu.option import ChoiceOption, StrOption, OptionDescription
def get_description():
"""generate description for this test
"""
option1 = ChoiceOption('choice', "Choice description", ("hide", "show"), default='hide', properties=('mandatory',))
option2 = StrOption('unicode2', "Unicode 2", requires=[{'option': option1,
'expected': 'hide',
'action': 'hidden'}])
descr1 = OptionDescription("options", "Common configuration", [option1, option2])
descr = OptionDescription("choice1_requires", "Choice with requirement", [descr1])
return descr

View File

@ -0,0 +1,44 @@
{
"schema": {
"options": {
"properties": {
"options.date": {
"type": "date",
"title": "Date description"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.date": {
"clearable": true,
"remote": true
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

9
tests/dict/data/date1.py Normal file
View File

@ -0,0 +1,9 @@
from tiramisu.option import DateOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = DateOption('date', "Date description")
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("date1", "Simple date", [descr1])
return descr

View File

@ -0,0 +1,48 @@
{
"schema": {
"options": {
"properties": {
"options.date": {
"type": "date",
"title": "Date description frozen"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {
"options.date": {
"readOnly": true
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.date": {
"clearable": true,
"remote": true
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,9 @@
from tiramisu.option import DateOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = DateOption('date', "Date description frozen", properties=('frozen',))
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("date1_frozen", "Simple date", [descr1])
return descr

View File

@ -0,0 +1,43 @@
{
"schema": {
"usbpath": {
"type": "filename",
"title": "Chemin d'acc\u00e8s"
}
},
"model": {
"usbpath": {
"required": true
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"usbpath": {
"clearable": true,
"pattern": "^[a-zA-Z0-9\\-\\._~/+]+$",
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from tiramisu.option import FilenameOption, OptionDescription
def get_description():
usbpath = FilenameOption('usbpath', "Chemin d'accès", properties=('mandatory',))
descr = OptionDescription("filename1", "Simple filename", [usbpath])
return descr

View File

@ -0,0 +1,72 @@
{
"schema": {
"options": {
"properties": {
"options.hostname1": {
"type": "domainname",
"title": "Domainname Description"
},
"options.hostname2": {
"type": "domainname",
"title": "Domainname without dot Description"
},
"options.hostname3": {
"type": "domainname",
"title": "Hostname or IP Description"
},
"options.hostname4": {
"type": "domainname",
"title": "Netbios Description"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.hostname1": {
"clearable": true,
"pattern": "^((?!-)[a-z0-9-]{1,63}\\.){1,}[a-z0-9-]{1,63}$",
"type": "input"
},
"options.hostname2": {
"clearable": true,
"pattern": "^((?!-)[a-z0-9-]{0,63}\\.){0,}[a-z0-9-]{1,63}$",
"type": "input"
},
"options.hostname3": {
"clearable": true,
"pattern": "^(?:((?!-)[a-z0-9-]{1,63})|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$",
"type": "input"
},
"options.hostname4": {
"clearable": true,
"pattern": "^((?!-)[a-z0-9-]{1,15})$",
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,12 @@
from tiramisu.option import DomainnameOption, OptionDescription
def get_description():
"""generate description for this test
"""
option1 = DomainnameOption('hostname1', "Domainname Description")
option2 = DomainnameOption('hostname2', "Domainname without dot Description", allow_without_dot=True)
option3 = DomainnameOption('hostname3', "Hostname or IP Description", type_='hostname', allow_ip=True)
option4 = DomainnameOption('hostname4', "Netbios Description", type_='netbios')
descr1 = OptionDescription("options", "Common configuration", [option1, option2, option3, option4])
descr = OptionDescription("hostname1", "Simple hostnames", [descr1])
return descr

45
tests/dict/data/ip1.json Normal file
View File

@ -0,0 +1,45 @@
{
"schema": {
"options": {
"properties": {
"options.ip": {
"type": "ip",
"title": "IP Description"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.ip": {
"clearable": true,
"remote": true,
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

9
tests/dict/data/ip1.py Normal file
View File

@ -0,0 +1,9 @@
from tiramisu.option import IPOption, OptionDescription
def get_description():
"""generate description for this test
"""
option1 = IPOption('ip', "IP Description")
descr1 = OptionDescription("options", "Common configuration", [option1])
descr = OptionDescription("ip1", "Simple IP", [descr1])
return descr

View File

@ -0,0 +1,49 @@
{
"schema": {
"options": {
"properties": {
"options.ip": {
"type": "ip",
"title": "IP Description frozen"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {
"options.ip": {
"readOnly": true
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.ip": {
"clearable": true,
"remote": true,
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,9 @@
from tiramisu.option import IPOption, OptionDescription
def get_description():
"""generate description for this test
"""
option1 = IPOption('ip', "IP Description frozen", properties=('frozen',))
descr1 = OptionDescription("options", "Common configuration", [option1])
descr = OptionDescription("ip1_frozen", "Simple IP", [descr1])
return descr

View File

@ -0,0 +1,45 @@
{
"schema": {
"options": {
"properties": {
"options.mail": {
"type": "email",
"title": "Mail Description"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.mail": {
"clearable": true,
"pattern": "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$",
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

10
tests/dict/data/mail1.py Normal file
View File

@ -0,0 +1,10 @@
from tiramisu.option import EmailOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = EmailOption('mail', "Mail Description")
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("mail1", "Simple mail", [descr1])
return descr

View File

@ -0,0 +1,45 @@
{
"schema": {
"options": {
"properties": {
"options.integer": {
"type": "integer",
"title": "integer 1"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.integer": {
"clearable": true,
"pattern": "^[0-9]+$",
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,10 @@
from tiramisu.option import IntOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = IntOption('integer', "integer 1")
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("number1", "Simple number", [descr1])
return descr

View File

@ -0,0 +1,49 @@
{
"schema": {
"options": {
"properties": {
"options.integer": {
"type": "integer",
"title": "integer 1 frozen"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {
"options.integer": {
"readOnly": true
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.integer": {
"clearable": true,
"pattern": "^[0-9]+$",
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,10 @@
from tiramisu.option import IntOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = IntOption('integer', "integer 1 frozen", properties=('frozen',))
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("number1_frozen", "Simple number", [descr1])
return descr

View File

@ -0,0 +1,51 @@
{
"schema": {
"options": {
"properties": {
"options.integer": {
"type": "integer",
"value": 0,
"title": "integer 1"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {
"options.integer": {
"value": 3,
"owner": "user"
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.integer": {
"clearable": true,
"pattern": "^[0-9]+$",
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,18 @@
from tiramisu.option import IntOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = IntOption('integer', "integer 1", 0)
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("number1_mod_value", "Number with modified value 3 and default value 0", [descr1])
return descr
def get_values(api, allpath=False):
if allpath:
root = 'number1_mod_value.'
else:
root = ''
api.option(root + 'options.integer').value.set(3)

View File

@ -0,0 +1,50 @@
{
"schema": {
"options": {
"properties": {
"options.integer": {
"type": "integer",
"value": 0,
"title": "integer 1"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {
"options.integer": {
"value": 0
}
},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.integer": {
"clearable": true,
"pattern": "^[0-9]+$",
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,11 @@
from tiramisu.option import IntOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = IntOption('integer', "integer 1", 0)
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("number1_value", "Number with value 0", [descr1])
return descr

View File

@ -0,0 +1 @@
{"options.unicode": null}

View File

@ -0,0 +1 @@
{"options.unicode": "val"}

View File

@ -0,0 +1,44 @@
{
"schema": {
"options": {
"properties": {
"options.unicode": {
"type": "string",
"title": "Unicode 1"
}
},
"type": "object",
"title": "Common configuration"
}
},
"model": {},
"global": {
"owner": "user",
"properties": [
"cache",
"demoting_error_warning",
"disabled",
"force_store_value",
"frozen",
"hidden",
"validator",
"warnings"
],
"permissives": [
"hidden"
]
},
"form": {
"options.unicode": {
"clearable": true,
"type": "input"
},
"null": [
{
"title": "Configurer",
"type": "submit"
}
]
},
"version": "1.0"
}

View File

@ -0,0 +1,5 @@
{"cmd": "config.option('options.unicode').value.set('val')",
"body": {"updates": [{"action": "modify",
"name": "options.unicode",
"value": "val"}]}
}

View File

@ -0,0 +1,11 @@
"""just an unicode option
"""
from tiramisu.option import StrOption, OptionDescription
def get_description():
"""generate description for this test
"""
option = StrOption('unicode', "Unicode 1")
descr1 = OptionDescription("options", "Common configuration", [option])
descr = OptionDescription("unicode1", "Simple unicode", [descr1])
return descr

View File

@ -0,0 +1,3 @@
{"updates": ["options.unicode"],
"model": {"options.unicode": {"owner": "user",
"value": "val"}}}

Some files were not shown because too many files have changed in this diff Show More