diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 00343c2..ea76cd2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -39,3 +39,55 @@ jobs: cd test msbuild.exe test.sln /verbosity:minimal /t:Build "/p:Configuration=Release;Platform=x64" x64\Release\test.exe + + + meson-build: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + + steps: + - name: Prepare Git for checkout on Windows + if: matrix.os == 'windows-latest' + run: | + git config --global core.autocrlf false + git config --global core.eol lf + + - uses: actions/checkout@v2 + + - name: Install dependencies on Linux + if: matrix.os == 'ubuntu-latest' + run: sudo apt-get -qq update && sudo apt-get -qq install meson libssl-dev zlib1g-dev libbrotli-dev libgtest-dev + + - name: Install dependencies on MacOS + if: matrix.os == 'macos-latest' + run: brew install meson openssl brotli googletest + + - name: Setup MSVC on Windows + if: matrix.os == 'windows-latest' + uses: ilammy/msvc-dev-cmd@v1 + + # It is necessary to remove MinGW and StrawberryPerl as they both provide + # GCC. This causes issues because CMake prefers to use MSVC, while Meson + # uses GCC, if found, causing linking errors. + - name: Install dependencies on Windows + if: matrix.os == 'windows-latest' + run: | + choco uninstall mingw strawberryperl --yes --all-versions --remove-dependencies --skip-autouninstaller --no-color + Remove-Item -Path C:\Strawberry -Recurse + choco install pkgconfiglite --yes --skip-virus-check --no-color + pip install meson ninja + Invoke-WebRequest -Uri https://github.com/google/googletest/archive/refs/heads/master.zip -OutFile googletest-master.zip + Expand-Archive -Path googletest-master.zip + cd googletest-master\googletest-master + cmake -S . -B build -DINSTALL_GTEST=ON -DBUILD_GMOCK=OFF -Dgtest_hide_internal_symbols=ON -DCMAKE_INSTALL_PREFIX=C:/googletest + cmake --build build --config=Release + cmake --install build --config=Release + cd ..\.. + + - name: Build and test + run: | + meson setup build -Dcpp-httplib_test=true -Dpkg_config_path=C:\googletest\lib\pkgconfig -Db_vscrt=static_from_buildtype + meson test --no-stdsplit --print-errorlogs -C build diff --git a/meson.build b/meson.build index cac65f8..6c0eef8 100644 --- a/meson.build +++ b/meson.build @@ -7,6 +7,7 @@ project( 'cpp', license: 'MIT', default_options: [ + 'cpp_std=c++11', 'buildtype=release', 'b_ndebug=if-release', 'b_lto=true', @@ -71,7 +72,7 @@ if brotli_found_all args += '-DCPPHTTPLIB_BROTLI_SUPPORT' endif -cpp_httplib_dep = dependency('', required : false) +cpp_httplib_dep = dependency('', required: false) if get_option('cpp-httplib_compile') httplib_ch = custom_target( @@ -106,3 +107,7 @@ endif if meson.version().version_compare('>=0.54.0') meson.override_dependency('cpp-httplib', cpp_httplib_dep) endif + +if get_option('cpp-httplib_test') + subdir('test') +endif diff --git a/meson_options.txt b/meson_options.txt index e53fb9c..0a14d2d 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -2,7 +2,8 @@ # # SPDX-License-Identifier: MIT -option('cpp-httplib_openssl', type: 'feature', value: 'auto', description: 'Enable OpenSSL support') -option('cpp-httplib_zlib', type: 'feature', value: 'auto', description: 'Enable zlib support') -option('cpp-httplib_brotli', type: 'feature', value: 'auto', description: 'Enable Brotli support') -option('cpp-httplib_compile', type: 'boolean', value: false, description: 'Split the header into a compilable header & source file (requires Python 3)') +option('cpp-httplib_openssl', type: 'feature', value: 'auto', description: 'Enable OpenSSL support') +option('cpp-httplib_zlib', type: 'feature', value: 'auto', description: 'Enable zlib support') +option('cpp-httplib_brotli', type: 'feature', value: 'auto', description: 'Enable Brotli support') +option('cpp-httplib_compile', type: 'boolean', value: false, description: 'Split the header into a compilable header & source file (requires Python 3)') +option('cpp-httplib_test', type: 'boolean', value: false, description: 'Build tests') diff --git a/test/meson.build b/test/meson.build new file mode 100644 index 0000000..354e8c8 --- /dev/null +++ b/test/meson.build @@ -0,0 +1,97 @@ +# SPDX-FileCopyrightText: 2021 Andrea Pappacoda +# +# SPDX-License-Identifier: MIT + +gtest_dep = dependency('gtest', main: true) +openssl = find_program('openssl') +test_conf = files('test.conf') + +key_pem = custom_target( + 'key_pem', + output: 'key.pem', + command: [openssl, 'genrsa', '-out', '@OUTPUT@', '2048'] +) + +temp_req = custom_target( + 'temp_req', + input: key_pem, + output: 'temp_req', + command: [openssl, 'req', '-new', '-batch', '-config', test_conf, '-key', '@INPUT@', '-out', '@OUTPUT@'] +) + +cert_pem = custom_target( + 'cert_pem', + input: [temp_req, key_pem], + output: 'cert.pem', + command: [openssl, 'x509', '-in', '@INPUT0@', '-days', '3650', '-req', '-signkey', '@INPUT1@', '-out', '@OUTPUT@'] +) + +cert2_pem = custom_target( + 'cert2_pem', + input: key_pem, + output: 'cert2.pem', + command: [openssl, 'req', '-x509', '-config', test_conf, '-key', '@INPUT@', '-sha256', '-days', '3650', '-nodes', '-out', '@OUTPUT@', '-extensions', 'SAN'] +) + +rootca_key_pem = custom_target( + 'rootca_key_pem', + output: 'rootCA.key.pem', + command: [openssl, 'genrsa', '-out', '@OUTPUT@', '2048'] +) + +rootca_cert_pem = custom_target( + 'rootca_cert_pem', + input: rootca_key_pem, + output: 'rootCA.cert.pem', + command: [openssl, 'req', '-x509', '-new', '-batch', '-config', files('test.rootCA.conf'), '-key', '@INPUT@', '-days', '1024', '-out', '@OUTPUT@'] +) + +client_key_pem = custom_target( + 'client_key_pem', + output: 'client.key.pem', + command: [openssl, 'genrsa', '-out', '@OUTPUT@', '2048'] +) + +client_temp_req = custom_target( + 'client_temp_req', + input: client_key_pem, + output: 'client_temp_req', + command: [openssl, 'req', '-new', '-batch', '-config', test_conf, '-key', '@INPUT@', '-out', '@OUTPUT@'] +) + +client_cert_pem = custom_target( + 'client_cert_pem', + input: [client_temp_req, rootca_cert_pem, rootca_key_pem], + output: 'client.cert.pem', + command: [openssl, 'x509', '-in', '@INPUT0@', '-days', '370', '-req', '-CA', '@INPUT1@', '-CAkey', '@INPUT2@', '-CAcreateserial', '-out', '@OUTPUT@'] +) + +# Copy test files to the build directory +configure_file(input: 'ca-bundle.crt', output: 'ca-bundle.crt', copy: true) +configure_file(input: 'image.jpg', output: 'image.jpg', copy: true) +subdir(join_paths('www', 'dir')) +subdir(join_paths('www2', 'dir')) +subdir(join_paths('www3', 'dir')) + +test( + 'main', + executable( + 'main', + 'test.cc', + dependencies: [ + cpp_httplib_dep, + gtest_dep + ] + ), + depends: [ + key_pem, + cert_pem, + cert2_pem, + rootca_key_pem, + rootca_cert_pem, + client_key_pem, + client_cert_pem + ], + workdir: meson.current_build_dir(), + timeout: 300 +) diff --git a/test/www/dir/meson.build b/test/www/dir/meson.build new file mode 100644 index 0000000..8339b63 --- /dev/null +++ b/test/www/dir/meson.build @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Andrea Pappacoda +# +# SPDX-License-Identifier: MIT + +configure_file(input: 'index.html', output: 'index.html', copy: true) +configure_file(input: 'test.abcde', output: 'test.abcde', copy: true) +configure_file(input: 'test.html', output: 'test.html', copy: true) diff --git a/test/www2/dir/meson.build b/test/www2/dir/meson.build new file mode 100644 index 0000000..74fe783 --- /dev/null +++ b/test/www2/dir/meson.build @@ -0,0 +1,6 @@ +# SPDX-FileCopyrightText: 2021 Andrea Pappacoda +# +# SPDX-License-Identifier: MIT + +configure_file(input: 'index.html', output: 'index.html', copy: true) +configure_file(input: 'test.html', output: 'test.html', copy: true) diff --git a/test/www3/dir/meson.build b/test/www3/dir/meson.build new file mode 100644 index 0000000..74fe783 --- /dev/null +++ b/test/www3/dir/meson.build @@ -0,0 +1,6 @@ +# SPDX-FileCopyrightText: 2021 Andrea Pappacoda +# +# SPDX-License-Identifier: MIT + +configure_file(input: 'index.html', output: 'index.html', copy: true) +configure_file(input: 'test.html', output: 'test.html', copy: true)