def test_non_ascii_encoding(self): fc = MockFileClient() # monkey patch file client _fc = SaltCacheLoader.file_client SaltCacheLoader.file_client = lambda loader: fc filename = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_import') out = render_jinja_tmpl( salt.utils.fopen(filename).read(), dict(opts={'cachedir': TEMPLATES_DIR, 'file_client': 'remote', 'file_roots': self.local_opts['file_roots'], 'pillar_roots': self.local_opts['pillar_roots']}, a='Hi', b='Sàlt', saltenv='test')) self.assertEqual(out, u'Hey world !Hi Sàlt !\n') self.assertEqual(fc.requests[0]['path'], 'salt://macro') SaltCacheLoader.file_client = _fc _fc = SaltCacheLoader.file_client SaltCacheLoader.file_client = lambda loader: fc filename = os.path.join(TEMPLATES_DIR, 'files', 'test', 'non_ascii') out = render_jinja_tmpl( salt.utils.fopen(filename).read(), dict(opts={'cachedir': TEMPLATES_DIR, 'file_client': 'remote', 'file_roots': self.local_opts['file_roots'], 'pillar_roots': self.local_opts['pillar_roots']}, a='Hi', b='Sàlt', saltenv='test')) self.assertEqual(u'Assunção\n', out) self.assertEqual(fc.requests[0]['path'], 'salt://macro') SaltCacheLoader.file_client = _fc
def test_saltenv(self): ''' If the template is within the searchpath it can import, include and extend other templates. The initial template is expected to be already cached get_template does not request it from the master again. ''' fc = MockFileClient() # monkey patch file client _fc = SaltCacheLoader.file_client SaltCacheLoader.file_client = lambda loader: fc filename = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_import') out = render_jinja_tmpl( salt.utils.fopen(filename).read(), dict(opts={ 'cachedir': TEMPLATES_DIR, 'file_client': 'remote', 'file_roots': self.local_opts['file_roots'], 'pillar_roots': self.local_opts['pillar_roots'] }, a='Hi', b='Salt', saltenv='test')) self.assertEqual(out, 'Hey world !Hi Salt !\n') self.assertEqual(fc.requests[0]['path'], 'salt://macro') SaltCacheLoader.file_client = _fc
def test_is_ipv6(self): '''Test the `is_ipv6` Jinja filter.''' rendered = render_jinja_tmpl( "{{ '192.168.0.1' | is_ipv6 }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'False') rendered = render_jinja_tmpl( "{{ 'FE80::' | is_ipv6 }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'True') rendered = render_jinja_tmpl( "{{ 'random' | is_ipv6 }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'False')
def test_saltenv(self): ''' If the template is within the searchpath it can import, include and extend other templates. The initial template is expected to be already cached get_template does not request it from the master again. ''' fc = MockFileClient() with patch.object(SaltCacheLoader, 'file_client', MagicMock(return_value=fc)): filename = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_import') with salt.utils.files.fopen(filename) as fp_: out = render_jinja_tmpl( fp_.read(), dict(opts={ 'cachedir': TEMPLATES_DIR, 'file_client': 'remote', 'file_roots': self.local_opts['file_roots'], 'pillar_roots': self.local_opts['pillar_roots'] }, a='Hi', b='Salt', saltenv='test', salt=self.local_salt)) self.assertEqual(out, 'Hey world !Hi Salt !' + os.linesep) self.assertEqual(fc.requests[0]['path'], 'salt://macro')
def test_http_query(minion_opts, local_salt, backend): """ Test the `http_query` Jinja filter. """ urls = ( # These cannot be HTTPS urls since urllib2 chokes on those "http://saltproject.io", "http://google.com", "http://duckduckgo.com", ) rendered = render_jinja_tmpl( "{{ '" + random.choice(urls) + "' | http_query(backend='" + backend + "') }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert isinstance( rendered, str), "Failed with rendered template: {}".format(rendered) dict_reply = ast.literal_eval(rendered) assert isinstance( dict_reply, dict), "Failed with rendered template: {}".format(rendered) assert ( "body" in dict_reply ), "'body' not found in request response({}). Rendered template: {!r}".format( dict_reply, rendered) assert isinstance( dict_reply["body"], str), "Failed with rendered template: {}".format(rendered)
def test_hmac(minion_opts, local_salt): """ Test the `hmac` Jinja filter. """ rendered = render_jinja_tmpl( "{{ 'random' | hmac('secret', 'blah') }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert rendered == "False" rendered = render_jinja_tmpl( "{{ 'get salted' | " "hmac('shared secret', 'eBWf9bstXg+NiP5AOwppB5HMvZiYMPzEM9W5YMm/AmQ=') }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert rendered == "True"
def test_saltenv(minion_opts, local_salt, mock_file_client, hello_import): """ If the template is within the searchpath it can import, include and extend other templates. The initial template is expected to be already cached get_template does not request it from the master again. """ fc = MockFileClient() opts = { "cachedir": minion_opts["cachedir"], "file_client": "remote", "file_roots": minion_opts["file_roots"], "pillar_roots": minion_opts["pillar_roots"], } with patch.object(SaltCacheLoader, "file_client", MagicMock(return_value=fc)): with salt.utils.files.fopen(str(hello_import)) as fp_: out = render_jinja_tmpl( salt.utils.stringutils.to_unicode(fp_.read()), dict( opts=opts, a="Hi", b="Salt", saltenv="test", salt=local_salt, ), ) assert out == "Hey world !Hi Salt !" + os.linesep assert fc.requests[0]["path"] == "salt://macro"
def test_http_query(minion_opts, local_salt, backend, httpserver): """ Test the `http_query` Jinja filter. """ urls = ( # These cannot be HTTPS urls since urllib2 chokes on those "http://saltproject.io", "http://google.com", "http://duckduckgo.com", ) response = { "backend": backend, "body": "Hey, this isn't http://google.com!", } httpserver.expect_request("/{}".format(backend)).respond_with_data( salt.utils.json.dumps(response), content_type="text/plain") rendered = render_jinja_tmpl( "{{ '" + httpserver.url_for("/{}".format(backend)) + "' | http_query(backend='" + backend + "') }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert isinstance( rendered, str), "Failed with rendered template: {}".format(rendered) dict_reply = ast.literal_eval(rendered) assert isinstance( dict_reply, dict), "Failed with rendered template: {}".format(rendered) assert ( "body" in dict_reply ), "'body' not found in request response({}). Rendered template: {!r}".format( dict_reply, rendered) assert isinstance( dict_reply["body"], str), "Failed with rendered template: {}".format(rendered)
def test_strftime(self): response = render_jinja_tmpl( '{{ "2002/12/25"|strftime }}', dict( opts=self.local_opts, saltenv='test', salt=self.local_salt )) self.assertEqual(response, '2002-12-25') objects = ( datetime.datetime(2002, 12, 25, 12, 00, 00, 00), '2002/12/25', 1040814000, '1040814000' ) for object in objects: response = render_jinja_tmpl( '{{ object|strftime }}', dict( object=object, opts=self.local_opts, saltenv='test', salt=self.local_salt )) self.assertEqual(response, '2002-12-25') response = render_jinja_tmpl( '{{ object|strftime("%b %d, %Y") }}', dict( object=object, opts=self.local_opts, saltenv='test', salt=self.local_salt )) self.assertEqual(response, 'Dec 25, 2002') response = render_jinja_tmpl( '{{ object|strftime("%y") }}', dict( object=object, opts=self.local_opts, saltenv='test', salt=self.local_salt )) self.assertEqual(response, '02')
def test_to_bool(self): '''Test the `to_bool` Jinja filter.''' rendered = render_jinja_tmpl("{{ 1 | to_bool }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'True') rendered = render_jinja_tmpl("{{ 'True' | to_bool }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'True') rendered = render_jinja_tmpl("{{ 0 | to_bool }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'False') rendered = render_jinja_tmpl("{{ 'Yes' | to_bool }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'True')
def test_fallback_noloader(self): """ A Template with a filesystem loader is returned as fallback if the file is not contained in the searchpath """ filename = os.path.join(TEMPLATES_DIR, "files", "test", "hello_import") out = render_jinja_tmpl(salt.utils.fopen(filename).read(), dict(opts=self.local_opts, env="other")) self.assertEqual(out, "Hey world !a b !\n")
def test_avg(self): ''' Test the `avg` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ [1, 2, 3] | avg }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, '2.0')
def test_md5(self): ''' Test the `md5` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ 'random' | md5 }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, '7ddf32e17a6ac5ce04a8ecbf782ca509')
def test_base64_decode(self): ''' Test the `base64_decode` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ 'cmFuZG9t' | base64_decode }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, 'random')
def test_intersect(self): ''' Test the `intersect` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ [1, 2, 3] | intersect([2, 3, 4]) | join(', ') }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, '2, 3')
def test_symmetric_difference(self): ''' Test the `symmetric_difference` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ [1, 2, 3] | symmetric_difference([2, 3, 4]) | join(', ') }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, '1, 4')
def test_regex_search(self): '''Test the `regex_search` Jinja filter.''' rendered = render_jinja_tmpl( "{{ 'abcdefabcdef' | regex_search('BC(.*)', ignorecase=True) }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual( rendered, u"('defabcdef',)") # because search looks only at the beginning
def test_union(self): ''' Test the `union` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ [1, 2, 3] | union([2, 3, 4]) | join(', ') }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, '1, 2, 3, 4')
def test_uuid(self): ''' Test the `uuid` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ 'random' | uuid }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, '3652b285-26ad-588e-a5dc-c2ee65edc804')
def test_max(self): ''' Test the `max` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ [1, 2, 3] | max }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, '3')
def test_regex_replace(self): ''' Test the `regex_replace` Jinja filter. ''' rendered = render_jinja_tmpl( r"{{ 'lets replace spaces' | regex_replace('\s+', '__') }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, 'lets__replace__spaces')
def test_regex_match(self): ''' Test the `regex_match` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ 'abcdefabcdef' | regex_match('BC(.*)', ignorecase=True)}}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, "None")
def test_quote(self): ''' Test the `quote` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ 'random' | quote }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, 'random')
def test_network_hosts(self): ''' Test the `network_hosts` Jinja filter. ''' rendered = render_jinja_tmpl( "{{ '192.168.0.1/30' | network_hosts | join(', ') }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, '192.168.0.1, 192.168.0.2')
def test_ipv6(self): '''Test the `ipv6` Jinja filter.''' rendered = render_jinja_tmpl("{{ '192.168.0.1' | ipv6 }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'None') rendered = render_jinja_tmpl("{{ 'random' | ipv6 }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'None') # returns the standard format value rendered = render_jinja_tmpl("{{ 'FE80:0:0::0' | ipv6 }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'fe80::') # fe80:: is link local therefore will be returned rendered = render_jinja_tmpl("{{ 'fe80::' | ipv6(options='ll') }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'fe80::') # fe80:: is not loopback rendered = render_jinja_tmpl("{{ 'fe80::' | ipv6(options='lo') }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'None') # returns only IPv6 addresses in the list rendered = render_jinja_tmpl("{{ ['fe80::', '192.168.0.1'] | ipv6 | join(', ') }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'fe80::') rendered = render_jinja_tmpl("{{ ['fe80::', '::'] | ipv6 | join(', ') }}", dict(opts=self.local_opts, saltenv='test', salt=self.local_salt)) self.assertEqual(rendered, u'fe80::, ::')
def test_fallback(self): """ A Template with a filesystem loader is returned as fallback if the file is not contained in the searchpath """ fn_ = os.path.join(TEMPLATES_DIR, "files", "test", "hello_simple") with salt.utils.fopen(fn_) as fp_: out = render_jinja_tmpl(fp_.read(), dict(opts=self.local_opts, env="other")) self.assertEqual(out, "world\n")
def test_md5(minion_opts, local_salt): """ Test the `md5` Jinja filter. """ rendered = render_jinja_tmpl( "{{ 'random' | md5 }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert rendered == "7ddf32e17a6ac5ce04a8ecbf782ca509"
def test_intersect(minion_opts, local_salt): """ Test the `intersect` Jinja filter. """ rendered = render_jinja_tmpl( "{{ [1, 2, 3] | intersect([2, 3, 4]) | join(', ') }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert rendered == "2, 3"
def test_symmetric_difference(minion_opts, local_salt): """ Test the `symmetric_difference` Jinja filter. """ rendered = render_jinja_tmpl( "{{ [1, 2, 3] | symmetric_difference([2, 3, 4]) | join(', ') }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert rendered == "1, 4"
def test_avg(minion_opts, local_salt): """ Test the `avg` Jinja filter. """ rendered = render_jinja_tmpl( "{{ [1, 2, 3] | avg }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert rendered == "2.0"
def test_max(minion_opts, local_salt): """ Test the `max` Jinja filter. """ rendered = render_jinja_tmpl( "{{ [1, 2, 3] | max }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert rendered == "3"
def test_uuid(minion_opts, local_salt): """ Test the `uuid` Jinja filter. """ rendered = render_jinja_tmpl( "{{ 'random' | uuid }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert rendered == "3652b285-26ad-588e-a5dc-c2ee65edc804"
def test_regex_replace(minion_opts, local_salt): """ Test the `regex_replace` Jinja filter. """ rendered = render_jinja_tmpl( r"{{ 'lets replace spaces' | regex_replace('\s+', '__') }}", dict(opts=minion_opts, saltenv="test", salt=local_salt), ) assert rendered == "lets__replace__spaces"
def test_fallback_noloader(self): ''' A Template with a filesystem loader is returned as fallback if the file is not contained in the searchpath ''' filename = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_import') out = render_jinja_tmpl( salt.utils.fopen(filename).read(), dict(opts=self.local_opts, saltenv='other')) self.assertEqual(out, 'Hey world !a b !\n')
def test_fallback(self): ''' A Template with a filesystem loader is returned as fallback if the file is not contained in the searchpath ''' fn_ = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_simple') with salt.utils.fopen(fn_) as fp_: out = render_jinja_tmpl( fp_.read(), dict(opts=self.local_opts, saltenv='other')) self.assertEqual(out, 'world\n')
def test_strftime(self): response = render_jinja_tmpl('{{ "2002/12/25"|strftime }}', dict(opts=self.local_opts, saltenv='other')) self.assertEqual(response, '2002-12-25') objects = ( datetime.datetime(2002, 12, 25, 12, 00, 00, 00), '2002/12/25', 1040814000, '1040814000' ) for object in objects: response = render_jinja_tmpl('{{ object|strftime }}', dict(object=object, opts=self.local_opts, saltenv='other')) self.assertEqual(response, '2002-12-25') response = render_jinja_tmpl('{{ object|strftime("%b %d, %Y") }}', dict(object=object, opts=self.local_opts, saltenv='other')) self.assertEqual(response, 'Dec 25, 2002') response = render_jinja_tmpl('{{ object|strftime("%y") }}', dict(object=object, opts=self.local_opts, saltenv='other')) self.assertEqual(response, '02')
def test_saltenv(self): ''' If the template is within the searchpath it can import, include and extend other templates. The initial template is expected to be already cached get_template does not request it from the master again. ''' fc = MockFileClient() # monkey patch file client _fc = SaltCacheLoader.file_client SaltCacheLoader.file_client = lambda loader: fc filename = os.path.join(TEMPLATES_DIR, 'files', 'test', 'hello_import') out = render_jinja_tmpl( salt.utils.fopen(filename).read(), dict(opts={'cachedir': TEMPLATES_DIR, 'file_client': 'remote'}, a='Hi', b='Salt', saltenv='test')) self.assertEqual(out, 'Hey world !Hi Salt !\n') self.assertEqual(fc.requests[0]['path'], 'salt://macro') SaltCacheLoader.file_client = _fc
def test_env(self): """ If the template is within the searchpath it can import, include and extend other templates. The initial template is expected to be already cached get_template does not request it from the master again. """ fc = MockFileClient() # monkey patch file client _fc = SaltCacheLoader.file_client SaltCacheLoader.file_client = lambda loader: fc filename = os.path.join(TEMPLATES_DIR, "files", "test", "hello_import") out = render_jinja_tmpl( salt.utils.fopen(filename).read(), dict(opts={"cachedir": TEMPLATES_DIR, "file_client": "remote"}, a="Hi", b="Salt", env="test"), ) self.assertEqual(out, "Hey world !Hi Salt !\n") self.assertEqual(fc.requests[0]["path"], "salt://macro") SaltCacheLoader.file_client = _fc