Commit 362c24c3 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Introduce '-expect-text LIN COL PAT' to wait for text somewhere on screen.

Also reappropriate test a00001 to exercise the Teken code with
the vttest (http://invisible-island.net/vttest/) program, if installed.
parent 5e84ab6e
+libh(teken/teken.h) +libh(teken.h)
// Tell FlexeLint when these don't return // Tell FlexeLint when these don't return
-function(exit, vtc_fatal) -function(exit, vtc_fatal)
......
...@@ -4,7 +4,6 @@ FLOPS=' ...@@ -4,7 +4,6 @@ FLOPS='
-DTOP_BUILDDIR="foo" -DTOP_BUILDDIR="foo"
-I../../lib/libvgz -I../../lib/libvgz
*.c *.c
teken/teken.c
' '
. ../../tools/flint_skel.sh . ../../tools/flint_skel.sh
......
# the first token in a varnishtest file must be "varnishtest", varnishtest "Test Teken terminal emulator"
# but whitespace (SP)
# and (TAB) and comments are fine feature cmd "vttest --version 2>&1 | grep -q Usage"
varnishtest "basic default HTTP transactions with expect"
process p4 -dump {vttest} -start
server s1 {
rxreq process p4 -expect-text 21 11 "Enter choice number (0 - 12):"
expect req.method == GET process p4 -screen_dump
expect req.proto == HTTP/1.1
expect req.url == "/" process p4 -writehex "31 0d"
txresp process p4 -expect-text 14 61 "RETURN"
} process p4 -screen_dump
server s1 -start process p4 -writehex 0d
process p4 -expect-text 14 87 "RETURN"
client c1 -connect ${s1_sock} { process p4 -screen_dump
txreq
rxresp process p4 -writehex 0d
expect resp.proto == HTTP/1.1 process p4 -expect-text 22 7 "RETURN"
expect resp.status == 200 process p4 -screen_dump
expect resp.reason == OK
} process p4 -writehex 0d
process p4 -expect-text 3 132 "i"
client c1 -run process p4 -expect-text 22 7 "RETURN"
process p4 -screen_dump
server s1 -wait
process p4 -writehex 0d
process p4 -expect-text 9 7 "RETURN"
process p4 -screen_dump
process p4 -writehex 0d
process p4 -expect-text 4 1 "This is a correct sentence"
process p4 -expect-text 20 7 "RETURN"
process p4 -screen_dump
process p4 -writehex 0d
process p4 -expect-text 21 11 "Enter choice number (0 - 12):"
process p4 -screen_dump
process p4 -writehex "30 0d"
process p4 -expect-text 12 30 "That's all, folks!"
process p4 -screen_dump
process p4 -wait
...@@ -95,6 +95,8 @@ struct process { ...@@ -95,6 +95,8 @@ struct process {
static VTAILQ_HEAD(, process) processes = static VTAILQ_HEAD(, process) processes =
VTAILQ_HEAD_INITIALIZER(processes); VTAILQ_HEAD_INITIALIZER(processes);
static void term_resize(struct process *pp, int lin, int col);
/********************************************************************** /**********************************************************************
* Terminal emulation * Terminal emulation
*/ */
...@@ -163,11 +165,40 @@ term_copy(void *priv, const teken_rect_t *r, const teken_pos_t *p) ...@@ -163,11 +165,40 @@ term_copy(void *priv, const teken_rect_t *r, const teken_pos_t *p)
} }
} }
static void
term_respond(void *priv, const void *p, size_t l)
{
struct process *pp;
int r;
CAST_OBJ_NOTNULL(pp, priv, PROCESS_MAGIC);
vtc_dump(pp->vl, 4, "term_response", p, l);
r = write(pp->fd_term, p, l);
if (r != l)
vtc_fatal(pp->vl, "Could not write to process: %s",
strerror(errno));
}
static void
term_param(void *priv, int p, unsigned int v)
{
struct process *pp;
CAST_OBJ_NOTNULL(pp, priv, PROCESS_MAGIC);
if (p == TP_132COLS && v)
term_resize(pp, pp->nlin, 132);
if (p == TP_132COLS && !v)
term_resize(pp, pp->nlin, 80);
}
static const teken_funcs_t process_teken_func = { static const teken_funcs_t process_teken_func = {
.tf_cursor = term_cursor, .tf_cursor = term_cursor,
.tf_putchar = term_putchar, .tf_putchar = term_putchar,
.tf_fill = term_fill, .tf_fill = term_fill,
.tf_copy = term_copy, .tf_copy = term_copy,
.tf_respond = term_respond,
.tf_param = term_param,
}; };
static void static void
...@@ -216,6 +247,69 @@ term_resize(struct process *pp, int lin, int col) ...@@ -216,6 +247,69 @@ term_resize(struct process *pp, int lin, int col)
teken_set_winsize(pp->tek, &pos); teken_set_winsize(pp->tek, &pos);
} }
static int
term_match_textline(const struct process *pp, int *x, int y, const char *pat)
{
const char *t;
if (*x == 0) {
t = strstr(pp->vram[y], pat);
if (t != NULL) {
*x = 1 + (t - pp->vram[y]);
return (1);
}
} else if (*x <= pp->ncol) {
t = pp->vram[y] + *x - 1;
if (!memcmp(t, pat, strlen(pat)))
return (1);
}
return (0);
}
static int
term_match_text(const struct process *pp, int *x, int *y, const char *pat)
{
int yy;
if (*y == 0) {
for (yy = 0; yy < pp->nlin; yy++) {
if (term_match_textline(pp, x, yy, pat)) {
*y = yy + 1;
return (1);
}
}
} else if (*y <= pp->nlin) {
if (term_match_textline(pp, x, *y - 1, pat))
return (1);
}
return (0);
}
static void
term_expect_text(struct process *pp,
const char *lin, const char *col, const char *pat)
{
int x, y, l;
char *t;
y = strtoul(lin, NULL, 0);
x = strtoul(col, NULL, 0);
l = strlen(pat);
AZ(pthread_mutex_lock(&pp->mtx));
while (!term_match_text(pp, &x, &y, pat)) {
if (x != 0 && y != 0) {
t = pp->vram[y - 1] + x - 1;
vtc_log(pp->vl, 4,
"text at %d,%d: '%.*s'", y, x, l, t);
}
AZ(pthread_mutex_unlock(&pp->mtx));
usleep(1000000);
AZ(pthread_mutex_lock(&pp->mtx));
}
AZ(pthread_mutex_unlock(&pp->mtx));
vtc_log(pp->vl, 4, "found expected text at %d,%d: '%s'", y, x, pat);
}
/********************************************************************** /**********************************************************************
* Allocate and initialize a process * Allocate and initialize a process
*/ */
...@@ -256,7 +350,7 @@ process_new(const char *name) ...@@ -256,7 +350,7 @@ process_new(const char *name)
VTAILQ_INSERT_TAIL(&processes, p, list); VTAILQ_INSERT_TAIL(&processes, p, list);
teken_init(p->tek, &process_teken_func, p); teken_init(p->tek, &process_teken_func, p);
term_resize(p, 25, 80); term_resize(p, 24, 80);
return (p); return (p);
} }
...@@ -336,7 +430,9 @@ process_stdout(const struct vev *ev, int what) ...@@ -336,7 +430,9 @@ process_stdout(const struct vev *ev, int what)
else if (p->log == 3) else if (p->log == 3)
vtc_hexdump(p->vl, 4, "stdout", buf, i); vtc_hexdump(p->vl, 4, "stdout", buf, i);
(void)write(p->f_stdout, buf, i); (void)write(p->f_stdout, buf, i);
AZ(pthread_mutex_lock(&p->mtx));
teken_input(p->tek, buf, i); teken_input(p->tek, buf, i);
AZ(pthread_mutex_unlock(&p->mtx));
return (0); return (0);
} }
...@@ -740,6 +836,15 @@ process_close(struct process *p) ...@@ -740,6 +836,15 @@ process_close(struct process *p)
* \-writeln STRING * \-writeln STRING
* Same as -write followed by a newline (\\n). * Same as -write followed by a newline (\\n).
* *
* \-writehex HEXSTRING
* Same as -write but interpreted as hexadecimal bytes.
*
* \-expect-text LIN COL PAT
* Wait for PAT to appear at LIN,COL on the virtual screen.
* Lines and columns are numbered 1...N
* LIN==0 means "on any line"
* COL==0 means "anywhere on the line"
*
* \-close * \-close
* Alias for "-kill HUP" * Alias for "-kill HUP"
* *
...@@ -852,6 +957,14 @@ cmd_process(CMD_ARGS) ...@@ -852,6 +957,14 @@ cmd_process(CMD_ARGS)
process_wait(p); process_wait(p);
continue; continue;
} }
if (!strcmp(*av, "-expect-text")) {
AN(av[1]);
AN(av[2]);
AN(av[3]);
term_expect_text(p, av[1], av[2], av[3]);
av += 3;
continue;
}
if (!strcmp(*av, "-screen_dump")) { if (!strcmp(*av, "-screen_dump")) {
term_screen_dump(p); term_screen_dump(p);
continue; continue;
...@@ -875,7 +988,9 @@ cmd_process(CMD_ARGS) ...@@ -875,7 +988,9 @@ cmd_process(CMD_ARGS)
col = atoi(av[2]); col = atoi(av[2]);
assert(col > 1); assert(col > 1);
av += 2; av += 2;
AZ(pthread_mutex_lock(&p->mtx));
term_resize(p, lin, col); term_resize(p, lin, col);
AZ(pthread_mutex_unlock(&p->mtx));
process_winsz(p, p->fd_term); process_winsz(p, p->fd_term);
} }
if (!strcmp(*av, "-write")) { if (!strcmp(*av, "-write")) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment