server/tests-py: Provide the admin secret to the HGE server.

When we run the HGE server inside the test harness, it needs to run with
an admin secret for some tests to make sense. This tags each test that
requires an admin secret with `pytest.mark.admin_secret`, which then
generates a UUID and injects that into both the server and the test case
(if required).

It also simplifies the way the test harness picks up an existing admin
secret, allowing it to use the environment variable instead of requiring
it via a parameter.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/6120
GitOrigin-RevId: 55c5b9e8c99bdad9c8304098444ddb9516749a2c
This commit is contained in:
Samir Talwar 2022-09-29 19:18:49 +02:00 committed by hasura-bot
parent a5dc3f8440
commit 3cb9bab9f1
20 changed files with 231 additions and 234 deletions

View File

@ -74,7 +74,7 @@ init_hge_and_test_jwt() {
run_hge_with_args serve
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" --hge-jwt-key-file="$key_file" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET" \
--hge-jwt-key-file="$key_file" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET" \
"$@"
kill_hge_servers
}
@ -266,7 +266,7 @@ admin-secret)
start_multiple_hge_servers
run_pytest_parallel --hge-key="$HASURA_GRAPHQL_ADMIN_SECRET"
run_pytest_parallel
kill_hge_servers
;;
@ -282,7 +282,6 @@ admin-secret-unauthorized-role)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-unauthorized-role \
test_graphql_queries.py::TestUnauthorizedRolePermission
@ -302,7 +301,7 @@ jwt-rs512)
start_multiple_hge_servers
run_pytest_parallel --hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" --hge-jwt-key-file="$OUTPUT_FOLDER/ssl/jwt_private.key" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET"
run_pytest_parallel --hge-jwt-key-file="$OUTPUT_FOLDER/ssl/jwt_private.key" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET"
kill_hge_servers
@ -320,7 +319,7 @@ jwt-ed25519)
start_multiple_hge_servers
run_pytest_parallel --hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" --hge-jwt-key-file="$OUTPUT_FOLDER/ssl/ed25519_jwt_private.key" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET"
run_pytest_parallel --hge-jwt-key-file="$OUTPUT_FOLDER/ssl/ed25519_jwt_private.key" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET"
kill_hge_servers
@ -574,7 +573,7 @@ jwt-cookie-unauthorized-role)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" --hge-jwt-key-file="$OUTPUT_FOLDER/ssl/jwt_private.key" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET" \
--hge-jwt-key-file="$OUTPUT_FOLDER/ssl/jwt_private.key" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET" \
--test-unauthorized-role \
test_graphql_queries.py::TestFallbackUnauthorizedRoleCookie
@ -586,7 +585,7 @@ jwt-cookie-unauthorized-role)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" --hge-jwt-key-file="$OUTPUT_FOLDER/ssl/jwt_private.key" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET" \
--hge-jwt-key-file="$OUTPUT_FOLDER/ssl/jwt_private.key" --hge-jwt-conf="$HASURA_GRAPHQL_JWT_SECRET" \
--test-no-cookie-and-unauth-role \
test_graphql_queries.py::TestMissingUnauthorizedRoleAndCookie
@ -605,7 +604,6 @@ cors-domains)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_cors.py
kill_hge_servers
@ -624,7 +622,7 @@ auth-webhook-cookie)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" --hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK" \
--hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK" \
--test-auth-webhook-header \
test_auth_webhook_cookie.py
@ -644,7 +642,6 @@ ws-init-cookie-read-cors-enabled)
echo "$(time_elapsed): testcase 1: read cookie, cors enabled"
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-ws-init-cookie=read \
test_websocket_init_cookie.py
@ -662,7 +659,6 @@ ws-init-cookie-noread)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-ws-init-cookie=noread \
test_websocket_init_cookie.py
@ -680,7 +676,6 @@ ws-init-cookie-read-cors-disabled)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-ws-init-cookie=read \
test_websocket_init_cookie.py
@ -698,7 +693,6 @@ ws-graphql-api-disabled)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_apis_disabled.py
kill_hge_servers
@ -716,7 +710,6 @@ ws-metadata-api-disabled)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_apis_disabled.py
kill_hge_servers
@ -731,7 +724,6 @@ remote-schema-permissions)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_remote_schema_permissions.py
unset HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS
@ -748,10 +740,8 @@ function-permissions)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_graphql_queries.py::TestGraphQLQueryFunctionPermissions
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_graphql_mutations.py::TestGraphQLMutationFunctions
unset HASURA_GRAPHQL_INFER_FUNCTION_PERMISSIONS
@ -771,7 +761,6 @@ roles-inheritance)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_roles_inheritance.py
unset HASURA_GRAPHQL_ADMIN_SECRET
@ -791,7 +780,6 @@ naming-conventions)
unset HASURA_GRAPHQL_EXPERIMENTAL_FEATURES
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_naming_conventions.py
kill_hge_servers
@ -801,7 +789,6 @@ naming-conventions)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_naming_conventions.py
kill_hge_servers
@ -815,7 +802,6 @@ naming-conventions)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_naming_conventions.py
unset HASURA_GRAPHQL_ADMIN_SECRET
@ -835,8 +821,6 @@ streaming-subscriptions)
# run all the subscriptions tests with streaming subscriptions enabled
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-streaming-subscriptions \
test_subscriptions.py
unset HASURA_GRAPHQL_ADMIN_SECRET
@ -853,7 +837,6 @@ query-caching)
run_hge_with_args +RTS -N1 -RTS serve
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_graphql_queries.py::TestGraphQLQueryCaching
kill_hge_servers
;;
@ -877,7 +860,6 @@ query-logs)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-logging \
test_logging.py
@ -912,7 +894,6 @@ startup-db-calls)
run_hge_with_args serve
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-startup-db-calls \
test_startup_db_calls.py
@ -961,7 +942,6 @@ EOF
pytest "${PYTEST_REPORTING_ARGS[@]}" \
--hge-urls "$HGE_URL" \
--pg-urls "$HASURA_GRAPHQL_PG_SOURCE_URL_1" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-read-only-source \
test_graphql_read_only_source.py
@ -1011,7 +991,7 @@ post-webhook)
WH_PID=$!
wait_for_port 9090
run_pytest_parallel --hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" --hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK"
run_pytest_parallel --hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK"
kill_hge_servers
;;
@ -1028,7 +1008,6 @@ webhook-request-context)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK" \
--test-webhook-request-context \
test_webhook_request_context.py
@ -1051,7 +1030,7 @@ get-webhook)
WH_PID=$!
wait_for_port 9090
run_pytest_parallel --hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" --hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK"
run_pytest_parallel --hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK"
kill_hge_servers
;;
@ -1077,7 +1056,6 @@ insecure-webhook)
wait_for_port 9090
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK" \
--test-webhook-insecure \
test_webhook_insecure.py
@ -1105,7 +1083,6 @@ insecure-webhook-with-admin-secret)
wait_for_port 9090
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--hge-webhook="$HASURA_GRAPHQL_AUTH_HOOK" \
--test-webhook-insecure \
test_webhook_insecure.py
@ -1124,7 +1101,6 @@ apollo-federation)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_apollo_federation.py
unset HASURA_GRAPHQL_EXPERIMENTAL_FEATURES
@ -1142,7 +1118,6 @@ allowlist-queries)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_allowlist_queries.py
kill_hge_servers
@ -1157,7 +1132,6 @@ developer-api-tests)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
test_dev_endpoints.py
unset HASURA_GRAPHQL_ENABLED_APIS
@ -1187,7 +1161,6 @@ jwk-url)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-jwk-url \
-k 'test_cache_control_header_max_age'
@ -1200,7 +1173,6 @@ jwk-url)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-jwk-url \
-k 'test_cache_control_header_max_age'
@ -1213,7 +1185,6 @@ jwk-url)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-jwk-url \
-k 'test_cache_control_header_no_caching'
@ -1226,7 +1197,6 @@ jwk-url)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-jwk-url \
-k 'test_cache_control_header_no_caching'
@ -1239,7 +1209,6 @@ jwk-url)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-jwk-url \
-k 'test_cache_control_header_no_caching'
@ -1252,7 +1221,6 @@ jwk-url)
wait_for_port 8080
pytest "${PYTEST_COMMON_ARGS[@]}" \
--hge-key="$HASURA_GRAPHQL_ADMIN_SECRET" \
--test-jwk-url \
-k 'test_expires_header'

