diff --git a/tests/pyrest_tests/basic_smoketest.yaml b/tests/pyrest_tests/basic_smoketest.yaml new file mode 100644 index 0000000000000000000000000000000000000000..282d730aa1ed0637aa9083fa5506ef573bd60aa2 --- /dev/null +++ b/tests/pyrest_tests/basic_smoketest.yaml @@ -0,0 +1,9 @@ +- config: + - testset: "Basic hivemind API Smoke Test" + +- test: + - name: "Test ip address" + - group: "basic_smoketest" + - url: "/rpc" + - method: "POST" + - body: '{}' diff --git a/tests/pyrest_tests/bridge_api/bridge_api_test.yaml b/tests/pyrest_tests/bridge_api/bridge_api_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3be66891ba4b6ea515330deb0c5249945a84266c --- /dev/null +++ b/tests/pyrest_tests/bridge_api/bridge_api_test.yaml @@ -0,0 +1,155 @@ +--- + - config: + - testset: "Bridge API Tests" + - api: &api "bridge_api" + - variable_binds: + - api: *api + - generators: + - test_id: {type: 'number_sequence', start: 1} + + - base_test: &base_test + - generator_binds: + - test_id: test_id + - group: *api + - url: "/rpc" + - method: "POST" + - body: {template: {file: "../templates/request_template.json"}} + - validators: + - extract_test: {jsonpath_mini: "error", test: "not_exists"} + - extract_test: {jsonpath_mini: "result", test: "exists"} + - compare: {jsonpath_mini: "id", comparator: "str_eq", expected: {template: $test_id}} + - json_file_validator: {jsonpath_mini: "result", comparator: "json_compare", expected: {template: '$api/$method'}} + + - test: + - name: "normalize_post" + - variable_binds: + - method: "normalize_post" + - args: {} + - <<: *base_test + + - test: + - name: "get_post_header" + - variable_binds: + - method: "get_post_header" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussion" + - variable_binds: + - method: "get_discussion" + - args: {} + - <<: *base_test + + - test: + - name: "get_post" + - variable_binds: + - method: "get_post" + - args: {} + - <<: *base_test + + - test: + - name: "get_account_posts" + - variable_binds: + - method: "get_account_posts" + - args: {} + - <<: *base_test + + + - test: + - name: "get_ranked_posts" + - variable_binds: + - method: "get_ranked_posts" + - args: {} + - <<: *base_test + + - test: + - name: "get_profile" + - variable_binds: + - method: "get_profile" + - args: {} + - <<: *base_test + + - test: + - name: "get_trending_topics" + - variable_binds: + - method: "get_trending_topics" + - args: {} + - <<: *base_test + + - test: + - name: "post_notifications" + - variable_binds: + - method: "post_notifications" + - args: {} + - <<: *base_test + + - test: + - name: "account_notifications" + - variable_binds: + - method: "account_notifications" + - args: {} + - <<: *base_test + + - test: + - name: "unread_notifications" + - variable_binds: + - method: "unread_notifications" + - args: {} + - <<: *base_test + + - test: + - name: "get_payout_stats" + - variable_binds: + - method: "get_payout_stats" + - args: {} + - <<: *base_test + + - test: + - name: "get_community" + - variable_binds: + - method: "get_community" + - args: {} + - <<: *base_test + + - test: + - name: "get_community_context" + - variable_binds: + - method: "get_community_context" + - args: {} + - <<: *base_test + + - test: + - name: "list_communities" + - variable_binds: + - method: "list_communities" + - args: {} + - <<: *base_test + + - test: + - name: "list_pop_communities" + - variable_binds: + - method: "list_pop_communities" + - args: {} + - <<: *base_test + + - test: + - name: "list_community_roles" + - variable_binds: + - method: "list_community_roles" + - args: {} + - <<: *base_test + + - test: + - name: "list_subscribers" + - variable_binds: + - method: "list_subscribers" + - args: {} + - <<: *base_test + + - test: + - name: "list_all_subscriptions" + - variable_binds: + - method: "list_all_subscriptions" + - args: {} + - <<: *base_test \ No newline at end of file diff --git a/tests/pyrest_tests/comparator_contain.py b/tests/pyrest_tests/comparator_contain.py new file mode 100644 index 0000000000000000000000000000000000000000..7a8751db2bed774c3e9db1c5449efce2340b0680 --- /dev/null +++ b/tests/pyrest_tests/comparator_contain.py @@ -0,0 +1,26 @@ +def dict_contain(response, pattern): + for key in pattern.keys(): + if (not key in response) or (pattern[key] != response[key]): + return False + return True + +def list_contain(response, pattern): + for item in pattern: + if item not in response: + return False + return True + +def contain(response, pattern): + if not isinstance(response, pattern): + return False + + if isinstance(response, dict): + return dict_contain(response, pattern) + if isinstance(response, list): + return list_contain(response, pattern) + if isinstance(response): + return pattern in response + # all other types + return pattern == response + +COMPARATORS = {'json_compare': contain} diff --git a/tests/pyrest_tests/comparator_equal.py b/tests/pyrest_tests/comparator_equal.py new file mode 100644 index 0000000000000000000000000000000000000000..02fe80971cd3d04a687eb7abc3b7a747e82a18f0 --- /dev/null +++ b/tests/pyrest_tests/comparator_equal.py @@ -0,0 +1,3 @@ +import operator + +COMPARATORS = {'json_compare': operator.eq} diff --git a/tests/pyrest_tests/condenser_api/condenser_api_test.yaml b/tests/pyrest_tests/condenser_api/condenser_api_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..47c106124b558ee4df83eaae3d8c8953ee0eece7 --- /dev/null +++ b/tests/pyrest_tests/condenser_api/condenser_api_test.yaml @@ -0,0 +1,189 @@ +--- + - config: + - testset: "Condenser API Tests" + - api: &api "condenser_api" + - variable_binds: + - api: *api + - generators: + - test_id: {type: 'number_sequence', start: 1} + + - base_test: &base_test + - generator_binds: + - test_id: test_id + - group: *api + - url: "/rpc" + - method: "POST" + - body: {template: {file: "../templates/request_template.json"}} + - validators: + - extract_test: {jsonpath_mini: "error", test: "not_exists"} + - extract_test: {jsonpath_mini: "result", test: "exists"} + - compare: {jsonpath_mini: "id", comparator: "str_eq", expected: {template: $test_id}} + - json_file_validator: {jsonpath_mini: "result", comparator: "json_compare", expected: {template: '$api/$method'}} + + - test: + - name: "get_followers" + - variable_binds: + - method: "get_followers" + - args: {} + - <<: *base_test + + - test: + - name: "get_following" + - variable_binds: + - method: "get_following" + - args: {} + - <<: *base_test + + - test: + - name: "get_follow_count" + - variable_binds: + - method: "get_follow_count" + - args: {} + - <<: *base_test + + - test: + - name: "get_content" + - variable_binds: + - method: "get_content" + - args: {} + - <<: *base_test + + - test: + - name: "get_content_replies" + - variable_binds: + - method: "get_content_replies" + - args: {} + - <<: *base_test + + - test: + - name: "get_state" + - variable_binds: + - method: "get_state" + - args: {} + - <<: *base_test + + - test: + - name: "get_trending_tags" + - variable_binds: + - method: "get_trending_tags" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_trending" + - variable_binds: + - method: "get_discussions_by_trending" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_hot" + - variable_binds: + - method: "get_discussions_by_hot" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_promoted" + - variable_binds: + - method: "get_discussions_by_promoted" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_created" + - variable_binds: + - method: "get_discussions_by_created" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_blog" + - variable_binds: + - method: "get_discussions_by_blog" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_feed" + - variable_binds: + - method: "get_discussions_by_feed" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_comments" + - variable_binds: + - method: "get_discussions_by_comments" + - args: {} + - <<: *base_test + + - test: + - name: "get_replies_by_last_update" + - variable_binds: + - method: "get_replies_by_last_update" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_author_before_date" + - variable_binds: + - method: "get_discussions_by_author_before_date" + - args: {} + - <<: *base_test + + - test: + - name: "get_post_discussions_by_payout" + - variable_binds: + - method: "get_post_discussions_by_payout" + - args: {} + - <<: *base_test + + - test: + - name: "get_comment_discussions_by_payout" + - variable_binds: + - method: "get_comment_discussions_by_payout" + - args: {} + - <<: *base_test + + - test: + - name: "get_blog" + - variable_binds: + - method: "get_blog" + - args: {} + - <<: *base_test + + - test: + - name: "get_blog_entries" + - variable_binds: + - method: "get_blog_entries" + - args: {} + - <<: *base_test + + - test: + - name: "get_account_reputations" + - variable_binds: + - method: "get_account_reputations" + - args: {} + - <<: *base_test + + - test: + - name: "get_reblogged_by" + - variable_binds: + - method: "get_reblogged_by" + - args: {} + - <<: *base_test + + - test: + - name: "get_accounts" + - variable_binds: + - method: "get_accounts" + - args: {} + - <<: *base_test + + - test: + - name: "get_account_votes" + - variable_binds: + - method: "get_account_votes" + - args: {} + - <<: *base_test \ No newline at end of file diff --git a/tests/pyrest_tests/database_api/database_api_test.yaml b/tests/pyrest_tests/database_api/database_api_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..27d3e01aba6e56af21026cefed158bd43b882001 --- /dev/null +++ b/tests/pyrest_tests/database_api/database_api_test.yaml @@ -0,0 +1,35 @@ +--- +- config: + - testset: "Database API Tests" + - api: &api "database_api" + - variable_binds: + - api: *api + - generators: + - test_id: {type: 'number_sequence', start: 1} + +- base_test: &base_test + - generator_binds: + - test_id: test_id + - group: *api + - url: "/rpc" + - method: "POST" + - body: {template: {file: "../templates/request_template.json"}} + - validators: + - extract_test: {jsonpath_mini: "error", test: "not_exists"} + - extract_test: {jsonpath_mini: "result", test: "exists"} + - compare: {jsonpath_mini: "id", comparator: "str_eq", expected: {template: $test_id}} + - json_file_validator: {jsonpath_mini: "result", comparator: "json_compare", expected: {template: '$api/$method'}} + +- test: + - name: "list_comments" + - variable_binds: + - method: "list_comments" + - args: {} + - <<: *base_test + +- test: + - name: "find_comments" + - variable_binds: + - method: "find_comments" + - args: {} + - <<: *base_test diff --git a/tests/pyrest_tests/follow_api/follow_api_test.yaml b/tests/pyrest_tests/follow_api/follow_api_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..59bc3f0059b9a6fefd3cbd6f9e9f2fc093a21c28 --- /dev/null +++ b/tests/pyrest_tests/follow_api/follow_api_test.yaml @@ -0,0 +1,91 @@ +--- + - config: + - testset: "Follow API Tests" + - api: &api "follow_api" + - variable_binds: + - api: *api + - generators: + - test_id: {type: 'number_sequence', start: 1} + + - base_test: &base_test + - generator_binds: + - test_id: test_id + - group: *api + - url: "/rpc" + - method: "POST" + - body: {template: {file: "../templates/request_template.json"}} + - validators: + - extract_test: {jsonpath_mini: "error", test: "not_exists"} + - extract_test: {jsonpath_mini: "result", test: "exists"} + - compare: {jsonpath_mini: "id", comparator: "str_eq", expected: {template: $test_id}} + - json_file_validator: {jsonpath_mini: "result", comparator: "json_compare", expected: {template: '$api/$method'}} + + - test: + - name: "get_followers" + - variable_binds: + - method: "get_followers" + - args: {} + - <<: *base_test + + - test: + - name: "get_following" + - variable_binds: + - method: "get_following" + - args: {} + - <<: *base_test + + - test: + - name: "get_follow_count" + - variable_binds: + - method: "get_follow_count" + - args: {} + - <<: *base_test + + - test: + - name: "get_account_reputations" + - variable_binds: + - method: "get_account_reputations" + - args: {} + - <<: *base_test + + - test: + - name: "get_blog" + - variable_binds: + - method: "get_blog" + - args: {} + - <<: *base_test + + - test: + - name: "get_blog_entries" + - variable_binds: + - method: "get_blog_entries" + - args: {} + - <<: *base_test + + - test: + - name: "get_reblogged_by" + - variable_binds: + - method: "get_reblogged_by" + - args: {} + - <<: *base_test + + - test: + - name: "get_feed_entries" + - variable_binds: + - method: "get_feed_entries" + - args: {} + - <<: *base_test + + - test: + - name: "get_feed" + - variable_binds: + - method: "get_feed" + - args: {} + - <<: *base_test + + - test: + - name: "get_blog_authors" + - variable_binds: + - method: "get_blog_authors" + - args: {} + - <<: *base_test \ No newline at end of file diff --git a/tests/pyrest_tests/hive_api/hive_api_test.yaml b/tests/pyrest_tests/hive_api/hive_api_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..9884da30c547e89e18eeb73807490d7335c1f139 --- /dev/null +++ b/tests/pyrest_tests/hive_api/hive_api_test.yaml @@ -0,0 +1,28 @@ +--- + - config: + - testset: "Hive API Tests" + - api: &api "hive" + - variable_binds: + - api: *api + - generators: + - test_id: {type: 'number_sequence', start: 1} + + - base_test: &base_test + - generator_binds: + - test_id: test_id + - group: *api + - url: "/rpc" + - method: "POST" + - body: {template: {file: "../templates/request_template.json"}} + - validators: + - extract_test: {jsonpath_mini: "error", test: "not_exists"} + - extract_test: {jsonpath_mini: "result", test: "exists"} + - compare: {jsonpath_mini: "id", comparator: "str_eq", expected: {template: $test_id}} + - json_file_validator: {jsonpath_mini: "result", comparator: "json_compare", expected: {template: '$api/$method'}} + + - test: + - name: "db_head_state" + - variable_binds: + - method: "db_head_state" + - args: {} + - <<: *base_test \ No newline at end of file diff --git a/tests/pyrest_tests/run_api_tests.sh b/tests/pyrest_tests/run_api_tests.sh new file mode 100644 index 0000000000000000000000000000000000000000..bbf42080cffcecd124480eb917a1dc79b6df6c47 --- /dev/null +++ b/tests/pyrest_tests/run_api_tests.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +NODE='http://127.0.0.1' +RPC_PORT=8080 +EXIT_CODE=0 +COMPARATOR='' + +if [ $1 == 'equal' ] +then + COMPARATOR='comparator_equal' +elif [ $1 == 'contain' ] +then + COMPARATOR='comparator_contain' +else + echo FATAL: $1 is not a valid comparator! && exit -1 +fi + +echo COMPARATOR: $COMPARATOR + +pyresttest $NODE:$RPC_PORT ./basic_smoketest.yaml +[ $? -ne 0 ] && echo FATAL: hivemind not running? && exit -1 + +pyresttest $NODE:$RPC_PORT ./bridge_api/bridge_api_test.yaml --import_extensions='validator_ex;'$COMPARATOR +[ $? -ne 0 ] && EXIT_CODE=-1 + +pyresttest $NODE:$RPC_PORT ./condenser_api/condenser_api_test.yaml --import_extensions='validator_ex;'$COMPARATOR +[ $? -ne 0 ] && EXIT_CODE=-1 + +pyresttest $NODE:$RPC_PORT ./database_api/database_api_test.yaml --import_extensions='validator_ex;'$COMPARATOR +[ $? -ne 0 ] && EXIT_CODE=-1 + +pyresttest $NODE:$RPC_PORT ./follow_api/follow_api_test.yaml --import_extensions='validator_ex;'$COMPARATOR +[ $? -ne 0 ] && EXIT_CODE=-1 + +pyresttest $NODE:$RPC_PORT ./hive_api/hive_api_test.yaml --import_extensions='validator_ex;'$COMPARATOR +[ $? -ne 0 ] && EXIT_CODE=-1 + +pyresttest $NODE:$RPC_PORT ./tags_api/tags_api_test.yaml --import_extensions='validator_ex;'$COMPARATOR +[ $? -ne 0 ] && EXIT_CODE=-1 + +exit $EXIT_CODE diff --git a/tests/pyrest_tests/tags_api/tags_api_test.yaml b/tests/pyrest_tests/tags_api/tags_api_test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b30c99d38f71330016449cea07829b8fd53dffce --- /dev/null +++ b/tests/pyrest_tests/tags_api/tags_api_test.yaml @@ -0,0 +1,147 @@ +--- + - config: + - testset: "Tags API Tests" + - api: &api "tags_api" + - variable_binds: + - api: *api + - generators: + - test_id: {type: 'number_sequence', start: 1} + + - base_test: &base_test + - generator_binds: + - test_id: test_id + - group: *api + - url: "/rpc" + - method: "POST" + - body: {template: {file: "../templates/request_template.json"}} + - validators: + - extract_test: {jsonpath_mini: "error", test: "not_exists"} + - extract_test: {jsonpath_mini: "result", test: "exists"} + - compare: {jsonpath_mini: "id", comparator: "str_eq", expected: {template: $test_id}} + - json_file_validator: {jsonpath_mini: "result", comparator: "json_compare", expected: {template: '$api/$method'}} + + - test: + - name: "get_discussion" + - variable_binds: + - method: "get_discussion" + - args: {} + - <<: *base_test + + - test: + - name: "get_content_replies" + - variable_binds: + - method: "get_content_replies" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_trending" + - variable_binds: + - method: "get_discussions_by_trending" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_hot" + - variable_binds: + - method: "get_discussions_by_hot" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_promoted" + - variable_binds: + - method: "get_discussions_by_promoted" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_created" + - variable_binds: + - method: "get_discussions_by_created" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_blog" + - variable_binds: + - method: "get_discussions_by_blog" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_comments" + - variable_binds: + - method: "get_discussions_by_comments" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_author_before_date" + - variable_binds: + - method: "get_discussions_by_author_before_date" + - args: {} + - <<: *base_test + + - test: + - name: "get_post_discussions_by_payout" + - variable_binds: + - method: "get_post_discussions_by_payout" + - args: {} + - <<: *base_test + + - test: + - name: "get_comment_discussions_by_payout" + - variable_binds: + - method: "get_comment_discussions_by_payout" + - args: {} + - <<: *base_test + + - test: + - name: "get_active_votes" + - variable_binds: + - method: "get_active_votes" + - args: {} + - <<: *base_test + + - test: + - name: "get_tags_used_by_author" + - variable_binds: + - method: "get_tags_used_by_author" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_active" + - variable_binds: + - method: "get_discussions_by_active" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_cashout" + - variable_binds: + - method: "get_discussions_by_cashout" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_votes" + - variable_binds: + - method: "get_discussions_by_votes" + - args: {} + - <<: *base_test + + - test: + - name: "get_discussions_by_children" + - variable_binds: + - method: "get_discussions_by_children" + - args: {} + - <<: *base_test + + - test: + - name: "get_account_votes" + - variable_binds: + - method: "get_account_votes" + - args: {} + - <<: *base_test \ No newline at end of file diff --git a/tests/pyrest_tests/templates/request_template.json b/tests/pyrest_tests/templates/request_template.json new file mode 100644 index 0000000000000000000000000000000000000000..30833b0377fffb2d9c7e7dc911648db46269d104 --- /dev/null +++ b/tests/pyrest_tests/templates/request_template.json @@ -0,0 +1,6 @@ +{ + "jsonrpc": "2.0", + "id": $test_id, + "method": "$api.$method", + "params": $args +} diff --git a/tests/pyrest_tests/validator_ex.py b/tests/pyrest_tests/validator_ex.py new file mode 100644 index 0000000000000000000000000000000000000000..29aebd243d4bbd4f40dc7c52501753d0f876e613 --- /dev/null +++ b/tests/pyrest_tests/validator_ex.py @@ -0,0 +1,172 @@ +import os +import sys +import traceback +import string +import ast +import json +import logging + +from six import binary_type +from six import text_type + +# Python 3 compatibility +PYTHON_MAJOR_VERSION = sys.version_info[0] +if PYTHON_MAJOR_VERSION > 2: + from past.builtins import basestring + from past.builtins import long + +try: # First try to load pyresttest from global namespace + from pyresttest import validators + from pyresttest import parsing +except ImportError: # Then try a relative import if possible + logging.error("Cannot import module") + +def dict_str_eq(x, y): + """ Check if dict object is equal to string object """ + assert isinstance(x, dict) + assert isinstance(y, str) + y = ast.literal_eval(y) + assert isinstance(y, dict) + return x == y + +COMPARATORS = {'dict_str_eq': dict_str_eq} +PATTERN_FILE_EXT = ".json.pat" +OUTPUT_FILE_EXT = ".json.out" + +def dump_output(output_file_name, output): + """ Dump JSON output to the file. """ + try: + with open(output_file_name, "w") as f: + json.dump(output, f, sort_keys=True, indent=4) + except Exception: + logging.error("Cannot dump output to file {0}.".format(output_file_name)) + logging.info(traceback.format_exc()) + +class JSONFileValidator(validators.AbstractValidator): + """ Does extract response body and compare with given my_file_name.pat.json. + If comparison failed response is save into my_file_name.out.json file. + """ + + name = 'ComparatorValidator' + config = None # Configuration text, if parsed + extractor = None + comparator = None + comparator_name = "" + expected = None + isTemplateExpected = False + + def get_readable_config(self, context=None): + """ Get a human-readable config string """ + string_frags = list() + string_frags.append( + "Extractor: " + self.extractor.get_readable_config(context=context)) + if isinstance(self.expected, validators.AbstractExtractor): + string_frags.append("Expected value extractor: " + + self.expected.get_readable_config(context=context)) + elif self.isTemplateExpected: + string_frags.append( + 'Expected is templated, raw value: {0}'.format(self.expected)) + return os.linesep.join(string_frags) + + def validate(self, body=None, headers=None, context=None): + try: + extracted_val = self.extractor.extract( + body=body, headers=headers, context=context) + except Exception: + trace = traceback.format_exc() + return validators.Failure(message="Extractor threw exception", details=trace, + validator=self, + failure_type=validators.FAILURE_EXTRACTOR_EXCEPTION) + + # Compute expected output, either templating or using expected value + file_name = None + if self.isTemplateExpected and context: + file_name = string.Template( + self.expected).safe_substitute(context.get_values()) + else: + file_name = self.expected + + expected_val = None + expected_file_name = file_name + PATTERN_FILE_EXT + output_file_name = file_name + OUTPUT_FILE_EXT + try: + with open(expected_file_name, "r") as f: + expected_val = json.load(f) + except Exception: + trace = traceback.format_exc() + dump_output(output_file_name, extracted_val) + return validators.Failure(message="Cannot load pattern file {0}.".format(expected_file_name), details=trace, validator=self, failure_type=validators.FAILURE_VALIDATOR_EXCEPTION) + + # Handle a bytes-based body and a unicode expected value seamlessly + if isinstance(extracted_val, binary_type) and isinstance(expected_val, text_type): + expected_val = expected_val.encode('utf-8') + comparison = self.comparator(extracted_val, expected_val) + + if not comparison: + failure = validators.Failure(validator=self) + failure.message = "Comparison failed, evaluating {0}({1}, {2}) returned False".format( + self.comparator_name, extracted_val, expected_val) + failure.details = self.get_readable_config(context=context) + failure.failure_type = validators.FAILURE_VALIDATOR_FAILED + dump_output(output_file_name, extracted_val) + return failure + return True + + @staticmethod + def parse(config): + """ Create a validator that does an extract from body and applies a comparator, + Then does comparison vs expected value + Syntax sample: + { jsonpath_mini: 'node.child', + operator: 'eq', + expected: 'my_file_name' + } + """ + + output = JSONFileValidator() + config = parsing.lowercase_keys(parsing.flatten_dictionaries(config)) + output.config = config + + # Extract functions are called by using defined extractor names + output.extractor = validators._get_extractor(config) + + if output.extractor is None: + raise ValueError( + "Extract function for comparison is not valid or not found!") + + if 'comparator' not in config: # Equals comparator if unspecified + output.comparator_name = 'eq' + else: + output.comparator_name = config['comparator'].lower() + output.comparator = validators.COMPARATORS[output.comparator_name] + if not output.comparator: + raise ValueError("Invalid comparator given!") + + try: + expected = config['expected'] + except KeyError: + raise ValueError( + "No expected value found in comparator validator config, one must be!") + + # Expected value can be base or templated string contains file name without extension. + if isinstance(expected, (basestring, int, long, float, complex)): + output.expected = expected + elif isinstance(expected, dict): + expected = parsing.lowercase_keys(expected) + template = expected.get('template') + if template: # Templated string + if not isinstance(template, basestring): + raise ValueError( + "Can't template a comparator-validator unless template value is a string") + output.isTemplateExpected = True + output.expected = template + else: # Extractor to compare against + raise ValueError( + "Can't supply a non-template, non-extract dictionary to comparator-validator") + + return output + +VALIDATORS = { + 'json_file_validator': JSONFileValidator.parse, + 'json_file_validate': JSONFileValidator.parse +}