Skip to content

Commit

Permalink
Merge pull request #2636 from niol/testsuite
Browse files Browse the repository at this point in the history
fix uwsgi_regexp_match() with pcre2 and corresponding unittest
  • Loading branch information
xrmx committed May 19, 2024
2 parents d3136d3 + 1a71973 commit 26ee7c0
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 20 deletions.
44 changes: 30 additions & 14 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,38 @@ on:
branches: [ master, uwsgi-2.0 ]

jobs:
python:

unittest:
runs-on: ubuntu-20.04
steps:
- name: Install dependencies
run: |
sudo apt update -qq
sudo apt install --no-install-recommends -qqyf \
libpcre2-dev libjansson-dev libcap2-dev \
check
- uses: actions/checkout@v4
- name: Run unit tests
run: make unittests

test:
runs-on: ubuntu-20.04
steps:
- name: Install dependencies
run: |
sudo apt update -qq
sudo apt install --no-install-recommends -qqyf \
libpcre2-dev libjansson-dev libcap2-dev
- uses: actions/checkout@v4
- name: Run integration tests
run: make all tests

python:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
test-suite: [unittest, python, deadlocks]
test-suite: [python, deadlocks]
steps:
- name: Add deadnakes ppa
run: sudo add-apt-repository ppa:deadsnakes/ppa -y
Expand All @@ -22,34 +47,27 @@ jobs:
sudo apt update -qq
sudo apt install --no-install-recommends -qqyf python${{ matrix.python-version }}-dev \
libpcre2-dev libjansson-dev libcap2-dev \
curl check
curl
- name: Install distutils
if: contains(fromJson('["3.6","3.7","3.8","3.9","3.10","3.11","3.12"]'), matrix.python-version)
run: |
sudo apt install --no-install-recommends -qqyf python${{ matrix.python-version }}-distutils \
- uses: actions/checkout@v4
- name: Run unit tests
if: matrix.test-suite == 'unittest'
run: make tests
- name: Build uWSGI binary
if: matrix.test-suite != 'unittest'
run: make
- name: Build python${{ matrix.python-version }} plugin
if: matrix.test-suite != 'unittest'
run: |
PYTHON_VERSION=${{ matrix.python-version }}
PYTHON_VERSION=python${PYTHON_VERSION//.}
/usr/bin/python${{ matrix.python-version }} -V
/usr/bin/python${{ matrix.python-version }} uwsgiconfig.py --plugin plugins/python base $PYTHON_VERSION
- name: run smoke tests
if: matrix.test-suite != 'unittest'
run: |
PYTHON_VERSION=${{ matrix.python-version }}
PYTHON_VERSION=python${PYTHON_VERSION//.}
./tests/gh-${{ matrix.test-suite }}.sh ${PYTHON_VERSION}
rack:

runs-on: ubuntu-20.04
strategy:
matrix:
Expand All @@ -59,11 +77,9 @@ jobs:
run: |
sudo apt update -qq
sudo apt install --no-install-recommends -qqyf python3-dev \
libpcre3-dev libjansson-dev libcap2-dev ruby2.7-dev \
curl check
libpcre2-dev libjansson-dev libcap2-dev ruby2.7-dev \
curl
- uses: actions/checkout@v4
- name: Run unit tests
run: make tests
- name: Build uWSGI binary
run: make
- name: Build rack plugin
Expand Down
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ all:

clean:
$(PYTHON) uwsgiconfig.py --clean
cd unittest && make clean

check:
$(PYTHON) uwsgiconfig.py --check

plugin.%:
$(PYTHON) uwsgiconfig.py --plugin plugins/$* $(PROFILE)

tests:
unittests:
$(PYTHON) uwsgiconfig.py --build unittest
cd check && make && make test
cd unittest && make test

tests:
$(PYTHON) t/runner

%:
$(PYTHON) uwsgiconfig.py --build $@
Expand Down
2 changes: 1 addition & 1 deletion core/regexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ int uwsgi_regexp_build(char *re, uwsgi_pcre ** pattern) {

int uwsgi_regexp_match(uwsgi_pcre *pattern, const char *subject, int length) {
#ifdef UWSGI_PCRE2
return pcre2_match(pattern, (const unsigned char *)subject, length, 0, 0, NULL, NULL);
return uwsgi_regexp_match_ovec(pattern, subject, length, NULL, 0);
#else
return pcre_exec((const pcre *) pattern->p, (const pcre_extra *) pattern->extra, subject, length, 0, 0, NULL, 0);
#endif
Expand Down
82 changes: 82 additions & 0 deletions t/runner
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/python3


import os
import requests
import signal
import socket
import subprocess
import time
import unittest


TESTS_DIR = os.path.dirname(__file__)
UWSGI_BINARY = os.getenv("UWSGI_BINARY", os.path.join(TESTS_DIR, "..", "uwsgi"))
UWSGI_ADDR = "127.0.0.1"
UWSGI_PORT = 8000
UWSGI_HTTP = f"{UWSGI_ADDR}:{UWSGI_PORT}"


class BaseTest:
"""
Container class to avoid base test being run
"""

class UwsgiServerTest(unittest.TestCase):
"""
Test case with a server instance available on a socket for requests
"""

@classmethod
def uwsgi_ready(cls):
try:
s = socket.socket()
s.connect(
(
UWSGI_ADDR,
UWSGI_PORT,
)
)
except socket.error:
return False
else:
return True
finally:
s.close()

@classmethod
def setUpClass(cls):
# launch server
cls.testserver = subprocess.Popen(
[UWSGI_BINARY, "--http-socket", UWSGI_HTTP] + cls.ARGS
)

# ensure server is ready
retries = 10
while not cls.uwsgi_ready() and retries > 0:
time.sleep(0.1)
retries = retries - 1
if retries == 0:
raise RuntimeError("uwsgi test server is not available")

@classmethod
def tearDownClass(cls):
cls.testserver.send_signal(signal.SIGTERM)
cls.testserver.wait()


class StaticTest(BaseTest.UwsgiServerTest):

ARGS = [
"--plugin",
"python3", # provide a request plugin if no embedded request plugin
os.path.join(TESTS_DIR, "static", "config.ini"),
]

def test_static_expires(self):
with requests.get(f"http://{UWSGI_HTTP}/foobar/config.ini") as r:
self.assertTrue("Expires" in r.headers)


if __name__ == "__main__":
unittest.main()
4 changes: 4 additions & 0 deletions t/static/config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[uwsgi]
need-app = False
static-map = /foobar=t/static
static-expires-uri = ^/foobar/ 315360000
7 changes: 4 additions & 3 deletions check/Makefile → unittest/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

CFLAGS = $(shell pkg-config --cflags check)
CFLAGS += -DUWSGI_PCRE2
LDFLAGS = $(shell pkg-config --libs check)
LDFLAGS += -ldl -lz
LDFLAGS += $(shell xml2-config --libs)
Expand All @@ -13,14 +14,14 @@ ifeq ($(UNAME_S),Linux)
endif


objects = check_core
objects = check_core check_regexp

all: $(objects)

$(objects): %: %.c
$(objects): %: %.c ../libuwsgi.a
$(CC) $(CFLAGS) -o $@ $< ../libuwsgi.a $(LDFLAGS)

test:
test: all
@for file in $(objects); do ./$$file; done

clean:
Expand Down
File renamed without changes.
86 changes: 86 additions & 0 deletions unittest/check_regexp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <check.h>
#include "../uwsgi.h"


START_TEST(test_uwsgi_regexp_match)
{
int result;
uwsgi_pcre *pattern_all;
uwsgi_pcre *pattern;

result = uwsgi_regexp_build(".*", &pattern_all);
ck_assert(result == 0);

result = uwsgi_regexp_match(pattern_all, "/fooba", 6);
ck_assert(result >= 0);

result = uwsgi_regexp_build("/foobar/.*", &pattern);
ck_assert(result == 0);

result = uwsgi_regexp_match(pattern, "/fooba", 6);
ck_assert(result < 0);

result = uwsgi_regexp_match(pattern, "/foobar/baz", 11);
ck_assert(result >= 0);

pcre2_code_free(pattern_all);
pcre2_code_free(pattern);
}
END_TEST

START_TEST(test_uwsgi_regexp_match_ovec)
{
int result;
uwsgi_pcre *pattern;
int *ovec = calloc((2+1)*2, sizeof(int));
char buf[20], sub[20];

result = uwsgi_regexp_build("^/foo/(.*)\\.jpg\\?([0-9]{2})", &pattern);
ck_assert(result == 0);
result = uwsgi_regexp_ovector(pattern);
ck_assert(result == 2);

result = uwsgi_regexp_match_ovec(pattern, "/fooba", 6, ovec, 2);
ck_assert(result < 0);

strcpy(buf, "/foo/bar.jpg?422");
result = uwsgi_regexp_match_ovec(pattern, buf, strlen(buf), ovec, 2);
ck_assert(result >= 0);
strncpy(sub, buf+ovec[0], ovec[1]-ovec[0]);
sub[ovec[1]-ovec[0]] = '\0';
ck_assert_str_eq(sub, "/foo/bar.jpg?42");
strncpy(sub, buf+ovec[2], ovec[3]-ovec[2]);
sub[ovec[3]-ovec[2]] = '\0';
ck_assert_str_eq(sub, "bar");
strncpy(sub, buf+ovec[4], ovec[5]-ovec[4]);
sub[ovec[5]-ovec[4]] = '\0';
ck_assert_str_eq(sub, "42");

strcpy(sub, uwsgi_regexp_apply_ovec(buf, strlen(buf), "key=$1.$2.jpg", 13, ovec, 2));
ck_assert_str_eq(sub, "key=bar.42.jpg");

pcre2_code_free(pattern);
free(ovec);
}
END_TEST

Suite *check_regexp(void)
{
Suite *s = suite_create("uwsgi regexp");
TCase *tc = tcase_create("regexp");

suite_add_tcase(s, tc);
tcase_add_test(tc, test_uwsgi_regexp_match);
tcase_add_test(tc, test_uwsgi_regexp_match_ovec);
return s;
}

int main(void)
{
int nf;
SRunner *r = srunner_create(check_regexp());
srunner_run_all(r, CK_NORMAL);
nf = srunner_ntests_failed(r);
srunner_free(r);
return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

0 comments on commit 26ee7c0

Please sign in to comment.