View File

@ -7,6 +7,7 @@ import sys
import threading
import time
from typing import Optional
import uuid
import auth_webhook_server
from context import HGECtx, HGECtxGQLServer, ActionsWebhookServer, EvtsWebhookServer, GQLWsClient, PytestConf, GraphQLWSClient
@ -34,9 +35,6 @@ def pytest_addoption(parser):
required=False,
nargs='+'
)
parser.addoption(
"--hge-key", metavar="HGE_KEY", help="admin secret key for graphql-engine", required=False
)
parser.addoption(
"--hge-webhook", metavar="HGE_WEBHOOK", help="url for graphql-engine's access control webhook", required=False
)
@ -85,14 +83,6 @@ def pytest_addoption(parser):
help="Run testcases for startup database calls"
)
parser.addoption(
"--test-streaming-subscriptions",
action="store_true",
default=False,
required=False,
help="Run streaming subscription tests"
)
parser.addoption(
"--test-jwk-url",
action="store_true",
@ -372,8 +362,23 @@ def hge_fixture_env() -> dict[str, str]:
return {}
@pytest.fixture(scope='class')
def hge_key(request) -> Optional[str]:
return request.config.getoption('--hge-key')
def hge_key(
request: pytest.FixtureRequest,
hge_bin: Optional[str],
) -> Optional[str]:
marker = request.node.get_closest_marker('admin_secret')
if hge_bin:
# If the test requests an admin secret, generate one.
return str(uuid.uuid4()) if marker else None
else:
# If the environment variable is set, use it.
# This will be used in the event that we start the server outside the test harness.
# We skip the test if it explicitly requires that we have no admin secret.
anti_marker = request.node.get_closest_marker('no_admin_secret')
env_key = os.environ.get('HASURA_GRAPHQL_ADMIN_SECRET')
if anti_marker and env_key:
pytest.skip('This test requires that the admin secret is not set.')
return env_key
@pytest.fixture(scope='class')
def hge_server(
@ -381,16 +386,28 @@ def hge_server(
hge_bin: Optional[str],
hge_port: int,
hge_url: str,
hge_key: Optional[str],
hge_fixture_env: dict[str, str],
pg_url: str,
) -> Optional[str]:
if not hge_bin:
return None
return fixtures.hge.hge_server(request, hge_bin, hge_port, hge_url, hge_fixture_env, pg_url)
return fixtures.hge.hge_server(request, hge_bin, hge_port, hge_url, hge_key, hge_fixture_env, pg_url)
@pytest.fixture(scope='class')
def hge_ctx(request, hge_url, pg_url, hge_server):
hge_ctx = HGECtx(hge_url, pg_url, request.config)
def enabled_apis(request: pytest.FixtureRequest, hge_bin: Optional[str]) -> Optional[set[str]]:
if hge_bin:
hge_marker_env: dict[str, str] = {marker.args[0]: marker.args[1] for marker in request.node.iter_markers('hge_env') if marker.args[1] is not None}
enabled_apis_str = hge_marker_env.get('HASURA_GRAPHQL_ENABLED_APIS')
else:
enabled_apis_str = os.environ.get('HASURA_GRAPHQL_ENABLED_APIS')
if not enabled_apis_str:
return None
return set(enabled_apis_str.split(','))
@pytest.fixture(scope='class')
def hge_ctx(request, hge_url, pg_url, hge_key, enabled_apis, hge_server):
hge_ctx = HGECtx(hge_url, pg_url, hge_key, enabled_apis, request.config)
yield hge_ctx
@ -442,12 +459,6 @@ def auth_hook(hge_fixture_env: dict[str, str]):
yield server
auth_webhook_server.stop_server(server)
@pytest.fixture(scope='class')
def streaming_subscriptions_fixtures(hge_ctx):
if not hge_ctx.streaming_subscriptions:
pytest.skip('These tests are meant to be run with --test-streaming-subscriptions set with pytest')
return
@pytest.fixture(scope='class')
def pro_tests_fixtures(hge_ctx):
if not hge_ctx.pro_tests:

View File

@ -790,10 +790,9 @@ class HGECtxGQLServer:
class HGECtx:
def __init__(self, hge_url, pg_url, config):
def __init__(self, hge_url, pg_url, hge_key, enabled_apis, config):
self.http = requests.Session()
self.hge_key = config.getoption('--hge-key')
self.hge_key = hge_key
self.timeout = 120 # BigQuery can take a while
self.hge_url = hge_url
self.pg_url = pg_url
@ -812,7 +811,6 @@ class HGECtx:
self.hge_jwt_algo = "EdDSA"
self.webhook_insecure = config.getoption('--test-webhook-insecure')
self.may_skip_test_teardown = False
self.streaming_subscriptions = config.getoption('--test-streaming-subscriptions')
# This will be GC'd, but we also explicitly dispose() in teardown()
self.engine = sqlalchemy.create_engine(self.pg_url)
@ -833,9 +831,6 @@ class HGECtx:
self.default_backend = 'postgres'
self.is_default_backend = self.backend == self.default_backend
enabled_apis_str = os.environ.get('HASURA_GRAPHQL_ENABLED_APIS')
enabled_apis = set(enabled_apis_str.split(',')) if enabled_apis_str else None
env_version = os.getenv('VERSION')
if env_version:
self.version = env_version

View File

@ -80,6 +80,14 @@ services:
volumes:
- /var/lib/postgresql/data
citus-healthy:
image: busybox
command:
- 'true'
depends_on:
citus:
condition: service_healthy
mssql:
# Uses a different image for arm64.
image: ${MSSQL_IMAGE:-mcr.microsoft.com/mssql/server:2019-latest@sha256:a098c9ff6fbb8e1c9608ad7511fa42dba8d22e0d50b48302761717840ccc26af}

View File

@ -24,6 +24,7 @@ def hge_server(
hge_bin: str,
hge_port: int,
hge_url: str,
hge_key: Optional[str],
hge_fixture_env: dict[str, str],
pg_url: str,
) -> Optional[str]:
@ -35,6 +36,8 @@ def hge_server(
**hge_marker_env,
}
hge_key_args = ['--admin-secret', hge_key] if hge_key else []
print(f'Starting GraphQL Engine on {hge_url}...')
hge_process = subprocess.Popen(
args = [
@ -43,6 +46,7 @@ def hge_server(
'serve',
'--server-port', str(hge_port),
'--stringify-numeric-types',
*hge_key_args,
],
env = env,
)

View File

@ -6,6 +6,7 @@ norecursedirs = queries webhook test_upgrade
xfail_strict = true
markers =
backend: The backends supported by the test case
admin_secret: Generate and use an admin secret
hge_env: Pass additional environment variables to the GraphQL Engine
skip_server_upgrade_test: Tests with this marker should not be run as part of server upgrade test
allow_server_upgrade_test: Add tests with this marker to server upgrade test, as far as they don't have the skip_server_upgarde_test market

View File

@ -30,7 +30,7 @@ if [[ "$(uname -m)" == 'arm64' ]]; then
fi
docker compose rm -svf citus mssql postgres
docker compose up -d citus mssql-healthcheck postgres-healthy
docker compose up -d citus-healthy mssql-healthcheck postgres-healthy
HASURA_GRAPHQL_CITUS_SOURCE_URL="postgresql://postgres:hasura@localhost:$(docker compose port citus 5432 | sed -E 's/.*://')/postgres"
HASURA_GRAPHQL_MSSQL_SOURCE_URL="DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost,$(docker compose port mssql 1433 | sed -E 's/.*://');Uid=sa;Pwd=Password!;"

View File

@ -49,12 +49,12 @@ else
fi
echo "*** Building HGE ***"
docker compose run hge-build
docker compose run --rm hge-build
for SERVER_TEST_TO_RUN in "${SERVER_TESTS_TO_RUN[@]}"; do
export SERVER_TEST_TO_RUN
echo
echo "*** Running test suite: ${SERVER_TEST_TO_RUN} ***"
docker compose rm -svf citus mssql postgres # tear down databases beforehand
docker compose run tests-py
docker compose run --rm tests-py
done

View File

@ -6,6 +6,7 @@ from context import PytestConf
pytestmark = [
pytest.mark.usefixtures('auth_hook'),
pytest.mark.admin_secret,
pytest.mark.hge_env('HASURA_GRAPHQL_AUTH_HOOK_MODE', 'POST'),
]

View File

@ -12,18 +12,20 @@ def make_request(url, query):
resp = requests.post(url, json=payload)
return resp
@pytest.mark.hge_env('HASURA_GRAPHQL_EXPERIMENTAL_FEATURES', 'apollo_federation')
@pytest.mark.usefixtures('per_class_tests_db_state')
@pytest.mark.admin_secret
@pytest.mark.hge_env('HASURA_GRAPHQL_EXPERIMENTAL_FEATURES', 'apollo_federation')
class TestApolloFederation:
@classmethod
def dir(cls):
return 'queries/apollo_federation'
def test_apollo_federated_server_with_hge_only(self, hge_url: str):
def test_apollo_federated_server_with_hge_only(self, hge_url: str, hge_key: str):
# start the node server
fed_server = NodeGraphQL(["node", "remote_schemas/nodejs/apollo_federated_server_with_hge_only.js"], env={
'HGE_URL': hge_url,
'HASURA_GRAPHQL_ADMIN_SECRET': hge_key,
})
fed_server.start()
@ -45,16 +47,16 @@ class TestApolloFederation:
assert resp.status_code == 200, resp.text
assert 'data' in resp.text
def test_apollo_federated_server_with_hge_and_apollo_graphql_server(self, hge_url: str):
def test_apollo_federated_server_with_hge_and_apollo_graphql_server(self, hge_url: str, hge_key: str):
# start the node servers
server_1 = NodeGraphQL(["node", "remote_schemas/nodejs/apollo_server_1.js"], env={
'HGE_URL': hge_url,
})
server_env = {
fed_server = NodeGraphQL(["node", "remote_schemas/nodejs/apollo_federated_server_with_hge_and_server1.js"], env={
'HGE_URL': hge_url,
'OTHER_URL': server_1.url,
}
fed_server = NodeGraphQL(["node", "remote_schemas/nodejs/apollo_federated_server_with_hge_and_server1.js"], env=server_env)
'HASURA_GRAPHQL_ADMIN_SECRET': hge_key,
})
server_1.start()
fed_server.start()
@ -80,8 +82,8 @@ class TestApolloFederation:
assert resp.status_code == 200, resp.text
assert 'data' in resp.text
def test_apollo_federation_fields(self,hge_ctx):
def test_apollo_federation_fields(self, hge_ctx):
check_query_f(hge_ctx, self.dir() + '/root_fields.yaml')
def test_apollo_federation_entities(self,hge_ctx):
def test_apollo_federation_entities(self, hge_ctx):
check_query_f(hge_ctx, self.dir() + '/entities.yaml')

View File

@ -14,6 +14,7 @@ if not PytestConf.config.getoption("--test-auth-webhook-header"):
pytest.skip("--test-auth-webhook-header flag is missing, skipping tests", allow_module_level=True)
@pytest.mark.usefixtures('auth_hook', 'per_class_tests_db_state')
@pytest.mark.admin_secret
class TestWebhookHeaderCookie(object):
'''
To run the test, run an instance of the auth_webhook server using `python3 auth_webhook_server.py`

View File

@ -1,10 +1,6 @@
import pytest
from context import PytestConf
if not PytestConf.config.getoption("--hge-key"):
pytest.skip("--hge-key flag is missing, skipping tests", allow_module_level=True)
def v1qCompat(hge_ctx, q, headers = {}):
def v1qCompat(hge_ctx, q):
h = {'X-Hasura-Access-Key': hge_ctx.hge_key}
resp = hge_ctx.http.post(
hge_ctx.hge_url + "/v1/query",
@ -13,6 +9,7 @@ def v1qCompat(hge_ctx, q, headers = {}):
)
return resp.status_code, resp.json()
@pytest.mark.admin_secret
class TestGraphQLCompatAccessKey():
export_metadata = {

View File

@ -1,6 +1,5 @@
import requests
import pytest
from context import PytestConf
"""
@ -25,6 +24,7 @@ def get_headers(hge_ctx, role='admin'):
headers['x-hasura-role'] = role
return headers
@pytest.mark.admin_secret
@pytest.mark.hge_env('HASURA_GRAPHQL_ENABLED_APIS', 'metadata,graphql,developer,config,pgdump')
class TestDevEndpoints:

View File

@ -798,6 +798,7 @@ class TestGraphQLMutateEnums:
# Tracking VOLATILE SQL functions as mutations, or queries (#1514)
@pytest.mark.parametrize('transport', ['http', 'websocket'])
@use_mutation_fixtures
@pytest.mark.admin_secret
@pytest.mark.hge_env('HASURA_GRAPHQL_INFER_FUNCTION_PERMISSIONS', 'false')
class TestGraphQLMutationFunctions:
@classmethod

View File

@ -1,12 +1,12 @@
import pytest
from validate import assert_response_code, check_query_f, check_query, get_conf_f
from context import PytestConf
import json
import textwrap
import pytest
import ruamel.yaml as yaml
import textwrap
import warnings
from context import PytestConf
from validate import assert_response_code, check_query_f, get_conf_f
# Mark that all tests in this module can be run as server upgrade tests
pytestmark = pytest.mark.allow_server_upgrade_test
@ -1303,6 +1303,7 @@ use_function_permission_fixtures = pytest.mark.usefixtures(
@pytest.mark.parametrize('transport', ['http', 'websocket'])
@pytest.mark.usefixtures('per_method_tests_db_state')
@pytest.mark.admin_secret
@pytest.mark.hge_env('HASURA_GRAPHQL_INFER_FUNCTION_PERMISSIONS', 'false')
class TestGraphQLQueryFunctionPermissions:
@classmethod

View File

@ -410,7 +410,7 @@ def gen_rsa_key():
class TestSubscriptionJwtExpiry(object):
def test_jwt_expiry(self, hge_ctx, ws_client):
def test_jwt_expiry(self, hge_ctx, hge_key, ws_client):
curr_time = datetime.now()
self.claims = {
'sub': '1234567890',
@ -433,7 +433,7 @@ class TestSubscriptionJwtExpiry(object):
authz_header = mk_authz_header(hge_ctx.hge_jwt_conf, token)
payload = dict()
payload['headers'] = authz_header
init_ws_conn(hge_ctx, ws_client, payload)
init_ws_conn(hge_key, ws_client, payload)
time.sleep(6)
assert ws_client.remote_closed == True, ws_client.remote_closed

View File

@ -7,6 +7,7 @@ from remote_server import NodeGraphQL
from validate import check_query_f
pytestmark = [
pytest.mark.admin_secret,
pytest.mark.hge_env('HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS', 'true'),
]

View File

@ -6,6 +6,7 @@ from remote_server import NodeGraphQL
from validate import check_query_f
pytestmark = [
pytest.mark.admin_secret,
pytest.mark.hge_env('HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS', 'true'),
]

View File

@ -1,111 +1,104 @@
#!/usr/bin/env python3
import datetime
import time
import pytest
import json
import queue
from validate import check_query_f
from collections import OrderedDict
from utils import insert_many
import json
import pytest
import queue
from ruamel.yaml import YAML
import time
import uuid
from validate import check_query_f
from utils import insert_many
usefixtures = pytest.mark.usefixtures
yaml=YAML(typ='safe', pure=True)
@pytest.fixture(scope='class')
def ws_conn_init(hge_ctx, ws_client):
init_ws_conn(hge_ctx, ws_client)
usefixtures = pytest.mark.usefixtures
@pytest.fixture(scope='class')
def ws_conn_init_graphql_ws(hge_ctx, ws_client_graphql_ws):
init_graphql_ws_conn(hge_ctx, ws_client_graphql_ws)
def ws_conn_init(hge_key, ws_client):
init_ws_conn(hge_key, ws_client)
@pytest.fixture(scope='class')
def ws_conn_init_graphql_ws(hge_key, ws_client_graphql_ws):
init_graphql_ws_conn(hge_key, ws_client_graphql_ws)
'''
Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_connection_init
'''
def init_ws_conn(hge_ctx, ws_client, payload = None):
if payload is None:
payload = {}
if hge_ctx.hge_key is not None:
payload = {
'headers' : {
'X-Hasura-Admin-Secret': hge_ctx.hge_key
}
}
# This is used in other test files! Be careful when modifying it.
def init_ws_conn(hge_key, ws_client, payload = None):
init_msg = {
'type': 'connection_init',
'payload': payload,
'payload': payload or ws_payload(hge_key),
}
ws_client.send(init_msg)
ev = ws_client.get_ws_event(3)
assert ev['type'] == 'connection_ack', ev
def init_graphql_ws_conn(hge_ctx, ws_client_graphql_ws, payload = None):
if payload is None:
payload = {}
if hge_ctx.hge_key is not None:
payload = {
'headers' : {
'X-Hasura-Admin-Secret': hge_ctx.hge_key
}
}
def init_graphql_ws_conn(hge_key, ws_client_graphql_ws):
init_msg = {
'type': 'connection_init',
'payload': payload,
'payload': ws_payload(hge_key),
}
ws_client_graphql_ws.send(init_msg)
ev = ws_client_graphql_ws.get_ws_event(3)
assert ev['type'] == 'connection_ack', ev
def get_explain_graphql_query_response(hge_ctx, query, variables, user_headers = {}):
admin_secret = hge_ctx.hge_key
def ws_payload(hge_key):
if hge_key is not None:
return {
'headers': {
'X-Hasura-Admin-Secret': hge_key,
}
}
else:
return {}
def get_explain_graphql_query_response(hge_ctx, hge_key, query, variables, user_headers = {}):
headers = {}
if admin_secret is not None:
headers['X-Hasura-Admin-Secret'] = admin_secret
if hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_key
request = { 'query': { 'query': query, 'variables': variables }, 'user': user_headers }
status_code, response, _ = hge_ctx.anyq('/v1/graphql/explain', request, headers)
assert status_code == 200, (request, status_code, response)
return response
class TestSubscriptionCtrl(object):
@pytest.mark.no_admin_secret
class TestSubscriptionCtrlWithoutSecret(object):
def test_connection(self, ws_client):
ws_client.recreate_conn()
init_ws_conn(None, ws_client)
def test_init_without_payload(self, hge_ctx, ws_client):
if hge_ctx.hge_key is not None:
pytest.skip("Payload is needed when admin secret is set")
init_msg = {
'type': 'connection_init'
}
ws_client.send(init_msg)
ev = ws_client.get_ws_event(15)
assert ev['type'] == 'connection_ack', ev
'''
Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_connection_init
'''
def test_init(self, hge_ctx, ws_client):
init_ws_conn(hge_ctx, ws_client)
'''
Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_connection_terminate
'''
def test_connection_terminate(self, hge_ctx, ws_client):
obj = {
'type': 'connection_terminate'
}
ws_client.send(obj)
with pytest.raises(queue.Empty):
ev = ws_client.get_ws_event(3)
ws_client.get_ws_event(3)
@pytest.mark.admin_secret
class TestSubscriptionCtrl(object):
'''
References:
https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_connection_init
https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_connection_terminate
'''
def test_connection(self, hge_key, ws_client):
ws_client.recreate_conn()
init_ws_conn(hge_key, ws_client)
obj = {
'type': 'connection_terminate'
}
ws_client.send(obj)
with pytest.raises(queue.Empty):
ws_client.get_ws_event(3)
@pytest.mark.backend('mssql', 'postgres')
@usefixtures('per_class_tests_db_state', 'ws_conn_init')
@pytest.mark.admin_secret
class TestSubscriptionBasic:
@classmethod
def dir(cls):
@ -129,6 +122,7 @@ class TestSubscriptionBasic:
'''
def test_start(self, ws_client):
id = str(uuid.uuid4())
query = """
subscription {
hge_tests_test_t1(order_by: {c1: desc}, limit: 1) {
@ -138,7 +132,7 @@ class TestSubscriptionBasic:
}
"""
obj = {
'id': '1',
'id': id,
'payload': {
'query': query
},
@ -148,13 +142,13 @@ class TestSubscriptionBasic:
'''
Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_data
'''
ev = ws_client.get_ws_query_event('1',15)
assert ev['type'] == 'data' and ev['id'] == '1', ev
ev = ws_client.get_ws_query_event(id, 15)
assert ev['type'] == 'data' and ev['id'] == id, ev
'''
Refer https://github.com/apollographql/subscriptions-transport-ws/blob/01e0b2b65df07c52f5831cce5c858966ba095993/src/server.ts#L306
'''
@pytest.mark.skip(reason="refer https://github.com/hasura/graphql-engine/pull/387#issuecomment-421343098")
@pytest.mark.skip(reason="refer to https://github.com/hasura/graphql-engine/pull/387#issuecomment-421343098")
def test_start_duplicate(self, ws_client):
self.test_start(ws_client)
@ -187,7 +181,7 @@ class TestSubscriptionBasic:
Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_complete
'''
def test_complete(self, hge_ctx, ws_client):
def test_complete(self, ws_client):
query = """
query {
hge_tests_test_t1(order_by: {c1: desc}, limit: 1) {
@ -215,6 +209,7 @@ class TestSubscriptionBasic:
## FIXME: There's an issue with the tests being parametrized with both
## postgres and mssql data sources enabled(See issue #2084).
@usefixtures('per_method_tests_db_state', 'ws_conn_init_graphql_ws')
@pytest.mark.admin_secret
class TestSubscriptionBasicGraphQLWS:
@classmethod
def dir(cls):
@ -224,10 +219,10 @@ class TestSubscriptionBasicGraphQLWS:
def test_negative(self, hge_ctx, transport):
check_query_f(hge_ctx, self.dir() + '/negative_test.yaml', transport, gqlws=True)
def test_connection_error(self, hge_ctx, ws_client_graphql_ws):
def test_connection_error(self, hge_key, ws_client_graphql_ws):
if ws_client_graphql_ws.get_conn_close_state():
ws_client_graphql_ws.create_conn()
if hge_ctx.hge_key == None:
if hge_key == None:
ws_client_graphql_ws.init()
else:
ws_client_graphql_ws.init_as_admin()
@ -236,13 +231,15 @@ class TestSubscriptionBasicGraphQLWS:
ev = ws_client_graphql_ws.get_conn_close_state()
assert ev == True, ev
def test_start(self, hge_ctx, ws_client_graphql_ws):
def test_start(self, hge_key, ws_client_graphql_ws):
if ws_client_graphql_ws.get_conn_close_state():
ws_client_graphql_ws.create_conn()
if hge_ctx.hge_key == None:
if hge_key == None:
ws_client_graphql_ws.init()
else:
ws_client_graphql_ws.init_as_admin()
id = str(uuid.uuid4())
query = """
subscription {
hge_tests_test_t1(order_by: {c1: desc}, limit: 1) {
@ -252,30 +249,30 @@ class TestSubscriptionBasicGraphQLWS:
}
"""
obj = {
'id': '1',
'id': id,
'payload': {
'query': query
},
'type': 'subscribe'
}
ws_client_graphql_ws.send(obj)
ev = ws_client_graphql_ws.get_ws_query_event('1',15)
assert ev['type'] == 'next' and ev['id'] == '1', ev
ev = ws_client_graphql_ws.get_ws_query_event(id, 15)
assert ev['type'] == 'next' and ev['id'] == id, ev
@pytest.mark.skip(reason="refer https://github.com/hasura/graphql-engine/pull/387#issuecomment-421343098")
def test_start_duplicate(self, hge_ctx, ws_client_graphql_ws):
@pytest.mark.skip(reason="refer to https://github.com/hasura/graphql-engine/pull/387#issuecomment-421343098")
def test_start_duplicate(self, hge_key, ws_client_graphql_ws):
if ws_client_graphql_ws.get_conn_close_state():
ws_client_graphql_ws.create_conn()
if hge_ctx.hge_key == None:
if hge_key == None:
ws_client_graphql_ws.init()
else:
ws_client_graphql_ws.init_as_admin()
self.test_start(ws_client_graphql_ws)
self.test_start(hge_key, ws_client_graphql_ws)
def test_stop_without_id(self, hge_ctx, ws_client_graphql_ws):
def test_stop_without_id(self, hge_key, ws_client_graphql_ws):
if ws_client_graphql_ws.get_conn_close_state():
ws_client_graphql_ws.create_conn()
if hge_ctx.hge_key == None:
if hge_key == None:
ws_client_graphql_ws.init()
else:
ws_client_graphql_ws.init_as_admin()
@ -287,10 +284,10 @@ class TestSubscriptionBasicGraphQLWS:
ev = ws_client_graphql_ws.get_conn_close_state()
assert ev == True, ev
def test_stop(self, hge_ctx, ws_client_graphql_ws):
def test_stop(self, hge_key, ws_client_graphql_ws):
if ws_client_graphql_ws.get_conn_close_state():
ws_client_graphql_ws.create_conn()
if hge_ctx.hge_key == None:
if hge_key == None:
ws_client_graphql_ws.init()
else:
ws_client_graphql_ws.init_as_admin()
@ -303,10 +300,10 @@ class TestSubscriptionBasicGraphQLWS:
with pytest.raises(queue.Empty):
ev = ws_client_graphql_ws.get_ws_event(3)
def test_start_after_stop(self, hge_ctx, ws_client_graphql_ws):
def test_start_after_stop(self, hge_key, hge_ctx, ws_client_graphql_ws):
if ws_client_graphql_ws.get_conn_close_state():
ws_client_graphql_ws.create_conn()
if hge_ctx.hge_key == None:
if hge_key == None:
ws_client_graphql_ws.init()
else:
ws_client_graphql_ws.init_as_admin()
@ -316,10 +313,11 @@ class TestSubscriptionBasicGraphQLWS:
ws_client_graphql_ws.clear_queue()
self.test_stop(hge_ctx, ws_client_graphql_ws)
def test_complete(self, hge_ctx, ws_client_graphql_ws):
def test_complete(self, hge_key, ws_client_graphql_ws):
id = str(uuid.uuid4())
if ws_client_graphql_ws.get_conn_close_state():
ws_client_graphql_ws.create_conn()
if hge_ctx.hge_key == None:
if hge_key == None:
ws_client_graphql_ws.init()
else:
ws_client_graphql_ws.init_as_admin()
@ -332,27 +330,28 @@ class TestSubscriptionBasicGraphQLWS:
}
"""
obj = {
'id': '2',
'id': id,
'payload': {
'query': query
},
'type': 'subscribe'
}
ws_client_graphql_ws.send(obj)
ev = ws_client_graphql_ws.get_ws_query_event('2',3)
assert ev['type'] == 'next' and ev['id'] == '2', ev
ev = ws_client_graphql_ws.get_ws_query_event(id, 3)
assert ev['type'] == 'next' and ev['id'] == id, ev
# Check for complete type
ev = ws_client_graphql_ws.get_ws_query_event('2',3)
assert ev['type'] == 'complete' and ev['id'] == '2', ev
ev = ws_client_graphql_ws.get_ws_query_event(id, 3)
assert ev['type'] == 'complete' and ev['id'] == id, ev
@usefixtures('per_method_tests_db_state','ws_conn_init')
@pytest.mark.admin_secret
class TestSubscriptionLiveQueries:
@classmethod
def dir(cls):
return 'queries/subscriptions/live_queries'
def test_live_queries(self, hge_ctx, ws_client):
def test_live_queries(self, hge_key, ws_client):
'''
Create connection using connection_init
'''
@ -375,8 +374,8 @@ class TestSubscriptionLiveQueries:
for i, resultLimit in queries:
query = queryTmplt.replace('{0}',str(i))
headers={}
if hge_ctx.hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_ctx.hge_key
if hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_key
subscrPayload = { 'query': query, 'variables': { 'result_limit': resultLimit } }
respLive = ws_client.send_query(subscrPayload, query_id='live_'+str(i), headers=headers, timeout=15)
liveQs.append(respLive)
@ -427,14 +426,15 @@ class TestSubscriptionLiveQueries:
with pytest.raises(queue.Empty):
ev = ws_client.get_ws_event(3)
@usefixtures('per_method_tests_db_state','ws_conn_init','streaming_subscriptions_fixtures')
@usefixtures('per_method_tests_db_state', 'ws_conn_init')
@pytest.mark.hge_env('HASURA_GRAPHQL_EXPERIMENTAL_FEATURES', 'streaming_subscriptions')
class TestStreamingSubscription:
@classmethod
def dir(cls):
return 'queries/subscriptions/streaming'
def test_basic_streaming_subscription_existing_static_data(self, hge_ctx, ws_client):
def test_basic_streaming_subscription_existing_static_data(self, hge_key, hge_ctx, ws_client):
'''
Create connection using connection_init
'''
@ -455,8 +455,8 @@ class TestStreamingSubscription:
for i in range(10):
articles_to_insert.append({"id": i + 1, "title": "Article title {}".format(i + 1)})
insert_many(hge_ctx, {"schema": "hge_tests", "name": "articles"}, articles_to_insert)
if hge_ctx.hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_ctx.hge_key
if hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_key
subscrPayload = { 'query': query, 'variables': { 'batch_size': 2 } }
respLive = ws_client.send_query(subscrPayload, query_id='stream_1', headers=headers, timeout=15)
liveQs.append(respLive)
@ -478,7 +478,7 @@ class TestStreamingSubscription:
with pytest.raises(queue.Empty):
ev = ws_client.get_ws_event(3)
def test_streaming_subscriptions_with_concurrent_data_inserts(self, hge_ctx, ws_client):
def test_streaming_subscriptions_with_concurrent_data_inserts(self, ws_client):
'''
Create connection using connection_init
'''
@ -534,7 +534,7 @@ class TestStreamingSubscription:
with pytest.raises(queue.Empty):
ev = ws_client.get_ws_event(3)
def test_streaming_subscription_with_custom_name_set_for_cursor(self, hge_ctx, ws_client):
def test_streaming_subscription_with_custom_name_set_for_cursor(self, hge_key, ws_client):
'''
Create connection using connection_init
'''
@ -551,8 +551,8 @@ class TestStreamingSubscription:
liveQs = []
headers={}
if hge_ctx.hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_ctx.hge_key
if hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_key
subscrPayload = { 'query': query, 'variables': { 'batch_size': 1 } }
respLive = ws_client.send_query(subscrPayload, query_id='stream_1', headers=headers, timeout=15)
liveQs.append(respLive)
@ -574,16 +574,15 @@ class TestStreamingSubscription:
with pytest.raises(queue.Empty):
ev = ws_client.get_ws_event(3)
@usefixtures('per_method_tests_db_state','ws_conn_init_graphql_ws')
@usefixtures('per_method_tests_db_state', 'ws_conn_init_graphql_ws')
@pytest.mark.admin_secret
class TestSubscriptionLiveQueriesForGraphQLWS:
@classmethod
def dir(cls):
return 'queries/subscriptions/live_queries'
def test_live_queries(self, hge_ctx, ws_client_graphql_ws):
def test_live_queries(self, hge_key, ws_client_graphql_ws):
'''
Create connection using connection_init
'''
@ -606,8 +605,8 @@ class TestSubscriptionLiveQueriesForGraphQLWS:
for i, resultLimit in queries:
query = queryTmplt.replace('{0}',str(i))
headers={}
if hge_ctx.hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_ctx.hge_key
if hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_key
subscrPayload = { 'query': query, 'variables': { 'result_limit': resultLimit } }
respLive = ws_client_graphql_ws.send_query(subscrPayload, query_id='live_'+str(i), headers=headers, timeout=15)
liveQs.append(respLive)
@ -658,13 +657,14 @@ class TestSubscriptionLiveQueriesForGraphQLWS:
@pytest.mark.backend('mssql', 'postgres')
@usefixtures('per_class_tests_db_state')
@pytest.mark.admin_secret
class TestSubscriptionMultiplexingPostgresMSSQL:
@classmethod
def dir(cls):
return 'queries/subscriptions/multiplexing'
def test_extraneous_session_variables_are_discarded_from_query(self, hge_ctx):
def test_extraneous_session_variables_are_discarded_from_query(self, hge_key, hge_ctx):
with open(self.dir() + '/articles_query.yaml') as c:
config = yaml.load(c)
@ -673,7 +673,7 @@ class TestSubscriptionMultiplexingPostgresMSSQL:
"X-Hasura-Role":"public",
"X-Hasura-User-Id":"1" # extraneous session variable
}
response = get_explain_graphql_query_response(hge_ctx, query, {}, session_variables)
response = get_explain_graphql_query_response(hge_ctx, hge_key, query, {}, session_variables)
# The input session variables should be ignored because the only check for the role is
# if `is_public` is `true`
assert response["variables"]["session"] == {}, response["variables"]
@ -683,35 +683,37 @@ class TestSubscriptionMultiplexingPostgresMSSQL:
"X-Hasura-User-Id":"1",
"X-Hasura-Allowed-Ids":"{1,3,4}" # extraneous session variable
}
response = get_explain_graphql_query_response(hge_ctx, query, {}, session_variables)
response = get_explain_graphql_query_response(hge_ctx, hge_key, query, {}, session_variables)
# The input session variable should not be ignored because the `user` role can only
# select those roles where `user_id = X-Hasura-User-Id`
assert response["variables"]["session"] == {'x-hasura-user-id':"1"}, response["variables"]
# test case for https://github.com/hasura/graphql-engine-mono/issues/3689
@usefixtures('per_class_tests_db_state')
@pytest.mark.admin_secret
class TestSubscriptionMultiplexingPostgres:
@classmethod
def dir(cls):
return 'queries/subscriptions/multiplexing'
def test_simple_variables_are_parameterized(self, hge_ctx):
def test_simple_variables_are_parameterized(self, hge_key, hge_ctx):
with open(self.dir() + '/articles_query_simple_variable.yaml') as c:
config = yaml.load(c)
response = get_explain_graphql_query_response(hge_ctx, config['query'], config['variables'], {})
response = get_explain_graphql_query_response(hge_ctx, hge_key, config['query'], config['variables'], {})
assert response["variables"]["synthetic"] == ['1'], response["variables"]
def test_array_variables_are_parameterized(self, hge_ctx):
def test_array_variables_are_parameterized(self, hge_key, hge_ctx):
with open(self.dir() + '/articles_query_array_variable.yaml') as c:
config = yaml.load(c)
response = get_explain_graphql_query_response(hge_ctx, config['query'], config['variables'], {})
response = get_explain_graphql_query_response(hge_ctx, hge_key, config['query'], config['variables'], {})
assert response["variables"]["synthetic"] == ['{1,2,3}'], response["variables"]
@pytest.mark.backend('postgres')
@usefixtures('per_class_tests_db_state', 'ws_conn_init')
@pytest.mark.admin_secret
class TestSubscriptionUDFWithSessionArg:
"""
Test a user-defined function which uses the entire session variables as argument
@ -730,11 +732,11 @@ class TestSubscriptionUDFWithSessionArg:
def dir(cls):
return 'queries/subscriptions/udf_session_args'
def test_user_defined_function_with_session_argument(self, hge_ctx, ws_client):
def test_user_defined_function_with_session_argument(self, hge_key, ws_client):
ws_client.init_as_admin()
headers = {'x-hasura-role': 'user', 'x-hasura-user-id': '42'}
if hge_ctx.hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_ctx.hge_key
if hge_key is not None:
headers['X-Hasura-Admin-Secret'] = hge_key
payload = {'query': self.query}
resp = ws_client.send_query(payload, headers=headers, timeout=15)
ev = next(resp)
@ -743,6 +745,7 @@ class TestSubscriptionUDFWithSessionArg:
@pytest.mark.backend('mssql', 'postgres')
@usefixtures('per_class_tests_db_state', 'ws_conn_init')
@pytest.mark.admin_secret
class TestSubscriptionCustomizedSourceMSSQLPostgres:
@classmethod
def dir(cls):
@ -754,7 +757,8 @@ class TestSubscriptionCustomizedSourceMSSQLPostgres:
Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_complete
'''
def test_complete(self, hge_ctx, ws_client):
def test_complete(self, ws_client):
id = str(uuid.uuid4())
query = """
subscription MySubscription {
a: my_source {
@ -766,7 +770,7 @@ class TestSubscriptionCustomizedSourceMSSQLPostgres:
}
"""
obj = {
'id': '1',
'id': id,
'payload': {
'query': query
},
@ -776,11 +780,11 @@ class TestSubscriptionCustomizedSourceMSSQLPostgres:
'''
Refer: https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md#gql_data
'''
ev = ws_client.get_ws_query_event('1',15)
assert ev['type'] == 'data' and ev['id'] == '1', ev
ev = ws_client.get_ws_query_event(id, 15)
assert ev['type'] == 'data' and ev['id'] == id, ev
assert ev['payload']['data']['a'] == OrderedDict([('b', [OrderedDict([('id', 1), ('name', 'Author 1')]), OrderedDict([('id', 2), ('name', 'Author 2')])])]), ev
def test_double_alias(self, hge_ctx, ws_client):
def test_double_alias(self, ws_client):
'''
This should give an error even though @_multiple_top_level_fields is specified.
The two different aliases for `my_source` mean that we would have to wrap different
@ -819,6 +823,7 @@ class TestSubscriptionCustomizedSourceMSSQLPostgres:
@pytest.mark.backend('mssql')
@usefixtures('per_class_tests_db_state', 'ws_conn_init')
@pytest.mark.admin_secret
class TestSubscriptionMSSQLChunkedResults:
@classmethod
def dir(cls):

View File

@ -19,7 +19,7 @@ usefixtures = pytest.mark.usefixtures
def ws_conn_recreate(ws_client):
ws_client.recreate_conn()
def connect_with(hge_ctx, ws_client, headers):
def connect_with(hge_key, ws_client, headers):
headers['X-Hasura-Role'] = 'user'
headers['X-Hasura-User-Id'] = '1234321'
headers['X-Hasura-Auth-Mode'] = 'webhook'
@ -27,22 +27,22 @@ def connect_with(hge_ctx, ws_client, headers):
token = base64.b64encode(json.dumps(headers).encode('utf-8')).decode('utf-8')
headers['Authorization'] = 'Bearer ' + token
payload = {'headers': headers}
init_ws_conn(hge_ctx, ws_client, payload)
init_ws_conn(hge_key, ws_client, payload)
EXPIRE_TIME_FORMAT = '%a, %d %b %Y %T GMT'
@usefixtures('ws_conn_recreate')
class TestWebhookSubscriptionExpiry(object):
def test_expiry_with_no_header(self, hge_ctx, ws_client):
def test_expiry_with_no_header(self, hge_key, ws_client):
# no expiry time => the connextion will remain alive
connect_with(hge_ctx, ws_client, {})
connect_with(hge_key, ws_client, {})
time.sleep(5)
assert ws_client.remote_closed == False, ws_client.remote_closed
def test_expiry_with_expires_header(self, hge_ctx, ws_client):
def test_expiry_with_expires_header(self, hge_key, ws_client):
exp = datetime.utcnow() + timedelta(seconds=6)
connect_with(hge_ctx, ws_client, {
connect_with(hge_key, ws_client, {
'Expires': exp.strftime(EXPIRE_TIME_FORMAT)
})
time.sleep(4)
@ -50,8 +50,8 @@ class TestWebhookSubscriptionExpiry(object):
time.sleep(4)
assert ws_client.remote_closed == True, ws_client.remote_closed
def test_expiry_with_cache_control(self, hge_ctx, ws_client):
connect_with(hge_ctx, ws_client, {
def test_expiry_with_cache_control(self, hge_key, ws_client):
connect_with(hge_key, ws_client, {
'Cache-Control': 'max-age=6'
})
time.sleep(4)
@ -59,9 +59,9 @@ class TestWebhookSubscriptionExpiry(object):
time.sleep(4)
assert ws_client.remote_closed == True, ws_client.remote_closed
def test_expiry_with_both(self, hge_ctx, ws_client):
def test_expiry_with_both(self, hge_key, ws_client):
exp = datetime.utcnow() + timedelta(seconds=6)
connect_with(hge_ctx, ws_client, {
connect_with(hge_key, ws_client, {
'Expires': exp.strftime(EXPIRE_TIME_FORMAT),
'Cache-Control': 'max-age=10',
})
@ -73,12 +73,12 @@ class TestWebhookSubscriptionExpiry(object):
time.sleep(4)
assert ws_client.remote_closed == True, ws_client.remote_closed
def test_expiry_with_parse_error(self, hge_ctx, ws_client):
def test_expiry_with_parse_error(self, hge_key, ws_client):
exp = datetime.utcnow() + timedelta(seconds=3)
connect_with(hge_ctx, ws_client, {
connect_with(hge_key, ws_client, {
'Expires': exp.strftime('%a, %d %m %Y %T UTC'),
'Cache-Control': 'maxage=3',
})
# neither will parse, the connection will remain alive
time.sleep(5)
assert ws_client.remote_closed == False, ws_client.remote_closed
assert ws_client.remote_closed == False, ws_client.remote_closed