def test_cached_read(self): """ Test method that creates a copy with file read already performed """ file_path = os.path.dirname(os.path.realpath(__file__)) file_path = os.path.join(file_path, 'person_body_template.json') # Read file to compare file_content = None with open(file_path, 'r') as f: file_content = f.read() handler = ContentHandler() handler.setup(file_path, is_file=True) # Check it read the file correctly cached_handler = handler.create_noread_version() self.assertEqual(file_content, handler.get_content()) self.assertFalse(cached_handler.is_file) # Check with templating handler.is_template_content = True cached_handler = handler.create_noread_version() self.assertEqual(file_content, handler.get_content()) self.assertEqual(handler.is_template_content, cached_handler.is_template_content) self.assertFalse(cached_handler.is_file) # Check dynamic paths don't try to template handler.is_template_path = True cached_handler = handler.create_noread_version() self.assertTrue(handler is cached_handler)
def test_test_content_templating(self): test = Test() handler = ContentHandler() handler.is_template_content = True handler.content = '{"first_name": "Gaius","id": "$id","last_name": "Baltar","login": "******"}' context = Context() context.bind_variables({'id': 9, 'login': '******'}) test.set_body(handler) templated = test.realize(context=context) self.assertEqual(string.Template(handler.content).safe_substitute(context.get_values()), templated.body)
def test_test_content_templating(self): test = Test() handler = ContentHandler() handler.is_template_content = True handler.content = '{"first_name": "Gaius","id": "$id","last_name": "Baltar","login": "******"}' context = Context() context.bind_variables({'id':9, 'login':'******'}) test.set_body(handler) templated = test.realize(context=context) self.assertEqual(string.Template(handler.content).safe_substitute(context.get_values()), templated.body)
def test_parse_content_templated_file_content(self): """ Test parsing of templated file content """ node = {'template': {'file': '/path.yaml'}} handler = ContentHandler.parse_content(node) self.assertEqual('/path.yaml', handler.content) self.assertTrue(handler.is_dynamic()) self.assertTrue(handler.is_file) self.assertFalse(handler.is_template_path) self.assertTrue(handler.is_template_content)
def test_parse_content_double_templated_file(self): """ Test parsing of file with path and content templated """ node = {'template': {'file': {'template': '/$var-path.yaml'}}} handler = ContentHandler.parse_content(node) self.assertEqual('/$var-path.yaml', handler.content) self.assertTrue(handler.is_dynamic()) self.assertTrue(handler.is_file) self.assertTrue(handler.is_template_path) self.assertTrue(handler.is_template_content)
def test_parse_content_file(self): """ Test parsing of file content """ node = {'file': '/myval'} handler = ContentHandler.parse_content(node) self.assertEqual(node['file'], handler.content) self.assertFalse(handler.is_dynamic()) self.assertTrue(handler.is_file) self.assertFalse(handler.is_template_path) self.assertFalse(handler.is_template_content)
def test_parse_content_file(self): """ Test parsing of file content """ node = {'file':'/myval'} handler = ContentHandler.parse_content(node) self.assertEqual(node['file'], handler.content) self.assertFalse(handler.is_dynamic()) self.assertTrue(handler.is_file) self.assertFalse(handler.is_template_path) self.assertFalse(handler.is_template_content)
def test_content_templating(self): """ Test content and templating of it """ handler = ContentHandler() body = '$variable value' context = Context() context.bind_variable('variable', 'bar') # No templating handler.setup(body, is_template_content=False) self.assertEqual(body, handler.get_content()) self.assertEqual(body, handler.get_content(context)) # Templating handler.setup(body, is_template_content=True) self.assertEqual(body, handler.get_content())
def test_parse_content_simple(self): """ Test parsing of simple content """ node = "myval" handler = ContentHandler.parse_content(node) self.assertEqual(node, handler.content) self.assertEqual(node, handler.get_content()) self.assertFalse(handler.is_dynamic()) self.assertFalse(handler.is_file) self.assertFalse(handler.is_template_path) self.assertFalse(handler.is_template_content)
def test_parse_content_templated(self): """ Test parsing of templated content """ node = {'template': 'myval $var'} handler = ContentHandler.parse_content(node) context = Context() context.bind_variable('var', 'cheese') self.assertEqual(node['template'], handler.content) self.assertEqual('myval cheese', handler.get_content(context)) self.assertTrue(handler.is_dynamic()) self.assertFalse(handler.is_file) self.assertFalse(handler.is_template_path) self.assertTrue(handler.is_template_content)
def test_parse_content_templated(self): """ Test parsing of templated content """ node = {'template':'myval $var'} handler = ContentHandler.parse_content(node) context = Context() context.bind_variable('var','cheese') self.assertEqual(node['template'], handler.content) self.assertEqual('myval cheese', handler.get_content(context)) self.assertTrue(handler.is_dynamic()) self.assertFalse(handler.is_file) self.assertFalse(handler.is_template_path) self.assertTrue(handler.is_template_content)
def test_parse_content_breaks(self): """ Test for handling parsing of some bad input cases """ failing_configs = list() failing_configs.append({'template' : None}) failing_configs.append({'file' : None}) failing_configs.append({'file': {'template': None}}) failing_configs.append({'file': {'template': 1}}) failing_configs.append({'file': {'template': 1}}) failing_configs.append({'fil': {'template': 'pathname.yaml'}}) for config in failing_configs: try: handler = ContentHandler.parse_content(node) self.fail("Should raise an exception on invalid parse, config: "+json.dumps(config, default=lambda o: o.__dict__)) except Exception: pass
def test_parse_content_breaks(self): """ Test for handling parsing of some bad input cases """ failing_configs = list() failing_configs.append({'template': None}) failing_configs.append({'file': None}) failing_configs.append({'file': {'template': None}}) failing_configs.append({'file': {'template': 1}}) failing_configs.append({'file': {'template': 1}}) failing_configs.append({'fil': {'template': 'pathname.yaml'}}) for config in failing_configs: try: handler = ContentHandler.parse_content(node) self.fail( "Should raise an exception on invalid parse, config: " + json.dumps(config, default=lambda o: o.__dict__)) except Exception: pass
def parse_test(cls, base_url, node, input_test = None, test_path=None): """ Create or modify a test, input_test, using configuration in node, and base_url If no input_test is given, creates a new one Test_path gives path to test file, used for setting working directory in setting up input bodies Uses explicitly specified elements from the test input structure to make life *extra* fun, we need to handle list <-- > dict transformations. This is to say: list(dict(),dict()) or dict(key,value) --> dict() for some elements Accepted structure must be a single dictionary of key-value pairs for test configuration """ mytest = input_test if not mytest: mytest = Test() node = lowercase_keys(flatten_dictionaries(node)) #Clean up for easy parsing #Copy/convert input elements into appropriate form for a test object for configelement, configvalue in node.items(): #Configure test using configuration elements if configelement == u'url': temp = configvalue if isinstance(configvalue, dict): # Template is used for URL val = lowercase_keys(configvalue)[u'template'] assert isinstance(val,str) or isinstance(val,unicode) or isinstance(val,int) url = base_url + unicode(val,'UTF-8').encode('ascii','ignore') mytest.set_url(url, isTemplate=True) else: assert isinstance(configvalue,str) or isinstance(configvalue,unicode) or isinstance(configvalue,int) mytest.url = base_url + unicode(configvalue,'UTF-8').encode('ascii','ignore') elif configelement == u'auth_username': assert isinstance(configvalue,str) or isinstance(configvalue,unicode) mytest.auth_username = unicode(configvalue,'UTF-8').encode('ascii','ignore') elif configelement == u'auth_password': assert isinstance(configvalue,str) or isinstance(configvalue,unicode) mytest.auth_password = unicode(configvalue,'UTF-8').encode('ascii','ignore') elif configelement == u'method': #Http method, converted to uppercase string var = unicode(configvalue,'UTF-8').upper() assert var in HTTP_METHODS mytest.method = var elif configelement == u'group': #Test group assert isinstance(configvalue,str) or isinstance(configvalue,unicode) or isinstance(configvalue,int) mytest.group = unicode(configvalue,'UTF-8') elif configelement == u'name': #Test name assert isinstance(configvalue,str) or isinstance(configvalue,unicode) or isinstance(configvalue,int) mytest.name = unicode(configvalue,'UTF-8') elif configelement == u'extract_binds': # Add a list of extractors, of format: # {variable_name: {extractor_type: extractor_config}, ... } binds = flatten_dictionaries(configvalue) if mytest.extract_binds is None: mytest.extract_binds = dict() for variable_name, extractor in binds.items(): if not isinstance(extractor, dict) or len(extractor) == 0: raise TypeError("Extractors must be defined as maps of extractorType:{configs} with 1 entry") if len(extractor) > 1: raise ValueError("Cannot define multiple extractors for given variable name") extractor_type, extractor_config = extractor.items()[0] extractor = validators.parse_extractor(extractor_type, extractor_config) mytest.extract_binds[variable_name] = extractor elif configelement == u'validators': # Add a list of validators if not isinstance(configvalue, list): raise Exception('Misconfigured validator section, must be a list of validators') if mytest.validators is None: mytest.validators = list() # create validator and add to list of validators for var in configvalue: if not isinstance(var, dict): raise TypeError("Validators must be defined as validatorType:{configs} ") for validator_type, validator_config in var.items(): validator = validators.parse_validator(validator_type, validator_config) mytest.validators.append(validator) elif configelement == u'body': #Read request body, as a ContentHandler # Note: os.path.expandirs removed mytest.body = ContentHandler.parse_content(configvalue) elif configelement == 'headers': #HTTP headers to use, flattened to a single string-string dictionary mytest.headers configvalue = flatten_dictionaries(configvalue) if isinstance(configvalue, dict): templates = filter(lambda x: str(x[0]).lower() == 'template', configvalue.items()) else: templates = None if templates: # Should have single entry in dictionary keys mytest.set_headers(templates[0][1], isTemplate=True) elif isinstance(configvalue, dict): mytest.headers = configvalue else: raise TypeError("Illegal header type: headers must be a dictionary or list of dictionary keys") elif configelement == 'expected_status': #List of accepted HTTP response codes, as integers expected = list() #If item is a single item, convert to integer and make a list of 1 #Otherwise, assume item is a list and convert to a list of integers if isinstance(configvalue,list): for item in configvalue: expected.append(int(item)) else: expected.append(int(configvalue)) mytest.expected_status = expected elif configelement == 'variable_binds': mytest.variable_binds = flatten_dictionaries(configvalue) elif configelement == 'generator_binds': output = flatten_dictionaries(configvalue) output2 = dict() for key, value in output.items(): output2[str(key)] = str(value) mytest.generator_binds = output2 elif configelement == 'stop_on_failure': mytest.stop_on_failure = safe_to_bool(configvalue) #Next, we adjust defaults to be reasonable, if the user does not specify them #For non-GET requests, accept additional response codes indicating success # (but only if not expected statuses are not explicitly specified) # this is per HTTP spec: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5 if 'expected_status' not in node.keys(): if mytest.method == 'POST': mytest.expected_status = [200,201,204] elif mytest.method == 'PUT': mytest.expected_status = [200,201,204] elif mytest.method == 'DELETE': mytest.expected_status = [200,202,204] return mytest
def test_content_file_template(self): """ Test file read and templating of read files in this directory """ variables = {'id':1, 'login':'******'} context = Context() file_path = os.path.dirname(os.path.realpath(__file__)) file_path = os.path.join(file_path, 'person_body_template.json') file_content = None with open(file_path, 'r') as f: file_content = f.read() # Test basic read handler = ContentHandler() handler.setup(file_path, is_file=True) self.assertEqual(file_content, handler.get_content()) # Test templating of read content handler.setup(file_path, is_file=True, is_template_content=True) self.assertEqual(file_content, handler.get_content()) self.assertEqual(file_content, handler.get_content(context)) # No substitution substituted = string.Template(file_content).safe_substitute(variables) context.bind_variables(variables) self.assertEqual(substituted, handler.get_content(context)) # Test path templating templated_file_path = '$filepath' context.bind_variable('filepath', file_path) handler.setup(file_path, is_file=True, is_template_path=True) self.assertEqual(file_content, handler.get_content(context)) # Test double templating with files handler.setup(file_path, is_file=True, is_template_path=True, is_template_content=True) self.assertEqual(substituted, handler.get_content(context=context))
def test_content_file_template(self): """ Test file read and templating of read files in this directory """ variables = {'id': 1, 'login': '******'} context = Context() file_path = os.path.dirname(os.path.realpath(__file__)) file_path = os.path.join(file_path, 'person_body_template.json') file_content = None with open(file_path, 'r') as f: file_content = f.read() # Test basic read handler = ContentHandler() handler.setup(file_path, is_file=True) self.assertEqual(file_content, handler.get_content()) # Test templating of read content handler.setup(file_path, is_file=True, is_template_content=True) self.assertEqual(file_content, handler.get_content()) self.assertEqual(file_content, handler.get_content(context)) # No substitution substituted = string.Template(file_content).safe_substitute(variables) context.bind_variables(variables) self.assertEqual(substituted, handler.get_content(context)) # Test path templating templated_file_path = '$filepath' context.bind_variable('filepath', file_path) handler.setup(file_path, is_file=True, is_template_path=True) self.assertEqual(file_content, handler.get_content(context)) # Test double templating with files handler.setup(file_path, is_file=True, is_template_path=True, is_template_content=True) self.assertEqual(substituted, handler.get_content(context=context))
def parse_test(cls, base_url, node, input_test=None, test_path=None): """ Create or modify a test, input_test, using configuration in node, and base_url If no input_test is given, creates a new one Test_path gives path to test file, used for setting working directory in setting up input bodies Uses explicitly specified elements from the test input structure to make life *extra* fun, we need to handle list <-- > dict transformations. This is to say: list(dict(),dict()) or dict(key,value) --> dict() for some elements Accepted structure must be a single dictionary of key-value pairs for test configuration """ mytest = input_test if not mytest: mytest = Test() node = lowercase_keys( flatten_dictionaries(node)) #Clean up for easy parsing #Copy/convert input elements into appropriate form for a test object for configelement, configvalue in node.items(): #Configure test using configuration elements if configelement == u'url': temp = configvalue if isinstance(configvalue, dict): # Template is used for URL val = lowercase_keys(configvalue)[u'template'] assert isinstance(val, str) or isinstance( val, unicode) or isinstance(val, int) url = base_url + unicode(val, 'UTF-8').encode( 'ascii', 'ignore') mytest.set_url(url, isTemplate=True) else: assert isinstance(configvalue, str) or isinstance( configvalue, unicode) or isinstance(configvalue, int) mytest.url = base_url + unicode( configvalue, 'UTF-8').encode('ascii', 'ignore') elif configelement == u'auth_username': assert isinstance(configvalue, str) or isinstance( configvalue, unicode) mytest.auth_username = unicode(configvalue, 'UTF-8').encode( 'ascii', 'ignore') elif configelement == u'auth_password': assert isinstance(configvalue, str) or isinstance( configvalue, unicode) mytest.auth_password = unicode(configvalue, 'UTF-8').encode( 'ascii', 'ignore') elif configelement == u'method': #Http method, converted to uppercase string var = unicode(configvalue, 'UTF-8').upper() assert var in HTTP_METHODS mytest.method = var elif configelement == u'group': #Test group assert isinstance(configvalue, str) or isinstance( configvalue, unicode) or isinstance(configvalue, int) mytest.group = unicode(configvalue, 'UTF-8') elif configelement == u'name': #Test name assert isinstance(configvalue, str) or isinstance( configvalue, unicode) or isinstance(configvalue, int) mytest.name = unicode(configvalue, 'UTF-8') elif configelement == u'extract_binds': # Add a list of extractors, of format: # {variable_name: {extractor_type: extractor_config}, ... } binds = flatten_dictionaries(configvalue) if mytest.extract_binds is None: mytest.extract_binds = dict() for variable_name, extractor in binds.items(): if not isinstance(extractor, dict) or len(extractor) == 0: raise TypeError( "Extractors must be defined as maps of extractorType:{configs} with 1 entry" ) if len(extractor) > 1: raise ValueError( "Cannot define multiple extractors for given variable name" ) extractor_type, extractor_config = extractor.items()[0] extractor = validators.parse_extractor( extractor_type, extractor_config) mytest.extract_binds[variable_name] = extractor elif configelement == u'validators': # Add a list of validators if not isinstance(configvalue, list): raise Exception( 'Misconfigured validator section, must be a list of validators' ) if mytest.validators is None: mytest.validators = list() # create validator and add to list of validators for var in configvalue: if not isinstance(var, dict): raise TypeError( "Validators must be defined as validatorType:{configs} " ) for validator_type, validator_config in var.items(): validator = validators.parse_validator( validator_type, validator_config) mytest.validators.append(validator) elif configelement == u'body': #Read request body, as a ContentHandler # Note: os.path.expandirs removed mytest.body = ContentHandler.parse_content(configvalue) elif configelement == 'headers': #HTTP headers to use, flattened to a single string-string dictionary mytest.headers configvalue = flatten_dictionaries(configvalue) if isinstance(configvalue, dict): templates = filter( lambda x: str(x[0]).lower() == 'template', configvalue.items()) else: templates = None if templates: # Should have single entry in dictionary keys mytest.set_headers(templates[0][1], isTemplate=True) elif isinstance(configvalue, dict): mytest.headers = configvalue else: raise TypeError( "Illegal header type: headers must be a dictionary or list of dictionary keys" ) elif configelement == 'expected_status': #List of accepted HTTP response codes, as integers expected = list() #If item is a single item, convert to integer and make a list of 1 #Otherwise, assume item is a list and convert to a list of integers if isinstance(configvalue, list): for item in configvalue: expected.append(int(item)) else: expected.append(int(configvalue)) mytest.expected_status = expected elif configelement == 'variable_binds': mytest.variable_binds = flatten_dictionaries(configvalue) elif configelement == 'generator_binds': output = flatten_dictionaries(configvalue) output2 = dict() for key, value in output.items(): output2[str(key)] = str(value) mytest.generator_binds = output2 elif configelement == 'stop_on_failure': mytest.stop_on_failure = safe_to_bool(configvalue) #Next, we adjust defaults to be reasonable, if the user does not specify them #For non-GET requests, accept additional response codes indicating success # (but only if not expected statuses are not explicitly specified) # this is per HTTP spec: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5 if 'expected_status' not in node.keys(): if mytest.method == 'POST': mytest.expected_status = [200, 201, 204] elif mytest.method == 'PUT': mytest.expected_status = [200, 201, 204] elif mytest.method == 'DELETE': mytest.expected_status = [200, 202, 204] return mytest