diff --git a/requirements/static/darwin.in b/requirements/static/darwin.in
index 5061b007faff..d3f777e8c6c8 100644
--- a/requirements/static/darwin.in
+++ b/requirements/static/darwin.in
@@ -27,3 +27,9 @@ supervisor==3.3.5; python_version < '3'
virtualenv
watchdog
yamlordereddictloader
+
+# Available template libraries that can be used
+Genshi
+Cheetah3==3.1.0
+Mako
+wempy; python_version <'3'
diff --git a/requirements/static/linux.in b/requirements/static/linux.in
index feafe459dc49..f72ea4dccab1 100644
--- a/requirements/static/linux.in
+++ b/requirements/static/linux.in
@@ -41,3 +41,9 @@ timelib
tornado<5.0
virtualenv
watchdog
+
+# Available template libraries that can be used
+Genshi
+Cheetah3==3.1.0
+Mako
+wempy; python_version <'3'
diff --git a/requirements/static/py2.7/darwin.txt b/requirements/static/py2.7/darwin.txt
index e4a0a761b704..07f08f36c534 100644
--- a/requirements/static/py2.7/darwin.txt
+++ b/requirements/static/py2.7/darwin.txt
@@ -134,3 +134,5 @@ zc.lockfile==1.4 # via cherrypy
zipp==0.6.0 # via importlib-metadata
# Passthrough dependencies from pkg/osx/req.txt
pyobjc==5.1.2
+# Passthrough dependencies from pkg/osx/req.txt
+pyobjc==5.1.2
diff --git a/requirements/static/py3.4/linux.txt b/requirements/static/py3.4/linux.txt
index 2d092b3f9ec3..ecbc66faca06 100644
--- a/requirements/static/py3.4/linux.txt
+++ b/requirements/static/py3.4/linux.txt
@@ -10,9 +10,8 @@ asn1crypto==0.24.0 # via cryptography
atomicwrites==1.3.0 # via pytest
attrs==19.1.0 # via pytest
aws-xray-sdk==0.95 # via moto
-backports-abc==0.5 # via tornado
backports.functools-lru-cache==1.5 # via cheroot
-backports.ssl-match-hostname==3.7.0.1 # via docker, websocket-client
+backports.ssl-match-hostname==3.7.0.1 # via docker
bcrypt==3.1.6 # via paramiko
boto3==1.9.132
boto==2.49.0
@@ -21,6 +20,7 @@ cachetools==3.1.0 # via google-auth
certifi==2019.3.9
cffi==1.12.2
chardet==3.0.4 # via requests
+cheetah3==3.1.0
cheroot==6.5.4 # via cherrypy
cherrypy==17.3.0
contextlib2==0.5.5 # via cherrypy
@@ -32,6 +32,7 @@ docker==3.7.2
docutils==0.14 # via botocore
ecdsa==0.13.3 # via python-jose
future==0.17.1 # via python-jose
+genshi==0.7.3
gitdb2==2.0.5 # via gitpython
gitpython==2.1.11
google-auth==1.6.3 # via kubernetes
@@ -51,6 +52,7 @@ kazoo==2.6.1
keyring==5.7.1
kubernetes==3.0.0
lxml==4.3.3 # via junos-eznc, ncclient
+mako==1.1.0
markupsafe==1.1.1
mock==3.0.5 ; python_version < "3.6"
more-itertools==5.0.0
@@ -101,8 +103,7 @@ scp==0.13.2 # via junos-eznc
selectors2==2.0.1 # via ncclient
setproctitle==1.1.10
setuptools-scm==3.2.0
-singledispatch==3.4.0.3 # via tornado
-six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pathlib2, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, singledispatch, tempora, websocket-client
+six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pathlib2, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend
diff --git a/requirements/static/py3.5/darwin.txt b/requirements/static/py3.5/darwin.txt
index 3dbadc4a8a86..3347fb04fc7e 100644
--- a/requirements/static/py3.5/darwin.txt
+++ b/requirements/static/py3.5/darwin.txt
@@ -10,9 +10,9 @@ asn1crypto==0.24.0 # via cryptography
atomicwrites==1.3.0 # via pytest
attrs==19.1.0 # via pytest
aws-xray-sdk==0.95 # via moto
-backports-abc==0.5
backports.functools-lru-cache==1.5 # via cheroot
backports.ssl_match_hostname==3.7.0.1
+backports_abc==0.5
bcrypt==3.1.6 # via paramiko
boto3==1.9.132
boto==2.49.0
@@ -21,6 +21,7 @@ cachetools==3.1.0 # via google-auth
certifi==2019.3.9
cffi==1.12.2
chardet==3.0.4 # via requests
+cheetah3==3.1.0
cheroot==6.5.5 # via cherrypy
cherrypy==17.4.1
click==7.0
@@ -35,6 +36,7 @@ docutils==0.14 # via botocore
ecdsa==0.13.3 # via python-jose
enum34==1.1.6
future==0.17.1 # via python-jose
+genshi==0.7.3
gitdb2==2.0.5 # via gitpython
gitdb==0.6.4
gitpython==2.1.11
diff --git a/requirements/static/py3.5/linux.txt b/requirements/static/py3.5/linux.txt
index 257fd1f542ca..2a07108fdbec 100644
--- a/requirements/static/py3.5/linux.txt
+++ b/requirements/static/py3.5/linux.txt
@@ -10,9 +10,7 @@ asn1crypto==0.24.0 # via cryptography
atomicwrites==1.3.0 # via pytest
attrs==19.1.0 # via pytest
aws-xray-sdk==0.95 # via moto
-backports-abc==0.5 # via tornado
backports.functools-lru-cache==1.5 # via cheroot
-backports.ssl-match-hostname==3.7.0.1 # via websocket-client
bcrypt==3.1.6 # via paramiko
boto3==1.9.132
boto==2.49.0
@@ -21,6 +19,7 @@ cachetools==3.1.0 # via google-auth
certifi==2019.3.9
cffi==1.12.2
chardet==3.0.4 # via requests
+cheetah3==3.1.0
cheroot==6.5.4 # via cherrypy
cherrypy==17.3.0
contextlib2==0.5.5 # via cherrypy
@@ -32,6 +31,7 @@ docker==3.7.2
docutils==0.14 # via botocore
ecdsa==0.13.3 # via python-jose
future==0.17.1 # via python-jose
+genshi==0.7.3
gitdb2==2.0.5 # via gitpython
gitpython==2.1.11
google-auth==1.6.3 # via kubernetes
@@ -51,6 +51,7 @@ kazoo==2.6.1
keyring==5.7.1
kubernetes==3.0.0
lxml==4.3.3 # via junos-eznc, ncclient
+mako==1.1.0
markupsafe==1.1.1
mock==3.0.5 ; python_version < "3.6"
more-itertools==5.0.0
@@ -99,8 +100,7 @@ salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
setuptools-scm==3.2.0
-singledispatch==3.4.0.3 # via tornado
-six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pathlib2, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, singledispatch, tempora, websocket-client
+six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pathlib2, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend
diff --git a/requirements/static/py3.5/windows.txt b/requirements/static/py3.5/windows.txt
index 493c25317872..044778aaf4a9 100644
--- a/requirements/static/py3.5/windows.txt
+++ b/requirements/static/py3.5/windows.txt
@@ -19,6 +19,7 @@ cachetools==3.1.0 # via google-auth
certifi==2019.3.9
cffi==1.12.2
chardet==3.0.4 # via requests
+cheetah3==3.1.0
cheroot==6.5.5 # via cherrypy
cherrypy==17.4.1
colorama==0.4.1 # via pytest
@@ -32,6 +33,7 @@ docutils==0.14 # via botocore
ecdsa==0.13.3 # via python-jose
enum34==1.1.6
future==0.17.1 # via python-jose
+genshi==0.7.3
gitdb2==2.0.5 # via gitpython
gitdb==0.6.4
gitpython==2.1.10
diff --git a/requirements/static/py3.6/darwin.txt b/requirements/static/py3.6/darwin.txt
index d1e48b881c89..8f2c3990118c 100644
--- a/requirements/static/py3.6/darwin.txt
+++ b/requirements/static/py3.6/darwin.txt
@@ -10,9 +10,9 @@ asn1crypto==0.24.0 # via cryptography
atomicwrites==1.3.0 # via pytest
attrs==19.1.0 # via pytest
aws-xray-sdk==0.95 # via moto
-backports-abc==0.5
backports.functools-lru-cache==1.5 # via cheroot
backports.ssl_match_hostname==3.7.0.1
+backports_abc==0.5
bcrypt==3.1.6 # via paramiko
boto3==1.9.132
boto==2.49.0
@@ -21,6 +21,7 @@ cachetools==3.1.0 # via google-auth
certifi==2019.3.9
cffi==1.12.2
chardet==3.0.4 # via requests
+cheetah3==3.1.0
cheroot==6.5.5 # via cherrypy
cherrypy==17.4.1
click==7.0
@@ -35,6 +36,7 @@ docutils==0.14 # via botocore
ecdsa==0.13.3 # via python-jose
enum34==1.1.6
future==0.17.1 # via python-jose
+genshi==0.7.3
gitdb2==2.0.5 # via gitpython
gitdb==0.6.4
gitpython==2.1.11
diff --git a/requirements/static/py3.6/linux.txt b/requirements/static/py3.6/linux.txt
index 5870cb053283..49ee9f32167f 100644
--- a/requirements/static/py3.6/linux.txt
+++ b/requirements/static/py3.6/linux.txt
@@ -10,9 +10,7 @@ asn1crypto==0.24.0 # via cryptography
atomicwrites==1.3.0 # via pytest
attrs==19.1.0 # via pytest
aws-xray-sdk==0.95 # via moto
-backports-abc==0.5 # via tornado
backports.functools-lru-cache==1.5 # via cheroot
-backports.ssl-match-hostname==3.7.0.1 # via websocket-client
bcrypt==3.1.6 # via paramiko
boto3==1.9.132
boto==2.49.0
@@ -21,6 +19,7 @@ cachetools==3.1.0 # via google-auth
certifi==2019.3.9
cffi==1.12.2
chardet==3.0.4 # via requests
+cheetah3==3.1.0
cheroot==6.5.4 # via cherrypy
cherrypy==17.3.0
contextlib2==0.5.5 # via cherrypy
@@ -32,6 +31,7 @@ docker==3.7.2
docutils==0.14 # via botocore
ecdsa==0.13.3 # via python-jose
future==0.17.1 # via python-jose
+genshi==0.7.3
gitdb2==2.0.5 # via gitpython
gitpython==2.1.11
google-auth==1.6.3 # via kubernetes
@@ -51,6 +51,7 @@ kazoo==2.6.1
keyring==5.7.1
kubernetes==3.0.0
lxml==4.3.3 # via junos-eznc, ncclient
+mako==1.1.0
markupsafe==1.1.1
mock==2.0.0 # via moto
more-itertools==5.0.0
@@ -99,8 +100,7 @@ salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
setuptools-scm==3.2.0
-singledispatch==3.4.0.3 # via tornado
-six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, singledispatch, tempora, websocket-client
+six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend
diff --git a/requirements/static/py3.6/windows.txt b/requirements/static/py3.6/windows.txt
index ae3a3f462398..79df42e81d9f 100644
--- a/requirements/static/py3.6/windows.txt
+++ b/requirements/static/py3.6/windows.txt
@@ -19,6 +19,7 @@ cachetools==3.1.0 # via google-auth
certifi==2019.3.9
cffi==1.12.2
chardet==3.0.4 # via requests
+cheetah3==3.1.0
cheroot==6.5.5 # via cherrypy
cherrypy==17.4.1
colorama==0.4.1 # via pytest
@@ -32,6 +33,7 @@ docutils==0.14 # via botocore
ecdsa==0.13.3 # via python-jose
enum34==1.1.6
future==0.17.1 # via python-jose
+genshi==0.7.3
gitdb2==2.0.5 # via gitpython
gitdb==0.6.4
gitpython==2.1.10
diff --git a/requirements/static/py3.7/darwin.txt b/requirements/static/py3.7/darwin.txt
index 692e9657c053..abc2a55891d8 100644
--- a/requirements/static/py3.7/darwin.txt
+++ b/requirements/static/py3.7/darwin.txt
@@ -10,9 +10,9 @@ asn1crypto==0.24.0 # via cryptography
atomicwrites==1.3.0 # via pytest
attrs==19.1.0 # via pytest
aws-xray-sdk==0.95 # via moto
-backports-abc==0.5
backports.functools-lru-cache==1.5 # via cheroot
backports.ssl_match_hostname==3.7.0.1
+backports_abc==0.5
bcrypt==3.1.6 # via paramiko
boto3==1.9.132
boto==2.49.0
@@ -21,6 +21,7 @@ cachetools==3.1.0 # via google-auth
certifi==2019.3.9
cffi==1.12.2
chardet==3.0.4 # via requests
+cheetah3==3.1.0
cheroot==6.5.5 # via cherrypy
cherrypy==17.4.1
click==7.0
@@ -35,6 +36,7 @@ docutils==0.14 # via botocore
ecdsa==0.13.3 # via python-jose
enum34==1.1.6
future==0.17.1 # via python-jose
+genshi==0.7.3
gitdb2==2.0.5 # via gitpython
gitdb==0.6.4
gitpython==2.1.11
diff --git a/requirements/static/py3.7/linux.txt b/requirements/static/py3.7/linux.txt
index 51bf795ff62c..dc2a5cb9c31a 100644
--- a/requirements/static/py3.7/linux.txt
+++ b/requirements/static/py3.7/linux.txt
@@ -10,9 +10,7 @@ asn1crypto==0.24.0 # via cryptography
atomicwrites==1.3.0 # via pytest
attrs==19.1.0 # via pytest
aws-xray-sdk==0.95 # via moto
-backports-abc==0.5 # via tornado
backports.functools-lru-cache==1.5 # via cheroot
-backports.ssl-match-hostname==3.7.0.1 # via websocket-client
bcrypt==3.1.6 # via paramiko
boto3==1.9.132
boto==2.49.0
@@ -21,6 +19,7 @@ cachetools==3.1.0 # via google-auth
certifi==2019.3.9
cffi==1.12.2
chardet==3.0.4 # via requests
+cheetah3==3.1.0
cheroot==6.5.4 # via cherrypy
cherrypy==17.3.0
contextlib2==0.5.5 # via cherrypy
@@ -32,6 +31,7 @@ docker==3.7.2
docutils==0.14 # via botocore
ecdsa==0.13.3 # via python-jose
future==0.17.1 # via python-jose
+genshi==0.7.3
gitdb2==2.0.5 # via gitpython
gitpython==2.1.11
google-auth==1.6.3 # via kubernetes
@@ -51,6 +51,7 @@ kazoo==2.6.1
keyring==5.7.1
kubernetes==3.0.0
lxml==4.3.3 # via junos-eznc, ncclient
+mako==1.1.0
markupsafe==1.1.1
mock==2.0.0 # via moto
more-itertools==5.0.0
@@ -99,8 +100,7 @@ salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
setuptools-scm==3.2.0
-singledispatch==3.4.0.3 # via tornado
-six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, singledispatch, tempora, websocket-client
+six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend
diff --git a/requirements/static/windows.in b/requirements/static/windows.in
index 72deeb14d189..0e46bcfe2671 100644
--- a/requirements/static/windows.in
+++ b/requirements/static/windows.in
@@ -31,3 +31,9 @@ virtualenv
timelib
tornado<5.0
wmi==1.4.9
+
+# Available template libraries that can be used
+Genshi
+Cheetah3==3.1.0
+Mako
+wempy; python_version <'3'
diff --git a/salt/utils/templates.py b/salt/utils/templates.py
index f76ef28dc178..c4b925f4c3d4 100644
--- a/salt/utils/templates.py
+++ b/salt/utils/templates.py
@@ -520,7 +520,26 @@ def render_cheetah_tmpl(tmplstr, context, tmplpath=None):
Render a Cheetah template.
'''
from Cheetah.Template import Template
- return salt.utils.data.decode(Template(tmplstr, searchList=[context]))
+
+ # Compile the template and render it into the class
+ tclass = Template.compile(tmplstr)
+ data = tclass(namespaces=[context])
+
+ # Figure out which method to call based on the type of tmplstr
+ if six.PY3 and isinstance(tmplstr, six.string_types):
+ # This should call .__unicode__()
+ res = str(data)
+ elif six.PY2 and isinstance(tmplstr, six.text_type):
+ # Expicitly call .__unicode__()
+ res = data.__unicode__()
+ elif isinstance(tmplstr, six.binary_type):
+ # This should call .__str()
+ res = str(data)
+ else:
+ raise SaltRenderError('Unknown type {!s} for Cheetah template while trying to render.'.format(type(tmplstr)))
+
+ # Now we can decode it to the correct encoding
+ return salt.utils.data.decode(res)
# pylint: enable=3rd-party-module-not-gated
diff --git a/tests/unit/utils/test_templates.py b/tests/unit/utils/test_templates.py
new file mode 100644
index 000000000000..3d5855dd21e8
--- /dev/null
+++ b/tests/unit/utils/test_templates.py
@@ -0,0 +1,183 @@
+# -*- coding: utf-8 -*-
+'''
+Unit tests for salt.utils.templates.py
+'''
+
+# Import python libs
+from __future__ import absolute_import, print_function, unicode_literals
+import sys
+import logging
+
+# Import Salt libs
+import salt.utils.templates
+
+# Import Salt Testing Libs
+from tests.support.unit import TestCase, skipIf
+
+log = logging.getLogger(__name__)
+
+
+### Here we go!
+class RenderTestCase(TestCase):
+ def setUp(self):
+ # Default context for salt.utils.templates.render_*_tmpl to work
+ self.context = {
+ 'opts': {
+ 'cachedir': '/D',
+ '__cli': 'salt',
+ },
+ 'saltenv': None,
+ }
+
+ ### Tests for Jinja (whitespace-friendly)
+ def test_render_jinja_sanity(self):
+ tmpl = '''OK'''
+ res = salt.utils.templates.render_jinja_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_jinja_evaluate(self):
+ tmpl = '''{{ "OK" }}'''
+ res = salt.utils.templates.render_jinja_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_jinja_evaluate_multi(self):
+ tmpl = '''{% if 1 -%}OK{%- endif %}'''
+ res = salt.utils.templates.render_jinja_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_jinja_variable(self):
+ tmpl = '''{{ var }}'''
+
+ ctx = dict(self.context)
+ ctx['var'] = 'OK'
+ res = salt.utils.templates.render_jinja_tmpl(tmpl, ctx)
+ self.assertEqual(res, 'OK')
+
+ ### Tests for mako template
+ def test_render_mako_sanity(self):
+ tmpl = '''OK'''
+ res = salt.utils.templates.render_mako_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_mako_evaluate(self):
+ tmpl = '''${ "OK" }'''
+ res = salt.utils.templates.render_mako_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_mako_evaluate_multi(self):
+ tmpl = '''
+ % if 1:
+ OK
+ % endif
+ '''
+ res = salt.utils.templates.render_mako_tmpl(tmpl, dict(self.context))
+ stripped = res.strip()
+ self.assertEqual(stripped, 'OK')
+
+ def test_render_mako_variable(self):
+ tmpl = '''${ var }'''
+
+ ctx = dict(self.context)
+ ctx['var'] = 'OK'
+ res = salt.utils.templates.render_mako_tmpl(tmpl, ctx)
+ self.assertEqual(res, 'OK')
+
+ ### Tests for wempy template
+ @skipIf(sys.version_info > (3,), 'The wempy module is currently unsupported under Python3')
+ def test_render_wempy_sanity(self):
+ tmpl = '''OK'''
+ res = salt.utils.templates.render_wempy_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ @skipIf(sys.version_info > (3,), 'The wempy module is currently unsupported under Python3')
+ def test_render_wempy_evaluate(self):
+ tmpl = '''{{="OK"}}'''
+ res = salt.utils.templates.render_wempy_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ @skipIf(sys.version_info > (3,), 'The wempy module is currently unsupported under Python3')
+ def test_render_wempy_evaluate_multi(self):
+ tmpl = '''{{if 1:}}OK{{pass}}'''
+ res = salt.utils.templates.render_wempy_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ @skipIf(sys.version_info > (3,), 'The wempy module is currently unsupported under Python3')
+ def test_render_wempy_variable(self):
+ tmpl = '''{{=var}}'''
+
+ ctx = dict(self.context)
+ ctx['var'] = 'OK'
+ res = salt.utils.templates.render_wempy_tmpl(tmpl, ctx)
+ self.assertEqual(res, 'OK')
+
+ ### Tests for genshi template (xml-based)
+ def test_render_genshi_sanity(self):
+ tmpl = '''OK'''
+ res = salt.utils.templates.render_genshi_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_genshi_evaluate(self):
+ tmpl = '''${ "OK" }'''
+ res = salt.utils.templates.render_genshi_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_genshi_evaluate_condition(self):
+ tmpl = '''OK'''
+ res = salt.utils.templates.render_genshi_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_genshi_variable(self):
+ tmpl = '''$var'''
+
+ ctx = dict(self.context)
+ ctx['var'] = 'OK'
+ res = salt.utils.templates.render_genshi_tmpl(tmpl, ctx)
+ self.assertEqual(res, 'OK')
+
+ def test_render_genshi_variable_replace(self):
+ tmpl = '''not ok'''
+
+ ctx = dict(self.context)
+ ctx['var'] = 'OK'
+ res = salt.utils.templates.render_genshi_tmpl(tmpl, ctx)
+ self.assertEqual(res, 'OK')
+
+ ### Tests for cheetah template (line-oriented and xml-friendly)
+ def test_render_cheetah_sanity(self):
+ tmpl = '''OK'''
+ res = salt.utils.templates.render_cheetah_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_cheetah_evaluate(self):
+ tmpl = '''<%="OK"%>'''
+ res = salt.utils.templates.render_cheetah_tmpl(tmpl, dict(self.context))
+ self.assertEqual(res, 'OK')
+
+ def test_render_cheetah_evaluate_xml(self):
+ tmpl = '''
+ <% if 1: %>
+ OK
+ <% pass %>
+ '''
+ res = salt.utils.templates.render_cheetah_tmpl(tmpl, dict(self.context))
+ stripped = res.strip()
+ self.assertEqual(stripped, 'OK')
+
+ def test_render_cheetah_evaluate_text(self):
+ tmpl = '''
+ #if 1
+ OK
+ #end if
+ '''
+
+ res = salt.utils.templates.render_cheetah_tmpl(tmpl, dict(self.context))
+ stripped = res.strip()
+ self.assertEqual(stripped, 'OK')
+
+ def test_render_cheetah_variable(self):
+ tmpl = '''$var'''
+
+ ctx = dict(self.context)
+ ctx['var'] = 'OK'
+ res = salt.utils.templates.render_cheetah_tmpl(tmpl, ctx)
+ self.assertEqual(res.strip(), 'OK')