Skip to content

Dev/oauth kqueue #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions .cirrus.tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ env:
MTEST_ARGS: --print-errorlogs --no-rebuild -C build
PGCTLTIMEOUT: 120 # avoids spurious failures during parallel tests
TEMP_CONFIG: ${CIRRUS_WORKING_DIR}/src/tools/ci/pg_ci_base.conf
PG_TEST_EXTRA: kerberos ldap ssl libpq_encryption load_balance oauth
PG_TEST_EXTRA: kerberos ldap ssl libpq_encryption load_balance oauth python


# What files to preserve in case tests fail
Expand Down Expand Up @@ -188,7 +188,7 @@ task:
chown root:postgres /tmp/cores
sysctl kern.corefile='/tmp/cores/%N.%P.core'
setup_additional_packages_script: |
#pkg install -y ...
pkg install -y security/py-cryptography

# NB: Intentionally build without -Dllvm. The freebsd image size is already
# large enough to make VM startup slow, and even without llvm freebsd
Expand Down Expand Up @@ -239,7 +239,6 @@ task:

task:
depends_on: SanityCheck
trigger_type: manual

env:
# Below are experimentally derived to be a decent choice.
Expand Down Expand Up @@ -270,7 +269,7 @@ task:
# -Duuid is not set for the NetBSD, see the comment below, above
# configure_script, for more information.
setup_additional_packages_script: |
#pkgin -y install ...
pkgin -y install py312-cryptography
<<: *netbsd_task_template

- name: OpenBSD - Meson
Expand All @@ -282,7 +281,7 @@ task:
UUID: -Duuid=e2fs
TCL: -Dtcl_version=tcl86
setup_additional_packages_script: |
#pkg_add -I ...
pkg_add -I py3-cryptography
# Always core dump to ${CORE_DUMP_DIR}
set_core_dump_script: sysctl -w kern.nosuidcoredump=2
<<: *openbsd_task_template
Expand Down Expand Up @@ -445,8 +444,9 @@ task:
EOF

setup_additional_packages_script: |
#apt-get update
#DEBIAN_FRONTEND=noninteractive apt-get -y install ...
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get -y install \
python3-venv \

matrix:
# SPECIAL:
Expand Down Expand Up @@ -554,8 +554,11 @@ task:
# can easily provide some here by running one of the sets of tests that
# way. Newer versions of python insist on changing the LC_CTYPE away
# from C, prevent that with PYTHONCOERCECLOCALE.
# XXX 32-bit Python tests are currently disabled, as the system's 64-bit
# Python modules can't link against libpq.
test_world_32_script: |
su postgres <<-EOF
export PG_TEST_EXTRA="${PG_TEST_EXTRA//python}"
ulimit -c unlimited
PYTHONCOERCECLOCALE=0 LANG=C meson test $MTEST_ARGS -C build-32 --num-processes ${TEST_JOBS}
EOF
Expand Down
109 changes: 105 additions & 4 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -943,10 +943,8 @@ if not libcurlopt.disabled()
# libcurl and one of either epoll or kqueue.
oauth_flow_supported = (
libcurl.found()
and (cc.check_header('sys/event.h', required: false,
args: test_c_args, include_directories: postgres_inc)
or cc.check_header('sys/epoll.h', required: false,
args: test_c_args, include_directories: postgres_inc))
and (cc.has_header('sys/event.h', include_directories: postgres_inc)
or cc.has_header('sys/epoll.h', include_directories: postgres_inc))
)

if oauth_flow_supported
Expand Down Expand Up @@ -3615,6 +3613,9 @@ else
endif

testwrap = files('src/tools/testwrap')
make_venv = files('src/tools/make_venv')

checked_working_venv = false

foreach test_dir : tests
testwrap_base = [
Expand Down Expand Up @@ -3783,6 +3784,106 @@ foreach test_dir : tests
)
endforeach
install_suites += test_group
elif kind == 'pytest'
venv_name = test_dir['name'] + '_venv'
venv_path = meson.build_root() / venv_name

# The Python tests require a working venv module. This is part of the
# standard library, but some platforms disable it until a separate package
# is installed. Those same platforms don't provide an easy way to check
# whether the venv command will work until the first time you try it, so
# we decide whether or not to enable these tests on the fly.
if not checked_working_venv
cmd = run_command(python, '-m', 'venv', venv_path, check: false)

have_working_venv = (cmd.returncode() == 0)
if not have_working_venv
warning('A working Python venv module is required to run Python tests.')
endif

checked_working_venv = true
endif

if not have_working_venv
continue
endif

# Make sure the temporary installation is in PATH (necessary both for
# --temp-instance and for any pip modules compiling against libpq, like
# psycopg2).
env = test_env
env.prepend('PATH', temp_install_bindir, test_dir['bd'])

foreach name, value : t.get('env', {})
env.set(name, value)
endforeach

