Skip to content

Commit f70ae45

Browse files
committed
added test for Cylc 7
1 parent 8f4a1ac commit f70ae45

File tree

2 files changed

+317
-0
lines changed

2 files changed

+317
-0
lines changed
Binary file not shown.
Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
#!/bin/bash
2+
# THIS FILE IS PART OF THE CYLC SUITE ENGINE.
3+
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
#-------------------------------------------------------------------------------
18+
# Basic tests for "cylc review".
19+
#-------------------------------------------------------------------------------
20+
. "$(dirname "$0")/test_header"
21+
requires_cherrypy
22+
23+
set_test_number 57
24+
#-------------------------------------------------------------------------------
25+
# Initialise, validate and run a suite for testing with
26+
# install_workflow "${TEST_NAME_BASE}" "${TEST_NAME_BASE}"
27+
init_workflow ${TEST_NAME_BASE} <<__HERE__
28+
__HERE__
29+
cp "$TEST_SOURCE_DIR/00-basic.db" "${WORKFLOW_RUN_DIR}/log/db"
30+
mv ${WORKFLOW_RUN_DIR}/flow.cylc ${WORKFLOW_RUN_DIR}/suite.rc
31+
for FILE in \
32+
'log/suite/log' \
33+
'log/job/20000101T0000Z/foo0/01/job' \
34+
'log/job/20000101T0000Z/foo0/01/job.out' \
35+
'log/job/20000101T0000Z/foo1/01/job' \
36+
'log/job/20000101T0000Z/foo1/01/job.out'
37+
do
38+
mkdir -p "$(dirname ${WORKFLOW_RUN_DIR}/${FILE})"
39+
echo "This is the ${FILE}" > "${WORKFLOW_RUN_DIR}/${FILE}"
40+
done
41+
#-------------------------------------------------------------------------------
42+
# Initialise WSGI application for the cylc review web service
43+
cylc_ws_init 'cylc' 'review'
44+
if [[ -z "${TEST_CYLC_WS_PORT}" ]]; then
45+
exit 1
46+
fi
47+
48+
# Set up standard URL escaping of forward slashes in 'cylctb-' suite names.
49+
ESC_WORKFLOW_NAME="$(echo ${WORKFLOW_NAME} | sed 's|/|%2F|g')"
50+
#-------------------------------------------------------------------------------
51+
# Data transfer output check for review homepage
52+
TEST_NAME="${TEST_NAME_BASE}-curl-root"
53+
run_ok "${TEST_NAME}" curl -I -s "${TEST_CYLC_WS_URL}"
54+
grep_ok 'HTTP/.* 200 OK' "${TEST_NAME}.stdout"
55+
56+
TEST_NAME="${TEST_NAME_BASE}-200-curl-root-json"
57+
run_ok "${TEST_NAME}" curl "${TEST_CYLC_WS_URL}/?form=json"
58+
59+
HOSTNAME=$(hostname -s)
60+
FULLHOSTNAME=$(hostname --fqdn)
61+
62+
cylc_ws_json_greps "${TEST_NAME}.stdout" "${TEST_NAME}.stdout" \
63+
"[('cylc_version',), '$(cylc version | cut -d' ' -f 2)']" \
64+
"[('title',), 'Cylc Review']" \
65+
"[('host',), '${HOSTNAME}']"
66+
#-------------------------------------------------------------------------------
67+
# Data transfer output check for a specific user's page including non-existent
68+
TEST_NAME="${TEST_NAME_BASE}-200-curl-suites"
69+
run_ok "${TEST_NAME}" curl -I "${TEST_CYLC_WS_URL}/suites/${USER}"
70+
grep_ok 'HTTP/.* 200 OK' "${TEST_NAME}.stdout"
71+
72+
TEST_NAME="${TEST_NAME_BASE}-200-curl-suites-json"
73+
run_ok "${TEST_NAME}" curl "${TEST_CYLC_WS_URL}/suites/${USER}?form=json"
74+
cylc_ws_json_greps "${TEST_NAME}.stdout" "${TEST_NAME}.stdout" \
75+
"[('cylc_version',), '$(cylc version | cut -d' ' -f 2)']" \
76+
"[('title',), 'Cylc Review']" \
77+
"[('host',), '${HOSTNAME}']" \
78+
"[('user',), '${USER}']"
79+
80+
TEST_NAME="${TEST_NAME_BASE}-404-curl-suites"
81+
run_ok "${TEST_NAME}" curl -I "${TEST_CYLC_WS_URL}/suites/no-such-user"
82+
grep_ok 'HTTP/.* 404 Not Found' "${TEST_NAME}.stdout"
83+
#-------------------------------------------------------------------------------
84+
# Connection check for a specific suite's cycles & jobs page
85+
for METHOD in 'cycles'; do
86+
TEST_NAME="${TEST_NAME_BASE}-200-curl-${METHOD}"
87+
run_ok "${TEST_NAME}" \
88+
curl -I "${TEST_CYLC_WS_URL}/${METHOD}/${USER}/${ESC_WORKFLOW_NAME}"
89+
grep_ok 'HTTP/.* 200 OK' "${TEST_NAME}.stdout"
90+
91+
TEST_NAME="${TEST_NAME_BASE}-404-1-curl-${METHOD}"
92+
run_ok "${TEST_NAME}" \
93+
curl -I "${TEST_CYLC_WS_URL}/${METHOD}/no-such-user/${ESC_WORKFLOW_NAME}"
94+
grep_ok 'HTTP/.* 404 Not Found' "${TEST_NAME}.stdout"
95+
96+
TEST_NAME="${TEST_NAME_BASE}-404-2-curl-${METHOD}"
97+
run_ok "${TEST_NAME}" \
98+
curl -I "${TEST_CYLC_WS_URL}/${METHOD}/${USER}?suite=no-such-suite"
99+
grep_ok 'HTTP/.* 404 Not Found' "${TEST_NAME}.stdout"
100+
done
101+
#-------------------------------------------------------------------------------
102+
# Check that waiting tasks appear when "task_status=waiting"
103+
TEST_NAME="${TEST_NAME_BASE}-200-waiting-tasks"
104+
105+
URL_PARAMS='?form=json&task_status=waiting'
106+
run_ok "${TEST_NAME}" \
107+
curl "${TEST_CYLC_WS_URL}/taskjobs/${USER}/${ESC_WORKFLOW_NAME}${URL_PARAMS}"
108+
109+
FOO2="{'cycle': '20010101T0000Z', 'name': 'foo0', 'submit_num': 0}"
110+
FOO3="{'cycle': '20010101T0000Z', 'name': 'foo1', 'submit_num': 0}"
111+
cylc_ws_json_greps "${TEST_NAME}.stdout" "${TEST_NAME}.stdout" \
112+
"[('entries', ${FOO2}, 'events',), [None, None, None]]" \
113+
"[('entries', ${FOO3}, 'events',), [None, None, None]]"
114+
#-------------------------------------------------------------------------------
115+
# Data transfer output check for a specific suite's cycles & jobs page
116+
TEST_NAME="${TEST_NAME_BASE}-200-curl-cycles"
117+
118+
run_ok "${TEST_NAME}" \
119+
curl "${TEST_CYLC_WS_URL}/cycles/${USER}/${ESC_WORKFLOW_NAME}?form=json"
120+
121+
cylc_ws_json_greps "${TEST_NAME}.stdout" "${TEST_NAME}.stdout" \
122+
"[('cylc_version',), '$(cylc version | cut -d' ' -f 2)']" \
123+
"[('title',), 'Cylc Review']" \
124+
"[('host',), '${HOSTNAME}']" \
125+
"[('user',), '${USER}']" \
126+
"[('suite',), '${WORKFLOW_NAME}']" \
127+
"[('page',), 1]" \
128+
"[('n_pages',), 1]" \
129+
"[('per_page',), 100]" \
130+
"[('order',), None]" \
131+
"[('states', 'is_running',), False]" \
132+
"[('states', 'is_failed',), False]" \
133+
"[('of_n_entries',), 1]" \
134+
"[('entries', {'cycle': '20000101T0000Z'}, 'n_states', 'success',), 2]" \
135+
"[('entries', {'cycle': '20000101T0000Z'}, 'n_states', 'job_success',), 2]"
136+
137+
TEST_NAME="${TEST_NAME_BASE}-200-curl-jobs"
138+
FOO0="{'cycle': '20000101T0000Z', 'name': 'foo0', 'submit_num': 1}"
139+
FOO0_JOB='log/job/20000101T0000Z/foo0/01/job'
140+
FOO1="{'cycle': '20000101T0000Z', 'name': 'foo1', 'submit_num': 1}"
141+
FOO1_JOB='log/job/20000101T0000Z/foo1/01/job'
142+
143+
# Because we simulating the creation of a Cylc 7 Workflow we have
144+
# to manually make all these files :( -
145+
for JOBDIR in "${FOO0_JOB}" "${FOO1_JOB}"; do
146+
JOBDIR="$(dirname ${WORKFLOW_RUN_DIR}/${JOBDIR})"
147+
mkdir -p "${JOBDIR}"
148+
for file in "out" "err"; do
149+
touch "${JOBDIR}/job.${file}"
150+
done
151+
for seq_key in 01 05 10; do
152+
touch "${JOBDIR}/job.${seq_key}.txt"
153+
done
154+
for BUNCH in "iris" "holly" "daisy"; do
155+
touch "${JOBDIR}/bunch.${BUNCH}.out"
156+
done
157+
for TRACE in 2 32 256; do
158+
touch "${JOBDIR}/job.trace.${TRACE}.html"
159+
done
160+
done
161+
162+
run_ok "${TEST_NAME}" \
163+
curl "${TEST_CYLC_WS_URL}/taskjobs/${USER}/${ESC_WORKFLOW_NAME}?form=json"
164+
165+
# of_n_entries should be 2, but only affects Cylc 7, so ignored:
166+
cylc_ws_json_greps "${TEST_NAME}.stdout" "${TEST_NAME}.stdout" \
167+
"[('cylc_version',), '$(cylc version | cut -d' ' -f 2)']" \
168+
"[('title',), 'Cylc Review']" \
169+
"[('host',), '${HOSTNAME}']" \
170+
"[('user',), '${USER}']" \
171+
"[('suite',), '${WORKFLOW_NAME}']" \
172+
"[('is_option_on',), False]" \
173+
"[('page',), 1]" \
174+
"[('n_pages',), 1]" \
175+
"[('per_page',), 15]" \
176+
"[('per_page_default',), 15]" \
177+
"[('per_page_max',), 300]" \
178+
"[('cycles',), None]" \
179+
"[('order',), None]" \
180+
"[('states', 'is_running',), False]" \
181+
"[('states', 'is_failed',), False]" \
182+
"[('of_n_entries',), 4]" \
183+
"[('entries', ${FOO0}, 'task_status',), 'succeeded']" \
184+
"[('entries', ${FOO0}, 'host',), '${FULLHOSTNAME}']" \
185+
"[('entries', ${FOO0}, 'submit_method',), 'background']" \
186+
"[('entries', ${FOO0}, 'logs', 'job', 'path'), '${FOO0_JOB}']" \
187+
"[('entries', ${FOO0}, 'logs', 'job.err', 'path'), '${FOO0_JOB}.err']" \
188+
"[('entries', ${FOO0}, 'logs', 'job.out', 'path'), '${FOO0_JOB}.out']" \
189+
"[('entries', ${FOO0}, 'logs', 'job.01.txt', 'seq_key'), 'job.*.txt']" \
190+
"[('entries', ${FOO0}, 'logs', 'job.05.txt', 'seq_key'), 'job.*.txt']" \
191+
"[('entries', ${FOO0}, 'logs', 'job.10.txt', 'seq_key'), 'job.*.txt']" \
192+
"[('entries', ${FOO0}, 'seq_logs_indexes', 'job.*.txt', '1'), 'job.01.txt']" \
193+
"[('entries', ${FOO0}, 'seq_logs_indexes', 'job.*.txt', '5'), 'job.05.txt']" \
194+
"[('entries', ${FOO0}, 'seq_logs_indexes', 'job.*.txt', '10'), 'job.10.txt']" \
195+
"[('entries', ${FOO0}, 'logs', 'bunch.holly.out', 'seq_key'), 'bunch.*.out']" \
196+
"[('entries', ${FOO0}, 'logs', 'bunch.iris.out', 'seq_key'), 'bunch.*.out']" \
197+
"[('entries', ${FOO0}, 'logs', 'bunch.daisy.out', 'seq_key'), 'bunch.*.out']" \
198+
"[('entries', ${FOO0}, 'seq_logs_indexes', 'bunch.*.out', 'holly'), 'bunch.holly.out']" \
199+
"[('entries', ${FOO0}, 'seq_logs_indexes', 'bunch.*.out', 'iris'), 'bunch.iris.out']" \
200+
"[('entries', ${FOO0}, 'seq_logs_indexes', 'bunch.*.out', 'daisy'), 'bunch.daisy.out']" \
201+
"[('entries', ${FOO0}, 'logs', 'job.trace.2.html', 'seq_key'), 'job.trace.*.html']" \
202+
"[('entries', ${FOO0}, 'logs', 'job.trace.32.html', 'seq_key'), 'job.trace.*.html']" \
203+
"[('entries', ${FOO0}, 'logs', 'job.trace.256.html', 'seq_key'), 'job.trace.*.html']" \
204+
"[('entries', ${FOO0}, 'seq_logs_indexes', 'job.trace.*.html', '2'), 'job.trace.2.html']" \
205+
"[('entries', ${FOO0}, 'seq_logs_indexes', 'job.trace.*.html', '32'), 'job.trace.32.html']" \
206+
"[('entries', ${FOO0}, 'seq_logs_indexes', 'job.trace.*.html', '256'), 'job.trace.256.html']" \
207+
"[('entries', ${FOO1}, 'task_status',), 'succeeded']" \
208+
"[('entries', ${FOO1}, 'host',), '${FULLHOSTNAME}']" \
209+
"[('entries', ${FOO1}, 'submit_method',), 'background']" \
210+
"[('entries', ${FOO1}, 'logs', 'job', 'path'), '${FOO1_JOB}']" \
211+
"[('entries', ${FOO1}, 'logs', 'job.err', 'path'), '${FOO1_JOB}.err']" \
212+
"[('entries', ${FOO1}, 'logs', 'job.out', 'path'), '${FOO1_JOB}.out']" \
213+
"[('entries', ${FOO1}, 'logs', 'job.01.txt', 'seq_key'), 'job.*.txt']" \
214+
"[('entries', ${FOO1}, 'logs', 'job.05.txt', 'seq_key'), 'job.*.txt']" \
215+
"[('entries', ${FOO1}, 'logs', 'job.10.txt', 'seq_key'), 'job.*.txt']" \
216+
"[('entries', ${FOO1}, 'seq_logs_indexes', 'job.*.txt', '1'), 'job.01.txt']" \
217+
"[('entries', ${FOO1}, 'seq_logs_indexes', 'job.*.txt', '5'), 'job.05.txt']" \
218+
"[('entries', ${FOO1}, 'seq_logs_indexes', 'job.*.txt', '10'), 'job.10.txt']" \
219+
"[('entries', ${FOO1}, 'logs', 'bunch.holly.out', 'seq_key'), 'bunch.*.out']" \
220+
"[('entries', ${FOO1}, 'logs', 'bunch.iris.out', 'seq_key'), 'bunch.*.out']" \
221+
"[('entries', ${FOO1}, 'logs', 'bunch.daisy.out', 'seq_key'), 'bunch.*.out']" \
222+
"[('entries', ${FOO1}, 'seq_logs_indexes', 'bunch.*.out', 'holly'), 'bunch.holly.out']" \
223+
"[('entries', ${FOO1}, 'seq_logs_indexes', 'bunch.*.out', 'iris'), 'bunch.iris.out']" \
224+
"[('entries', ${FOO1}, 'seq_logs_indexes', 'bunch.*.out', 'daisy'), 'bunch.daisy.out']" \
225+
"[('entries', ${FOO1}, 'logs', 'job.trace.2.html', 'seq_key'), 'job.trace.*.html']" \
226+
"[('entries', ${FOO1}, 'logs', 'job.trace.32.html', 'seq_key'), 'job.trace.*.html']" \
227+
"[('entries', ${FOO1}, 'logs', 'job.trace.256.html', 'seq_key'), 'job.trace.*.html']" \
228+
"[('entries', ${FOO1}, 'seq_logs_indexes', 'job.trace.*.html', '2'), 'job.trace.2.html']" \
229+
"[('entries', ${FOO1}, 'seq_logs_indexes', 'job.trace.*.html', '32'), 'job.trace.32.html']" \
230+
"[('entries', ${FOO1}, 'seq_logs_indexes', 'job.trace.*.html', '256'), 'job.trace.256.html']"
231+
232+
#-------------------------------------------------------------------------------
233+
# Data transfer output check for a suite run directory with only a "log/db"
234+
COPY_NAME="${WORKFLOW_NAME}-copy"
235+
cylc register "${COPY_NAME}"
236+
237+
CYLC_RUN_DIR="${HOME}/cylc-run"
238+
mkdir -p "${CYLC_RUN_DIR}/${COPY_NAME}/log/"
239+
cp "${WORKFLOW_RUN_DIR}/log/db" "${CYLC_RUN_DIR}/${COPY_NAME}/log/"
240+
cp "${WORKFLOW_RUN_DIR}/suite.rc" "${CYLC_RUN_DIR}/${COPY_NAME}/"
241+
242+
ESC_COPY_NAME="$(echo ${COPY_NAME} | sed 's|/|%2F|g')"
243+
run_ok "${TEST_NAME}-bare" \
244+
curl "${TEST_CYLC_WS_URL}/taskjobs/${USER}?suite=${ESC_COPY_NAME}&form=json"
245+
246+
cylc_ws_json_greps "${TEST_NAME}-bare.stdout" "${TEST_NAME}-bare.stdout" \
247+
"[('suite',), '${COPY_NAME}']"
248+
249+
for FILE in \
250+
'log/suite/log' \
251+
'log/job/20000101T0000Z/foo0/01/job' \
252+
'log/job/20000101T0000Z/foo0/01/job.out' \
253+
'log/job/20000101T0000Z/foo1/01/job' \
254+
'log/job/20000101T0000Z/foo1/01/job.out'
255+
do
256+
TEST_NAME="${TEST_NAME_BASE}-200-curl-view-$(tr '/' '-' <<<"${FILE}")"
257+
run_ok "${TEST_NAME}" \
258+
curl -I "${TEST_CYLC_WS_URL}/view/${USER}/${ESC_WORKFLOW_NAME}?path=${FILE}"
259+
grep_ok 'HTTP/.* 200 OK' "${TEST_NAME}.stdout"
260+
MODE='&mode=download'
261+
run_ok "${TEST_NAME}-download" \
262+
curl "${TEST_CYLC_WS_URL}/view/${USER}/${ESC_WORKFLOW_NAME}?path=${FILE}${MODE}"
263+
cmp_ok "${TEST_NAME}-download.stdout" \
264+
"${TEST_NAME}-download.stdout" "${HOME}/cylc-run/${WORKFLOW_NAME}/${FILE}"
265+
done
266+
267+
TEST_NAME="${TEST_NAME_BASE}-404-curl-view-garbage"
268+
run_ok "${TEST_NAME}" \
269+
curl -I \
270+
"${TEST_CYLC_WS_URL}/view/${USER}/${ESC_WORKFLOW_NAME}?path=log/of/minus-one"
271+
grep_ok 'HTTP/.* 404 Not Found' "${TEST_NAME}.stdout"
272+
#-------------------------------------------------------------------------------
273+
# Test of the file search feature
274+
TEST_NAME="${TEST_NAME_BASE}-200-curl-viewsearch"
275+
FILE='log/job/20000101T0000Z/foo1/01/job.out'
276+
MODE="&mode=text"
277+
URL="${TEST_CYLC_WS_URL}/viewsearch/${USER}/${ESC_WORKFLOW_NAME}?path=${FILE}${MODE}\
278+
&search_mode=TEXT&search_string=This%20is%20the%20log"
279+
280+
run_ok "${TEST_NAME}" curl -I "${URL}"
281+
grep_ok 'HTTP/.* 200 OK' "${TEST_NAME}.stdout"
282+
283+
TEST_NAME="${TEST_NAME_BASE}-200-curl-viewsearch-download"
284+
run_ok "${TEST_NAME}" \
285+
curl "${URL}"
286+
grep_ok '<span class="highlight">This is the log</span>' \
287+
"${TEST_NAME}.stdout"
288+
#-------------------------------------------------------------------------------
289+
# Test requesting a file outside of the suite directory tree:
290+
# 1. By absolute path.
291+
TEST_NAME="${TEST_NAME_BASE}-403-curl-view-outside-absolute"
292+
run_ok "${TEST_NAME}" \
293+
curl -I \
294+
"${TEST_CYLC_WS_URL}/view/${USER}/${ESC_WORKFLOW_NAME}?path=/dev/null"
295+
grep_ok 'HTTP/.* 403 Forbidden' "${TEST_NAME}.stdout"
296+
# 2. By absolute path to imaginary suite directory.
297+
TEST_NAME="${TEST_NAME_BASE}-403-curl-view-outside-imag"
298+
IMG_TEST_DIR="${WORKFLOW_RUN_DIR}-imag"
299+
mkdir -p "${IMG_TEST_DIR}"
300+
echo 'Welcome to the imaginary suite.'>"${IMG_TEST_DIR}/welcome.txt"
301+
run_ok "${TEST_NAME}" \
302+
curl -I \
303+
"${TEST_CYLC_WS_URL}/view/${USER}/${ESC_WORKFLOW_NAME}?path=${IMG_TEST_DIR}/welcome.txt"
304+
grep_ok 'HTTP/.* 403 Forbidden' "${TEST_NAME}.stdout"
305+
# 3. By relative path.
306+
TEST_NAME="${TEST_NAME_BASE}-403-curl-view-outside-relative"
307+
run_ok "${TEST_NAME}" \
308+
curl -I \
309+
"${TEST_CYLC_WS_URL}/view/${USER}/${ESC_WORKFLOW_NAME}?path=../$(basename $IMG_TEST_DIR)/welcome.txt"
310+
grep_ok 'HTTP/.* 403 Forbidden' "${TEST_NAME}.stdout"
311+
rm "${IMG_TEST_DIR}/welcome.txt"
312+
rmdir "${IMG_TEST_DIR}"
313+
#-------------------------------------------------------------------------------
314+
# Tidy up - note suite trivial so stops early on by itself
315+
purge "${WORKFLOW_NAME}"
316+
cylc_ws_kill
317+
exit

0 commit comments

Comments
 (0)