Add renderd_config.c usage into render_* targets (#400)

* Add support for reading `renderd.conf` to `render_expired`
* Add support for reading `renderd.conf` to `render_list`
* Add support for reading `renderd.conf` to `render_old`
* Add support for reading `renderd.conf` to `render_speedtest`
* Move renderd/render_* execution tests to own files
* Reduce variable scope & minor clean up
* Use `stat` rather than `access` to check if file exists
This commit is contained in:
Hummeltech
2024-03-04 12:03:16 -07:00
committed by GitHub
parent d5534bda27
commit 7389b160bf
21 changed files with 2311 additions and 1067 deletions

View File

@ -4,6 +4,7 @@
!docs/man
!etc/apache2/renderd-example-map.conf
!etc/apache2/tile.load.in
!etc/renderd/renderd.conf.examples
!etc/renderd/renderd.conf.in
!includes
!src

View File

@ -24,7 +24,13 @@ bin_PROGRAMS = \
render_list \
render_old \
render_speedtest
noinst_PROGRAMS = gen_tile_test
noinst_PROGRAMS = \
gen_tile_test \
renderd_test \
render_expired_test \
render_list_test \
render_old_test \
render_speedtest_test
man_MANS = \
docs/man/renderd.1 \
@ -57,49 +63,82 @@ render_speedtest_SOURCES = \
src/g_logger.c \
src/protocol_helper.c \
src/render_submit_queue.c \
src/renderd_config.c \
src/sys_utils.c
render_speedtest_LDADD = $(PTHREAD_CFLAGS) $(GLIB_LIBS)
render_speedtest_LDADD = $(PTHREAD_CFLAGS) $(GLIB_LIBS) $(INIPARSER_LDFLAGS)
render_list_SOURCES = \
src/render_list.c \
src/protocol_helper.c \
src/render_submit_queue.c \
src/renderd_config.c \
src/sys_utils.c \
$(STORE_SOURCES)
render_list_LDADD = $(PTHREAD_CFLAGS) $(STORE_LDFLAGS)
render_list_LDADD = $(PTHREAD_CFLAGS) $(STORE_LDFLAGS) $(INIPARSER_LDFLAGS)
render_expired_SOURCES = \
src/render_expired.c \
src/protocol_helper.c \
src/render_submit_queue.c \
src/renderd_config.c \
src/sys_utils.c \
$(STORE_SOURCES)
render_expired_LDADD = $(PTHREAD_CFLAGS) $(STORE_LDFLAGS)
render_expired_LDADD = $(PTHREAD_CFLAGS) $(STORE_LDFLAGS) $(INIPARSER_LDFLAGS)
render_old_SOURCES = \
src/render_old.c \
src/g_logger.c \
src/protocol_helper.c \
src/render_submit_queue.c \
src/renderd_config.c \
src/store_file_utils.c \
src/sys_utils.c
render_old_LDADD = $(PTHREAD_CFLAGS) $(GLIB_LIBS)
render_old_LDADD = $(PTHREAD_CFLAGS) $(GLIB_LIBS) $(INIPARSER_LDFLAGS)
#convert_meta_SOURCES = src/dir_utils.c src/store.c src/convert_meta.c
noinst_LIBRARIES = catch_main.o catch_test_common.o
catch_main_o_SOURCES = tests/catch/catch_main.cpp
catch_test_common_o_SOURCES = tests/catch/catch_test_common.cpp
gen_tile_test_SOURCES = \
tests/gen_tile_test.cpp \
$(renderd_SOURCES)
gen_tile_test_CFLAGS = -DMAIN_ALREADY_DEFINED
gen_tile_test_CXXFLAGS = $(renderd_CXXFLAGS)
gen_tile_test_LDADD = $(renderd_LDADD)
gen_tile_test_LDADD = $(renderd_LDADD) catch_test_common.o
renderd_test_SOURCES = \
tests/renderd_test.cpp
renderd_test_LDADD = $(GLIB_LIBS) catch_main.o catch_test_common.o
render_expired_test_SOURCES = \
tests/render_expired_test.cpp
render_expired_test_LDADD = $(GLIB_LIBS) catch_main.o catch_test_common.o
render_list_test_SOURCES = \
tests/render_list_test.cpp
render_list_test_LDADD = $(GLIB_LIBS) catch_main.o catch_test_common.o
render_old_test_SOURCES = \
tests/render_old_test.cpp
render_old_test_LDADD = $(GLIB_LIBS) catch_main.o catch_test_common.o
render_speedtest_test_SOURCES = \
tests/render_speedtest_test.cpp
render_speedtest_test_LDADD = $(GLIB_LIBS) catch_main.o catch_test_common.o
CLEANFILES=*.slo mod_tile.la stderr.out src/*.slo src/*.lo src/.libs/* src/*.la
COMMA=,
test: gen_tile_test
test: gen_tile_test renderd_test render_expired_test render_list_test render_old_test render_speedtest_test
./gen_tile_test
./renderd_test
./render_expired_test
./render_list_test
./render_old_test
./render_speedtest_test
all-local:
$(APXS) -c $(DEF_LDLIBS) $(AM_CFLAGS) \

View File

@ -135,7 +135,7 @@ RUN export DESTDIR=/tmp/mod_tile && \
./autogen.sh && \
./configure && \
make DESTDIR=${DESTDIR} install install-mod_tile
RUN ./gen_tile_test
RUN make test
# Runner
FROM quay.io/centos/centos:stream${centos_stream_version} as runner

View File

@ -36,7 +36,7 @@ RUN export DESTDIR=/tmp/mod_tile && \
./autogen.sh && \
./configure && \
make DESTDIR=${DESTDIR} install install-mod_tile
RUN ./gen_tile_test
RUN make test
# Runner
FROM debian:${debian_version} as runner

View File

@ -36,7 +36,7 @@ RUN export DESTDIR=/tmp/mod_tile && \
./autogen.sh && \
./configure && \
make DESTDIR=${DESTDIR} install install-mod_tile
RUN ./gen_tile_test
RUN make test
# Runner
FROM ubuntu:${ubuntu_version} as runner

View File

@ -87,9 +87,11 @@ set(render_expired_SRCS
protocol_helper.c
render_expired.c
render_submit_queue.c
renderd_config.c
)
set(render_expired_LIBS
${COMMON_LIBRARIES}
${INIPARSER_LIBRARIES}
${STORE_LIBRARIES}
)
add_executable(render_expired ${render_expired_SRCS})
@ -107,9 +109,11 @@ set(render_list_SRCS
protocol_helper.c
render_list.c
render_submit_queue.c
renderd_config.c
)
set(render_list_LIBS
${COMMON_LIBRARIES}
${INIPARSER_LIBRARIES}
${STORE_LIBRARIES}
)
add_executable(render_list ${render_list_SRCS})
@ -126,10 +130,12 @@ set(render_old_SRCS
protocol_helper.c
render_old.c
render_submit_queue.c
renderd_config.c
store_file_utils.c
)
set(render_old_LIBS
${COMMON_LIBRARIES}
${INIPARSER_LIBRARIES}
)
add_executable(render_old ${render_old_SRCS})
target_link_libraries(render_old ${render_old_LIBS})
@ -145,9 +151,11 @@ set(render_speedtest_SRCS
protocol_helper.c
render_speedtest.cpp
render_submit_queue.c
renderd_config.c
)
set(render_speedtest_LIBS
${COMMON_LIBRARIES}
${INIPARSER_LIBRARIES}
)
add_executable(render_speedtest ${render_speedtest_SRCS})
target_link_libraries(render_speedtest ${render_speedtest_LIBS})
@ -195,6 +203,7 @@ if(ENABLE_TESTS)
#-----------------------------------------------------------------------------
set(gen_tile_test_SRCS
$<TARGET_OBJECTS:catch_test_common_o>
${renderd_SRCS}
${PROJECT_SOURCE_DIR}/tests/gen_tile_test.cpp
)

View File

@ -15,32 +15,22 @@
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <getopt.h>
#include <glib.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/un.h>
#include <getopt.h>
#include <time.h>
#include <utime.h>
#include <string.h>
#include <strings.h>
#include <limits.h>
#include <utime.h>
#include <unistd.h>
#include <pthread.h>
#include "g_logger.h"
#include "protocol.h"
#include "config.h"
#include "g_logger.h"
#include "render_config.h"
#include "store.h"
#include "render_submit_queue.h"
const char * tile_dir_default = RENDERD_TILE_DIR;
#include "renderd_config.h"
#include "store.h"
// macros handling our tile marking arrays (these are essentially bit arrays
// that have one bit for each tile on the repsective zoom level; since we only
@ -48,11 +38,10 @@ const char * tile_dir_default = RENDERD_TILE_DIR;
// we'd still only use 4^17 bits = 2 GB RAM (plus a little for the lower zoom
// levels) - this saves us the hassle of working with a tree structure.
#define TILE_REQUESTED(z,x,y) \
(tile_requested[z][((x)*twopow[z]+(y))/(8*sizeof(int))]>>(((x)*twopow[z]+(y))%(8*sizeof(int))))&0x01
#define SET_TILE_REQUESTED(z,x,y) \
tile_requested[z][((x)*twopow[z]+(y))/(8*sizeof(int))] |= (0x01 << (((x)*twopow[z]+(y))%(8*sizeof(int))));
#define TILE_REQUESTED(z, x, y) \
(tile_requested[z][((x)*twopow[z] + (y)) / (8 * sizeof(int))] >> (((x)*twopow[z] + (y)) % (8 * sizeof(int)))) & 0x01
#define SET_TILE_REQUESTED(z, x, y) \
tile_requested[z][((x)*twopow[z] + (y)) / (8 * sizeof(int))] |= (0x01 << (((x)*twopow[z] + (y)) % (8 * sizeof(int))));
#ifndef METATILE
#warning("render_expired not implemented for non-metatile mode. Feel free to submit fix")
@ -70,45 +59,56 @@ unsigned int **tile_requested;
// for base 2
unsigned long long twopow[MAX_ZOOM];
static int minZoom = 0;
static int maxZoom = 18;
static int verbose = 0;
static int maxLoad = MAX_LOAD_OLD;
void display_rate(struct timeval start, struct timeval end, int num)
{
int d_s, d_us;
float sec;
d_s = end.tv_sec - start.tv_sec;
d_s = end.tv_sec - start.tv_sec;
d_us = end.tv_usec - start.tv_usec;
sec = d_s + d_us / 1000000.0;
printf("Rendered %d tiles in %.2f seconds (%.2f tiles/s)\n", num, sec, num / sec);
fflush(NULL);
g_logger(G_LOG_LEVEL_MESSAGE, "\tRendered %d tiles in %.2f seconds (%.2f tiles/s)", num, sec, num / sec);
}
int main(int argc, char **argv)
{
char *spath = strdup(RENDERD_SOCKET);
const char *config_file_name_default = RENDERD_CONFIG;
const char *mapname_default = XMLCONFIG_DEFAULT;
const char *socketname_default = RENDERD_SOCKET;
const char *tile_dir_default = RENDERD_TILE_DIR;
int max_load_default = MAX_LOAD_OLD;
int max_zoom_default = 18;
int min_zoom_default = 0;
int num_threads_default = 1;
const char *config_file_name = config_file_name_default;
const char *mapname = mapname_default;
const char *socketname = socketname_default;
const char *tile_dir = tile_dir_default;
int max_load = max_load_default;
int max_zoom = max_zoom_default;
int min_zoom = min_zoom_default;
int num_threads = num_threads_default;
int config_file_name_passed = 0;
int mapname_passed = 0;
int socketname_passed = 0;
int tile_dir_passed = 0;
int max_load_passed = 0;
int max_zoom_passed = 0;
int min_zoom_passed = 0;
int num_threads_passed = 0;
int x, y, z;
struct timeval start, end;
int num_render = 0, num_all = 0, num_read = 0, num_ignore = 0, num_unlink = 0, num_touch = 0;
int c;
int numThreads = 1;
int deleteFrom = -1;
int touchFrom = -1;
int deleteFrom = -1, touchFrom = -1;
int doRender = 0;
int progress = 1;
int i;
struct storage_backend * store;
char name[PATH_MAX];
int verbose = 0;
struct storage_backend *store;
// excess_zoomlevels is how many zoom levels at the large end
// we can ignore because their tiles will share one meta tile.
@ -126,16 +126,17 @@ int main(int argc, char **argv)
while (1) {
int option_index = 0;
static struct option long_options[] = {
{"config", required_argument, 0, 'c'},
{"delete-from", required_argument, 0, 'd'},
{"map", required_argument, 0, 'm'},
{"max-load", required_argument, 0, 'l'},
{"max-zoom", required_argument, 0, 'Z'},
{"min-zoom", required_argument, 0, 'z'},
{"no-progress", no_argument, 0, 'N'},
{"num-threads", required_argument, 0, 'n'},
{"socket", required_argument, 0, 's'},
{"tile-dir", required_argument, 0, 't'},
{"touch-from", required_argument, 0, 'T'},
{"no-progress", no_argument, 0, 'N'},
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, 0, 'h'},
@ -143,97 +144,89 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "d:m:l:Z:z:n:s:t:T:vhV", long_options, &option_index);
int c = getopt_long(argc, argv, "c:d:m:l:Z:z:Nn:s:t:T:vhV", long_options, &option_index);
if (c == -1) {
break;
}
switch (c) {
case 's': /* -s, --socket */
spath = strdup(optarg);
break;
case 'c': /* -c, --config */
config_file_name = strndup(optarg, PATH_MAX);
config_file_name_passed = 1;
case 't': /* -t, --tile-dir */
tile_dir = strdup(optarg);
break;
struct stat buffer;
case 'm': /* -m, --map */
mapname = strdup(optarg);
break;
case 'n': /* -n, --num-threads */
numThreads = atoi(optarg);
if (numThreads <= 0) {
fprintf(stderr, "Invalid number of threads, must be at least 1\n");
if (stat(config_file_name, &buffer) != 0) {
g_logger(G_LOG_LEVEL_CRITICAL, "Config file '%s' does not exist, please specify a valid file", config_file_name);
return 1;
}
break;
case 'd': /* -d, --delete-from */
deleteFrom = atoi(optarg);
if (deleteFrom < 0 || deleteFrom > MAX_ZOOM) {
fprintf(stderr, "Invalid 'delete-from' zoom, must be between 0 and %d\n", MAX_ZOOM);
return 1;
}
case 'd': /* -d, --delete-from */
deleteFrom = min_max_int_opt(optarg, "delete-from", 0, MAX_ZOOM);
break;
case 'T': /* -T, --touch-from */
touchFrom = atoi(optarg);
if (touchFrom < 0 || touchFrom > MAX_ZOOM) {
fprintf(stderr, "Invalid 'touch-from' zoom, must be between 0 and %d\n", MAX_ZOOM);
return 1;
}
case 'm': /* -m, --map */
mapname = strndup(optarg, XMLCONFIG_MAX);
mapname_passed = 1;
break;
case 'z': /* -z, --min-zoom */
minZoom = atoi(optarg);
if (minZoom < 0 || minZoom > MAX_ZOOM) {
fprintf(stderr, "Invalid minimum zoom selected, must be between 0 and %d\n", MAX_ZOOM);
return 1;
}
case 'l': /* -l, --max-load */
max_load = min_max_int_opt(optarg, "maximum load", 0, -1);
max_load_passed = 1;
break;
case 'Z': /* -Z, --max-zoom */
maxZoom = atoi(optarg);
if (maxZoom < 0 || maxZoom > MAX_ZOOM) {
fprintf(stderr, "Invalid maximum zoom selected, must be between 0 and %d\n", MAX_ZOOM);
return 1;
}
case 'Z': /* -Z, --max-zoom */
max_zoom = min_max_int_opt(optarg, "maximum zoom", 0, MAX_ZOOM);
max_zoom_passed = 1;
break;
case 'l': /* -l, --max-load */
maxLoad = atoi(optarg);
case 'z': /* -z, --min-zoom */
min_zoom = min_max_int_opt(optarg, "minimum zoom", 0, MAX_ZOOM);
min_zoom_passed = 1;
break;
case 'N': /* --no-progress */
case 'N': /* -N, --no-progress */
progress = 0;
break;
case 'v': /* -v, --verbose */
case 'n': /* -n, --num-threads */
num_threads = min_max_int_opt(optarg, "number of threads", 1, -1);
num_threads_passed = 1;
break;
case 's': /* -s, --socket */
socketname = strndup(optarg, PATH_MAX);
socketname_passed = 1;
break;
case 't': /* -t, --tile-dir */
tile_dir = strndup(optarg, PATH_MAX);
tile_dir_passed = 1;
break;
case 'T': /* -T, --touch-from */
touchFrom = min_max_int_opt(optarg, "touch-from", 0, MAX_ZOOM);
break;
case 'v': /* -v, --verbose */
verbose = 1;
break;
case 'h': /* -h, --help */
case 'h': /* -h, --help */
fprintf(stderr, "Usage: render_expired [OPTION] ...\n");
fprintf(stderr, " -c, --config=CONFIG specify the renderd config file (default is off)\n");
fprintf(stderr, " -d, --delete-from=ZOOM when expiring tiles of ZOOM or higher, delete them instead of re-rendering (default is off)\n");
fprintf(stderr, " -m, --map=MAP render tiles in this map (defaults to '" XMLCONFIG_DEFAULT "')\n");
fprintf(stderr, " -n, --num-threads=N the number of parallel request threads (default 1)\n");
fprintf(stderr, " -s, --socket=SOCKET|HOSTNAME:PORT unix domain socket name or hostname and port for contacting renderd\n");
fprintf(stderr, " -t, --tile-dir tile cache directory (defaults to '" RENDERD_TILE_DIR "')\n");
fprintf(stderr, " -m, --map=MAP render tiles in this map (default is '%s')\n", mapname_default);
fprintf(stderr, " -l, --max-load=LOAD sleep if load is this high (default is '%d')\n", max_load_default);
fprintf(stderr, " -n, --num-threads=N the number of parallel request threads (default is '%d')\n", num_threads_default);
fprintf(stderr, " -s, --socket=SOCKET|HOSTNAME:PORT unix domain socket name or hostname and port for contacting renderd (default is '%s')\n", socketname_default);
fprintf(stderr, " -t, --tile-dir=TILE_DIR tile cache directory (default is '%s')\n", tile_dir_default);
fprintf(stderr, " -T, --touch-from=ZOOM when expiring tiles of ZOOM or higher, touch them instead of re-rendering (default is off)\n");
fprintf(stderr, " -Z, --max-zoom=ZOOM filter input to only render tiles less than or equal to this zoom level (default is %d)\n", 18);
fprintf(stderr, " -z, --min-zoom=ZOOM filter input to only render tiles greater or equal to this zoom level (default is 0)\n");
fprintf(stderr, " -Z, --max-zoom=ZOOM filter input to only render tiles less than or equal to this zoom level (default is '%d')\n", max_zoom_default);
fprintf(stderr, " -z, --min-zoom=ZOOM filter input to only render tiles greater than or equal to this zoom level (default is '%d')\n", min_zoom_default);
fprintf(stderr, "\n");
fprintf(stderr, " -h, --help display this help and exit\n");
fprintf(stderr, " -V, --version display the version number and exit\n");
@ -246,71 +239,117 @@ int main(int argc, char **argv)
fprintf(stderr, " 1/0/0\n");
fprintf(stderr, " 1/1/0\n");
fprintf(stderr, "The above would cause all 4 tiles at zoom 1 to be rendered\n");
exit(0);
return 0;
case 'V':
case 'V': /* -V, --version */
fprintf(stdout, "%s\n", VERSION);
exit(0);
return 0;
default:
fprintf(stderr, "unhandled char '%c'\n", c);
exit(1);
g_logger(G_LOG_LEVEL_CRITICAL, "unhandled char '%c'", c);
return 1;
}
}
if (maxZoom < minZoom) {
fprintf(stderr, "Invalid zoom range, max zoom must be greater or equal to minimum zoom\n");
if (max_zoom < min_zoom) {
g_logger(G_LOG_LEVEL_CRITICAL, "Specified min zoom (%i) is larger than max zoom (%i).", min_zoom, max_zoom);
return 1;
}
if (minZoom < excess_zoomlevels) {
minZoom = excess_zoomlevels;
}
if (config_file_name_passed) {
int map_section_num = -1;
process_config_file(config_file_name, 0, G_LOG_LEVEL_DEBUG);
// initialise arrays for tile markings
for (int i = 0; i < XMLCONFIGS_MAX; ++i) {
if (maps[i].xmlname && strcmp(maps[i].xmlname, mapname) == 0) {
map_section_num = i;
}
}
tile_requested = (unsigned int **) malloc((maxZoom - excess_zoomlevels + 1) * sizeof(unsigned int *));
for (i = 0; i <= maxZoom - excess_zoomlevels; i++) {
// initialize twopow array
twopow[i] = (i == 0) ? 1 : twopow[i - 1] * 2;
unsigned long long fourpow = twopow[i] * twopow[i];
tile_requested[i] = (unsigned int *) calloc((fourpow / METATILE) + 1, 1);
if (NULL == tile_requested[i]) {
fprintf(stderr, "not enough memory available.\n");
if (map_section_num < 0) {
g_logger(G_LOG_LEVEL_CRITICAL, "Map section '%s' does not exist in config file '%s'.", mapname, config_file_name);
return 1;
}
}
if (!max_zoom_passed) {
max_zoom = maps[map_section_num].max_zoom;
max_zoom_passed = 1;
}
fprintf(stderr, "Rendering client\n");
if (!min_zoom_passed) {
min_zoom = maps[map_section_num].min_zoom;
min_zoom_passed = 1;
}
gettimeofday(&start, NULL);
if (!num_threads_passed) {
num_threads = maps[map_section_num].num_threads;
num_threads_passed = 1;
}
if ((touchFrom != -1 && minZoom < touchFrom)
|| (deleteFrom != -1 && minZoom < deleteFrom)
|| (touchFrom == -1 && deleteFrom == -1)) {
// No need to spawn render threads, when we're not actually going to rerender tiles
spawn_workers(numThreads, spath, maxLoad);
doRender = 1;
if (!socketname_passed) {
socketname = strndup(config.socketname, PATH_MAX);
socketname_passed = 1;
}
if (!tile_dir_passed) {
tile_dir = strndup(maps[map_section_num].tile_dir, PATH_MAX);
tile_dir_passed = 1;
}
}
store = init_storage_backend(tile_dir);
if (store == NULL) {
fprintf(stderr, "failed to initialise storage backend %s\n", tile_dir);
g_logger(G_LOG_LEVEL_CRITICAL, "Failed to initialise storage backend %s", tile_dir);
return 1;
}
if (min_zoom < excess_zoomlevels) {
min_zoom = excess_zoomlevels;
}
// initialise arrays for tile markings
tile_requested = (unsigned int **)malloc((max_zoom - excess_zoomlevels + 1) * sizeof(unsigned int *));
for (int i = 0; i <= max_zoom - excess_zoomlevels; i++) {
// initialize twopow array
twopow[i] = (i == 0) ? 1 : twopow[i - 1] * 2;
unsigned long long fourpow = twopow[i] * twopow[i];
tile_requested[i] = (unsigned int *)calloc((fourpow / METATILE) + 1, 1);
if (NULL == tile_requested[i]) {
g_logger(G_LOG_LEVEL_CRITICAL, "not enough memory available");
return 1;
}
}
if ((touchFrom != -1 && min_zoom < touchFrom) || (deleteFrom != -1 && min_zoom < deleteFrom) || (touchFrom == -1 && deleteFrom == -1)) {
// No need to spawn render threads, when we're not actually going to rerender tiles
spawn_workers(num_threads, socketname, max_load);
doRender = 1;
}
g_logger(G_LOG_LEVEL_INFO, "Started render_expired with the following options:");
if (config_file_name_passed) {
g_logger(G_LOG_LEVEL_INFO, "\t--config = '%s' (user-specified)", config_file_name);
}
g_logger(G_LOG_LEVEL_INFO, "\t--map = '%s' (%s)", mapname, mapname_passed ? "user-specified" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--max-load = '%i' (%s)", max_load, max_load_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--max-zoom = '%i' (%s)", max_zoom, max_zoom_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--min-zoom = '%i' (%s)", min_zoom, min_zoom_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--num-threads = '%i' (%s)", num_threads, num_threads_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--socket = '%s' (%s)", socketname, socketname_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--tile-dir = '%s' (%s)", tile_dir, tile_dir_passed ? "user-specified/from config" : "default");
gettimeofday(&start, NULL);
while (!feof(stdin)) {
struct stat_info s;
int n = fscanf(stdin, "%d/%d/%d", &z, &x, &y);
if (verbose) {
printf("read: x=%d y=%d z=%d\n", x, y, z);
}
if (n != 3) {
// Discard input line
char tmp[1024];
@ -320,32 +359,41 @@ int main(int argc, char **argv)
continue;
}
fprintf(stderr, "bad line %d: %s", num_all, tmp);
if (verbose) {
g_logger(G_LOG_LEVEL_WARNING, "bad line %d: %s", num_all, tmp);
}
continue;
}
while (z > maxZoom) {
if (verbose) {
g_logger(G_LOG_LEVEL_MESSAGE, "read: x=%d y=%d z=%d", x, y, z);
}
while (z > max_zoom) {
x >>= 1;
y >>= 1;
z--;
}
while (z < maxZoom) {
while (z < max_zoom) {
x <<= 1;
y <<= 1;
z++;
}
//printf("loop: x=%d y=%d z=%d up to z=%d\n", x, y, z, minZoom);
g_logger(G_LOG_LEVEL_DEBUG, "loop: x=%d y=%d z=%d up to z=%d", x, y, z, min_zoom);
num_read++;
if (progress && (num_read % 100) == 0) {
printf("Read and expanded %i tiles from list.\n", num_read);
g_logger(G_LOG_LEVEL_INFO, "Read and expanded %i tiles from list.", num_read);
}
for (; z >= minZoom; z--, x >>= 1, y >>= 1) {
for (; z >= min_zoom; z--, x >>= 1, y >>= 1) {
char name[PATH_MAX];
if (verbose) {
printf("process: x=%d y=%d z=%d\n", x, y, z);
g_logger(G_LOG_LEVEL_MESSAGE, "process: x=%d y=%d z=%d", x, y, z);
}
// don't do anything if this tile was already requested.
@ -354,7 +402,7 @@ int main(int argc, char **argv)
// cause extra work.
if (TILE_REQUESTED(z - excess_zoomlevels, x >> excess_zoomlevels, y >> excess_zoomlevels)) {
if (verbose) {
printf("already requested\n");
g_logger(G_LOG_LEVEL_MESSAGE, "already requested");
}
break;
@ -367,7 +415,7 @@ int main(int argc, char **argv)
// commented out - seems to cause problems in MT environment,
// trying to write to already-closed file
//check_load();
// check_load();
num_all++;
s = store->tile_stat(store, mapname, "", x, y, z);
@ -375,42 +423,21 @@ int main(int argc, char **argv)
if (s.size > 0) { // Tile exists
// tile exists on disk; render it
if (deleteFrom != -1 && z >= deleteFrom) {
if (verbose) {
printf("deleting: %s\n", store->tile_storage_id(store, mapname, "", x, y, z, name));
}
g_logger(G_LOG_LEVEL_MESSAGE, "delete: %s", store->tile_storage_id(store, mapname, "", x, y, z, name));
store->metatile_delete(store, mapname, x, y, z);
num_unlink++;
} else if (touchFrom != -1 && z >= touchFrom) {
if (verbose) {
printf("touch: %s\n", store->tile_storage_id(store, mapname, "", x, y, z, name));
}
g_logger(G_LOG_LEVEL_MESSAGE, "touch: %s", store->tile_storage_id(store, mapname, "", x, y, z, name));
store->metatile_expire(store, mapname, x, y, z);
num_touch++;
} else if (doRender) {
printf("render: %s\n", store->tile_storage_id(store, mapname, "", x, y, z, name));
g_logger(G_LOG_LEVEL_MESSAGE, "render: %s", store->tile_storage_id(store, mapname, "", x, y, z, name));
enqueue(mapname, x, y, z);
num_render++;
}
/*
if (!(num_render % 10))
{
gettimeofday(&end, NULL);
printf("\n");
printf("Meta tiles rendered: ");
display_rate(start, end, num_render);
printf("Total tiles rendered: ");
display_rate(start, end, num_render * METATILE * METATILE);
printf("Total tiles in input: %d\n", num_read);
printf("Total tiles expanded from input: %d\n", num_all);
printf("Total tiles ignored (not on disk): %d\n", num_ignore);
}
*/
} else {
if (verbose) {
printf("not on disk: %s\n", store->tile_storage_id(store, mapname, "", x, y, z, name));
g_logger(G_LOG_LEVEL_MESSAGE, "not on disk: %s", store->tile_storage_id(store, mapname, "", x, y, z, name));
}
num_ignore++;
@ -422,36 +449,43 @@ int main(int argc, char **argv)
finish_workers();
}
free(spath);
if (config_file_name_passed) {
free((void *)config_file_name);
}
if (mapname != mapname_default) {
if (mapname_passed) {
free((void *)mapname);
}
if (tile_dir != tile_dir_default) {
if (socketname_passed) {
free((void *)socketname);
}
if (tile_dir_passed) {
free((void *)tile_dir);
}
store->close_storage(store);
free(store);
for (i = 0; i <= maxZoom - excess_zoomlevels; i++) {
for (int i = 0; i <= max_zoom - excess_zoomlevels; i++) {
free(tile_requested[i]);
}
free(tile_requested);
gettimeofday(&end, NULL);
printf("\nTotal for all tiles rendered\n");
printf("Meta tiles rendered: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Read and expanded %i tiles from list.", num_read);
g_logger(G_LOG_LEVEL_MESSAGE, "Total for all tiles rendered");
g_logger(G_LOG_LEVEL_MESSAGE, "Meta tiles rendered:");
display_rate(start, end, num_render);
printf("Total tiles rendered: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles rendered:");
display_rate(start, end, num_render * METATILE * METATILE);
printf("Total tiles in input: %d\n", num_read);
printf("Total tiles expanded from input: %d\n", num_all);
printf("Total meta tiles deleted: %d\n", num_unlink);
printf("Total meta tiles touched: %d\n", num_touch);
printf("Total tiles ignored (not on disk): %d\n", num_ignore);
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles in input: %d", num_read);
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles expanded from input: %d", num_all);
g_logger(G_LOG_LEVEL_MESSAGE, "Total meta tiles deleted: %d", num_unlink);
g_logger(G_LOG_LEVEL_MESSAGE, "Total meta tiles touched: %d", num_touch);
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles ignored (not on disk): %d", num_ignore);
return 0;
}

View File

@ -15,35 +15,23 @@
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <getopt.h>
#include <glib.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/un.h>
#include <poll.h>
#include <errno.h>
#include <math.h>
#include <getopt.h>
#include <time.h>
#include <limits.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <pthread.h>
#include "g_logger.h"
#include "gen_tile.h"
#include "protocol.h"
#include "config.h"
#include "g_logger.h"
#include "protocol.h"
#include "render_config.h"
#include "store.h"
#include "sys_utils.h"
#include "render_submit_queue.h"
const char * tile_dir_default = RENDERD_TILE_DIR;
#include "renderd_config.h"
#include "store.h"
#ifndef METATILE
#warning("render_list not implemented for non-metatile mode. Feel free to submit fix")
@ -54,67 +42,67 @@ int main(int argc, char **argv)
}
#else
static int minZoom = 0;
static int maxZoom = MAX_ZOOM;
static int verbose = 0;
static int maxLoad = MAX_LOAD_OLD;
void display_rate(struct timeval start, struct timeval end, int num)
{
int d_s, d_us;
float sec;
d_s = end.tv_sec - start.tv_sec;
d_s = end.tv_sec - start.tv_sec;
d_us = end.tv_usec - start.tv_usec;
sec = d_s + d_us / 1000000.0;
printf("Rendered %d tiles in %.2f seconds (%.2f tiles/s)\n", num, sec, num / sec);
fflush(NULL);
}
int min_max_opt(char *opt_arg, char *opt_type_name, int minimum, int maximum)
{
int opt = atoi(opt_arg);
float opt_float;
if (minimum != -1 && opt < minimum) {
fprintf(stderr, "Invalid %s, must be >= %i (%s was provided)\n", opt_type_name, minimum, opt_arg);
exit(1);
}
if (maximum != -1 && opt > maximum) {
fprintf(stderr, "Invalid %s, must be <= %i (%s was provided)\n", opt_type_name, maximum, opt_arg);
exit(1);
}
if (sscanf(opt_arg, "%f", &opt_float) != 0) {
if ((float) opt != opt_float) {
fprintf(stderr, "Invalid %s, must be an integer (%s was provided)\n", opt_type_name, opt_arg);
exit(1);
}
}
return opt;
g_logger(G_LOG_LEVEL_MESSAGE, "\tRendered %d tiles in %.2f seconds (%.2f tiles/s)", num, sec, num / sec);
}
int main(int argc, char **argv)
{
char *spath = strdup(RENDERD_SOCKET);
const char *config_file_name_default = RENDERD_CONFIG;
const char *mapname_default = XMLCONFIG_DEFAULT;
const char *socketname_default = RENDERD_SOCKET;
const char *tile_dir_default = RENDERD_TILE_DIR;
int max_load_default = MAX_LOAD_OLD;
int max_x_default = -1;
int max_y_default = -1;
int max_zoom_default = 18;
int min_x_default = -1;
int min_y_default = -1;
int min_zoom_default = 0;
int num_threads_default = 1;
const char *config_file_name = config_file_name_default;
const char *mapname = mapname_default;
const char *socketname = socketname_default;
const char *tile_dir = tile_dir_default;
int minX = -1, maxX = -1, minY = -1, maxY = -1;
int max_load = max_load_default;
int max_x = max_x_default;
int max_y = max_y_default;
int max_zoom = max_zoom_default;
int min_x = min_x_default;
int min_y = min_y_default;
int min_zoom = min_zoom_default;
int num_threads = num_threads_default;
int config_file_name_passed = 0;
int mapname_passed = 0;
int socketname_passed = 0;
int tile_dir_passed = 0;
int max_load_passed = 0;
int max_x_passed = 0;
int max_y_passed = 0;
int max_zoom_passed = 0;
int min_x_passed = 0;
int min_y_passed = 0;
int min_zoom_passed = 0;
int num_threads_passed = 0;
int x, y, z;
char name[PATH_MAX];
struct timeval start, end;
int num_render = 0, num_all = 0;
int c;
int all = 0;
int numThreads = 1;
int force = 0;
struct storage_backend * store;
int verbose = 0;
struct storage_backend *store;
struct stat_info s;
foreground = 1;
@ -123,6 +111,7 @@ int main(int argc, char **argv)
int option_index = 0;
static struct option long_options[] = {
{"all", no_argument, 0, 'a'},
{"config", required_argument, 0, 'c'},
{"force", no_argument, 0, 'f'},
{"map", required_argument, 0, 'm'},
{"max-load", required_argument, 0, 'l'},
@ -142,81 +131,105 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "afm:l:X:Y:Z:x:y:z:n:s:t:vhV", long_options, &option_index);
int c = getopt_long(argc, argv, "ac:fm:l:X:Y:Z:x:y:z:n:s:t:vhV", long_options, &option_index);
if (c == -1) {
break;
}
switch (c) {
case 'a': /* -a, --all */
case 'a': /* -a, --all */
all = 1;
break;
case 's': /* -s, --socket */
free(spath);
spath = strdup(optarg);
case 'c': /* -c, --config */
config_file_name = strndup(optarg, PATH_MAX);
config_file_name_passed = 1;
struct stat buffer;
if (stat(config_file_name, &buffer) != 0) {
g_logger(G_LOG_LEVEL_CRITICAL, "Config file '%s' does not exist, please specify a valid file", config_file_name);
return 1;
}
break;
case 't': /* -t, --tile-dir */
tile_dir = strdup(optarg);
break;
case 'm': /* -m, --map */
mapname = strdup(optarg);
break;
case 'l': /* -l, --max-load */
maxLoad = min_max_opt(optarg, "maximum load", 0, -1);
break;
case 'n': /* -n, --num-threads */
numThreads = min_max_opt(optarg, "number of threads", 1, -1);
break;
case 'x': /* -x, --min-x */
minX = min_max_opt(optarg, "minimum X tile coordinate", 0, -1);
break;
case 'X': /* -X, --max-x */
maxX = min_max_opt(optarg, "maximum X tile coordinate", 0, -1);
break;
case 'y': /* -y, --min-y */
minY = min_max_opt(optarg, "minimum Y tile coordinate", 0, -1);
break;
case 'Y': /* -Y, --max-y */
maxY = min_max_opt(optarg, "maximum Y tile coordinate", 0, -1);
break;
case 'z': /* -z, --min-zoom */
minZoom = min_max_opt(optarg, "minimum zoom", 0, MAX_ZOOM);
break;
case 'Z': /* -Z, --max-zoom */
maxZoom = min_max_opt(optarg, "maximum zoom", 0, MAX_ZOOM);
break;
case 'f': /* -f, --force */
case 'f': /* -f, --force */
force = 1;
break;
case 'v': /* -v, --verbose */
case 'm': /* -m, --map */
mapname = strndup(optarg, XMLCONFIG_MAX);
mapname_passed = 1;
break;
case 'l': /* -l, --max-load */
max_load = min_max_int_opt(optarg, "maximum load", 0, -1);
max_load_passed = 1;
break;
case 'X': /* -X, --max-x */
max_x = min_max_int_opt(optarg, "maximum X tile coordinate", 0, -1);
max_x_passed = 1;
break;
case 'Y': /* -Y, --max-y */
max_y = min_max_int_opt(optarg, "maximum Y tile coordinate", 0, -1);
max_y_passed = 1;
break;
case 'Z': /* -Z, --max-zoom */
max_zoom = min_max_int_opt(optarg, "maximum zoom", 0, MAX_ZOOM);
max_zoom_passed = 1;
break;
case 'x': /* -x, --min-x */
min_x = min_max_int_opt(optarg, "minimum X tile coordinate", 0, -1);
min_x_passed = 1;
break;
case 'y': /* -y, --min-y */
min_y = min_max_int_opt(optarg, "minimum Y tile coordinate", 0, -1);
min_y_passed = 1;
break;
case 'z': /* -z, --min-zoom */
min_zoom = min_max_int_opt(optarg, "minimum zoom", 0, MAX_ZOOM);
min_zoom_passed = 1;
break;
case 'n': /* -n, --num-threads */
num_threads = min_max_int_opt(optarg, "number of threads", 1, -1);
num_threads_passed = 1;
break;
case 's': /* -s, --socket */
socketname = strndup(optarg, PATH_MAX);
socketname_passed = 1;
break;
case 't': /* -t, --tile-dir */
tile_dir = strndup(optarg, PATH_MAX);
tile_dir_passed = 1;
break;
case 'v': /* -v, --verbose */
verbose = 1;
break;
case 'h': /* -h, --help */
case 'h': /* -h, --help */
fprintf(stderr, "Usage: render_list [OPTION] ...\n");
fprintf(stderr, " -a, --all render all tiles in given zoom level range instead of reading from STDIN\n");
fprintf(stderr, " -c, --config=CONFIG specify the renderd config file (default is off)\n");
fprintf(stderr, " -f, --force render tiles even if they seem current\n");
fprintf(stderr, " -l, --max-load=LOAD sleep if load is this high (defaults to %d)\n", MAX_LOAD_OLD);
fprintf(stderr, " -m, --map=MAP render tiles in this map (defaults to '" XMLCONFIG_DEFAULT "')\n");
fprintf(stderr, " -n, --num-threads=N the number of parallel request threads (default 1)\n");
fprintf(stderr, " -s, --socket=SOCKET|HOSTNAME:PORT unix domain socket name or hostname and port for contacting renderd\n");
fprintf(stderr, " -t, --tile-dir tile cache directory (defaults to '" RENDERD_TILE_DIR "')\n");
fprintf(stderr, " -Z, --max-zoom=ZOOM filter input to only render tiles less than or equal to this zoom level (default is %d)\n", MAX_ZOOM);
fprintf(stderr, " -z, --min-zoom=ZOOM filter input to only render tiles greater or equal to this zoom level (default is 0)\n");
fprintf(stderr, " -l, --max-load=LOAD sleep if load is this high (default is '%d')\n", max_load_default);
fprintf(stderr, " -m, --map=MAP render tiles in this map (default is '%s')\n", mapname_default);
fprintf(stderr, " -l, --max-load=LOAD sleep if load is this high (default is '%d')\n", max_load_default);
fprintf(stderr, " -s, --socket=SOCKET|HOSTNAME:PORT unix domain socket name or hostname and port for contacting renderd (default is '%s')\n", socketname_default);
fprintf(stderr, " -t, --tile-dir=TILE_DIR tile cache directory (default is '%s')\n", tile_dir_default);
fprintf(stderr, " -Z, --max-zoom=ZOOM filter input to only render tiles less than or equal to this zoom level (default is '%d')\n", max_zoom_default);
fprintf(stderr, " -z, --min-zoom=ZOOM filter input to only render tiles greater than or equal to this zoom level (default is '%d')\n", min_zoom_default);
fprintf(stderr, "\n");
fprintf(stderr, "If you are using --all, you can restrict the tile range by adding these options:\n");
fprintf(stderr, " (please note that tile coordinates must be positive integers and are not latitude and longitude values)\n");
@ -236,85 +249,137 @@ int main(int argc, char **argv)
fprintf(stderr, " 1 0 1\n");
fprintf(stderr, " 1 1 1\n");
fprintf(stderr, "The above would cause all 4 tiles at zoom 1 to be rendered\n");
exit(0);
return 0;
case 'V':
case 'V': /* -V, --version */
fprintf(stdout, "%s\n", VERSION);
exit(0);
return 0;
default:
fprintf(stderr, "unhandled char '%c'\n", c);
exit(1);
g_logger(G_LOG_LEVEL_CRITICAL, "unhandled char '%c'", c);
return 1;
}
}
if (maxZoom < minZoom) {
fprintf(stderr, "Invalid zoom range, max zoom must be greater or equal to minimum zoom\n");
if (max_zoom < min_zoom) {
g_logger(G_LOG_LEVEL_CRITICAL, "Specified min zoom (%i) is larger than max zoom (%i).", min_zoom, max_zoom);
return 1;
}
if (config_file_name_passed) {
int map_section_num = -1;
process_config_file(config_file_name, 0, G_LOG_LEVEL_DEBUG);
for (int i = 0; i < XMLCONFIGS_MAX; ++i) {
if (maps[i].xmlname && strcmp(maps[i].xmlname, mapname) == 0) {
map_section_num = i;
}
}
if (map_section_num < 0) {
g_logger(G_LOG_LEVEL_CRITICAL, "Map section '%s' does not exist in config file '%s'.", mapname, config_file_name);
return 1;
}
if (!max_zoom_passed) {
max_zoom = maps[map_section_num].max_zoom;
max_zoom_passed = 1;
}
if (!min_zoom_passed) {
min_zoom = maps[map_section_num].min_zoom;
min_zoom_passed = 1;
}
if (!num_threads_passed) {
num_threads = maps[map_section_num].num_threads;
num_threads_passed = 1;
}
if (!socketname_passed) {
socketname = strndup(config.socketname, PATH_MAX);
socketname_passed = 1;
}
if (!tile_dir_passed) {
tile_dir = strndup(maps[map_section_num].tile_dir, PATH_MAX);
tile_dir_passed = 1;
}
}
store = init_storage_backend(tile_dir);
if (store == NULL) {
fprintf(stderr, "Failed to initialise storage backend %s\n", tile_dir);
g_logger(G_LOG_LEVEL_CRITICAL, "Failed to initialise storage backend %s", tile_dir);
return 1;
}
if (all) {
if ((minX != -1 || minY != -1 || maxX != -1 || maxY != -1) && minZoom != maxZoom) {
fprintf(stderr, "min-zoom must be equal to max-zoom when using min-x, max-x, min-y, or max-y options\n");
if ((min_x != -1 || min_y != -1 || max_x != -1 || max_y != -1) && min_zoom != max_zoom) {
g_logger(G_LOG_LEVEL_CRITICAL, "min-zoom must be equal to max-zoom when using min-x, max-x, min-y, or max-y options");
return 1;
}
if (minX == -1) {
minX = 0;
if (min_x == -1) {
min_x = 0;
}
if (minY == -1) {
minY = 0;
if (min_y == -1) {
min_y = 0;
}
int lz = (1 << minZoom) - 1;
int lz = (1 << min_zoom) - 1;
if (minZoom == maxZoom) {
if (maxX == -1) {
maxX = lz;
if (min_zoom == max_zoom) {
if (max_x == -1) {
max_x = lz;
}
if (maxY == -1) {
maxY = lz;
if (max_y == -1) {
max_y = lz;
}
if (minX > lz || minY > lz || maxX > lz || maxY > lz) {
fprintf(stderr, "Invalid range, x and y values must be <= %d (2^zoom-1)\n", lz);
if (min_x > lz || min_y > lz || max_x > lz || max_y > lz) {
g_logger(G_LOG_LEVEL_CRITICAL, "Invalid range, x and y values must be <= %d (2^zoom-1)", lz);
return 1;
}
}
if (minX < 0 || minY < 0 || maxX < -1 || maxY < -1) {
fprintf(stderr, "Invalid range, x and y values must be >= 0\n");
if (min_x < 0 || min_y < 0 || max_x < -1 || max_y < -1) {
g_logger(G_LOG_LEVEL_CRITICAL, "Invalid range, x and y values must be >= 0");
return 1;
}
}
fprintf(stderr, "Rendering client\n");
g_logger(G_LOG_LEVEL_INFO, "Started render_list with the following options:");
if (config_file_name_passed) {
g_logger(G_LOG_LEVEL_INFO, "\t--config = '%s' (user-specified)", config_file_name);
}
g_logger(G_LOG_LEVEL_INFO, "\t--map = '%s' (%s)", mapname, mapname_passed ? "user-specified" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--max-load = '%i' (%s)", max_load, max_load_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--max-zoom = '%i' (%s)", max_zoom, max_zoom_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--min-zoom = '%i' (%s)", min_zoom, min_zoom_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--num-threads = '%i' (%s)", num_threads, num_threads_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--socket = '%s' (%s)", socketname, socketname_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--tile-dir = '%s' (%s)", tile_dir, tile_dir_passed ? "user-specified/from config" : "default");
gettimeofday(&start, NULL);
spawn_workers(numThreads, spath, maxLoad);
spawn_workers(num_threads, socketname, max_load);
if (all) {
int x, y, z;
printf("Rendering all tiles from zoom %d to zoom %d\n", minZoom, maxZoom);
g_logger(G_LOG_LEVEL_MESSAGE, "Rendering all tiles from zoom %d to zoom %d", min_zoom, max_zoom);
for (z = minZoom; z <= maxZoom; z++) {
int current_maxX = (maxX == -1) ? (1 << z) - 1 : maxX;
int current_maxY = (maxY == -1) ? (1 << z) - 1 : maxY;
printf("Rendering all tiles for zoom %d from (%d, %d) to (%d, %d)\n", z, minX, minY, current_maxX, current_maxY);
for (z = min_zoom; z <= max_zoom; z++) {
int current_max_x = (max_x == -1) ? (1 << z) - 1 : max_x;
int current_max_y = (max_y == -1) ? (1 << z) - 1 : max_y;
g_logger(G_LOG_LEVEL_MESSAGE, "Rendering all tiles for zoom %d from (%d, %d) to (%d, %d)", z, min_x, min_y, current_max_x, current_max_y);
for (x = minX; x <= current_maxX; x += METATILE) {
for (y = minY; y <= current_maxY; y += METATILE) {
for (x = min_x; x <= current_max_x; x += METATILE) {
for (y = min_y; y <= current_max_y; y += METATILE) {
if (!force) {
s = store->tile_stat(store, mapname, "", x, y, z);
}
@ -325,7 +390,6 @@ int main(int argc, char **argv)
}
num_all++;
}
}
}
@ -333,28 +397,28 @@ int main(int argc, char **argv)
while (!feof(stdin)) {
int n = fscanf(stdin, "%d %d %d", &x, &y, &z);
if (verbose)
if (n != 3) {
// Discard input line
char tmp[1024];
char *r = fgets(tmp, sizeof(tmp), stdin);
if (n != 3) {
// Discard input line
char tmp[1024];
char *r = fgets(tmp, sizeof(tmp), stdin);
if (!r) {
continue;
}
fprintf(stderr, "bad line %d: %s", num_all, tmp);
if (!r) {
continue;
}
if (verbose) {
printf("got: x(%d) y(%d) z(%d)\n", x, y, z);
if (verbose) {
g_logger(G_LOG_LEVEL_WARNING, "bad line %d: %s", num_all, tmp);
}
continue;
}
if (z < minZoom || z > maxZoom) {
printf("Ignoring tile, zoom %d outside valid range (%d..%d)\n", z, minZoom, maxZoom);
if (verbose) {
g_logger(G_LOG_LEVEL_MESSAGE, "got: x(%d) y(%d) z(%d)", x, y, z);
}
if (z < min_zoom || z > max_zoom) {
g_logger(G_LOG_LEVEL_MESSAGE, "Ignoring tile, zoom %d outside valid range (%d..%d)", z, min_zoom, max_zoom);
continue;
}
@ -372,46 +436,50 @@ int main(int argc, char **argv)
// Attempts to adjust the stats for the QMAX tiles which are likely in the queue
if (!(num_render % 10)) {
gettimeofday(&end, NULL);
printf("\n");
printf("Meta tiles rendered: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Meta tiles rendered:");
display_rate(start, end, num_render);
printf("Total tiles rendered: ");
display_rate(start, end, (num_render) * METATILE * METATILE);
printf("Total tiles handled from input: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles rendered:");
display_rate(start, end, num_render * METATILE * METATILE);
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles handled:");
display_rate(start, end, num_all);
}
} else {
if (verbose) {
printf("Tile %s is clean, ignoring\n", store->tile_storage_id(store, mapname, "", x, y, z, name));
char name[PATH_MAX];
g_logger(G_LOG_LEVEL_MESSAGE, "Tile %s is clean, ignoring", store->tile_storage_id(store, mapname, "", x, y, z, name));
}
}
}
}
store->close_storage(store);
free(store);
finish_workers();
free(spath);
if (config_file_name_passed) {
free((void *)config_file_name);
}
if (mapname != mapname_default) {
if (mapname_passed) {
free((void *)mapname);
}
if (tile_dir != tile_dir_default) {
if (socketname_passed) {
free((void *)socketname);
}
if (tile_dir_passed) {
free((void *)tile_dir);
}
store->close_storage(store);
free(store);
gettimeofday(&end, NULL);
printf("\n*****************************************************\n");
printf("*****************************************************\n");
printf("Total for all tiles rendered\n");
printf("Meta tiles rendered: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Total for all tiles rendered");
g_logger(G_LOG_LEVEL_MESSAGE, "Meta tiles rendered:");
display_rate(start, end, num_render);
printf("Total tiles rendered: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles rendered:");
display_rate(start, end, num_render * METATILE * METATILE);
printf("Total tiles handled: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles handled:");
display_rate(start, end, num_all);
print_statistics();

View File

@ -15,37 +15,27 @@
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <dirent.h>
#include <errno.h>
#include <getopt.h>
#include <glib.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/un.h>
#include <poll.h>
#include <errno.h>
#include <math.h>
#include <getopt.h>
#include <time.h>
#include <sys/types.h>
#include <dirent.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "g_logger.h"
#include "gen_tile.h"
#include "protocol.h"
#include "config.h"
#include "g_logger.h"
#include "protocol.h"
#include "render_config.h"
#include "store_file_utils.h"
#include "render_submit_queue.h"
#include "renderd_config.h"
#include "store_file_utils.h"
#include "sys_utils.h"
const char * tile_dir_default = RENDERD_TILE_DIR;
#ifndef METATILE
#warning("render_old not implemented for non-metatile mode. Feel free to submit fix")
int main(int argc, char **argv)
@ -55,35 +45,28 @@ int main(int argc, char **argv)
}
#else
#define INILINE_MAX 256
static int minZoom = 0;
static int maxZoom = MAX_ZOOM;
static int verbose = 0;
static int num_render = 0, num_all = 0;
static int max_load = MAX_LOAD_OLD;
static time_t planetTime;
static int max_load;
static time_t planet_timestamp = 0;
static struct timeval start, end;
void display_rate(struct timeval start, struct timeval end, int num)
{
int d_s, d_us;
float sec;
d_s = end.tv_sec - start.tv_sec;
d_s = end.tv_sec - start.tv_sec;
d_us = end.tv_usec - start.tv_usec;
sec = d_s + d_us / 1000000.0;
printf("%d tiles in %.2f seconds (%.2f tiles/s)\n", num, sec, num / sec);
fflush(NULL);
g_logger(G_LOG_LEVEL_MESSAGE, "\tRendered %d tiles in %.2f seconds (%.2f tiles/s)", num, sec, num / sec);
}
static time_t getPlanetTime(const char *tile_dir)
static time_t get_planet_time(const char *tile_dir)
{
static time_t last_check;
static time_t planet_timestamp;
static time_t planet_time;
time_t now = time(NULL);
struct stat buf;
char filename[PATH_MAX];
@ -92,23 +75,23 @@ static time_t getPlanetTime(const char *tile_dir)
// Only check for updates periodically
if (now < last_check + 300) {
return planet_timestamp;
return planet_time;
}
last_check = now;
if (stat(filename, &buf)) {
fprintf(stderr, "Planet timestamp file (%s) is missing\n", filename);
g_logger(G_LOG_LEVEL_MESSAGE, "Planet timestamp file (%s) is missing", filename);
// Make something up
planet_timestamp = now - 3 * 24 * 60 * 60;
planet_time = now - 3 * 24 * 60 * 60;
} else {
if (buf.st_mtime != planet_timestamp) {
printf("Planet file updated at %s", ctime(&buf.st_mtime));
planet_timestamp = buf.st_mtime;
if (buf.st_mtime != planet_time) {
g_logger(G_LOG_LEVEL_MESSAGE, "Planet file updated at %s", strtok(ctime(&buf.st_mtime), "\n"));
planet_time = buf.st_mtime;
}
}
return planet_timestamp;
return planet_time;
}
static void check_load(void)
@ -116,7 +99,7 @@ static void check_load(void)
double avg = get_load_avg();
while (avg >= max_load) {
printf("Load average %f, sleeping\n", avg);
g_logger(G_LOG_LEVEL_MESSAGE, "Load average %f, sleeping", avg);
sleep(5);
avg = get_load_avg();
}
@ -131,7 +114,7 @@ static void descend(const char *tile_dir, const char *search)
int x, y, z;
if (!tiles) {
fprintf(stderr, "Unable to open directory: %s\n", search);
g_logger(G_LOG_LEVEL_DEBUG, "%s: %s", strerror(errno), search);
return;
}
@ -159,43 +142,65 @@ static void descend(const char *tile_dir, const char *search)
p = strrchr(path, '.');
if (p && !strcmp(p, ".meta")) {
num_all++;
if (planetTime > b.st_mtime) {
if (planet_timestamp > b.st_mtime) {
// request rendering of old tile
path_to_xyz(tile_dir, path, mapname, &x, &y, &z);
enqueue(mapname, x, y, z);
num_render++;
}
num_all++;
}
}
closedir(tiles);
}
void render_layer(const char *tilepath, const char *name)
void render_layer(const char *tile_dir, const char *mapname, int min_zoom, int max_zoom, int verbose)
{
int z;
for (z = minZoom; z <= maxZoom; z++) {
for (int z = min_zoom; z <= max_zoom; z++) {
if (verbose) {
printf("Rendering zoom %d\n", z);
g_logger(G_LOG_LEVEL_MESSAGE, "Rendering zoom %d", z);
}
char path[PATH_MAX];
snprintf(path, PATH_MAX, "%s/%s/%d", tilepath, name, z);
descend(tilepath, path);
char search[PATH_MAX];
snprintf(search, PATH_MAX, "%s/%s/%d", tile_dir, mapname, z);
descend(tile_dir, search);
}
}
int main(int argc, char **argv)
{
char spath[PATH_MAX] = RENDERD_SOCKET;
char *config_file = RENDERD_CONFIG;
const char *config_file_name_default = RENDERD_CONFIG;
const char *mapname_default = XMLCONFIG_DEFAULT;
const char *socketname_default = RENDERD_SOCKET;
const char *tile_dir_default = RENDERD_TILE_DIR;
int max_load_default = MAX_LOAD_OLD;
int max_zoom_default = 18;
int min_zoom_default = 0;
int num_threads_default = 1;
const char *config_file_name = config_file_name_default;
const char *mapname = mapname_default;
const char *socketname = socketname_default;
const char *tile_dir = tile_dir_default;
char *map = NULL;
int c;
int numThreads = 1;
max_load = max_load_default;
int max_zoom = max_zoom_default;
int min_zoom = min_zoom_default;
int num_threads = num_threads_default;
int config_file_name_passed = 0;
int mapname_passed = 0;
int socketname_passed = 0;
int tile_dir_passed = 0;
int max_load_passed = 0;
int max_zoom_passed = 0;
int min_zoom_passed = 0;
int num_threads_passed = 0;
int map_section_num = -1;
int dd, mm, yy;
int verbose = 0;
struct tm tm;
foreground = 1;
@ -219,72 +224,62 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "c:m:l:Z:z:n:s:t:T:vhV", long_options, &option_index);
int c = getopt_long(argc, argv, "c:m:l:Z:z:n:s:t:T:vhV", long_options, &option_index);
if (c == -1) {
break;
}
switch (c) {
case 's': /* -s, --socket */
strncpy(spath, optarg, PATH_MAX - 1);
spath[PATH_MAX - 1] = 0;
break;
case 'c': /* -c, --config */
config_file_name = strndup(optarg, PATH_MAX);
config_file_name_passed = 1;
case 't': /* -t, --tile-dir */
tile_dir = strdup(optarg);
break;
struct stat buffer;
case 'c': /* -c, --config */
config_file = strdup(optarg);
break;
case 'm': /* -m, --map */
map = strdup(optarg);
break;
case 'n': /* -n, --num-threads */
numThreads = atoi(optarg);
if (numThreads <= 0) {
fprintf(stderr, "Invalid number of threads, must be at least 1\n");
if (stat(config_file_name, &buffer) != 0) {
g_logger(G_LOG_LEVEL_CRITICAL, "Config file '%s' does not exist, please specify a valid file", config_file_name);
return 1;
}
break;
case 'z': /* -z, --min-zoom */
minZoom = atoi(optarg);
if (minZoom < 0 || minZoom > MAX_ZOOM) {
fprintf(stderr, "Invalid minimum zoom selected, must be between 0 and %d\n", MAX_ZOOM);
return 1;
}
case 'm': /* -m, --map */
mapname = strndup(optarg, XMLCONFIG_MAX);
mapname_passed = 1;
break;
case 'Z': /* -Z, --max-zoom */
maxZoom = atoi(optarg);
if (maxZoom < 0 || maxZoom > MAX_ZOOM) {
fprintf(stderr, "Invalid maximum zoom selected, must be between 0 and %d\n", MAX_ZOOM);
return 1;
}
case 'l': /* -l, --max-load */
max_load = min_max_int_opt(optarg, "maximum load", 0, -1);
max_load_passed = 1;
break;
case 'l':
max_load = atoi(optarg);
case 'Z': /* -Z, --max-zoom */
max_zoom = min_max_int_opt(optarg, "maximum zoom", 0, MAX_ZOOM);
max_zoom_passed = 1;
break;
if (max_load < 0) {
fprintf(stderr, "Invalid maximum load specified, must be greater than 0\n");
return 1;
}
case 'z': /* -z, --min-zoom */
min_zoom = min_max_int_opt(optarg, "minimum zoom", 0, MAX_ZOOM);
min_zoom_passed = 1;
break;
case 'n': /* -n, --num-threads */
num_threads = min_max_int_opt(optarg, "number of threads", 1, -1);
num_threads_passed = 1;
break;
case 's': /* -s, --socket */
socketname = strndup(optarg, PATH_MAX);
socketname_passed = 1;
break;
case 't': /* -t, --tile-dir */
tile_dir = strndup(optarg, PATH_MAX);
tile_dir_passed = 1;
break;
case 'T':
if (sscanf(optarg, "%d/%d/%d", &dd, &mm, &yy) == 3) {
if (yy > 100) {
yy -= 1900;
@ -297,114 +292,130 @@ int main(int argc, char **argv)
memset(&tm, 0, sizeof(tm));
tm.tm_mday = dd;
tm.tm_mon = mm - 1;
tm.tm_year = yy;
planetTime = mktime(&tm);
tm.tm_year = yy;
planet_timestamp = mktime(&tm);
} else if (sscanf(optarg, "%d", &dd) == 1) {
planetTime = dd;
planet_timestamp = dd;
} else {
fprintf(stderr, "Invalid planet time stamp, must be a unix timestamp or in the format dd/mm/yyyy\n");
g_logger(G_LOG_LEVEL_CRITICAL, "Invalid planet timestamp, must be a unix timestamp or in the format dd/mm/yyyy");
return 1;
}
break;
case 'v': /* -v, --verbose */
case 'v': /* -v, --verbose */
verbose = 1;
break;
case 'h': /* -h, --help */
case 'h': /* -h, --help */
fprintf(stderr, "Usage: render_old [OPTION] ...\n");
fprintf(stderr, "Search the rendered tiles and re-render tiles which are older then the last planet import\n");
fprintf(stderr, " -c, --config=CONFIG specify the renderd config file\n");
fprintf(stderr, " -l, --max-load=LOAD maximum system load with which requests are submitted\n");
fprintf(stderr, " -m, --map=STYLE Instead of going through all styls of CONFIG, only use a specific map-style\n");
fprintf(stderr, " -n, --num-threads=N the number of parallel request threads (default 1)\n");
fprintf(stderr, " -s, --socket=SOCKET|HOSTNAME:PORT unix domain socket name or hostname and port for contacting renderd\n");
fprintf(stderr, " -t, --tile-dir tile cache directory (defaults to '" RENDERD_TILE_DIR "')\n");
fprintf(stderr, " -c, --config=CONFIG specify the renderd config file (default is '%s')\n", config_file_name_default);
fprintf(stderr, " -l, --max-load=LOAD sleep if load is this high (default is '%d')\n", max_load_default);
fprintf(stderr, " -m, --map=STYLE Instead of going through all styles of CONFIG, only use a specific map-style\n");
fprintf(stderr, " -n, --num-threads=N the number of parallel request threads (default is '%d')\n", num_threads_default);
fprintf(stderr, " -s, --socket=SOCKET|HOSTNAME:PORT unix domain socket name or hostname and port for contacting renderd (default is '%s')\n", socketname_default);
fprintf(stderr, " -t, --tile-dir=TILE_DIR tile cache directory (default is '%s')\n", tile_dir_default);
fprintf(stderr, " -T, --timestamp=DD/MM/YY Overwrite the assumed data of the planet import\n");
fprintf(stderr, " -Z, --max-zoom=ZOOM filter input to only render tiles less than or equal to this zoom level (default is %d)\n", MAX_ZOOM);
fprintf(stderr, " -z, --min-zoom=ZOOM filter input to only render tiles greater or equal to this zoom level (default is 0)\n");
fprintf(stderr, " -Z, --max-zoom=ZOOM filter input to only render tiles less than or equal to this zoom level (default is '%d')\n", max_zoom_default);
fprintf(stderr, " -z, --min-zoom=ZOOM filter input to only render tiles greater than or equal to this zoom level (default is '%d')\n", min_zoom_default);
fprintf(stderr, "\n");
fprintf(stderr, " -h, --help display this help and exit\n");
fprintf(stderr, " -V, --version display the version number and exit\n");
exit(0);
return 0;
case 'V':
case 'V': /* -V, --version */
fprintf(stdout, "%s\n", VERSION);
exit(0);
return 0;
default:
fprintf(stderr, "unhandled char '%c'\n", c);
exit(1);
g_logger(G_LOG_LEVEL_CRITICAL, "unhandled char '%c'", c);
return 1;
}
}
if (maxZoom < minZoom) {
fprintf(stderr, "Invalid zoom range, max zoom must be greater or equal to minimum zoom\n");
if (max_zoom < min_zoom) {
g_logger(G_LOG_LEVEL_CRITICAL, "Specified min zoom (%i) is larger than max zoom (%i).", min_zoom, max_zoom);
return 1;
}
fprintf(stderr, "Rendering old tiles\n");
process_config_file(config_file_name, 0, G_LOG_LEVEL_DEBUG);
if (planetTime == 0) {
planetTime = getPlanetTime(tile_dir);
for (int i = 0; i < XMLCONFIGS_MAX; ++i) {
if (mapname_passed && maps[i].xmlname && strcmp(maps[i].xmlname, mapname) == 0) {
map_section_num = i;
}
}
if (mapname_passed && map_section_num < 0) {
g_logger(G_LOG_LEVEL_CRITICAL, "Map section '%s' does not exist in config file '%s'.", mapname, config_file_name);
return 1;
}
if (!socketname_passed) {
socketname = strndup(config.socketname, PATH_MAX);
socketname_passed = 1;
}
g_logger(G_LOG_LEVEL_INFO, "Started render_old with the following options:");
g_logger(G_LOG_LEVEL_INFO, "\t--config = '%s' (%s)", config_file_name, config_file_name_passed ? "user-specified" : "default");
if (mapname_passed) {
g_logger(G_LOG_LEVEL_INFO, "\t--map = '%s' (user-specified)", mapname);
}
g_logger(G_LOG_LEVEL_INFO, "\t--max-load = '%i' (%s)", max_load, max_load_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--max-zoom = '%i' (%s)", max_zoom, max_zoom_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--min-zoom = '%i' (%s)", min_zoom, min_zoom_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--num-threads = '%i' (%s)", num_threads, num_threads_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--socket = '%s' (%s)", socketname, socketname_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--tile-dir = '%s' (%s)", tile_dir, tile_dir_passed ? "user-specified/from config" : "default");
if (planet_timestamp == 0) {
planet_timestamp = get_planet_time(tile_dir);
} else {
printf("Overwriting planet file update to %s", ctime(&planetTime));
g_logger(G_LOG_LEVEL_MESSAGE, "Overwriting planet file update to %s", strtok(ctime(&planet_timestamp), "\n"));
}
gettimeofday(&start, NULL);
FILE * hini ;
char line[INILINE_MAX];
char value[INILINE_MAX];
spawn_workers(num_threads, socketname, max_load);
// Load the config
if ((hini = fopen(config_file, "r")) == NULL) {
fprintf(stderr, "Config: cannot open %s\n", config_file);
exit(7);
}
spawn_workers(numThreads, spath, max_load);
if (map) {
render_layer(tile_dir, map);
} else {
while (fgets(line, INILINE_MAX, hini) != NULL) {
if (line[0] == '[') {
if (strlen(line) >= XMLCONFIG_MAX) {
fprintf(stderr, "XML name too long: %s\n", line);
exit(7);
}
if (sscanf(line, "[%[^]]", value) != 1) {
fprintf(stderr, "Config: malformed config file on line %s\n", line);
exit(7);
};
// Skip mapnik & renderd sections which are config, not tile layers
if (strcmp(value, "mapnik") && strncmp(value, "renderd", 7)) {
render_layer(tile_dir, value);
}
}
for (int i = 0; i < XMLCONFIGS_MAX; ++i) {
if (mapname_passed && maps[i].xmlname && strcmp(maps[i].xmlname, mapname) != 0) {
continue;
}
}
fclose(hini);
free(map);
if (maps[i].xmlname != NULL) {
if (!max_zoom_passed) {
max_zoom = maps[i].max_zoom;
}
if (tile_dir != tile_dir_default) {
free((void *)tile_dir);
if (!min_zoom_passed) {
min_zoom = maps[i].min_zoom;
}
if (!tile_dir_passed) {
tile_dir = strndup(maps[i].tile_dir, PATH_MAX);
}
if (verbose) {
g_logger(G_LOG_LEVEL_MESSAGE, "Rendering map '%s' from zoom '%i' to zoom '%i'", maps[i].xmlname, min_zoom, max_zoom);
}
render_layer(tile_dir, maps[i].xmlname, min_zoom, max_zoom, verbose);
}
}
finish_workers();
gettimeofday(&end, NULL);
printf("\nTotal for all tiles rendered\n");
printf("Meta tiles rendered: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Total for all tiles rendered");
g_logger(G_LOG_LEVEL_MESSAGE, "Meta tiles rendered:");
display_rate(start, end, num_render);
printf("Total tiles rendered: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles rendered:");
display_rate(start, end, num_render * METATILE * METATILE);
printf("Total tiles handled: ");
g_logger(G_LOG_LEVEL_MESSAGE, "Total tiles handled:");
display_rate(start, end, num_all);
return 0;

View File

@ -15,32 +15,24 @@
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <getopt.h>
#include <glib.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/un.h>
#include <poll.h>
#include <errno.h>
#include <math.h>
#include <limits.h>
#include <string.h>
#include <strings.h>
#include <getopt.h>
#include <unistd.h>
#include "g_logger.h"
#include "gen_tile.h"
#include "protocol.h"
#include "config.h"
#include "g_logger.h"
#include "render_config.h"
#include "render_submit_queue.h"
#include "renderd_config.h"
#define DEG_TO_RAD (M_PI/180)
#define RAD_TO_DEG (180/M_PI)
#define DEG_TO_RAD (M_PI / 180)
#define RAD_TO_DEG (180 / M_PI)
#ifndef METATILE
#warning("Speed test not implemented for non-metatile mode. Feel free to submit fix")
@ -72,7 +64,6 @@ static double boundx1 = 3.2;
static double boundy1 = 58.8;
#endif
static double minmax(double a, double b, double c)
{
a = MAX(a, b);
@ -124,37 +115,48 @@ void display_rate(struct timeval start, struct timeval end, int num)
int d_s, d_us;
float sec;
d_s = end.tv_sec - start.tv_sec;
d_s = end.tv_sec - start.tv_sec;
d_us = end.tv_usec - start.tv_usec;
sec = d_s + d_us / 1000000.0;
printf("Rendered %d tiles in %.2f seconds (%.2f tiles/s)\n", num, sec, num / sec);
fflush(NULL);
g_logger(G_LOG_LEVEL_MESSAGE, "\tRendered %d tiles in %.2f seconds (%.2f tiles/s)", num, sec, num / sec);
}
int main(int argc, char **argv)
{
const char *spath = RENDERD_SOCKET;
int fd;
struct sockaddr_un addr;
int ret = 0;
const char *config_file_name_default = RENDERD_CONFIG;
const char *mapname_default = XMLCONFIG_DEFAULT;
const char *socketname_default = RENDERD_SOCKET;
int max_zoom_default = 18;
int min_zoom_default = 0;
int num_threads_default = 1;
const char *config_file_name = config_file_name_default;
const char *mapname = mapname_default;
const char *socketname = socketname_default;
int max_zoom = max_zoom_default;
int min_zoom = min_zoom_default;
int num_threads = num_threads_default;
int config_file_name_passed = 0;
int mapname_passed = 0;
int socketname_passed = 0;
int max_zoom_passed = 0;
int min_zoom_passed = 0;
int num_threads_passed = 0;
int z;
int c;
char name[PATH_MAX];
struct timeval start, end;
struct timeval start_all, end_all;
int num, num_all = 0;
const char * mapname = XMLCONFIG_DEFAULT;
int maxZoom = MAX_ZOOM;
int minZoom = 0;
int numThreads = 1;
int num_all = 0;
foreground = 1;
while (1) {
int option_index = 0;
static struct option long_options[] = {
{"config", required_argument, 0, 'c'},
{"map", required_argument, 0, 'm'},
{"max-zoom", required_argument, 0, 'Z'},
{"min-zoom", required_argument, 0, 'z'},
@ -166,83 +168,135 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "m:Z:z:n:s:hV", long_options, &option_index);
int c = getopt_long(argc, argv, "c:m:Z:z:n:s:hV", long_options, &option_index);
if (c == -1) {
break;
}
switch (c) {
case 's': /* -s, --socket */
spath = strdup(optarg);
break;
case 'c': /* -c, --config */
config_file_name = strndup(optarg, PATH_MAX);
config_file_name_passed = 1;
case 'm': /* -m, --map */
mapname = strdup(optarg);
break;
struct stat buffer;
case 'n': /* -n, --num-threads */
numThreads = atoi(optarg);
if (numThreads <= 0) {
fprintf(stderr, "Invalid number of threads, must be at least 1\n");
if (stat(config_file_name, &buffer) != 0) {
g_logger(G_LOG_LEVEL_CRITICAL, "Config file '%s' does not exist, please specify a valid file", config_file_name);
return 1;
}
break;
case 'z': /* -z, --min-zoom */
minZoom = atoi(optarg);
if (minZoom < 0 || minZoom > MAX_ZOOM) {
fprintf(stderr, "Invalid minimum zoom selected, must be between 0 and %d\n", MAX_ZOOM);
return 1;
}
case 'm': /* -m, --map */
mapname = strndup(optarg, XMLCONFIG_MAX);
mapname_passed = 1;
break;
case 'Z': /* -Z, --max-zoom */
maxZoom = atoi(optarg);
if (maxZoom < 0 || maxZoom > MAX_ZOOM) {
fprintf(stderr, "Invalid maximum zoom selected, must be between 0 and %d\n", MAX_ZOOM);
return 1;
}
case 'Z': /* -Z, --max-zoom */
max_zoom = min_max_int_opt(optarg, "maximum zoom", 0, MAX_ZOOM);
max_zoom_passed = 1;
break;
case 'h': /* -h, --help */
case 'z': /* -z, --min-zoom */
min_zoom = min_max_int_opt(optarg, "minimum zoom", 0, MAX_ZOOM);
min_zoom_passed = 1;
break;
case 'n': /* -n, --num-threads */
num_threads = min_max_int_opt(optarg, "number of threads", 1, -1);
num_threads_passed = 1;
break;
case 's': /* -s, --socket */
socketname = strndup(optarg, PATH_MAX);
socketname_passed = 1;
break;
case 'h': /* -h, --help */
fprintf(stderr, "Usage: render_speedtest [OPTION] ...\n");
fprintf(stderr, " -m, --map=MAP render tiles in this map (defaults to '%s')\n", XMLCONFIG_DEFAULT);
fprintf(stderr, " -n, --num-threads=N the number of parallel request threads (default 1)\n");
fprintf(stderr, " -s, --socket=SOCKET|HOSTNAME:PORT unix domain socket name or hostname and port for contacting renderd\n");
fprintf(stderr, " -Z, --max-zoom=ZOOM only render tiles less than or equal to this zoom level (default is %d)\n", MAX_ZOOM);
fprintf(stderr, " -z, --min-zoom=ZOOM only render tiles greater or equal to this zoom level (default is 0)\n");
fprintf(stderr, " -c, --config=CONFIG specify the renderd config file (default is off)\n");
fprintf(stderr, " -m, --map=MAP render tiles in this map (default is '%s')\n", mapname_default);
fprintf(stderr, " -n, --num-threads=N the number of parallel request threads (default is '%d')\n", num_threads_default);
fprintf(stderr, " -s, --socket=SOCKET|HOSTNAME:PORT unix domain socket name or hostname and port for contacting renderd (default is '%s')\n", socketname_default);
fprintf(stderr, " -Z, --max-zoom=ZOOM only render tiles less than or equal to this zoom level (default is '%d')\n", max_zoom_default);
fprintf(stderr, " -z, --min-zoom=ZOOM only render tiles greater than or equal to this zoom level (default is '%d')\n", min_zoom_default);
fprintf(stderr, "\n");
fprintf(stderr, " -h, --help display this help and exit\n");
fprintf(stderr, " -V, --version display the version number and exit\n");
exit(0);
return 0;
case 'V':
case 'V': /* -V, --version */
fprintf(stdout, "%s\n", VERSION);
exit(0);
return 0;
default:
fprintf(stderr, "unhandled char '%c'\n", c);
exit(1);
g_logger(G_LOG_LEVEL_CRITICAL, "unhandled char '%c'", c);
return 1;
}
}
static GoogleProjection gprj(maxZoom + 1);
if (max_zoom < min_zoom) {
g_logger(G_LOG_LEVEL_CRITICAL, "Specified min zoom (%i) is larger than max zoom (%i).", min_zoom, max_zoom);
return 1;
}
fprintf(stderr, "Rendering client\n");
if (config_file_name_passed) {
int map_section_num = -1;
process_config_file(config_file_name, 0, G_LOG_LEVEL_DEBUG);
spawn_workers(numThreads, spath, 1000);
for (int i = 0; i < XMLCONFIGS_MAX; ++i) {
if (maps[i].xmlname && strcmp(maps[i].xmlname, mapname) == 0) {
map_section_num = i;
}
}
if (map_section_num < 0) {
g_logger(G_LOG_LEVEL_CRITICAL, "Map section '%s' does not exist in config file '%s'.", mapname, config_file_name);
return 1;
}
if (!max_zoom_passed) {
max_zoom = maps[map_section_num].max_zoom;
max_zoom_passed = 1;
}
if (!min_zoom_passed) {
min_zoom = maps[map_section_num].min_zoom;
min_zoom_passed = 1;
}
if (!num_threads_passed) {
num_threads = maps[map_section_num].num_threads;
num_threads_passed = 1;
}
if (!socketname_passed) {
socketname = strndup(config.socketname, PATH_MAX);
socketname_passed = 1;
}
}
g_logger(G_LOG_LEVEL_INFO, "Started render_speedtest with the following options:");
if (config_file_name_passed) {
g_logger(G_LOG_LEVEL_INFO, "\t--config = '%s' (user-specified)", config_file_name);
}
g_logger(G_LOG_LEVEL_INFO, "\t--map = '%s' (%s)", mapname, mapname_passed ? "user-specified" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--max-zoom = '%i' (%s)", max_zoom, max_zoom_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--min-zoom = '%i' (%s)", min_zoom, min_zoom_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--num-threads = '%i' (%s)", num_threads, num_threads_passed ? "user-specified/from config" : "default");
g_logger(G_LOG_LEVEL_INFO, "\t--socket = '%s' (%s)", socketname, socketname_passed ? "user-specified/from config" : "default");
static GoogleProjection gprj(max_zoom + 1);
spawn_workers(num_threads, socketname, 1000);
// Render something to counter act the startup costs
// of obtaining the Postgis table extents
printf("Initial startup costs\n");
g_logger(G_LOG_LEVEL_MESSAGE, "Initial startup costs");
gettimeofday(&start, NULL);
enqueue(mapname, 0, 0, 0);
gettimeofday(&end, NULL);
@ -250,11 +304,12 @@ int main(int argc, char **argv)
gettimeofday(&start_all, NULL);
for (z = minZoom; z <= maxZoom; z++) {
for (z = min_zoom; z <= max_zoom; z++) {
double px0 = boundx0;
double py0 = boundy1;
double px1 = boundx1;
double py1 = boundy0;
gprj.fromLLtoPixel(px0, py0, z);
gprj.fromLLtoPixel(px1, py1, z);
@ -266,13 +321,9 @@ int main(int argc, char **argv)
ymin = (int)(py0 / 256.0);
ymax = (int)(py1 / 256.0);
num = (xmax - xmin + 1) * (ymax - ymin + 1);
// if (!num) {
// printf("No tiles at zoom(%d)\n", z);
// continue;
// }
int num = (xmax - xmin + 1) * (ymax - ymin + 1);
printf("\nZoom(%d) Now rendering %d tiles\n", z, num);
g_logger(G_LOG_LEVEL_MESSAGE, "Zoom(%d) Now rendering %d tiles", z, num);
num_all += num;
gettimeofday(&start, NULL);
@ -283,7 +334,6 @@ int main(int argc, char **argv)
}
wait_for_empty_queue();
//printf("\n");
gettimeofday(&end, NULL);
display_rate(start, end, num);
}
@ -291,9 +341,12 @@ int main(int argc, char **argv)
finish_workers();
gettimeofday(&end_all, NULL);
printf("\nTotal for all tiles rendered\n");
g_logger(G_LOG_LEVEL_MESSAGE, "Total for all tiles rendered");
display_rate(start_all, end_all, num_all);
return ret;
free_map_sections(maps);
free_renderd_sections(config_slaves);
return 0;
}
#endif

View File

@ -96,13 +96,11 @@ static const char *cmdStr(enum protoCmd c)
void send_response(struct item *item, enum protoCmd rsp, int render_time)
{
struct protocol *req = &item->req;
struct item *prev;
request_queue_remove_request(render_request_queue, item, render_time);
while (item) {
req = &item->req;
struct item *prev;
struct protocol *req = &item->req;
if ((item->fd != FD_INVALID) && ((req->cmd == cmdRender) || (req->cmd == cmdRenderPrio) || (req->cmd == cmdRenderLow) || (req->cmd == cmdRenderBulk))) {
req->cmd = rsp;
@ -337,7 +335,6 @@ void *stats_writeout_thread(void * arg)
continue;
} else {
noFailedAttempts = 0;
fprintf(statfile, "ReqQueueLength: %i\n", reqQueueLength);
fprintf(statfile, "ReqPrioQueueLength: %i\n", reqPrioQueueLength);
fprintf(statfile, "ReqLowQueueLength: %i\n", reqLowQueueLength);
@ -369,7 +366,7 @@ void *stats_writeout_thread(void * arg)
g_logger(G_LOG_LEVEL_WARNING, "Failed to overwrite stats file: %i", errno);
noFailedAttempts++;
if (noFailedAttempts > 3) {
if (noFailedAttempts > 6) {
g_logger(G_LOG_LEVEL_ERROR, "Failed repeatedly to overwrite stats, giving up");
break;
}
@ -744,7 +741,7 @@ int main(int argc, char **argv)
}
switch (c) {
case 'c': /* -c, --config */
case 'c': /* -c, --config */
config_file_name = strndup(optarg, PATH_MAX);
config_file_name_passed = 1;
@ -757,16 +754,16 @@ int main(int argc, char **argv)
break;
case 'f': /* -f, --foreground */
case 'f': /* -f, --foreground */
foreground = 1;
break;
case 's': /* -s, --slave */
case 's': /* -s, --slave */
active_renderd_section_num = min_max_int_opt(optarg, "active renderd section", 0, -1);
active_renderd_section_num_passed = 1;
break;
case 'h': /* -h, --help */
case 'h': /* -h, --help */
fprintf(stderr, "Usage: renderd [OPTION] ...\n");
fprintf(stderr, "Mapnik rendering daemon\n");
fprintf(stderr, " -c, --config=CONFIG specify the renderd config file (default is '%s')\n", config_file_name_default);
@ -777,7 +774,7 @@ int main(int argc, char **argv)
fprintf(stderr, " -V, --version display the version number and exit\n");
return 0;
case 'V': /* -V, --version */
case 'V': /* -V, --version */
fprintf(stdout, "%s\n", VERSION);
return 0;

View File

@ -172,7 +172,31 @@ endfunction()
add_test(NAME gen_tile_test
COMMAND gen_tile_test
WORKING_DIRECTORY src
)
add_test(
NAME render_expired_test
COMMAND render_expired_test
)
add_test(
NAME render_list_test
COMMAND render_list_test
)
add_test(
NAME render_old_test
COMMAND render_old_test
)
add_test(
NAME render_speedtest_test
COMMAND render_speedtest_test
)
add_test(
NAME renderd_test
COMMAND renderd_test
)
foreach(STORAGE_BACKEND_INDEX RANGE ${STORAGE_BACKENDS_LENGTH})
@ -322,6 +346,18 @@ foreach(STORAGE_BACKEND_INDEX RANGE ${STORAGE_BACKENDS_LENGTH})
FIXTURES_REQUIRED services_started_${STORAGE_BACKEND}
TIMEOUT 90
)
add_test(NAME render_expired_config_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
echo '3/0/3' | $<TARGET_FILE:render_expired> \
--config ${RENDERD_CONF}
"
WORKING_DIRECTORY tests
)
set_tests_properties(render_expired_config_${SOCKET_TYPE}_${STORAGE_BACKEND} PROPERTIES
DEPENDS render_speedtest_${SOCKET_TYPE}_${STORAGE_BACKEND}
FIXTURES_REQUIRED services_started_${STORAGE_BACKEND}
TIMEOUT 60
)
add_test(NAME render_expired_delete_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
echo '0/0/0' | $<TARGET_FILE:render_expired> \
@ -382,6 +418,19 @@ foreach(STORAGE_BACKEND_INDEX RANGE ${STORAGE_BACKENDS_LENGTH})
FIXTURES_REQUIRED services_started_${STORAGE_BACKEND}
TIMEOUT 90
)
add_test(NAME render_list_config_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
$<TARGET_FILE:render_list> \
--all \
--config ${RENDERD_CONF}
"
WORKING_DIRECTORY tests
)
set_tests_properties(render_list_config_${SOCKET_TYPE}_${STORAGE_BACKEND} PROPERTIES
DEPENDS render_speedtest_${SOCKET_TYPE}_${STORAGE_BACKEND}
FIXTURES_REQUIRED services_started_${STORAGE_BACKEND}
TIMEOUT 60
)
add_test(NAME render_list_stdin_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
echo '0 0 0' | $<TARGET_FILE:render_list> \
@ -401,6 +450,18 @@ foreach(STORAGE_BACKEND_INDEX RANGE ${STORAGE_BACKENDS_LENGTH})
FIXTURES_REQUIRED services_started_${STORAGE_BACKEND}
TIMEOUT 90
)
add_test(NAME render_list_stdin_config_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
echo '0 0 0' | $<TARGET_FILE:render_list> \
--config ${RENDERD_CONF}
"
WORKING_DIRECTORY tests
)
set_tests_properties(render_list_stdin_config_${SOCKET_TYPE}_${STORAGE_BACKEND} PROPERTIES
DEPENDS render_speedtest_${SOCKET_TYPE}_${STORAGE_BACKEND}
FIXTURES_REQUIRED services_started_${STORAGE_BACKEND}
TIMEOUT 60
)
add_test(NAME render_old_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
${TOUCH_EXECUTABLE} -d '+1 month' ${TEST_TILES_DIR}/planet-import-complete
@ -421,6 +482,32 @@ foreach(STORAGE_BACKEND_INDEX RANGE ${STORAGE_BACKENDS_LENGTH})
FIXTURES_REQUIRED services_started_${STORAGE_BACKEND}
TIMEOUT 90
)
add_test(NAME render_old_config_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
${TOUCH_EXECUTABLE} -d '+1 month' ${TEST_TILES_DIR}/planet-import-complete
$<TARGET_FILE:render_old> \
--config ${RENDERD_CONF}
"
WORKING_DIRECTORY tests
)
set_tests_properties(render_old_config_${SOCKET_TYPE}_${STORAGE_BACKEND} PROPERTIES
DEPENDS render_speedtest_${SOCKET_TYPE}_${STORAGE_BACKEND}
FIXTURES_REQUIRED services_started_${STORAGE_BACKEND}
TIMEOUT 60
)
add_test(NAME render_old_config_timestamp_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
$<TARGET_FILE:render_old> \
--config ${RENDERD_CONF} \
--timestamp 01/01/2024
"
WORKING_DIRECTORY tests
)
set_tests_properties(render_old_config_timestamp_${SOCKET_TYPE}_${STORAGE_BACKEND} PROPERTIES
DEPENDS render_speedtest_${SOCKET_TYPE}_${STORAGE_BACKEND}
FIXTURES_REQUIRED services_started_${STORAGE_BACKEND}
TIMEOUT 60
)
add_test(NAME render_speedtest_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
$<TARGET_FILE:render_speedtest> \
@ -436,6 +523,17 @@ foreach(STORAGE_BACKEND_INDEX RANGE ${STORAGE_BACKENDS_LENGTH})
FIXTURES_REQUIRED "services_started_${STORAGE_BACKEND};tiles_downloaded_${STORAGE_BACKEND}"
TIMEOUT 90
)
add_test(NAME render_speedtest_config_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
$<TARGET_FILE:render_speedtest> \
--config ${RENDERD_CONF}
"
WORKING_DIRECTORY tests
)
set_tests_properties(render_speedtest_config_${SOCKET_TYPE}_${STORAGE_BACKEND} PROPERTIES
FIXTURES_REQUIRED "services_started_${STORAGE_BACKEND};tiles_downloaded_${STORAGE_BACKEND}"
TIMEOUT 60
)
add_test(NAME add_tile_config_${SOCKET_TYPE}_${STORAGE_BACKEND}
COMMAND ${BASH} -c "
CONFIG_NAME=\"bad_tile_config_${SOCKET_TYPE}\"
@ -1003,3 +1101,108 @@ foreach(DIRECTIVE_INDEX RANGE ${DIRECTIVES_LENGTH})
WORKING_DIRECTORY tests
)
endforeach()
#-----------------------------------------------------------------------------
#
# Test targets
#
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#
# catch_main_o
#
#-----------------------------------------------------------------------------
add_library(catch_main_o OBJECT
catch/catch_main.cpp
${PROJECT_SOURCE_DIR}/tests/catch/catch_test_common.cpp
)
target_include_directories(catch_main_o PRIVATE ${GLIB_INCLUDE_DIRS})
#-----------------------------------------------------------------------------
#
# catch_test_common_o
#
#-----------------------------------------------------------------------------
add_library(catch_test_common_o OBJECT ${PROJECT_SOURCE_DIR}/tests/catch/catch_test_common.cpp)
target_include_directories(catch_test_common_o PRIVATE ${GLIB_INCLUDE_DIRS})
#-----------------------------------------------------------------------------
#
# gen_tile_test
#
#-----------------------------------------------------------------------------
# Added by ${PROJECT_SOURCE_DIR}/src/CMakeLists.txt
# (in order to reduce redundant source and library definitions)
#-----------------------------------------------------------------------------
#
# Additional options for targets added hereafter
#
#-----------------------------------------------------------------------------
add_compile_definitions(
PROJECT_BINARY_DIR="${PROJECT_BINARY_DIR}/src"
RENDERD_CONF="${PROJECT_SOURCE_DIR}/etc/renderd/renderd.conf"
)
include_directories(${PROJECT_SOURCE_DIR}/includes)
link_libraries(${GLIB_LIBRARIES})
#-----------------------------------------------------------------------------
#
# render_expired_test
#
#-----------------------------------------------------------------------------
add_executable(render_expired_test
$<TARGET_OBJECTS:catch_main_o>
render_expired_test.cpp
)
#-----------------------------------------------------------------------------
#
# render_list_test
#
#-----------------------------------------------------------------------------
add_executable(render_list_test
$<TARGET_OBJECTS:catch_main_o>
render_list_test.cpp
)
#-----------------------------------------------------------------------------
#
# render_old_test
#
#-----------------------------------------------------------------------------
add_executable(render_old_test
$<TARGET_OBJECTS:catch_main_o>
render_old_test.cpp
)
#-----------------------------------------------------------------------------
#
# render_speedtest_test
#
#-----------------------------------------------------------------------------
add_executable(render_speedtest_test
$<TARGET_OBJECTS:catch_main_o>
render_speedtest_test.cpp
)
#-----------------------------------------------------------------------------
#
# renderd_test
#
#-----------------------------------------------------------------------------
add_executable(renderd_test
$<TARGET_OBJECTS:catch_main_o>
renderd_test.cpp
)

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2007 - 2023 by mod_tile contributors (see AUTHORS file)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "catch_test_common.hpp"
int foreground = 1;
struct CaptureListener : Catch::TestEventListenerBase {
using TestEventListenerBase::TestEventListenerBase;
void testCaseStarting(Catch::TestCaseInfo const &testCaseInfo) override
{
start_capture();
}
void testCaseEnded(Catch::TestCaseStats const &testCaseStats) override
{
bool print = false;
if (testCaseStats.totals.assertions.failed > 0) {
print = true;
}
end_capture(print);
}
};
CATCH_REGISTER_LISTENER(CaptureListener)

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2007 - 2023 by mod_tile contributors (see AUTHORS file)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <glib.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <tuple>
#include <unistd.h>
extern int foreground;
typedef struct _captured_stdio {
int temp_fd;
int pipes[2];
} captured_stdio;
captured_stdio captured_stderr;
captured_stdio captured_stdout;
void capture_stderr()
{
// Flush stderr first if you've previously printed something
fflush(stderr);
// Save stderr so it can be restored later
int temp_stderr;
temp_stderr = dup(fileno(stderr));
// Redirect stderr to a new pipe
int pipes[2];
pipe(pipes);
dup2(pipes[1], fileno(stderr));
captured_stderr.temp_fd = temp_stderr;
captured_stderr.pipes[0] = pipes[0];
captured_stderr.pipes[1] = pipes[1];
}
std::string get_captured_stderr(bool print = false)
{
// Terminate captured output with a zero
write(captured_stderr.pipes[1], "", 1);
// Restore stderr
fflush(stderr);
dup2(captured_stderr.temp_fd, fileno(stderr));
// Save & return the captured output
std::string log_lines;
const int buffer_size = 4096;
char buffer[buffer_size];
read(captured_stderr.pipes[0], buffer, buffer_size);
log_lines += buffer;
if (print) {
std::cout << "err_log_lines: " << log_lines << "\n";
}
return log_lines;
}
void capture_stdout()
{
// Flush stdout first if you've previously printed something
fflush(stdout);
// Save stdout so it can be restored later
int temp_stdout;
temp_stdout = dup(fileno(stdout));
// Redirect stdout to a new pipe
int pipes[2];
pipe(pipes);
dup2(pipes[1], fileno(stdout));
captured_stdout.temp_fd = temp_stdout;
captured_stdout.pipes[0] = pipes[0];
captured_stdout.pipes[1] = pipes[1];
}
std::string get_captured_stdout(bool print = false)
{
// Terminate captured output with a zero
write(captured_stdout.pipes[1], "", 1);
// Restore stdout
fflush(stdout);
dup2(captured_stdout.temp_fd, fileno(stdout));
// Save & return the captured output
std::string log_lines;
const int buffer_size = 4096;
char buffer[buffer_size];
read(captured_stdout.pipes[0], buffer, buffer_size);
log_lines += buffer;
if (print) {
std::cout << "out_log_lines: " << log_lines << "\n";
}
return log_lines;
}
void start_capture(bool debug = false)
{
foreground = debug ? 1 : 0;
if (debug) {
setenv("G_MESSAGES_DEBUG", "all", 1);
#if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 79
// https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3710
std::cout << "Resetting G_MESSAGES_DEBUG env var in runtime no longer has an effect.\n";
const gchar *domains[] = {"all", NULL};
g_log_writer_default_set_debug_domains(domains);
#endif
}
capture_stderr();
capture_stdout();
}
std::tuple<std::string, std::string> end_capture(bool print = false)
{
setenv("G_MESSAGES_DEBUG", "", 1);
#if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 79
g_log_writer_default_set_debug_domains(NULL);
#endif
foreground = 0;
return std::tuple<std::string, std::string>(get_captured_stderr(print), get_captured_stdout(print));
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2007 - 2023 by mod_tile contributors (see AUTHORS file)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <string>
#ifndef CATCH_TEST_COMMON_HPP
#define CATCH_TEST_COMMON_HPP
void capture_stderr();
void capture_stdout();
std::string get_captured_stderr(bool print = false);
std::string get_captured_stdout(bool print = false);
void start_capture(bool debug = false);
std::tuple<std::string, std::string> end_capture(bool print = false);
#endif

View File

@ -37,6 +37,7 @@
#include <unistd.h>
#include "catch/catch.hpp"
#include "catch/catch_test_common.hpp"
#include "config.h"
#include "g_logger.h"
#include "gen_tile.h"
@ -49,14 +50,6 @@
#include "store.h"
#include "string.h"
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
#ifdef __FreeBSD__
#include <sys/wait.h>
#endif
#if MAPNIK_MAJOR_VERSION >= 4
#include <mapnik/geometry/box2d.hpp>
#else
@ -73,129 +66,6 @@ extern mapnik::box2d<double> tile2prjbounds(struct projectionconfig *prj, int x,
// mutex to guard access to the shared render request counter
static pthread_mutex_t item_counter_lock;
typedef struct _captured_stdio {
int temp_fd;
int pipes[2];
} captured_stdio;
captured_stdio captured_stderr;
captured_stdio captured_stdout;
void capture_stderr()
{
// Flush stderr first if you've previously printed something
fflush(stderr);
// Save stderr so it can be restored later
int temp_stderr;
temp_stderr = dup(fileno(stderr));
// Redirect stderr to a new pipe
int pipes[2];
pipe(pipes);
dup2(pipes[1], fileno(stderr));
captured_stderr.temp_fd = temp_stderr;
captured_stderr.pipes[0] = pipes[0];
captured_stderr.pipes[1] = pipes[1];
}
std::string get_captured_stderr(bool print = false)
{
// Terminate captured output with a zero
write(captured_stderr.pipes[1], "", 1);
// Restore stderr
fflush(stderr);
dup2(captured_stderr.temp_fd, fileno(stderr));
// Save & return the captured output
std::string log_lines;
const int buffer_size = 1024;
char buffer[buffer_size];
read(captured_stderr.pipes[0], buffer, buffer_size);
log_lines += buffer;
if (print) {
std::cout << "err_log_lines: " << log_lines << "\n";
}
return log_lines;
}
void capture_stdout()
{
// Flush stdout first if you've previously printed something
fflush(stdout);
// Save stdout so it can be restored later
int temp_stdout;
temp_stdout = dup(fileno(stdout));
// Redirect stdout to a new pipe
int pipes[2];
pipe(pipes);
dup2(pipes[1], fileno(stdout));
captured_stdout.temp_fd = temp_stdout;
captured_stdout.pipes[0] = pipes[0];
captured_stdout.pipes[1] = pipes[1];
}
std::string get_captured_stdout(bool print = false)
{
// Terminate captured output with a zero
write(captured_stdout.pipes[1], "", 1);
// Restore stdout
fflush(stdout);
dup2(captured_stdout.temp_fd, fileno(stdout));
// Save & return the captured output
std::string log_lines;
const int buffer_size = 1024;
char buffer[buffer_size];
read(captured_stdout.pipes[0], buffer, buffer_size);
log_lines += buffer;
if (print) {
std::cout << "out_log_lines: " << log_lines << "\n";
}
return log_lines;
}
void start_capture(bool debug = false)
{
foreground = debug ? 1 : 0;
if (debug) {
#if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION == 79
// https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3710
std::cout << "Resetting G_MESSAGES_DEBUG env var in runtime no longer has an effect.\n";
const gchar *domains[] = {"all", NULL};
g_log_writer_default_set_debug_domains(domains);
#else
setenv("G_MESSAGES_DEBUG", "all", 1);
#endif
}
capture_stderr();
capture_stdout();
}
std::tuple<std::string, std::string> end_capture(bool print = false)
{
#if GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION == 79
g_log_writer_default_set_debug_domains(NULL);
#else
setenv("G_MESSAGES_DEBUG", "", 1);
#endif
foreground = 0;
return std::tuple<std::string, std::string>(get_captured_stderr(print), get_captured_stdout(print));
}
struct item *init_render_request(enum protoCmd type)
{
static int counter;
@ -266,221 +136,6 @@ int delete_tile_dir(std::string tile_dir)
return rmdir(tile_dir.c_str());
}
TEST_CASE("render_expired", "render expired")
{
SECTION("render_expired startup --help", "should start and show help message") {
// flawfinder: ignore
int ret = system("./render_expired -h");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 0);
}
SECTION("render_expired startup --version", "should start and show version number") {
// flawfinder: ignore
FILE *pipe = popen("./render_expired -V", "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
pclose(pipe);
REQUIRE(output == VERSION);
}
SECTION("render_expired startup unrecognized option", "should return 1") {
// flawfinder: ignore
int ret = system("./render_expired --doesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_expired startup invalid option", "should return 1") {
// flawfinder: ignore
int ret = system("./render_expired -oesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
}
TEST_CASE("render_list", "render list")
{
SECTION("render_list startup --help", "should start and show help message") {
// flawfinder: ignore
int ret = system("./render_list -h");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 0);
}
SECTION("render_list startup --version", "should start and show version number") {
// flawfinder: ignore
FILE *pipe = popen("./render_list -V", "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
pclose(pipe);
REQUIRE(output == VERSION);
}
SECTION("render_list startup unrecognized option", "should return 1") {
// flawfinder: ignore
int ret = system("./render_list --doesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_list startup invalid option", "should return 1") {
// flawfinder: ignore
int ret = system("./render_list -doesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_list option is positive with --help", "should return 0") {
std::string option = GENERATE("--max-load", "--max-x", "--max-y", "--max-zoom", "--min-x", "--min-y", "--min-zoom", "--num-threads");
std::string command = "./render_list " + option + " 1 --help";
// flawfinder: ignore
int ret = system(command.c_str());
ret = WEXITSTATUS(ret);
REQUIRE(ret == 0);
}
SECTION("render_list option is negative", "should return 1") {
std::string option = GENERATE("--max-load", "--max-x", "--max-y", "--max-zoom", "--min-x", "--min-y", "--min-zoom", "--num-threads");
std::string command = "./render_list " + option + " -1";
// flawfinder: ignore
int ret = system(command.c_str());
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_list option is float", "should return 1") {
std::string option = GENERATE("--max-load", "--max-x", "--max-y", "--max-zoom", "--min-x", "--min-y", "--min-zoom", "--num-threads");
std::string command = "./render_list " + option + " 0.12345";
// flawfinder: ignore
int ret = system(command.c_str());
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_list num threads subceeds minimum of 1", "should return 1") {
// flawfinder: ignore
int ret = system("./render_list -n 0");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_list zoom exceeds maximum of MAX_ZOOM", "should return 1") {
std::string option = GENERATE("--max-zoom", "--min-zoom");
std::string command = "./render_list " + option + " 1000";
// flawfinder: ignore
int ret = system(command.c_str());
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_list min zoom exceeds max zoom", "should return 1") {
// flawfinder: ignore
int ret = system("./render_list -z 10 -Z 9");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_list all min zoom not equal to max zoom with X/Y options", "should return 1") {
// flawfinder: ignore
int ret = system("./render_list -z 9 -Z 10 -a -X 1 -Y 1");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_list all max x/y options exceed maximum (2^zoom-1)", "should return 1") {
// flawfinder: ignore
int ret = system("./render_list -z 1 -Z 1 -a -X 2 -Y 2");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_list all min x/y options exceed maximum (2^zoom-1)", "should return 1") {
// flawfinder: ignore
int ret = system("./render_list -z 1 -Z 1 -a -x 2 -y 2");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
}
TEST_CASE("render_old", "render old")
{
SECTION("render_old startup --help", "should start and show help message") {
// flawfinder: ignore
int ret = system("./render_old -h");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 0);
}
SECTION("render_old startup --version", "should start and show version number") {
// flawfinder: ignore
FILE *pipe = popen("./render_old -V", "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
pclose(pipe);
REQUIRE(output == VERSION);
}
SECTION("render_old startup unrecognized option", "should return 1") {
// flawfinder: ignore
int ret = system("./render_old --doesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_old startup invalid option", "should return 1") {
// flawfinder: ignore
int ret = system("./render_old -doesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
}
TEST_CASE("render_speedtest", "render speed test")
{
SECTION("render_speedtest startup --help", "should start and show help message") {
// flawfinder: ignore
int ret = system("./render_speedtest -h");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 0);
}
SECTION("render_speedtest startup --version", "should start and show version number") {
// flawfinder: ignore
FILE *pipe = popen("./render_speedtest -V", "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
pclose(pipe);
REQUIRE(output == VERSION);
}
SECTION("render_speedtest startup unrecognized option", "should return 1") {
// flawfinder: ignore
int ret = system("./render_speedtest --doesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("render_speedtest startup invalid option", "should return 1") {
// flawfinder: ignore
int ret = system("./render_speedtest -doesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
}
TEST_CASE("renderd/queueing", "request queueing")
{
SECTION("renderd/queueing/initialisation", "test the initialisation of the request queue") {
@ -1005,85 +660,6 @@ TEST_CASE("renderd", "tile generation")
request_queue_close(render_request_queue);
SUCCEED();
}
SECTION("renderd startup --help", "should start and show help message") {
// flawfinder: ignore
int ret = system("./renderd -h");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 0);
}
SECTION("renderd startup --version", "should start and show version number") {
// flawfinder: ignore
FILE *pipe = popen("./renderd -V", "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
pclose(pipe);
REQUIRE(output == VERSION);
}
SECTION("renderd startup --config fakefile.conf --foreground", "should not start and return 1") {
// flawfinder: ignore
int ret = system("./renderd -c fakefile.conf -f");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("renderd startup unrecognized option", "should return 1") {
// flawfinder: ignore
int ret = system("./renderd --doesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("renderd startup invalid option", "should return 1") {
// flawfinder: ignore
int ret = system("./renderd -doesnotexit");
ret = WEXITSTATUS(ret);
REQUIRE(ret == 1);
}
SECTION("--config invalid file", "should return 1") {
std::string option = "--config /path/is/invalid";
std::string command = "./renderd " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--slave is not a number", "should return 1") {
std::string option = "--slave abcdefg";
std::string command = "./renderd " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--slave is a float", "should return 1") {
std::string option = "--slave 1.23456789";
std::string command = "./renderd " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--slave subceeds minimum of 0", "should return 1") {
std::string option = "--slave -1";
std::string command = "./renderd " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("storage-backend", "Tile storage backend router")

View File

@ -0,0 +1,226 @@
/*
* Copyright (c) 2007 - 2023 by mod_tile contributors (see AUTHORS file)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "catch/catch.hpp"
#include "config.h"
#include "render_config.h"
#ifdef __FreeBSD__
#include <sys/wait.h>
#endif
#ifndef PROJECT_BINARY_DIR
#define PROJECT_BINARY_DIR "."
#endif
#ifndef RENDERD_CONF
#define RENDERD_CONF "./etc/renderd/renderd.conf"
#endif
std::string test_binary = (std::string)PROJECT_BINARY_DIR + "/" + "render_expired";
TEST_CASE("render_expired common", "common testing")
{
SECTION("invalid long option", "should return 1") {
std::string option = "--doesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("invalid short options", "should return 1") {
std::string option = "-oesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--help", "should return 0") {
std::string option = "--help";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--version", "should show version number") {
std::string option = "--version";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
REQUIRE(output == VERSION);
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--config invalid file", "should return 1") {
std::string option = "--config /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("render_expired specific", "specific testing")
{
SECTION("--num-threads subceeds minimum of 1", "should return 1") {
std::string option = "--num-threads 0";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--min-zoom/--max-zoom exceeds maximum of MAX_ZOOM", "should return 1") {
std::string option = GENERATE("--max-zoom", "--min-zoom");
std::string command = test_binary + " " + option + " " + std::to_string(MAX_ZOOM + 1);
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--min-zoom exceeds --max-zoom", "should return 1") {
std::string option = "--max-zoom " + std::to_string(MAX_ZOOM - 2) + " --min-zoom " + std::to_string(MAX_ZOOM - 1);
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config without maps", "should return 1") {
std::string option = "--config " + (std::string)RENDERD_CONF;
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config with invalid --map", "should return 1") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config with valid --map and --tile-dir with invalid path", "should return 1") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map example-map --tile-dir /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config with valid --map, --verbose and bad input lines", "should return 0") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map example-map --tile-dir " + P_tmpdir + " --verbose";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "w");
fputs("z/x/y\n", pipe);
fputs("x y z\n", pipe);
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--tile-dir with invalid option", "should return 1") {
std::string option = "--tile-dir invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--tile-dir with invalid path", "should return 1") {
std::string option = "--tile-dir /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("render_expired generator", "generator testing")
{
std::string option = GENERATE("--delete-from", "--max-load", "--max-zoom", "--min-zoom", "--num-threads", "--touch-from");
SECTION("option is positive with --help", "should return 0") {
std::string command = test_binary + " " + option + " 1 --help";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("option is negative", "should return 1") {
std::string command = test_binary + " " + option + " -1";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("option is float", "should return 1") {
std::string command = test_binary + " " + option + " 1.23456789";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}

269
tests/render_list_test.cpp Normal file
View File

@ -0,0 +1,269 @@
/*
* Copyright (c) 2007 - 2023 by mod_tile contributors (see AUTHORS file)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "catch/catch.hpp"
#include "config.h"
#include "render_config.h"
#ifdef __FreeBSD__
#include <sys/wait.h>
#endif
#ifndef PROJECT_BINARY_DIR
#define PROJECT_BINARY_DIR "."
#endif
#ifndef RENDERD_CONF
#define RENDERD_CONF "./etc/renderd/renderd.conf"
#endif
std::string test_binary = (std::string)PROJECT_BINARY_DIR + "/" + "render_list";
TEST_CASE("render_list common", "common testing")
{
SECTION("invalid long option", "should return 1") {
std::string option = "--doesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("invalid short options", "should return 1") {
std::string option = "-doesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--help", "should return 0") {
std::string option = "--help";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--version", "should show version number") {
std::string option = "--version";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
REQUIRE(output == VERSION);
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--config invalid file", "should return 1") {
std::string option = "--config /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("render_list specific", "specific testing")
{
SECTION("--num-threads subceeds minimum of 1", "should return 1") {
std::string option = "--num-threads 0";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--min-zoom/--max-zoom exceeds maximum of MAX_ZOOM", "should return 1") {
std::string option = GENERATE("--max-zoom", "--min-zoom");
std::string command = test_binary + " " + option + " " + std::to_string(MAX_ZOOM + 1);
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--min-zoom exceeds --max-zoom", "should return 1") {
std::string option = "--max-zoom " + std::to_string(MAX_ZOOM - 2) + " --min-zoom " + std::to_string(MAX_ZOOM - 1);
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--all --min-zoom not equal to --max-zoom with X/Y options", "should return 1") {
std::string option = "--all --max-x 1 --max-zoom 10 --max-y 1 --min-zoom 9";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--all --max-x/y options exceed maximum (2^zoom-1)", "should return 1") {
std::string option = "--all --max-x 2 --max-y 2 --max-zoom 1 --min-zoom 1";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--all --min-x/y options exceed maximum (2^zoom-1)", "should return 1") {
std::string option = "--all --max-zoom 1 --min-x 2 --min-y 2 --min-zoom 1";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config without maps", "should return 1") {
std::string option = "--config " + (std::string)RENDERD_CONF;
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config with invalid --map", "should return 1") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config with valid --map and --tile-dir with invalid path", "should return 1") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map example-map --tile-dir /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config with valid --map, --verbose and bad input lines", "should return 0") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map example-map --tile-dir " + P_tmpdir + " --verbose";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "w");
fputs("z/x/y\n", pipe);
fputs("x y z\n", pipe);
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--config with valid --map, --verbose and invalid zoom input lines", "should return 0") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map example-map --tile-dir " + P_tmpdir + " --verbose";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "w");
fputs("0 0 -100\n", pipe);
fputs("0 0 100\n", pipe);
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--tile-dir with invalid option", "should return 1") {
std::string option = "--tile-dir invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--tile-dir with invalid path", "should return 1") {
std::string option = "--tile-dir /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("render_list generator", "generator testing")
{
std::string option = GENERATE("--max-load", "--max-x", "--max-y", "--max-zoom", "--min-x", "--min-y", "--min-zoom", "--num-threads");
SECTION("option is positive with --help", "should return 0") {
std::string command = test_binary + " " + option + " 1 --help";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("option is negative", "should return 1") {
std::string command = test_binary + " " + option + " -1";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("option is float", "should return 1") {
std::string command = test_binary + " " + option + " 1.23456789";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}

212
tests/render_old_test.cpp Normal file
View File

@ -0,0 +1,212 @@
/*
* Copyright (c) 2007 - 2023 by mod_tile contributors (see AUTHORS file)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "catch/catch.hpp"
#include "config.h"
#include "render_config.h"
#ifdef __FreeBSD__
#include <sys/wait.h>
#endif
#ifndef PROJECT_BINARY_DIR
#define PROJECT_BINARY_DIR "."
#endif
#ifndef RENDERD_CONF
#define RENDERD_CONF "./etc/renderd/renderd.conf"
#endif
std::string test_binary = (std::string)PROJECT_BINARY_DIR + "/" + "render_old";
TEST_CASE("render_old common", "common testing")
{
SECTION("invalid long option", "should return 1") {
std::string option = "--doesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("invalid short options", "should return 1") {
std::string option = "-doesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--help", "should return 0") {
std::string option = "--help";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--version", "should show version number") {
std::string option = "--version";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
REQUIRE(output == VERSION);
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--config invalid file", "should return 1") {
std::string option = "--config /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("render_old specific", "specific testing")
{
SECTION("--num-threads subceeds minimum of 1", "should return 1") {
std::string option = "--num-threads 0";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--min-zoom/--max-zoom exceeds maximum of MAX_ZOOM", "should return 1") {
std::string option = GENERATE("--max-zoom", "--min-zoom");
std::string command = test_binary + " " + option + " " + std::to_string(MAX_ZOOM + 1);
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--min-zoom exceeds --max-zoom", "should return 1") {
std::string option = "--max-zoom " + std::to_string(MAX_ZOOM - 2) + " --min-zoom " + std::to_string(MAX_ZOOM - 1);
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--timestamp is not an integer", "should return 1") {
std::string option = "--timestamp invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--timestamp is a date with --help", "should return 0") {
std::string option = GENERATE("--timestamp 01/01/01", "--timestamp 01/01/1901");
std::string command = test_binary + " " + option + " --help";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--timestamp is an integer with --help", "should return 0") {
std::string option = "--timestamp 111 --help";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--config without maps", "should return 1") {
std::string option = "--config " + (std::string)RENDERD_CONF;
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config with invalid --map", "should return 1") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("render_old generator", "generator testing")
{
std::string option = GENERATE("--max-load", "--max-zoom", "--min-zoom", "--num-threads");
SECTION("option is positive with --help", "should return 0") {
std::string command = test_binary + " " + option + " 1 --help";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("option is negative", "should return 1") {
std::string command = test_binary + " " + option + " -1";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("option is float", "should return 1") {
std::string command = test_binary + " " + option + " 1.23456789";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}

View File

@ -0,0 +1,213 @@
/*
* Copyright (c) 2007 - 2023 by mod_tile contributors (see AUTHORS file)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "catch/catch.hpp"
#include "config.h"
#include "render_config.h"
#ifdef __FreeBSD__
#include <sys/wait.h>
#endif
#ifndef PROJECT_BINARY_DIR
#define PROJECT_BINARY_DIR "."
#endif
#ifndef RENDERD_CONF
#define RENDERD_CONF "./etc/renderd/renderd.conf"
#endif
std::string test_binary = (std::string)PROJECT_BINARY_DIR + "/" + "render_speedtest";
TEST_CASE("render_speedtest common", "common testing")
{
SECTION("invalid long option", "should return 1") {
std::string option = "--doesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("invalid short options", "should return 1") {
std::string option = "-doesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--help", "should return 0") {
std::string option = "--help";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--version", "should show version number") {
std::string option = "--version";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
REQUIRE(output == VERSION);
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--config invalid file", "should return 1") {
std::string option = "--config /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("render_speedtest specific", "specific testing")
{
SECTION("--num-threads subceeds minimum of 1", "should return 1") {
std::string option = "--num-threads 0";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--min-zoom/--max-zoom exceeds maximum of MAX_ZOOM", "should return 1") {
std::string option = GENERATE("--max-zoom", "--min-zoom");
std::string command = test_binary + " " + option + " " + std::to_string(MAX_ZOOM + 1);
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--min-zoom exceeds --max-zoom", "should return 1") {
std::string option = "--max-zoom " + std::to_string(MAX_ZOOM - 2) + " --min-zoom " + std::to_string(MAX_ZOOM - 1);
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config without maps", "should return 1") {
std::string option = "--config " + (std::string)RENDERD_CONF;
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config with invalid --map", "should return 1") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--config with valid --map and --tile-dir with invalid path", "should return 1") {
std::string renderd_conf_examples = (std::string)RENDERD_CONF + ".examples";
std::string option = "--config " + renderd_conf_examples + " --map example-map --tile-dir /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--tile-dir with invalid option", "should return 1") {
std::string option = "--tile-dir invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--tile-dir with invalid path", "should return 1") {
std::string option = "--tile-dir /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("render_speedtest generator", "generator testing")
{
std::string option = GENERATE("--max-zoom", "--min-zoom", "--num-threads");
SECTION("option is positive with --help", "should return 0") {
std::string command = test_binary + " " + option + " 1 --help";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("option is negative", "should return 1") {
std::string command = test_binary + " " + option + " -1";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("option is float", "should return 1") {
std::string command = test_binary + " " + option + " 1.23456789";
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}

108
tests/renderd_test.cpp Normal file
View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2007 - 2023 by mod_tile contributors (see AUTHORS file)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "catch/catch.hpp"
#include "config.h"
#ifdef __FreeBSD__
#include <sys/wait.h>
#endif
#ifndef PROJECT_BINARY_DIR
#define PROJECT_BINARY_DIR "."
#endif
#ifndef RENDERD_CONF
#define RENDERD_CONF "./etc/renderd/renderd.conf"
#endif
std::string test_binary = (std::string)PROJECT_BINARY_DIR + "/" + "renderd";
TEST_CASE("renderd common", "common testing")
{
SECTION("invalid long option", "should return 1") {
std::string option = "--doesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("invalid short options", "should return 1") {
std::string option = "-doesnotexist";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
SECTION("--help", "should return 0") {
std::string option = "--help";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--version", "should show version number") {
std::string option = "--version";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
std::string output;
char buffer[sizeof(VERSION)];
fgets(buffer, sizeof(buffer), pipe);
output += buffer;
REQUIRE(output == VERSION);
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 0);
}
SECTION("--config invalid file", "should return 1") {
std::string option = "--config /path/is/invalid";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}
TEST_CASE("renderd specific", "specific testing")
{
SECTION("--slave subceeds minimum of 0", "should return 1") {
std::string option = "--slave -1";
std::string command = test_binary + " " + option;
// flawfinder: ignore
FILE *pipe = popen(command.c_str(), "r");
int status = pclose(pipe);
REQUIRE(WEXITSTATUS(status) == 1);
}
}