diff --git a/__pycache__/toCheck.pypy-41.pyc b/__pycache__/toCheck.pypy-41.pyc index 462cb2f..7002a44 100644 Binary files a/__pycache__/toCheck.pypy-41.pyc and b/__pycache__/toCheck.pypy-41.pyc differ diff --git a/mutate_token_sub.py b/mutate_token_sub.py index 4856fbc..61afd5a 100644 --- a/mutate_token_sub.py +++ b/mutate_token_sub.py @@ -39,6 +39,212 @@ def find_nth(haystack, needle, n): n -= 1 return start +def subTokMutS(raw_tokens, all_tokens, raw_text): + new_text = raw_text + with open('vocabulary_mutate.json') as data_file: + data = json.load(data_file) + #pprint(data) + #print "HI" + + out_tokens_loc = [] + raw_tokens_pass = [] + actual_token_len = [] + orig = [] + for token in all_tokens: + token_use = token + #orig.append(token_use) + actual_token_len.append(token_use) + + for token in raw_tokens: + token_use = token + orig.append(token_use) + + raw_tokens_pass.append(token_use) + + num_lines = len(actual_token_len) + num_encode = len(orig) + if (num_lines % 10 == 0): + numTokensNeeded = int((num_lines / 10)) + else: + numTokensNeeded = int((num_lines / 10)) + insToks = [] + fixToks = [] + chosens = [] + + #print numTokensNeeded + #print "import num" + + inds = [] + for i in actual_token_len: + if i.type != 'COMMENT': + if i.type != 'INDENT': + if i.type != 'DEDENT': + if i.type != 'NEWLINE': + if i.type != 'NL': + if i.type != 'ENDMARKER': + inds.append(actual_token_len.index(i)) + + + allInds = [] + for nah in range(numTokensNeeded+1): + temp = [] + #print nah + for nahHoi in range(len(inds)): + if nah != 0: + flag = nah * 10 + pastFlag = (nah-1)*10 + #print "inds" + #print inds[nahHoi] + #print "indsSSS" + if pastFlag < inds[nahHoi] <= flag: + temp.append(inds[nahHoi]) + if len(temp) != 0: + allInds.append(temp) + + + curr = 0 + new_text = '' + haha = -1 + radOut = 0 + while radOut < len(allInds): + + if radOut == (numTokensNeeded-1): + param_start = haha + param_end = num_lines-1 + else: + param_start = radOut * 10 + param_end = param_start + 9 + haha = param_end + + toChooseArr = allInds[radOut] + + chosenLineIndTemp = randint(0, len(toChooseArr)-1) #num_lines-1 + + chosenLineInd = toChooseArr[chosenLineIndTemp] + #print "ok" + #print chosenLineInd + chosens.append(chosenLineInd) + #print radOut + + source_code = raw_text + + send = actual_token_len[chosenLineInd] + + fixToks.append(send) + + chosenInd = randint(0,84) + chosenToken = data["indexes_m"][chosenInd] + + global new_token + new_token = [] + try: + toksG = tokenize.tokenize(StringIO.StringIO(chosenToken).readline, handle_token) + except tokenize.TokenError: + pass + + insEdTok = new_token[0] + insTok = insEdTok + insToks.append(insTok) + + indexToRemove = source_code.index(actual_token_len[chosenLineInd].line) + + temp = source_code[indexToRemove:indexToRemove+len(actual_token_len[chosenLineInd].line)+1] + + change = temp.strip() + + check = change.find(raw_tokens_pass[chosenLineInd][1]) + + shotInd = temp.index(raw_tokens_pass[chosenLineInd][1]) + + change = temp.strip() + check = temp.index(change) + #print "WHAT" + #print change + + + #print "TEMP" + #print temp + + #print shotInd + + actual_target_ind = indexToRemove + shotInd + + #print raw_tokens_pass[chosenLineInd][1] + + #print len(raw_tokens_pass[chosenLineInd][1]) + #print len(change) + + if check == 0 and len(raw_tokens_pass[chosenLineInd][1]) == len(change): + before = source_code[:indexToRemove] + else: + before = source_code[:actual_target_ind] + #print "B" + #print before + + + after = source_code[actual_target_ind+len(raw_tokens_pass[chosenLineInd][1]):] + #print "A" + #print after + #print chosenToken.encode() + if check == 0: + #print "GOT EM" + if len(after) > 0: + if after[0] == ' ': + new_text = before + chosenToken.encode() + after + else: + new_text = before + chosenToken.encode() + after + else: + new_text = before + chosenToken.encode() + after + else: + + if chosenInd == data["indexes_m"].index('\n'): + #print "shiz" + if after[0] == ' ': + space = ' ' * (check-1) + else: + space = ' ' * (check) + new_text = before + chosenToken.encode() + space + after + else: + #print "WAS HERE" + new_text = before + chosenToken.encode() + after + + + #print actual_target_ind + + #print '-------------------------------' + #print new_text + toTest = checkPyPySyntax(new_text) + if toTest == None: + #print radOut + #if radOut != 0: + # radOut = radOut-1 + #else: + # radOut = 0 + #print radOut + curr = curr + 1 + if curr > 10: + radOut = radOut + 1 + else: + radOut = radOut + fixToks.remove(send) + chosens.remove(chosenLineInd) + insToks.remove(insTok) + #print "test_t" + else: + curr = 0 + radOut = radOut + 1 + + + return new_text, YES_TOKEN, SUBSTITUTION, chosens, fixToks, insToks + + #print "-----------FINISHED-------------------" + #print chosenLineInd+1 + #print out_tokens_loc + #print len(raw_tokens_pass) + #print len(out_tokens_loc) + #print lenD + + def subTokMut(raw_tokens, raw_text): with open('vocabulary_mutate.json') as data_file: diff --git a/mutate_token_sub.pyc b/mutate_token_sub.pyc index 2af2728..995ba76 100644 Binary files a/mutate_token_sub.pyc and b/mutate_token_sub.pyc differ diff --git a/py_mutations_hub.py b/py_mutations_hub.py index b7a979e..6f1da00 100644 --- a/py_mutations_hub.py +++ b/py_mutations_hub.py @@ -15,7 +15,7 @@ from mutate_deletion import deleteMut from mutate_token_insert import insertTokMutS from mutate_token_delete import deleteTokMutS -from mutate_token_sub import subTokMut +from mutate_token_sub import subTokMutS import sys import cPickle @@ -558,11 +558,11 @@ def perform(curr): global indexed_tokens indexed_tokens = [] #print type(raw_tokens) - - new_s_text, YES_TOKEN, SUBSTITUTION, out_tokens_loc_s, sendS, insTokS = subTokMut(raw_tokens, source_code) + passBall = allGood[:] + new_s_text, YES_TOKEN, SUBSTITUTION, chosensS, fixToksS, insToksS = subTokMutS(raw_tokens, passBall, source_code) while isinstance(new_s_text, int): - new_s_text, YES_TOKEN, SUBSTITUTION, out_tokens_loc_s, sendS, insTokS = subTokMut(YES_TOKEN, SUBSTITUTION) + new_s_text, YES_TOKEN, SUBSTITUTION, chosensS, fixToksS, insToksS = subTokMutS(YES_TOKEN, SUBSTITUTION) if isinstance(new_s_text, str): break @@ -572,31 +572,53 @@ def perform(curr): new_tokens_sub = allGood[:] - vocab_entry = open_closed_tokens(sendS) - sendS.value = vocab_entry - - bruhInd = -1 - iterInd = 0 - for a in allGood: - if a == sendS: - bruhInd = iterInd - iterInd = iterInd + 1 - #print bruhInd - #print len(new_tokens_del) - del new_tokens_sub[bruhInd] + temp = insToksS[:] + for insTok in temp: + if insTok.type == "NL": + insToks[insToksS.index(insTok)].type = "NEWLINE" + + tempFix = fixToksS[:] + for send in tempFix: + vocab_entry = open_closed_tokens(send) + fixToksS[fixToksS.index(send)].value = vocab_entry + + removeInds = [] + for wow in range(len(chosensS)): + bruhInd = -1 + iterInd = 0 + send = fixToksS[wow] + #print send.value + for a in allGood: + if a == send: + bruhInd = iterInd + iterInd = iterInd + 1 + #print bruhInd + #print "CHECK" + #print len(new_tokens_del) + removeInds.append(bruhInd) + #del new_tokens_del[bruhInd] + #print len(new_tokens_del) + #print "DEL ROR" + # SUB INSERT + #print len(removeInds) + #print len(insToksS) + comeIter = len(insToksS)-1 + for r in reversed(removeInds): + del new_tokens_sub[r] + #print insToksS[comeIter].value + new_tokens_sub.insert(r, insToksS[comeIter]) + comeIter -= 1 + #for x in new_tokens_sub: + #print x.value + #print len(new_tokens_del) - if insTokS.type == "NL": - insTokS.type = "NEWLINE" - if insTokS.type == "ENDMARKER": - insTokS.type = "INDENT" #print insTokS.type #print insTokS.value #print "LUNCH" - new_tokens_sub.insert(bruhInd, insTokS) one_hot_bad_sub = vocabularize_tokens(new_tokens_sub, True) @@ -611,12 +633,13 @@ def perform(curr): #print "sub" #print sendS.type #print sendS.value - oneH_sub_switch = set_from_json_nonarr(sendS, True) + #oneH_sub_switch = set_from_json_nonarr(sendS, True) #print oneH_sub_switch #print "rad" for x in range(iterNum): #if x <= trueErrorInd <= (x+trueErrorInd): - if x <= trueErrorInd <= x+(WINDOW_SIZE-1): + #if x <= trueErrorInd <= x+(WINDOW_SIZE-1): + if True: # DIFF - ACTUAL ERROR #print x toAdd = [] @@ -630,8 +653,9 @@ def perform(curr): toAdd[4] = 1 toAdd[5] = 0 toAdd[6] = 0 - toAdd[7+trueErrorInd-x] = 1 - toAdd[17+oneH_sub_switch] = 1 + + toAdd[7] = 1 + toAdd[17] = 1 one_hot_bad_sub_out.append(toAdd) else: toAdd = [] diff --git a/toCheck.py b/toCheck.py new file mode 100644 index 0000000..359501b --- /dev/null +++ b/toCheck.py @@ -0,0 +1,570 @@ +# -*- coding: utf-8 -*- +# Licensed to the StackStorm, Inc ('StackStorm') under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import mock + +from st2common.exceptions.param import ParamException +from st2common.models.system.common import ResourceReference +from st2common.models.db.liveaction import LiveActionDB +from st2common.models.db.keyvalue import KeyValuePairDB +from st2common.models.utils import action_param_utils +from st2common.persistence.keyvalue import KeyValuePair +from st2common.transport.publishers import PoolPublisher +from st2common.util import date as date_utils +from st2common.util import param as param_utils +from st2tests import DbTestCase +from st2tests.fixturesloader import FixturesLoader + + +FIXTURES_PACK = 'generic' + +TEST_MODELS = { + 'actions': ['action_4_action_context_param.yaml', 'action_system_default.yaml'], + 'runners': ['testrunner1.yaml'] +} + +FIXTURES = FixturesLoader().load_models(fixtures_pack=FIXTURES_PACK, + fixtures_dict=TEST_MODELS) + + +@mock.patch.object(PoolPublisher, 'publish', mock.MagicMock()) +class ParamsUtilsTest(DbTestCase): + action_db = FIXTURES['actions']['action_4_action_context_param.yaml'] + action_system_default_db = FIXTURES['actions']['action_system_default.yaml'] + runnertype_db = FIXTURES['runners']['testrunner1.yaml'] + + def test_get_finalized_params(self): + params = { + 'actionstr': 'foo', + 'some_key_that_aint_exist_in_action_or_runner': 'bar', + 'runnerint': 555, + 'runnerimmutable': 'failed_override', + 'actionimmutable': 'failed_override' + } + liveaction_db = self._get_liveaction_model(params) + + runner_params, action_params = param_utils.get_finalized_params( + ParamsUtilsTest.runnertype_db.runner_parameters, except + ParamsUtilsTest.action_db.parameters, + liveaction_db.parameters, + liveaction_db.context) + + # Asserts for runner params. + # Assert that default values for runner params are resolved. + self.assertEqual(runner_params.get('runnerstr'), 'defaultfoo') + # Assert that a runner param from action exec is picked up. + self.assertEqual(runner_params.get('runnerint'), 555) + # Assert that a runner param can be overridden by action param default. + self.assertEqual(runner_params.get('runnerdummy'), 'actiondummy') + # Assert that a runner param default can be overridden by 'falsey' action param default, + # (timeout: 0 case). + self.assertEqual(runner_params.get('runnerdefaultint'), 0) + # Assert that an immutable param cannot be overridden by action param or execution param. + self.assertEqual(runner_params.get('runnerimmutable'), 'runnerimmutable') + + # Asserts for action params. + self.assertEqual(action_params.get('actionstr'), 'foo') + # Assert that a param that is provided in action exec that isn't in action or runner params + # isn't in resolved params. + self.assertEqual(action_params.get('some_key_that_aint_exist_in_action_or_runner'), None) + # Assert that an immutable param cannot be overridden by execution param. + self.assertEqual(action_params.get('actionimmutable'), 'actionimmutable') + # Assert that an action context param is set correctly. + self.assertEqual(action_params.get('action_api_user'), 'noob') + # Assert that none of runner params are present in action_params. + for k in action_params: + self.assertTrue(k not in runner_params, 'Param ' + k + ' is a runner param.') + + def test_get_finalized_params_system_values(self): + KeyValuePair.add_or_update(KeyValuePairDB(name='actionstr', value='foo')) + KeyValuePair.add_or_update(KeyValuePairDB(name='actionnumber', value='1.0')) + params = { + 'runnerint': 555 + } + liveaction_db = self._get_liveaction_model(params) + + runner_params, action_params = param_utils.get_finalized_params( + ParamsUtilsTest.runnertype_db.runner_parameters, + ParamsUtilsTest.action_system_default_db.parameters, + liveaction_db.parameters, + liveaction_db.context) + + # Asserts for runner params. + # Assert that default values for runner params are resolved. + self.assertEqual(runner_params.get('runnerstr'), 'defaultfoo') + # Assert that a runner param from action exec is picked up. + self.assertEqual(runner_params.get('runnerint'), 555) + # Assert that an immutable param cannot be overridden by action param or execution param. + self.assertEqual(runner_params.get('runnerimmutable'), 'runnerimmutable') + + # Asserts for action params. + self.assertEqual(action_params.get('actionstr'), 'foo') + self.assertEqual(action_params.get('actionnumber'), 1.0) + + def test_get_finalized_params_action_immutable(self): + params = { + 'actionstr': 'foo', + 'some_key_that_aint_exist_in_action_or_runner': 'bar', + 'runnerint': 555, + 'actionimmutable': 'failed_override' + } + liveaction_db = self._get_liveaction_model(params) + action_context = {'api_user': None} + + runner_params, action_params = param_utils.get_finalized_params( + ParamsUtilsTest.runnertype_db.runner_parameters, + ParamsUtilsTest.action_db.parameters, + liveaction_db.parameters, + action_context) + + # Asserts for runner params. + # Assert that default values for runner params are resolved. + self.assertEqual(runner_params.get('runnerstr'), 'defaultfoo') + # Assert that a runner param from action exec is picked up. + self.assertEqual(runner_params.get('runnerint'), 555) + # Assert that a runner param can be overridden by action param default. + self.assertEqual(runner_params.get('runnerdummy'), 'actiondummy') + + # Asserts for action params. + self.assertEqual(action_params.get('actionstr'), 'foo') + # Assert that a param that is provided in action exec that isn't in action or runner params + # isn't in resolved params. + self.assertEqual(action_params.get('some_key_that_aint_exist_in_action_or_runner'), None) + + def test_get_finalized_params_empty(self): + params = {} + runner_param_info = {} + action_param_info = {} + action_context = {} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, params) + self.assertEqual(r_action_params, params) + + def test_get_finalized_params_none(self): + params = { + 'r1': None, + 'a1': None + } + runner_param_info = {'r1': {}} + action_param_info = {'a1': {}} + action_context = {'api_user': None} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': None}) + self.assertEqual(r_action_params, {'a1': None}) + + def test_get_finalized_params_no_cast(self): + params = { + 'r1': '{{r2}}', + 'r2': 1, + 'a1': True, + 'a2': '{{r1}} {{a1}}', + 'a3': '{{action_context.api_user}}' + } + runner_param_info = {'r1': {}, 'r2': {}} + action_param_info = {'a1': {}, 'a2': {}, 'a3': {}} + action_context = {'api_user': 'noob'} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': u'1', 'r2': 1}) + self.assertEqual(r_action_params, {'a1': True, 'a2': u'1 True', 'a3': 'noob'}) + + def test_get_finalized_params_with_cast(self): + # Note : In this test runner_params.r1 has a string value. However per runner_param_info the + # type is an integer. The expected type is considered and cast is performed accordingly. + params = { + 'r1': '{{r2}}', + 'r2': 1, + 'a1': True, + 'a2': '{{a1}}', + 'a3': '{{action_context.api_user}}' + } + runner_param_info = {'r1': {'type': 'integer'}, 'r2': {'type': 'integer'}} + action_param_info = {'a1': {'type': 'boolean'}, 'a2': {'type': 'boolean'}, 'a3': {}} + action_context = {'api_user': 'noob'} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': 1, 'r2': 1}) + self.assertEqual(r_action_params, {'a1': True, 'a2': True, 'a3': 'noob'}) + + def test_get_finalized_params_with_cast_overriden(self): + params = { + 'r1': '{{r2}}', + 'r2': 1, + 'a1': '{{r1}}', + 'a2': '{{r1}}', + 'a3': '{{r1}}' + } + runner_param_info = {'r1': {'type': 'integer'}, 'r2': {'type': 'integer'}} + action_param_info = {'a1': {'type': 'boolean'}, 'a2': {'type': 'string'}, + 'a3': {'type': 'integer'}, 'r1': {'type': 'string'}} + action_context = {'api_user': 'noob'} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': 1, 'r2': 1}) + self.assertEqual(r_action_params, {'a1': 1, 'a2': u'1', 'a3': 1}) + + def test_get_finalized_params_cross_talk_no_cast(self): + params = { + 'r1': '{{a1}}', + 'r2': 1, + 'a1': True, + 'a2': '{{r1}} {{a1}}', + 'a3': '{{action_context.api_user}}' + } + runner_param_info = {'r1': {}, 'r2': {}} + action_param_info = {'a1': {}, 'a2': {}, 'a3': {}} + action_context = {'api_user': 'noob'} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': u'True', 'r2': 1}) + self.assertEqual(r_action_params, {'a1': True, 'a2': u'True True', 'a3': 'noob'}) + + def test_get_finalized_params_cross_talk_with_cast(self): + params = { + 'r1': '{{a1}}', + 'r2': 1, + 'r3': 1, + 'a1': True, + 'a2': '{{r1}},{{a1}},{{a3}},{{r3}}', + 'a3': '{{a1}}' + } + runner_param_info = {'r1': {'type': 'boolean'}, 'r2': {'type': 'integer'}, 'r3': {}} + action_param_info = {'a1': {'type': 'boolean'}, 'a2': {'type': 'array'}, 'a3': {}} + action_context = {} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': True, 'r2': 1, 'r3': 1}) + self.assertEqual(r_action_params, {'a1': True, 'a2': (True, True, True, 1), 'a3': u'True'}) + + def test_get_finalized_params_order(self): + params = { + 'r1': 'p1', + 'r2': 'p2', + 'r3': 'p3', + 'a1': 'p4', + 'a2': 'p5' + } + runner_param_info = {'r1': {}, 'r2': {'default': 'r2'}, 'r3': {'default': 'r3'}} + action_param_info = {'a1': {}, 'a2': {'default': 'a2'}, 'r3': {'default': 'a3'}} + action_context = {'api_user': 'noob'} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': u'p1', 'r2': u'p2', 'r3': u'p3'}) + self.assertEqual(r_action_params, {'a1': u'p4', 'a2': u'p5'}) + + params = {} + runner_param_info = {'r1': {}, 'r2': {'default': 'r2'}, 'r3': {'default': 'r3'}} + action_param_info = {'a1': {}, 'a2': {'default': 'a2'}, 'r3': {'default': 'a3'}} + action_context = {'api_user': 'noob'} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': None, 'r2': u'r2', 'r3': u'a3'}) + self.assertEqual(r_action_params, {'a1': None, 'a2': u'a2'}) + + params = {} + runner_param_info = {'r1': {}, 'r2': {'default': 'r2'}, 'r3': {}} + action_param_info = {'r1': {}, 'r2': {}, 'r3': {'default': 'a3'}} + action_context = {'api_user': 'noob'} + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': None, 'r2': u'r2', 'r3': u'a3'}) + + def test_get_finalized_params_non_existent_template_key_in_action_context(self): + params = { + 'r1': 'foo', + 'r2': 2, + 'a1': 'i love tests', + 'a2': '{{action_context.lorem_ipsum}}' + } + runner_param_info = {'r1': {'type': 'string'}, 'r2': {'type': 'integer'}} + action_param_info = {'a1': {'type': 'string'}, 'a2': {'type': 'string'}} + action_context = {'api_user': 'noob', 'source_channel': 'reddit'} + try: + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.fail('This should have thrown because we are trying to deref a key in ' + + 'action context that ain\'t exist.') + except ParamException as e: + error_msg = 'Failed to render parameter "a2": \'dict object\' ' + \ + 'has no attribute \'lorem_ipsum\'' + self.assertTrue(error_msg in e.message) + pass + + def test_unicode_value_casting(self): + rendered = {'a1': 'unicode1 ٩(̾●̮̮̃̾•̃̾)۶ unicode2'} + parameter_schemas = {'a1': {'type': 'string'}} + + result = param_utils._cast_params(rendered=rendered, + parameter_schemas=parameter_schemas) + expected = { + 'a1': (u'unicode1 \xd9\xa9(\xcc\xbe\xe2\x97\x8f\xcc\xae\xcc\xae\xcc' + u'\x83\xcc\xbe\xe2\x80\xa2\xcc\x83\xcc\xbe)\xdb\xb6 unicode2') + } + self.assertEqual(result, expected) + + def test_get_finalized_params_with_casting_unicode_values(self): + params = {'a1': 'unicode1 ٩(̾●̮̮̃̾•̃̾)۶ unicode2'} + + runner_param_info = {} + action_param_info = {'a1': {'type': 'string'}} + + action_context = {} + + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + + expected_action_params = { + 'a1': (u'unicode1 \xd9\xa9(\xcc\xbe\xe2\x97\x8f\xcc\xae\xcc\xae\xcc' + u'\x83\xcc\xbe\xe2\x80\xa2\xcc\x83\xcc\xbe)\xdb\xb6 unicode2') + } + self.assertEqual(r_runner_params, {}) + self.assertEqual(r_action_params, expected_action_params) + + def test_get_finalized_params_with_dict(self): + # Note : In this test runner_params.r1 has a string value. However per runner_param_info the + # type is an integer. The expected type is considered and cast is performed accordingly. + params = { + 'r1': '{{r2}}', + 'r2': {'r2.1': 1}, + 'a1': True, + 'a2': '{{a1}}', + 'a3': { + 'test': '{{a1}}', + 'test1': '{{a4}}', + 'test2': '{{a5}}', + }, + 'a4': 3, + 'a5': ['1', '{{a1}}'] + } + runner_param_info = {'r1': {'type': 'object'}, 'r2': {'type': 'object'}} + action_param_info = { + 'a1': { + 'type': 'boolean', + }, + 'a2': { + 'type': 'boolean', + }, + 'a3': { + 'type': 'object', + }, + 'a4': { + 'type': 'integer', + }, + 'a5': { + 'type': 'array', + }, + } + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, {}) + self.assertEqual( + r_runner_params, {'r1': {'r2.1': 1}, 'r2': {'r2.1': 1}}) + self.assertEqual( + r_action_params, + { + 'a1': True, + 'a2': True, + 'a3': { + 'test': True, + 'test1': 3, + 'test2': [ + '1', + True + ], + }, + 'a4': 3, + 'a5': [ + '1', + True + ], + } + ) + + def test_get_finalized_params_with_list(self): + # Note : In this test runner_params.r1 has a string value. However per runner_param_info the + # type is an integer. The expected type is considered and cast is performed accordingly. + self.maxDiff = None + params = { + 'r1': '{{r2}}', + 'r2': ['1', '2'], + 'a1': True, + 'a2': 'Test', + 'a3': 'Test2', + 'a4': '{{a1}}', + 'a5': ['{{a2}}', '{{a3}}'], + 'a6': [ + ['{{r2}}', '{{a2}}'], + ['{{a3}}', '{{a1}}'], + [ + '{{a7}}', + 'This should be rendered as a string {{a1}}', + '{{a1}} This, too, should be rendered as a string {{a1}}', + ] + ], + 'a7': 5, + } + runner_param_info = {'r1': {'type': 'array'}, 'r2': {'type': 'array'}} + action_param_info = { + 'a1': {'type': 'boolean'}, + 'a2': {'type': 'string'}, + 'a3': {'type': 'string'}, + 'a4': {'type': 'boolean'}, + 'a5': {'type': 'array'}, + 'a6': {'type': 'array'}, + 'a7': {'type': 'integer'}, + } + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, {}) + self.assertEqual(r_runner_params, {'r1': ['1', '2'], 'r2': ['1', '2']}) + self.assertEqual( + r_action_params, + { + 'a1': True, + 'a2': 'Test', + 'a3': 'Test2', + 'a4': True, + 'a5': ['Test', 'Test2'], + 'a6': [ + [['1', '2'], 'Test'], + ['Test2', True], + [ + 5, + u'This should be rendered as a string True', + u'True This, too, should be rendered as a string True' + ] + ], + 'a7': 5, + } + ) + + def test_get_finalized_params_with_cyclic_dependency(self): + params = {'r1': '{{r2}}', 'r2': '{{r1}}'} + runner_param_info = {'r1': {}, 'r2': {}} + action_param_info = {} + test_pass = True + try: + param_utils.get_finalized_params(runner_param_info, action_param_info, params, {}) + test_pass = False + except ParamException as e: + test_pass = e.message.find('Cyclic') == 0 + self.assertTrue(test_pass) + + def test_get_finalized_params_with_missing_dependency(self): + params = {'r1': '{{r3}}', 'r2': '{{r3}}'} + runner_param_info = {'r1': {}, 'r2': {}} + action_param_info = {} + test_pass = True + try: + param_utils.get_finalized_params(runner_param_info, action_param_info, params, {}) + test_pass = False + except ParamException as e: + test_pass = e.message.find('Dependecy') == 0 + self.assertTrue(test_pass) + + params = {} + runner_param_info = {'r1': {'default': '{{r3}}'}, 'r2': {'default': '{{r3}}'}} + action_param_info = {} + test_pass = True + try: + param_utils.get_finalized_params(runner_param_info, action_param_info, params, {}) + test_pass = False + except ParamException as e: + test_pass = e.message.find('Dependecy') == 0 + self.assertTrue(test_pass) + + def test_get_finalized_params_no_double_rendering(self): + params = { + 'r1': '{{ action_context.h1 }}{{ action_context.h2 }}' + } + runner_param_info = {'r1': {}} + action_param_info = {} + action_context = { + 'h1': '{', + 'h2': '{ missing }}' + } + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + self.assertEqual(r_runner_params, {'r1': '{{ missing }}'}) + self.assertEqual(r_action_params, {}) + + def test_get_finalized_params_jinja_filters(self): + params = {'cmd': 'echo {{"1.6.0" | version_bump_minor}}'} + runner_param_info = {'r1': {}} + action_param_info = {'cmd': {}} + action_context = {} + + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + + self.assertEqual(r_action_params['cmd'], "echo 1.7.0") + + def test_get_finalized_params_param_rendering_failure(self): + params = {'cmd': '{{a2.foo}}', 'a2': 'test'} + action_param_info = {'cmd': {}, 'a2': {}} + + expected_msg = 'Failed to render parameter "cmd": .*' + self.assertRaisesRegexp(ParamException, + expected_msg, + param_utils.get_finalized_params, + runnertype_parameter_info={}, + action_parameter_info=action_param_info, + liveaction_parameters=params, + action_context={}) + + def test_get_finalized_param_object_contains_template_notation_in_the_value(self): + runner_param_info = {'r1': {}} + action_param_info = { + 'params': { + 'type': 'object', + 'default': { + 'host': '{{host}}', + 'port': '{{port}}', + 'path': '/bar'} + } + } + params = { + 'host': 'lolcathost', + 'port': 5555 + } + action_context = {} + + r_runner_params, r_action_params = param_utils.get_finalized_params( + runner_param_info, action_param_info, params, action_context) + + expected_params = { + 'host': 'lolcathost', + 'port': 5555, + 'path': '/bar' + } + self.assertEqual(r_action_params['params'], expected_params) + + def test_cast_param_referenced_action_doesnt_exist(self): + # Make sure the function throws if the action doesnt exist + expected_msg = 'Action with ref "foo.doesntexist" doesn\'t exist' + self.assertRaisesRegexp(ValueError, expected_msg, action_param_utils.cast_params, + action_ref='foo.doesntexist', params={}) + + def _get_liveaction_model(self, params): + status = 'initializing' + start_timestamp = date_utils.get_datetime_utc_now() + action_ref = ResourceReference(name=ParamsUtilsTest.action_db.name, + pack=ParamsUtilsTest.action_db.pack).ref + liveaction_db = LiveActionDB(status=status, start_timestamp=start_timestamp, + action=action_ref, parameters=params) + liveaction_db.context = {'source_channel': 'awesome', 'api_user': 'noob'} + + return liveaction_db