reqs = files(t['requirements'])
test('install_' + venv_name,
python,
args: [ make_venv, '--requirements', reqs, venv_path ],
env: env,
priority: setup_tests_priority - 1, # must run after tmp_install
is_parallel: false,
suite: ['setup'],
timeout: 60, # 30s is too short for the cryptography package compile
)

test_group = test_dir['name']
test_output = test_result_dir / test_group / kind
test_kwargs = {
#'protocol': 'tap',
'suite': test_group,
'timeout': 1000,
'depends': test_deps,
'env': env,
} + t.get('test_kwargs', {})

if fs.is_dir(venv_path / 'Scripts')
# Windows virtualenv layout
pytest = venv_path / 'Scripts' / 'py.test'
else
pytest = venv_path / 'bin' / 'py.test'
endif

test_command = [
pytest,
# Avoid running these tests against an existing database.
'--temp-instance', test_output / 'data',

# FIXME pytest-tap's stream feature accidentally suppresses errors that
# are critical for debugging:
# https://github.com/python-tap/pytest-tap/issues/30
# Don't use the meson TAP protocol for now...
#'--tap-stream',
]

foreach pyt : t['tests']
# Similarly to TAP, strip ./ and .py to make the names prettier
pyt_p = pyt
if pyt_p.startswith('./')
pyt_p = pyt_p.split('./')[1]
endif
if pyt_p.endswith('.py')
pyt_p = fs.stem(pyt_p)
endif

testwrap_pytest = testwrap_base + [
'--testgroup', test_group,
'--testname', pyt_p,
'--skip-without-extra', 'python',
]

test(test_group / pyt_p,
python,
kwargs: test_kwargs,
args: testwrap_pytest + [
'--', test_command,
test_dir['sd'] / pyt,
],
)
endforeach
install_suites += test_group
else
error('unknown kind @0@ of test in @1@'.format(kind, test_dir['sd']))
endif
Expand Down
2 changes: 2 additions & 0 deletions src/backend/libpq/auth-oauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ generate_error_response(struct oauth_ctx *ctx, char **output, int *outputlen)
initStringInfo(&buf);

/*
* TODO
* Escaping the string here is belt-and-suspenders defensive programming
* since escapable characters aren't valid in either the issuer URI or the
* scope list, but the HBA doesn't enforce that yet.
Expand Down Expand Up @@ -699,6 +700,7 @@ validate(Port *port, const char *auth)
/* Make sure the validator authenticated the user. */
if (ret->authn_id == NULL || ret->authn_id[0] == '\0')
{
/* TODO: test logdetail; reduce message duplication elsewhere */
ereport(LOG,
errmsg("OAuth bearer authentication failed for user \"%s\"",
port->user_name),
Expand Down
14 changes: 14 additions & 0 deletions src/interfaces/libpq-oauth/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,19 @@ uninstall:
rm -f '$(DESTDIR)$(libdir)/$(stlib)'
rm -f '$(DESTDIR)$(libdir)/$(shlib)'

.PHONY: all-tests
all-tests: oauth_tests$(X)

oauth_tests$(X): test-oauth-curl.o oauth-utils.o $(WIN32RES) | submake-libpgport submake-libpq
$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(SHLIB_LINK) -o $@

check: all-tests
$(prove_check)

installcheck: all-tests
$(prove_installcheck)

clean distclean: clean-lib
rm -f $(OBJS) $(OBJS_STATIC) $(OBJS_SHLIB)
rm -f test-oauth-curl.o oauth_tests$(X)
rm -rf tmp_check
35 changes: 35 additions & 0 deletions src/interfaces/libpq-oauth/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,38 @@ libpq_oauth_so = shared_module(libpq_oauth_name,
link_args: export_fmt.format(export_file.full_path()),
kwargs: default_lib_args,
)

libpq_oauth_test_deps = []

oauth_test_sources = files('test-oauth-curl.c') + libpq_oauth_so_sources

if host_system == 'windows'
oauth_test_sources += rc_bin_gen.process(win32ver_rc, extra_args: [
'--NAME', 'oauth_tests',
'--FILEDESC', 'OAuth unit test program',])
endif

libpq_oauth_test_deps += executable('oauth_tests',
oauth_test_sources,
dependencies: [frontend_shlib_code, libpq, libpq_oauth_deps],
kwargs: default_bin_args + {
'c_args': default_bin_args.get('c_args', []) + libpq_oauth_so_c_args,
'c_pch': pch_postgres_fe_h,
'include_directories': [libpq_inc, postgres_inc],
'install': false,
}
)

testprep_targets += libpq_oauth_test_deps

tests += {
'name': 'libpq-oauth',
'sd': meson.current_source_dir(),
'bd': meson.current_build_dir(),
'tap': {
'tests': [
't/001_oauth.pl',
],
'deps': libpq_oauth_test_deps,
},
}
Loading