From 42aea6f1987655d624d85325378c9b81639443e6 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Wed, 8 Feb 2023 19:16:57 +0800 Subject: [PATCH] Enable C++ unit test on macOS CI (#674) Co-authored-by: wei chen Co-authored-by: Ovidiu Voda Co-authored-by: Bart Louwers --- .github/workflows/macos-ci.yml | 14 +- expression-test/main.cpp | 10 +- package.json | 2 +- platform/ios/CMakeLists.txt | 5 +- .../default/src/mbgl/render-test/main.cpp | 6 +- platform/macos/macos.cmake | 9 +- test/fixtures/.gitignore | 2 + .../local_glyphs/ping_fang/expected.png | Bin 18292 -> 18207 bytes .../ping_fang_semibold/expected.png | Bin 18645 -> 18500 bytes test/src/mbgl/test/http_server.cpp | 1 + test/src/mbgl/test/test.cpp | 4 - test/storage/resource.test.cpp | 2 +- test/storage/server.js | 182 ++++++++++++++++++ test/storage/with-server.js | 34 ++++ test/tile/tile_coordinate.test.cpp | 4 +- 15 files changed, 260 insertions(+), 15 deletions(-) create mode 100644 test/fixtures/.gitignore create mode 100755 test/storage/server.js create mode 100644 test/storage/with-server.js diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml index f56a5b9f4..05244621e 100644 --- a/.github/workflows/macos-ci.yml +++ b/.github/workflows/macos-ci.yml @@ -118,10 +118,22 @@ jobs: ccache --max-size=2G ccache --show-stats - - name: Build macos test + - name: Run macOS Objective-C tests run: | make macos-test + - name: npm install # C++ tests are run with root as working directory + run: npm ci --ignore-scripts + working-directory: . + + - name: Run macOS C++ unit tests + run: | + cmake -S . -B $BUILD_DIR + cmake --build $BUILD_DIR --target mbgl-test-runner + ctest -VV --test-dir $BUILD_DIR -R mbgl-test-runner + env: + BUILD_DIR: ../../../maplibre-gl-native-macostestbuild + - name: Check public symbols run: make darwin-check-public-symbols diff --git a/expression-test/main.cpp b/expression-test/main.cpp index db468dffe..0bc3fd1a6 100644 --- a/expression-test/main.cpp +++ b/expression-test/main.cpp @@ -3,8 +3,10 @@ #include "expression_test_logger.hpp" #include +#include -int main(int argc, char** argv) { +int main(int argc, char** argv) +try { // Parse args std::vector testPaths; mbgl::filesystem::path rootPath; @@ -70,6 +72,10 @@ int main(int argc, char** argv) { printStats(stats); writeHTMLResults(stats, rootPath.string(), shuffle, seed); - + return stats.errored.size() + stats.failed.size() == 0 ? 0 : 1; } +catch (std::exception const& ex) { + std::cerr << "Caught an exception while running tests:\n" << ex.what() << '\n'; + return 1; +} diff --git a/package.json b/package.json index 9be00573f..3b1f77e92 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,9 @@ }, "license": "BSD-2-Clause", "dependencies": { - "@mapbox/cmake-node-module": "^1.2.0", "@acalcutt/node-pre-gyp": "^1.0.11", "@acalcutt/node-pre-gyp-github": "1.4.8", + "@mapbox/cmake-node-module": "^1.2.0", "minimatch": "^6.1.6", "npm-run-all": "^4.0.2" }, diff --git a/platform/ios/CMakeLists.txt b/platform/ios/CMakeLists.txt index 443ff20ad..8b137a76e 100644 --- a/platform/ios/CMakeLists.txt +++ b/platform/ios/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.19) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../ ${CMAKE_CURRENT_BINARY_DIR}/mapbox-gl-native ) +project (mbgl) +enable_testing() -project (mbgl) \ No newline at end of file +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../ ${CMAKE_CURRENT_BINARY_DIR}/mapbox-gl-native ) diff --git a/platform/ios/platform/default/src/mbgl/render-test/main.cpp b/platform/ios/platform/default/src/mbgl/render-test/main.cpp index 9b22b20e0..b997c7d1b 100644 --- a/platform/ios/platform/default/src/mbgl/render-test/main.cpp +++ b/platform/ios/platform/default/src/mbgl/render-test/main.cpp @@ -1,5 +1,9 @@ #include -int main(int argc, char *argv[]) { +int main(int argc, char *argv[]) +try { return mbgl::runRenderTests(argc, argv); +} catch (std::exception const& e) { + std::cerr << "Caught an exception while running tests\n" << e.what() << '\n'; + return 1; } diff --git a/platform/macos/macos.cmake b/platform/macos/macos.cmake index 4d2970d1d..dc6576e9b 100644 --- a/platform/macos/macos.cmake +++ b/platform/macos/macos.cmake @@ -158,4 +158,11 @@ set_target_properties(mbgl-benchmark-runner mbgl-test-runner mbgl-render-test-ru if(NOT DEFINED ENV{CI}) add_test(NAME mbgl-benchmark-runner COMMAND mbgl-benchmark-runner WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) endif() -add_test(NAME mbgl-test-runner COMMAND mbgl-test-runner WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) +add_test( + NAME mbgl-test-runner + COMMAND + node + ${PROJECT_SOURCE_DIR}/test/storage/with-server.js + ${PROJECT_SOURCE_DIR}/test/storage/server.js + $ + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) diff --git a/test/fixtures/.gitignore b/test/fixtures/.gitignore new file mode 100644 index 000000000..3a379d66b --- /dev/null +++ b/test/fixtures/.gitignore @@ -0,0 +1,2 @@ +diff.png +actual.png \ No newline at end of file diff --git a/test/fixtures/local_glyphs/ping_fang/expected.png b/test/fixtures/local_glyphs/ping_fang/expected.png index 6e7e5c80b9c7cca2f323e350e375668641f7c704..0284836130450d01b88a9bb3d30f8b6a14ddd11e 100644 GIT binary patch literal 18207 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 diff --git a/test/fixtures/local_glyphs/ping_fang_semibold/expected.png b/test/fixtures/local_glyphs/ping_fang_semibold/expected.png index 6bb0a2503fc2819d0a99da9f9b745e5cb125de4a..9723cc2826f8b5293cea16d1f180c7c6f85f6a54 100644 GIT binary patch literal 18500 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 rXmOWDFNvQ=`IBXKXiu@f^_#Y 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 z z9C~3-FuMd(`SK}kH76q^GGcBHScorf6g+IIad1+FPY4HBgy&E?^2C_2(TYSdJMXL zX5Xs;zVj$OIh#f0UUfV6$O*GF&^K-L!XB%b)Ps41nv_o81qk`GfBreYwr{Vw&73?! zO2rBM6d~P{tAuKF>!2@?smnNYPWKQq@ z*jZ_{{iR?qNiW-i&!8F75ug=YNdhmZ6|J8HeN^7bJf0rW7umkwyx^SgA>f09n-tS> zO7vk4&QK%9TvU#qBQ{Pjnz^Q$)jlJrlPsOBHp8m^TE~|C$fVID_v??Au(j0|xc^L;B>ixfaJ=i99s-=V!;YRT*O~*@MVNUP|bT zS1K;<5kD$lw6GaEmc*)6%p)>WT=v9a1GDZ2vtwm$WfgTEZSs@%oZq~J4-FQ`9DE4%ZtJ6Pk_z3@%Kg8_D|11U|#i!J*A9e31Km-7(&NN}Xs?PnChLPoFyyJYXj zN}c0^ra_+Es|OWSX0yzyHs;Hf0xvuVLQcX1HG4s-l>v%xD8s%>K{d{i0z4l%eF*cP zNF^$JH@6~@nZzrH%o=0!fM6yXJU9Hgq)Z;G7-z98$y}rvkv??vX+^OQ%}Hg8Akrk? z#Vm25j)$VhJqJ8$A76{d)nKftG`FmD>kaiIMZPP`L2`bm4BY#D$loGfm^R^C6~%g! zeWzP0)FB6>dcV#;16qT%^Fv@5dc7t1(tp2RBJEoFeAsRLo>8|KBiS9dMoAWjXT*A` zsP&)eIvP?C;mboiU?C49YKS2J(); -#endif - testing::InitGoogleTest(&argc, argv); // In order to run specific tests diff --git a/test/storage/resource.test.cpp b/test/storage/resource.test.cpp index 41bf71471..e03f339a9 100644 --- a/test/storage/resource.test.cpp +++ b/test/storage/resource.test.cpp @@ -86,7 +86,7 @@ TEST(Resource, Tile) { Resource wmsTile = Resource::tile("http://example.com/?bbox={bbox-epsg-3857}", 2.0, 0, 0, 1, Tileset::Scheme::XYZ); EXPECT_EQ(Resource::Kind::Tile, wmsTile.kind); - EXPECT_EQ("http://example.com/?bbox=-20037508.342789245,0,0,20037508.342789245", wmsTile.url); + EXPECT_EQ("http://example.com/?bbox=-20037508.342789244,0,0,20037508.342789244", wmsTile.url); EXPECT_EQ("http://example.com/?bbox={bbox-epsg-3857}", wmsTile.tileData->urlTemplate); EXPECT_EQ(1, wmsTile.tileData->pixelRatio); EXPECT_EQ(0, wmsTile.tileData->x); diff --git a/test/storage/server.js b/test/storage/server.js new file mode 100755 index 000000000..cfacf7ce9 --- /dev/null +++ b/test/storage/server.js @@ -0,0 +1,182 @@ +#!/usr/bin/env node +/* jshint node: true */ +'use strict'; + +// This needs to be here to make sure the pipe stays open. +// We're waiting until the stdin pipe gets closed (e.g. because the parent +// process dies) +process.stdin.on('readable', function() {}); +process.stdin.on('end', function() { process.exit(0); }); + + +var fs = require('fs'); +var express = require('express'); +var app = express(); + +// We're manually setting Etag headers. +app.disable('etag'); + +app.get('/test', function (req, res) { + if (req.query.modified) { + res.setHeader('Last-Modified', (new Date(req.query.modified * 1000)).toUTCString()); + } + if (req.query.expires) { + res.setHeader('Expires', (new Date(req.query.expires * 1000)).toUTCString()); + } + if (req.query.etag) { + res.setHeader('ETag', req.query.etag); + } + if (req.query.cachecontrol) { + res.setHeader('Cache-Control', req.query.cachecontrol); + } + res.send('Hello World!'); +}); + +app.get('/stale/*', function() { + // Never respond. +}); + +var cacheCounter = 0; +app.get('/cache', function(req, res) { + res.setHeader('Cache-Control', 'max-age=30'); // Allow caching for 30 seconds + res.send('Response ' + (++cacheCounter)); +}); + +app.get('/revalidate-same', function(req, res) { + if (req.headers['if-none-match'] == 'snowfall') { + // Second request can be cached for 1 second. + res.setHeader('Cache-Control', 'max-age=1, must-revalidate'); + res.status(304).end(); + } else { + // First request must always be revalidated. + res.setHeader('ETag', 'snowfall'); + res.setHeader('Cache-Control', 'must-revalidate'); + res.status(200).send('Response'); + } +}); + +var expiresCounter = 0; +app.get('/clockskew', function (req, res) { + res.setHeader('Expires', (new Date(2010, 1, 1, 10, ++expiresCounter, 0)).toUTCString()); + res.status(200).send('Response'); +}); + +app.get('/revalidate-modified', function(req, res) { + var jan1 = new Date('jan 1 2015 utc'); + + if (req.headers['if-modified-since']) { + var modified_since = new Date(req.headers['if-modified-since']); + if (modified_since >= jan1) { + res.setHeader('Cache-Control', 'max-age=1, must-revalidate'); + res.status(304).end(); + return; + } + } + + // First request must always be revalidated. + res.setHeader('Last-Modified', jan1.toUTCString()); + res.setHeader('Cache-Control', 'must-revalidate'); + res.status(200).send('Response'); +}); + + +var revalidateEtagCounter = 1; +app.get('/revalidate-etag', function(req, res) { + res.setHeader('ETag', 'response-' + revalidateEtagCounter); + res.setHeader('Cache-Control', 'must-revalidate'); + + res.status(200).send('Response ' + revalidateEtagCounter); + revalidateEtagCounter++; +}); + +app.get('/empty-data', function(req, res) { + res.status(200).send(); +}); + +app.get('/no-content', function(req, res) { + res.status(204).send(); +}); + +app.get('/not-found', function(req, res) { + res.status(404).send('Not Found!'); +}); + +app.get('/permanent-error', function(req, res) { + res.status(500).send('Server Error!'); +}); + +var temporaryErrorCounter = 0; +app.get('/temporary-error', function(req, res) { + if (temporaryErrorCounter === 0) { + res.status(500).end(); + } else { + res.status(200).send('Hello World!'); + } + + temporaryErrorCounter++; +}); + +app.get('/rate-limit', function(req, res) { + + if (req.query.std) { + res.setHeader('Retry-After', 1); + } else if (req.query.mbx) { + res.setHeader('x-rate-limit-reset', Math.round(Date.now() / 1000) + 1); + } + + res.status(429).end(); +}); + +var styleFailOnce500 = true; +app.get('/style-fail-once-500', function (req, res) { + if (styleFailOnce500) { + res.status(500).send('Server Error!'); + styleFailOnce500 = false; + } else { + res.status(200).send('{ "version": 8, "name": "Teste Style" }'); + } +}); + +var styleFailOnce404 = true; +app.get('/style-fail-once-404', function (req, res) { + if (styleFailOnce404) { + res.status(404).send('Not found!'); + styleFailOnce404 = false; + } else { + res.status(200).send('{ "version": 8, "name": "Teste Style" }'); + } +}); + +var styleFailOnce404Cache = true; +app.get('/style-fail-once-404-cache', function (req, res) { + if (styleFailOnce404Cache) { + res.setHeader('Cache-Control', 'max-age=30'); + res.status(404).send('Not found!'); + styleFailOnce404Cache = false; + } else { + res.status(200).send('{ "version": 8, "name": "Teste Style" }'); + } +}); + +app.get('/delayed', function(req, res) { + setTimeout(function() { + res.status(200).send('Response'); + }, 200); +}); + + +app.get('/load/:number(\\d+)', function(req, res) { + res.send('Request ' + req.params.number); +}); + +app.get('/online/:style(*)', function(req, res) { + const file = (__dirname + "/../fixtures/map/online/" + req.params.style).replace("storage/../", ""); + res.sendFile(file); // Set disposition and send it. + // res.status(200).send(); + // res.send('Request ' + req.params.style); +}); + +var server = app.listen(3000, function () { + // Tell parent that we're now listening. + process.stdout.write("OK"); +}); diff --git a/test/storage/with-server.js b/test/storage/with-server.js new file mode 100644 index 000000000..45bc50489 --- /dev/null +++ b/test/storage/with-server.js @@ -0,0 +1,34 @@ +// This script runs a Node.js server passed to it while running aother program. + +const { spawn } = require('child_process') + +if (process.argv.length < 4) { + console.error("Usage: node with-server.js [arg]..."); + process.exit(1); +} + +const serverScript = process.argv[2]; + +const prog = process.argv[3]; +const args = process.argv.slice(4); + +const sameStdio = { stdio: [process.stdin, process.stdout, process.stderr] }; + +const server = spawn('node', [serverScript]); + +server.stdout.on('data', (data) => { + const dataAsStr = data.toString(); + + if (dataAsStr === "OK") { + const test = spawn(prog, args, sameStdio); + + test.on('close', (code) => { + console.error(`Sub process exited with code '${code}', killing server`); + server.kill(); + process.exit(code); + }); + return; + } + + console.error(`[server] ${dataAsStr}`); +}); diff --git a/test/tile/tile_coordinate.test.cpp b/test/tile/tile_coordinate.test.cpp index a5b5bd991..9ad2d1d96 100644 --- a/test/tile/tile_coordinate.test.cpp +++ b/test/tile/tile_coordinate.test.cpp @@ -94,8 +94,8 @@ TEST(TileCoordinate, ToGeometryCoordinate) { for (uint8_t zoom = 0; zoom <= 16; ++zoom) { auto maxTilesPerAxis = static_cast(std::pow(2, zoom)); for (const auto& edge : edges) { - uint32_t tileX = edge.x == 0 ? 0 : edge.x == 1 ? maxTilesPerAxis - 1 : (maxTilesPerAxis / 2) - 1; - uint32_t tileY = edge.y == 0 ? 0 : edge.y == 1 ? maxTilesPerAxis - 1 : (maxTilesPerAxis / 2) - 1; + uint32_t tileX = edge.x == 0 ? 0 : edge.x == 1 ? maxTilesPerAxis - 1 : (maxTilesPerAxis / 2.0) - 1; + uint32_t tileY = edge.y == 0 ? 0 : edge.y == 1 ? maxTilesPerAxis - 1 : (maxTilesPerAxis / 2.0) - 1; UnwrappedTileID unwrapped(0, CanonicalTileID { zoom, tileX, tileY }); auto tilePointX = ((edge.x * maxTilesPerAxis) - tileX) * util::EXTENT;