-
-
Notifications
You must be signed in to change notification settings - Fork 227
/
Copy pathtest.sh
executable file
·563 lines (466 loc) · 23.1 KB
/
test.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
#!/usr/bin/env bash
set -euo pipefail
MARTIN_DATABASE_URL="${DATABASE_URL:-postgres://postgres@localhost/db}"
unset DATABASE_URL
# TODO: use --fail-with-body to get the response body on failure
CURL=${CURL:-curl --silent --show-error --fail --compressed}
MARTIN_BUILD_ALL="${MARTIN_BUILD_ALL:-cargo build}"
STATICS_URL="${STATICS_URL:-http://localhost:5412}"
MARTIN_PORT="${MARTIN_PORT:-3111}"
MARTIN_URL="http://localhost:${MARTIN_PORT}"
MARTIN_ARGS="${MARTIN_ARGS:---listen-addresses localhost:${MARTIN_PORT}}"
# Using direct compiler output paths to avoid extra log entries
MARTIN_BIN="${MARTIN_BIN:-target/debug/martin} ${MARTIN_ARGS}"
MARTIN_CP_BIN="${MARTIN_CP_BIN:-target/debug/martin-cp}"
MBTILES_BIN="${MBTILES_BIN:-target/debug/mbtiles}"
TEST_OUT_BASE_DIR="$(dirname "$0")/output"
LOG_DIR="${LOG_DIR:-target/test_logs}"
mkdir -p "$LOG_DIR"
TEST_TEMP_DIR="$(dirname "$0")/mbtiles_temp_files"
rm -rf "$TEST_TEMP_DIR"
mkdir -p "$TEST_TEMP_DIR"
# Verify the tools used in the tests are available
# todo add more verification for other tools like jq file curl sqlite3...
if [[ $OSTYPE == linux* ]]; then # We only used ogrmerge.py on Linux see the test_pbf() function
if ! command -v ogrmerge.py > /dev/null; then
echo "gdal-bin is required for testing"
echo "For Ubuntu, you could install it with sudo apt update && sudo apt install gdal-bin -y"
echo "see more at https://gdal.org/en/stable/download.html#binaries"
exit 1
fi
fi
function wait_for {
# Seems the --retry-all-errors option is not available on older curl versions, but maybe in the future we can just use this:
# timeout -k 20s 20s curl --retry 10 --retry-all-errors --retry-delay 1 -sS "$MARTIN_URL/health"
PROCESS_ID=$1
PROC_NAME=$2
TEST_URL=$3
echo "Waiting for $PROC_NAME ($PROCESS_ID) to start by checking $TEST_URL to be valid..."
for _ in {1..60}; do
if $CURL "$TEST_URL" 2>/dev/null >/dev/null; then
echo "$PROC_NAME is up!"
if [[ "$PROC_NAME" == "Martin" ]]; then
$CURL "$TEST_URL"
fi
return
fi
if ps -p "$PROCESS_ID" > /dev/null ; then
echo "$PROC_NAME is not up yet, waiting for $TEST_URL ..."
sleep 1
else
echo "$PROC_NAME died!"
ps au
lsof -i || true;
exit 1
fi
done
echo "$PROC_NAME did not start in time"
ps au
lsof -i || true;
exit 1
}
function kill_process {
PROCESS_ID=$1
PROC_NAME=$2
echo "Waiting for $PROC_NAME ($PROCESS_ID) to stop..."
kill "$PROCESS_ID"
for _ in {1..50}; do
if ps -p "$PROCESS_ID" > /dev/null ; then
sleep 0.1
else
echo "$PROC_NAME ($PROCESS_ID) has stopped"
return
fi
done
echo "$PROC_NAME did not stop in time, killing it"
kill -9 "$PROCESS_ID"
# wait for it to die using timeout and wait
timeout -k 1s 1s wait "$PROCESS_ID" || true;
}
test_jsn() {
FILENAME="$TEST_OUT_DIR/$1.json"
URL="$MARTIN_URL/$2"
echo "Testing $(basename "$FILENAME") from $URL"
# jq before 1.6 had a different float->int behavior, so trying to make it consistent in all
$CURL "$URL" | jq --sort-keys -e 'walk(if type == "number" then .+0.0 else . end)' > "$FILENAME"
}
test_pbf() {
FILENAME="$TEST_OUT_DIR/$1.pbf"
URL="$MARTIN_URL/$2"
echo "Testing $(basename "$FILENAME") from $URL"
$CURL "$URL" > "$FILENAME"
if [[ $OSTYPE == linux* ]]; then
./tests/fixtures/vtzero-check "$FILENAME"
# see https://gdal.org/en/stable/programs/ogrmerge.html#ogrmerge
ogrmerge.py -o "$FILENAME.geojson" "$FILENAME" -single -src_layer_field_name "source_mvt_layer" -src_layer_field_content "{LAYER_NAME}" -f "GeoJSON" -overwrite_ds
jq --sort-keys '.features |= sort_by(.properties.source_mvt_layer, .properties.gid) | walk(if type == "number" then .+0.0 else . end)' "$FILENAME.geojson" > "$FILENAME.sorted.geojson"
mv "$FILENAME.sorted.geojson" "$FILENAME.geojson"
fi
}
test_png() {
# 3rd argument is optional, .png by default
FILENAME="$TEST_OUT_DIR/$1.${3:-png}"
URL="$MARTIN_URL/$2"
echo "Testing $(basename "$FILENAME") from $URL"
$CURL "$URL" > "$FILENAME"
if [[ $OSTYPE == linux* ]]; then
file "$FILENAME" > "$FILENAME.txt"
fi
}
test_jpg() {
# test_png can test any image format, but this is a separate function to make it easier to find all the jpeg tests
test_png "$1" "$2" jpg
}
test_font() {
FILENAME="$TEST_OUT_DIR/$1.pbf"
URL="$MARTIN_URL/$2"
echo "Testing $(basename "$FILENAME") from $URL"
$CURL "$URL" > "$FILENAME"
}
# Delete a line from a file $1 that matches parameter $2
remove_line() {
FILE="$1"
LINE_TO_REMOVE="$2"
>&2 echo "Removing line '$LINE_TO_REMOVE' from $FILE"
grep -v "$LINE_TO_REMOVE" "${FILE}" > "${FILE}.tmp"
mv "${FILE}.tmp" "${FILE}"
}
test_log_has_str() {
LOG_FILE="$1"
EXPECTED_TEXT="$2"
echo "Checking $LOG_FILE for expected text: '$EXPECTED_TEXT'"
grep -q "$EXPECTED_TEXT" "$LOG_FILE"
remove_line "$LOG_FILE" "$EXPECTED_TEXT"
}
test_martin_cp() {
TEST_NAME="$1"
ARG=("${@:2}")
LOG_FILE="${LOG_DIR}/${TEST_NAME}.txt"
SAVE_CONFIG_FILE="${TEST_OUT_DIR}/${TEST_NAME}_save_config.yaml"
SUMMARY_FILE="$TEST_OUT_DIR/${TEST_NAME}_summary.txt"
TEST_FILE="${TEST_TEMP_DIR}/cp_${TEST_NAME}.mbtiles"
ARG_EXTRAS=(--output-file "$TEST_FILE" --save-config "$SAVE_CONFIG_FILE")
set -x
$MARTIN_CP_BIN "${ARG[@]}" "${ARG_EXTRAS[@]}" 2>&1 | tee "$LOG_FILE"
$MBTILES_BIN validate --agg-hash off "$TEST_FILE" 2>&1 | tee "$TEST_OUT_DIR/${TEST_NAME}_validate.txt"
$MBTILES_BIN summary "$TEST_FILE" 2>&1 | tee "$SUMMARY_FILE"
$MBTILES_BIN meta-all "$TEST_FILE" 2>&1 | tee "$TEST_OUT_DIR/${TEST_NAME}_metadata.txt"
{ set +x; } 2> /dev/null
remove_line "$SAVE_CONFIG_FILE" " connection_string: "
# These tend to vary between runs. In theory, vacuuming might make it the same.
remove_line "$SUMMARY_FILE" "File size: "
remove_line "$SUMMARY_FILE" "Page count: "
}
validate_log() {
LOG_FILE="$1"
>&2 echo "Validating log file $LOG_FILE"
# Older versions of PostGIS don't support the margin parameter, so we need to remove it from the log
remove_line "$LOG_FILE" 'Margin parameter in ST_TileEnvelope is not supported'
remove_line "$LOG_FILE" 'Source IDs must be unique'
remove_line "$LOG_FILE" 'PostgreSQL 11.10.0 is older than the recommended minimum 12.0.0'
remove_line "$LOG_FILE" 'In the used version, some geometry may be hidden on some zoom levels.'
echo "Checking for no other warnings or errors in the log"
if grep -e ' ERROR ' -e ' WARN ' "$LOG_FILE"; then
echo "Log file $LOG_FILE has unexpected warnings or errors"
exit 1
fi
}
echo "------------------------------------------------------------------------------------------------------------------------"
curl --version
jq --version
grep --version
# Make sure all targets are built - this way it won't timeout while waiting for it to start
# If set to "-", skip this step (e.g. when testing a pre-built binary)
if [[ "$MARTIN_BUILD_ALL" != "-" ]]; then
rm -rf "$MARTIN_BIN" "$MARTIN_CP_BIN" "$MBTILES_BIN"
$MARTIN_BUILD_ALL
fi
echo "------------------------------------------------------------------------------------------------------------------------"
echo "Check HTTP server is running"
$CURL --head "$STATICS_URL/webp2.pmtiles"
echo "------------------------------------------------------------------------------------------------------------------------"
echo "Test auto configured Martin"
TEST_NAME="auto"
LOG_FILE="${LOG_DIR}/${TEST_NAME}.txt"
TEST_OUT_DIR="${TEST_OUT_BASE_DIR}/${TEST_NAME}"
mkdir -p "$TEST_OUT_DIR"
ARG=(--default-srid 900913 --auto-bounds calc --save-config "${TEST_OUT_DIR}/save_config.yaml" tests/fixtures/mbtiles tests/fixtures/pmtiles tests/fixtures/cog "$STATICS_URL/webp2.pmtiles" --sprite tests/fixtures/sprites/src1 --font tests/fixtures/fonts/overpass-mono-regular.ttf --font tests/fixtures/fonts)
export DATABASE_URL="$MARTIN_DATABASE_URL"
set -x
$MARTIN_BIN "${ARG[@]}" 2>&1 | tee "$LOG_FILE" &
MARTIN_PROC_ID=$(jobs -p | tail -n 1)
{ set +x; } 2> /dev/null
trap "echo 'Stopping Martin server $MARTIN_PROC_ID...'; kill -9 $MARTIN_PROC_ID 2> /dev/null || true; echo 'Stopped Martin server $MARTIN_PROC_ID';" EXIT HUP INT TERM
wait_for "$MARTIN_PROC_ID" Martin "$MARTIN_URL/health"
unset DATABASE_URL
>&2 echo "Test catalog"
test_jsn catalog_auto catalog
>&2 echo "***** Test server response for table source *****"
test_jsn table_source table_source
test_pbf tbl_0_0_0 table_source/0/0/0
test_pbf tbl_6_57_29 table_source/6/57/29
test_pbf tbl_12_3673_1911 table_source/12/3673/1911
test_pbf tbl_13_7346_3822 table_source/13/7346/3822
test_pbf tbl_14_14692_7645 table_source/14/14692/7645
test_pbf tbl_17_117542_61161 table_source/17/117542/61161
test_pbf tbl_18_235085_122323 table_source/18/235085/122323
>&2 echo "***** Test server response for composite source *****"
test_jsn cmp table_source,points1,points2
test_pbf cmp_0_0_0 table_source,points1,points2/0/0/0
test_pbf cmp_6_57_29 table_source,points1,points2/6/57/29
test_pbf cmp_12_3673_1911 table_source,points1,points2/12/3673/1911
test_pbf cmp_13_7346_3822 table_source,points1,points2/13/7346/3822
test_pbf cmp_14_14692_7645 table_source,points1,points2/14/14692/7645
test_pbf cmp_17_117542_61161 table_source,points1,points2/17/117542/61161
test_pbf cmp_18_235085_122323 table_source,points1,points2/18/235085/122323
>&2 echo "***** Test server response for function source *****"
test_jsn fnc function_zxy_query
test_pbf fnc_0_0_0 function_zxy_query/0/0/0
test_pbf fnc_6_57_29 function_zxy_query/6/57/29
test_pbf fnc_12_3673_1911 function_zxy_query/12/3673/1911
test_pbf fnc_13_7346_3822 function_zxy_query/13/7346/3822
test_pbf fnc_14_14692_7645 function_zxy_query/14/14692/7645
test_pbf fnc_17_117542_61161 function_zxy_query/17/117542/61161
test_pbf fnc_18_235085_122323 function_zxy_query/18/235085/122323
test_jsn fnc_token function_zxy_query_test
test_pbf fnc_token_0_0_0 function_zxy_query_test/0/0/0?token=martin
test_jsn fnc_b function_zxy_query_jsonb
test_pbf fnc_b_6_38_20 function_zxy_query_jsonb/6/57/29
>&2 echo "***** Test server response for different function call types *****"
test_pbf fnc_zoom_xy_6_57_29 function_zoom_xy/6/57/29
test_pbf fnc_zxy_6_57_29 function_zxy/6/57/29
test_pbf fnc_zxy2_6_57_29 function_zxy2/6/57/29
test_pbf fnc_zxy_query_6_57_29 function_zxy_query/6/57/29
test_pbf fnc_zxy_row_6_57_29 function_zxy_row/6/57/29
test_pbf fnc_zxy_row2_6_57_29 function_Mixed_Name/6/57/29
test_pbf fnc_zxy_row_key_6_57_29 function_zxy_row_key/6/57/29
>&2 echo "***** Test server response for table source with different SRID *****"
test_jsn points3857_srid points3857
test_pbf points3857_srid_0_0_0 points3857/0/0/0
>&2 echo "***** Test server response for PMTiles source *****"
test_jsn pmt stamen_toner__raster_CC-BY-ODbL_z3
test_png pmt_3_4_2 stamen_toner__raster_CC-BY-ODbL_z3/3/4/2
test_png webp2_1_0_0 webp2/1/0/0 # HTTP pmtiles
>&2 echo "***** Test server response for MbTiles source *****"
test_jsn mb_jpg geography-class-jpg
test_jpg mb_jpg_0_0_0 geography-class-jpg/0/0/0
test_jsn mb_png geography-class-png
test_png mb_png_0_0_0 geography-class-png/0/0/0
test_jsn mb_mvt world_cities
test_pbf mb_mvt_2_3_1 world_cities/2/3/1
>&2 echo "***** Test server response for COG(Cloud Optimized GeoTiff) source *****"
test_jsn rgb_u8 rgb_u8
test_png rgb_u8_0_0_0 rgb_u8/0/0/0
test_png rgb_u8_3_0_0 rgb_u8/3/0/0
test_png rgb_u8_3_1_1 rgb_u8/3/1/1
test_jsn rgba_u8 rgba_u8
test_png rgba_u8_0_0_0 rgba_u8/0/0/0
test_png rgba_u8_3_0_0 rgba_u8/3/0/0
test_png rgba_u8_3_1_1 rgba_u8/3/1/1
test_jsn rgba_u8_nodata rgba_u8_nodata
test_png rgba_u8_nodata_0_0_0 rgba_u8_nodata/0/0/0
test_png rgba_u8_nodata_1_0_0 rgba_u8_nodata/1/0/0
>&2 echo "***** Test server response for table source with empty SRID *****"
test_pbf points_empty_srid_0_0_0 points_empty_srid/0/0/0
>&2 echo "***** Test server response for comments *****"
test_jsn tbl_comment MixPoints
test_jsn fnc_comment function_Mixed_Name
kill_process "$MARTIN_PROC_ID" Martin
test_log_has_str "$LOG_FILE" 'WARN martin::pg::query_tables] Table public.table_source has no spatial index on column geom'
test_log_has_str "$LOG_FILE" 'WARN martin::pg::query_tables] Table public.table_source_geog has no spatial index on column geog'
test_log_has_str "$LOG_FILE" 'WARN martin::fonts] Ignoring duplicate font Overpass Mono Regular from tests'
validate_log "$LOG_FILE"
remove_line "${TEST_OUT_DIR}/save_config.yaml" " connection_string: "
echo "------------------------------------------------------------------------------------------------------------------------"
echo "Test minimum auto configured Martin"
TEST_NAME="auto_mini"
LOG_FILE="${LOG_DIR}/${TEST_NAME}.txt"
TEST_OUT_DIR="${TEST_OUT_BASE_DIR}/${TEST_NAME}"
mkdir -p "$TEST_OUT_DIR"
ARG=(--save-config "${TEST_OUT_DIR}/save_config.yaml" tests/fixtures/pmtiles2)
set -x
$MARTIN_BIN "${ARG[@]}" 2>&1 | tee "$LOG_FILE" &
MARTIN_PROC_ID=$(jobs -p | tail -n 1)
{ set +x; } 2> /dev/null
trap "echo 'Stopping Martin server $MARTIN_PROC_ID...'; kill -9 $MARTIN_PROC_ID 2> /dev/null || true; echo 'Stopped Martin server $MARTIN_PROC_ID';" EXIT HUP INT TERM
wait_for "$MARTIN_PROC_ID" Martin "$MARTIN_URL/health"
>&2 echo "Test catalog"
test_jsn catalog_auto catalog
kill_process "$MARTIN_PROC_ID" Martin
validate_log "$LOG_FILE"
echo "------------------------------------------------------------------------------------------------------------------------"
echo "Test pre-configured Martin"
TEST_NAME="configured"
LOG_FILE="${LOG_DIR}/${TEST_NAME}.txt"
TEST_OUT_DIR="${TEST_OUT_BASE_DIR}/${TEST_NAME}"
mkdir -p "$TEST_OUT_DIR"
ARG=(--config tests/config.yaml --max-feature-count 1000 --save-config "${TEST_OUT_DIR}/save_config.yaml" -W 1)
export DATABASE_URL="$MARTIN_DATABASE_URL"
set -x
$MARTIN_BIN "${ARG[@]}" 2>&1 | tee "$LOG_FILE" &
MARTIN_PROC_ID=$(jobs -p | tail -n 1)
{ set +x; } 2> /dev/null
trap "echo 'Stopping Martin server $MARTIN_PROC_ID...'; kill -9 $MARTIN_PROC_ID 2> /dev/null || true; echo 'Stopped Martin server $MARTIN_PROC_ID';" EXIT HUP INT TERM
wait_for "$MARTIN_PROC_ID" Martin "$MARTIN_URL/health"
unset DATABASE_URL
>&2 echo "Test catalog"
test_jsn catalog_cfg catalog
test_jsn cmp table_source,points1,points2
# Test tile sources
test_pbf tbl_0_0_0 table_source/0/0/0
test_pbf cmp_0_0_0 points1,points2/0/0/0
test_pbf fnc_0_0_0 function_zxy_query/0/0/0
test_pbf fnc2_0_0_0 function_zxy_query_test/0/0/0?token=martin
test_png pmt_0_0_0 pmt/0/0/0
test_png pmt2_0_0_0 pmt2/0/0/0 # HTTP pmtiles
# Test sprites
test_jsn spr_src1 sprite/src1.json
test_jsn sdf_spr_src1 sdf_sprite/src1.json
test_png spr_src1 sprite/src1.png
test_png sdf_spr_src1 sdf_sprite/src1.png
test_jsn spr_src1_2x sprite/[email protected]
test_jsn sdf_spr_src1_ sdf_sprite/[email protected]
test_png spr_src1_2x sprite/[email protected]
test_png sdf_spr_src1_ sdf_sprite/[email protected]
test_jsn spr_mysrc sprite/mysrc.json
test_jsn sdf_spr_mysrc sdf_sprite/mysrc.json
test_png spr_mysrc sprite/mysrc.png
test_png sdf_spr_mysrc sdf_sprite/mysrc.png
test_jsn spr_mysrc_2x sprite/[email protected]
test_jsn sdf_spr_mysrc sdf_sprite/[email protected]
test_png spr_mysrc_2x sprite/[email protected]
test_png sdf_spr_mysrc sdf_sprite/[email protected]
test_jsn spr_cmp sprite/src1,mysrc.json
test_jsn sdf_spr_cmp sdf_sprite/src1,mysrc.json
test_png spr_cmp sprite/src1,mysrc.png
test_png sdf_spr_cmp sdf_sprite/src1,mysrc.png
test_jsn spr_cmp_2x sprite/src1,[email protected]
test_jsn sdf_spr_cmp_2 sdf_sprite/src1,[email protected]
test_png spr_cmp_2x sprite/src1,[email protected]
test_png sdf_spr_cmp_2 sdf_sprite/src1,[email protected]
# Test fonts
test_font font_1 font/Overpass%20Mono%20Light/0-255
test_font font_2 font/Overpass%20Mono%20Regular/0-255
test_font font_3 font/Overpass%20Mono%20Regular,Overpass%20Mono%20Light/0-255
# Test comments override
test_jsn tbl_comment_cfg MixPoints
test_jsn fnc_comment_cfg fnc_Mixed_Name
kill_process "$MARTIN_PROC_ID" Martin
test_log_has_str "$LOG_FILE" 'WARN martin::pg::query_tables] Table public.table_source has no spatial index on column geom'
test_log_has_str "$LOG_FILE" 'WARN martin::pg::query_tables] Table public.table_source_geog has no spatial index on column geog'
test_log_has_str "$LOG_FILE" 'WARN martin::fonts] Ignoring duplicate font Overpass Mono Regular from tests'
validate_log "$LOG_FILE"
remove_line "${TEST_OUT_DIR}/save_config.yaml" " connection_string: "
echo "------------------------------------------------------------------------------------------------------------------------"
echo "Test martin-cp"
if [[ "$MARTIN_CP_BIN" != "-" ]]; then
TEST_NAME="martin-cp"
TEST_OUT_DIR="${TEST_OUT_BASE_DIR}/${TEST_NAME}"
mkdir -p "$TEST_OUT_DIR"
export DATABASE_URL="$MARTIN_DATABASE_URL"
CFG=(--default-srid 900913 --auto-bounds calc tests/fixtures/mbtiles tests/fixtures/pmtiles tests/fixtures/pmtiles2)
test_martin_cp "flat" "${CFG[@]}" \
--source table_source --mbtiles-type flat --concurrency 3 \
--min-zoom 0 --max-zoom 6 "--bbox=-2,-1,142.84,45" \
--set-meta "generator=martin-cp v0.0.0"
test_martin_cp "flat-with-hash" "${CFG[@]}" \
--source function_zxy_query_test --url-query 'foo=bar&token=martin' --encoding 'identity' --mbtiles-type flat-with-hash --concurrency 3 \
--min-zoom 0 --max-zoom 6 "--bbox=-2,-1,142.84,45" \
--set-meta "generator=martin-cp v0.0.0"
test_martin_cp "normalized" "${CFG[@]}" \
--source geography-class-png --mbtiles-type normalized --concurrency 3 \
--min-zoom 0 --max-zoom 6 "--bbox=-2,-1,142.84,45" \
--set-meta "generator=martin-cp v0.0.0" --set-meta "name=normalized" --set-meta=center=0,0,0
unset DATABASE_URL
else
echo "Skipping martin-cp tests"
fi
echo "------------------------------------------------------------------------------------------------------------------------"
echo "Test mbtiles utility"
if [[ "$MBTILES_BIN" != "-" ]]; then
TEST_NAME="mbtiles"
TEST_OUT_DIR="${TEST_OUT_BASE_DIR}/${TEST_NAME}"
mkdir -p "$TEST_OUT_DIR"
set -x
$MBTILES_BIN summary ./tests/fixtures/mbtiles/world_cities.mbtiles 2>&1 | tee "$TEST_OUT_DIR/summary.txt"
$MBTILES_BIN meta-all --help 2>&1 | tee "$TEST_OUT_DIR/meta-all_help.txt"
$MBTILES_BIN meta-all ./tests/fixtures/mbtiles/world_cities.mbtiles 2>&1 | tee "$TEST_OUT_DIR/meta-all.txt"
$MBTILES_BIN meta-get --help 2>&1 | tee "$TEST_OUT_DIR/meta-get_help.txt"
$MBTILES_BIN meta-get ./tests/fixtures/mbtiles/world_cities.mbtiles name 2>&1 | tee "$TEST_OUT_DIR/meta-get_name.txt"
$MBTILES_BIN meta-get ./tests/fixtures/mbtiles/world_cities.mbtiles missing_value 2>&1 | tee "$TEST_OUT_DIR/meta-get_missing_value.txt"
$MBTILES_BIN validate ./tests/fixtures/mbtiles/zoomed_world_cities.mbtiles 2>&1 | tee "$TEST_OUT_DIR/validate-ok.txt"
if $MBTILES_BIN validate ./tests/fixtures/files/invalid-tile-idx.mbtiles 2>&1 | tee "$TEST_OUT_DIR/validate-bad-tiles.txt"; then
echo "ERROR: validate with invalid-tile-idx.mbtiles should have failed"
exit 1
fi
if $MBTILES_BIN validate ./tests/fixtures/files/bad_hash.mbtiles 2>&1 | tee "$TEST_OUT_DIR/validate-bad-hash.txt"; then
echo "ERROR: validate with bad_hash.mbtiles should have failed"
exit 1
fi
cp ./tests/fixtures/files/bad_hash.mbtiles "$TEST_TEMP_DIR/fix_bad_hash.mbtiles"
$MBTILES_BIN validate --agg-hash update "$TEST_TEMP_DIR/fix_bad_hash.mbtiles" 2>&1 | tee "$TEST_OUT_DIR/validate-fix.txt"
$MBTILES_BIN validate "$TEST_TEMP_DIR/fix_bad_hash.mbtiles" 2>&1 | tee "$TEST_OUT_DIR/validate-fix2.txt"
# Create diff file
$MBTILES_BIN copy \
./tests/fixtures/mbtiles/world_cities.mbtiles \
"$TEST_TEMP_DIR/world_cities_diff.mbtiles" \
--diff-with-file ./tests/fixtures/mbtiles/world_cities_modified.mbtiles \
2>&1 | tee "$TEST_OUT_DIR/copy_diff.txt"
$MBTILES_BIN diff \
./tests/fixtures/mbtiles/world_cities.mbtiles \
./tests/fixtures/mbtiles/world_cities_modified.mbtiles \
"$TEST_TEMP_DIR/world_cities_diff2.mbtiles" \
2>&1 | tee "$TEST_OUT_DIR/copy_diff2.txt"
$MBTILES_BIN copy \
./tests/fixtures/mbtiles/world_cities.mbtiles \
--diff-with-file ./tests/fixtures/mbtiles/world_cities_modified.mbtiles \
"$TEST_TEMP_DIR/world_cities_bindiff.mbtiles" \
--patch-type bin-diff-gz \
2>&1 | tee "$TEST_OUT_DIR/copy_bindiff.txt"
test_log_has_str "$TEST_OUT_DIR/copy_bindiff.txt" '.*Processing bindiff patches using .* threads...'
$MBTILES_BIN copy \
./tests/fixtures/mbtiles/world_cities.mbtiles \
--apply-patch "$TEST_TEMP_DIR/world_cities_bindiff.mbtiles" \
"$TEST_TEMP_DIR/world_cities_modified2.mbtiles" \
2>&1 | tee "$TEST_OUT_DIR/copy_bindiff2.txt"
test_log_has_str "$TEST_OUT_DIR/copy_bindiff2.txt" '.*Processing bindiff patches using .* threads...'
# Ensure that world_cities_modified and world_cities_modified2 are identical (regular diff is empty)
$MBTILES_BIN copy \
./tests/fixtures/mbtiles/world_cities_modified.mbtiles \
--diff-with-file "$TEST_TEMP_DIR/world_cities_modified2.mbtiles" \
"$TEST_TEMP_DIR/world_cities_bindiff_modified.mbtiles" \
2>&1 | tee "$TEST_OUT_DIR/copy_bindiff3.txt"
$MBTILES_BIN summary "$TEST_TEMP_DIR/world_cities_bindiff_modified.mbtiles" \
2>&1 | tee "$TEST_OUT_DIR/copy_bindiff4.txt"
if command -v sqlite3 > /dev/null; then
# Apply this diff to the original version of the file
cp ./tests/fixtures/mbtiles/world_cities.mbtiles "$TEST_TEMP_DIR/world_cities_copy.mbtiles"
sqlite3 "$TEST_TEMP_DIR/world_cities_copy.mbtiles" \
-bail \
-cmd ".parameter set @diffDbFilename $TEST_TEMP_DIR/world_cities_diff.mbtiles" \
"ATTACH DATABASE @diffDbFilename AS diffDb;" \
"DELETE FROM tiles WHERE (zoom_level, tile_column, tile_row) IN (SELECT zoom_level, tile_column, tile_row FROM diffDb.tiles WHERE tile_data ISNULL);" \
"INSERT OR REPLACE INTO tiles (zoom_level, tile_column, tile_row, tile_data) SELECT * FROM diffDb.tiles WHERE tile_data NOTNULL;"
# Ensure that applying the diff resulted in the modified version of the file
$MBTILES_BIN copy \
--diff-with-file "$TEST_TEMP_DIR/world_cities_copy.mbtiles" \
./tests/fixtures/mbtiles/world_cities_modified.mbtiles \
"$TEST_TEMP_DIR/world_cities_diff_modified.mbtiles" \
2>&1 | tee "$TEST_OUT_DIR/copy_diff2.txt"
sqlite3 "$TEST_TEMP_DIR/world_cities_diff_modified.mbtiles" \
"SELECT COUNT(*) FROM tiles;" \
2>&1 | tee "$TEST_OUT_DIR/copy_apply.txt"
else
echo "---------------------------------------------------------"
echo "##### sqlite3 is not installed, skipping apply test #####"
# Copy expected output files as if they were generated by the test
EXPECTED_DIR="$(dirname "$0")/expected/mbtiles"
cp "$EXPECTED_DIR/copy_diff2.txt" "$TEST_OUT_DIR/copy_diff2.txt"
cp "$EXPECTED_DIR/copy_apply.txt" "$TEST_OUT_DIR/copy_apply.txt"
fi
{ set +x; } 2> /dev/null
else
echo "Skipping mbtiles utility tests"
fi
rm -rf "$TEST_TEMP_DIR"
>&2 echo "All integration tests have passed"