def test_old_jmeter(self): """ versions before 3.0 must use JSON plugin for extracting purposes """ self.configure(scenario={ "requests": [{ "url": "http://blazedemo.com", "extract-jsonpath": { "IP": "$.net[0].ip", "URL": { "jsonpath": "$.net[1].url", "default": "def", "from-variable": "Jm_VaR" } } }] }, version="2.13") self.obj.save(self.jmx) xml_tree = etree.fromstring(open(self.jmx, "rb").read()) cfg = self.get_plugin_json_extractor_config(xml_tree) self.assertEqual(2, len(cfg)) target = { "IP": { "jsonpath": "$.net[0].ip", "default": "NOT_FOUND", "from_variable": None }, "URL": { "jsonpath": "$.net[1].url", "default": "def", "from_variable": "Jm_VaR" } } self.assertEqual(target, cfg)
def test_new_extractor(self): """ versions after 3.0 use integrated JSON extractor """ self.configure(scenario={"requests": [{ "url": "http://blazedemo.com", "extract-jsonpath": { "IP": "$.net[0].ip", "URL": {"jsonpath": "$.url[1]", "default": "d1", "scope": "all", "concat": True, "from_variable": "V"}, "ID": {"jsonpath": "$.net[3].id", "default": "d2", "scope": "children", "concat": True}, "NuM": {"jsonpath": "$.num", "scope": "variable", "from-variable": "JMVaR", "match_no": 3}, }}]}, version=3.3) self.obj.save(self.jmx) xml_tree = etree.fromstring(open(self.jmx, "rb").read()) cfg = self.get_internal_json_extractor_config(xml_tree) self.assertEqual(4, len(cfg)) target = {'IP': {'from_variable': None, 'default': 'NOT_FOUND', 'match_no': '0', 'jsonpath': '$.net[0].ip', 'scope': None, 'concat': None}, 'URL': {'from_variable': None, 'default': 'd1', 'match_no': '0', 'jsonpath': '$.url[1]', 'scope': None, 'concat': None}, 'ID': {'from_variable': None, 'default': 'd2', 'match_no': '0', 'jsonpath': '$.net[3].id', 'scope': None, 'concat': None}, 'NuM': {'from_variable': 'JMVaR', 'default': 'NOT_FOUND', 'match_no': '0', 'jsonpath': '$.num', 'scope': 'variable', 'concat': None}} self.assertEqual(target, cfg)
def test_no_cookies(self): self.configure(scenario={"requests": ["http://localhost"], "store-cookie": False }) self.obj.save(self.jmx) xml_tree = etree.fromstring(open(self.jmx, "rb").read()) include = xml_tree.find(".//boolProp[@name='CookieManager.clearEachIteration']") self.assertIsNone(include)
def test_transaction_include_timers(self): self.configure(scenario={"requests": [{ "transaction": "tran", "include-timers": True, "do": ["http://blazedemo.com/"]}] }) self.obj.save(self.jmx) xml_tree = etree.fromstring(open(self.jmx, "rb").read()) include = xml_tree.find(".//TransactionController/boolProp[@name='TransactionController.includeTimers']") self.assertIsNotNone(include) self.assertEqual(include.text, 'true')
def test_internal_extractor_config_reader(self): xml_tree = etree.fromstring( open(RESOURCES_DIR + "jmeter/jmx/json_extractors.jmx", "rb").read()) target = { 'v1': { 'from_variable': None, 'default': 'd1', 'match_no': 'm1', 'jsonpath': 'e1', 'scope': None, 'concat': None }, 'v2': { 'from_variable': None, 'default': 'd2', 'match_no': 'm2', 'jsonpath': 'e2', 'scope': None, 'concat': None }, 'v3': { 'from_variable': None, 'default': 'd3', 'match_no': 'm3', 'jsonpath': 'e3', 'scope': None, 'concat': None }, 'v4': { 'from_variable': 'var4', 'default': 'd4', 'match_no': '4', 'jsonpath': 'e4', 'scope': 'variable', 'concat': None }, 'v-empty': { 'from_variable': None, 'default': None, 'match_no': None, 'jsonpath': 'p1', 'scope': None, 'concat': None } } xml = self.get_internal_json_extractor_config(xml_tree) self.assertEqual(target, xml)
def test_plugin_extractor_config_reader(self): xml_tree = etree.fromstring( open(RESOURCES_DIR + "jmeter/jmx/json_extractors.jmx", "rb").read()) target = { 'pv1': { 'default': 'pd1', 'from_variable': 'pJV', 'jsonpath': 'pe1' }, 'pv2': { 'default': None, 'from_variable': None, 'jsonpath': 'pe2' } } self.assertEqual(target, self.get_plugin_json_extractor_config(xml_tree))
def test_xml_format_sample_labels(self): # generate xml, compare hash obj = JUnitXMLReporter() obj.engine = EngineEmul() rep = BlazeMeterUploader() rep.results_url = "http://report/123" obj.engine.reporters.append(rep) path_from_config = tempfile.mktemp(suffix='.xml', prefix='junit-xml-sample-labels', dir=obj.engine.artifacts_dir) # data-source: finalstats by default obj.parameters = BetterDict.from_dict({"filename": path_from_config}) obj.prepare() datapoint = DataPoint(0, []) cumul_data = datapoint[DataPoint.CUMULATIVE] cumul_data[""] = KPISet.from_dict({ KPISet.AVG_CONN_TIME: 7.890211417203362e-06, KPISet.RESP_TIMES: Counter({ 0.0: 32160, 0.001: 24919, 0.002: 1049, 0.003: 630, 0.004: 224, 0.005: 125, 0.006: 73, 0.007: 46, 0.008: 32, 0.009: 20, 0.011: 8, 0.01: 8, 0.017: 3, 0.016: 3, 0.014: 3, 0.013: 3, 0.04: 2, 0.012: 2, 0.079: 1, 0.081: 1, 0.019: 1, 0.015: 1}), KPISet.ERRORS: [{'msg': 'Forbidden', 'cnt': 7300, 'type': 0, 'urls': Counter({'http://192.168.1.1/anotherquery': 7300}), KPISet.RESP_CODES: '403'}, {'msg': 'Assertion failed: text /smth/ not found', 'cnt': 73, 'type': 1, 'urls': Counter({'http://192.168.1.1/anotherquery': 73}), KPISet.RESP_CODES: '200'}, ], KPISet.STDEV_RESP_TIME: 0.04947974228872108, KPISet.AVG_LATENCY: 0.0002825639815220692, KPISet.RESP_CODES: Counter({'304': 29656, '403': 29656, '200': 2}), KPISet.PERCENTILES: {'95.0': 0.001, '0.0': 0.0, '99.9': 0.008, '90.0': 0.001, '100.0': 0.081, '99.0': 0.003, '50.0': 0.0}, KPISet.SUCCESSES: 29658, KPISet.SAMPLE_COUNT: 59314, KPISet.CONCURRENCY: 0, KPISet.AVG_RESP_TIME: 0.0005440536804127192, KPISet.FAILURES: 29656}) cumul_data["http://192.168.1.1/somequery"] = KPISet.from_dict({ KPISet.AVG_CONN_TIME: 9.609548856969457e-06, KPISet.RESP_TIMES: Counter({ 0.0: 17219, 0.001: 11246, 0.002: 543, 0.003: 341, 0.004: 121, 0.005: 66, 0.006: 36, 0.007: 33, 0.008: 18, 0.009: 12, 0.011: 6, 0.01: 5, 0.013: 2, 0.017: 2, 0.012: 2, 0.079: 1, 0.016: 1, 0.014: 1, 0.019: 1, 0.04: 1, 0.081: 1}), KPISet.ERRORS: [], KPISet.STDEV_RESP_TIME: 0.04073402130687656, KPISet.AVG_LATENCY: 1.7196034796682178e-06, KPISet.RESP_CODES: Counter({'304': 29656, '200': 2}), KPISet.PERCENTILES: {'95.0': 0.001, '0.0': 0.0, '99.9': 0.009, '90.0': 0.001, '100.0': 0.081, '99.0': 0.004, '50.0': 0.0}, KPISet.SUCCESSES: 29658, KPISet.SAMPLE_COUNT: 29658, KPISet.CONCURRENCY: 0, KPISet.AVG_RESP_TIME: 0.0005164542450603551, KPISet.FAILURES: 0}) cumul_data["http://192.168.1.1/anotherquery"] = KPISet.from_dict({ KPISet.AVG_CONN_TIME: 6.1707580253574335e-06, KPISet.RESP_TIMES: Counter({0.0: 14941, 0.001: 13673, 0.002: 506, 0.003: 289, 0.004: 103, 0.005: 59, 0.006: 37, 0.008: 14, 0.007: 13, 0.009: 8, 0.01: 3, 0.011: 2, 0.016: 2, 0.014: 2, 0.017: 1, 0.013: 1, 0.015: 1, 0.04: 1}), KPISet.ERRORS: [ {'msg': 'Forbidden', 'cnt': 7300, 'type': 0, 'urls': Counter({'http://192.168.1.1/anotherquery': 7300}), KPISet.RESP_CODES: '403'}, {'msg': 'Assertion failed: text /smth/ not found', 'cnt': 73, 'type': 1, 'urls': Counter({'http://192.168.1.1/anotherquery': 73}), KPISet.RESP_CODES: '200'}, ], KPISet.STDEV_RESP_TIME: 0.032465137860758844, KPISet.AVG_LATENCY: 0.0005634272997032645, KPISet.RESP_CODES: Counter({'403': 29656}), KPISet.PERCENTILES: {'95.0': 0.001, '0.0': 0.0, '99.9': 0.008, '90.0': 0.001, '100.0': 0.04, '99.0': 0.003, '50.0': 0.0}, KPISet.SUCCESSES: 0, KPISet.SAMPLE_COUNT: 29656, KPISet.CONCURRENCY: 0, KPISet.AVG_RESP_TIME: 0.0005716549770704078, KPISet.FAILURES: 29656}) cumul_data["http://192.168.100.100/somequery"] = KPISet.from_dict({ KPISet.AVG_CONN_TIME: 9.609548856969457e-06, KPISet.RESP_TIMES: Counter({ 0.0: 17219, 0.001: 11246, 0.002: 543, 0.003: 341, 0.004: 121, 0.005: 66, 0.006: 36, 0.007: 33, 0.008: 18, 0.009: 12, 0.011: 6, 0.01: 5, 0.013: 2, 0.017: 2, 0.012: 2, 0.079: 1, 0.016: 1, 0.014: 1, 0.019: 1, 0.04: 1, 0.081: 1}), KPISet.ERRORS: [], KPISet.STDEV_RESP_TIME: 0.04073402130687656, KPISet.AVG_LATENCY: 1.7196034796682178e-06, KPISet.RESP_CODES: Counter({'304': 29656, '200': 2}), KPISet.PERCENTILES: {'95.0': 0.001, '0.0': 0.0, '99.9': 0.009, '90.0': 0.001, '100.0': 0.081, '99.0': 0.004, '50.0': 0.0}, KPISet.SUCCESSES: 29658, KPISet.SAMPLE_COUNT: 29658, KPISet.CONCURRENCY: 0, KPISet.AVG_RESP_TIME: 0.0005164542450603551, KPISet.FAILURES: 0}) obj.aggregated_second(datapoint) obj.post_process() with open(obj.report_file_path, 'rb') as fds: f_contents = fds.read() ROOT_LOGGER.info("File: %s", f_contents) xml_tree = etree.fromstring(f_contents) self.assertEqual('testsuites', xml_tree.tag) suite = xml_tree.getchildren()[0] self.assertEqual('testsuite', suite.tag) self.assertListEqual(['sample_labels', "bzt"], suite.values()) test_cases = suite.getchildren() self.assertEqual(3, len(test_cases)) self.assertEqual('testcase', test_cases[0].tag) self.assertEqual('error', test_cases[0].getchildren()[1].tag) self.assertEqual('failure', test_cases[0].getchildren()[2].tag) self.assertEqual('system-out', test_cases[0].getchildren()[0].tag) self.assertIn('BlazeMeter report link: http://report/123', test_cases[0].getchildren()[0].text)
def test_xml_format_passfail(self): obj = JUnitXMLReporter() obj.engine = EngineEmul() obj.parameters = BetterDict() obj.engine.provisioning = CloudProvisioning() obj.engine.provisioning.results_url = "http://test/report/123" pass_fail1 = CriteriaProcessor([], None) crit_cfg1 = BetterDict() crit_cfg2 = BetterDict() crit_cfg3 = BetterDict() crit_cfg4 = BetterDict() crit_cfg1.merge({ 'stop': True, 'label': 'Sample 1 Triggered', 'fail': True, 'timeframe': -1, 'threshold': '150ms', 'condition': '<', 'subject': 'avg-rt'}) crit_cfg2.merge({ 'stop': True, 'label': 'Sample 1 Not Triggered', 'fail': True, 'timeframe': -1, 'threshold': '300ms', 'condition': '>', 'subject': 'avg-rt'}) crit_cfg3.merge({ 'stop': True, 'label': 'Sample 2 Triggered', 'fail': True, 'timeframe': -1, 'threshold': '150ms', 'condition': '<=', 'subject': 'avg-rt'}) crit_cfg4.merge({ 'stop': True, 'label': 'Sample 2 Not Triggered', 'fail': True, 'timeframe': -1, 'threshold': '300ms', 'condition': '=', 'subject': 'avg-rt'}) fc1_triggered = DataCriterion(crit_cfg1, pass_fail1) fc1_not_triggered = DataCriterion(crit_cfg2, pass_fail1) pass_fail2 = CriteriaProcessor([], None) fc2_triggered = DataCriterion(crit_cfg3, pass_fail1) fc2_not_triggered = DataCriterion(crit_cfg4, pass_fail1) pass_fail1.criteria.append(fc1_triggered) pass_fail1.criteria.append(fc1_not_triggered) pass_fail2.criteria.append(fc2_triggered) pass_fail2.criteria.append(fc2_not_triggered) fc1_triggered.is_triggered = True fc2_triggered.is_triggered = True pass_fail = PassFailStatus() pass_fail.processors.append(pass_fail1) pass_fail.processors.append(pass_fail2) obj.engine.reporters.append(pass_fail) obj.engine.reporters.append(BlazeMeterUploader()) path_from_config = tempfile.mktemp(suffix='.xml', prefix='junit-xml_passfail', dir=obj.engine.artifacts_dir) obj.parameters.merge({"filename": path_from_config, "data-source": "pass-fail"}) obj.prepare() obj.last_second = DataPoint(0) obj.post_process() with open(obj.report_file_path, 'rb') as fds: f_contents = fds.read() ROOT_LOGGER.info("File: %s", f_contents) xml_tree = etree.fromstring(f_contents) self.assertEqual('testsuites', xml_tree.tag) suite = xml_tree.getchildren()[0] self.assertEqual('testsuite', suite.tag) test_cases = suite.getchildren() self.assertEqual(4, len(test_cases)) self.assertEqual('testcase', test_cases[0].tag) self.assertEqual('error', test_cases[0].getchildren()[1].tag) self.assertEqual('error', test_cases[2].getchildren()[1].tag) sys_out = test_cases[0].getchildren()[0] self.assertEqual('system-out', sys_out.tag) self.assertIn('BlazeMeter report link: http://test/report/123', sys_out.text)