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
|
/*
* Test suite for streaming data from the server.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2019 Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2009-2010, 2012-2014
* The Board of Trustees of the Leland Stanford Junior University
*
* SPDX-License-Identifier: MIT
*/
#include <config.h>
#include <portable/system.h>
#include <client/internal.h>
#include <client/remctl.h>
#include <tests/tap/basic.h>
#include <tests/tap/kerberos.h>
#include <tests/tap/remctl.h>
#include <util/protocol.h>
int
main(void)
{
struct kerberos_config *config;
struct remctl *r;
struct remctl_output *output;
size_t total;
const char *command_streaming[] = {"test", "streaming", NULL};
const char *command_cat[] = {"test", "large-output", "1728361", NULL};
/* Unless we have Kerberos available, we can't really do anything. */
config = kerberos_setup(TAP_KRB_NEEDS_KEYTAB);
remctld_start(config, "data/conf-simple", NULL);
plan(45);
/* First, version 2. */
r = remctl_new();
ok(r != NULL, "remctl_new");
ok(remctl_open(r, "localhost", 14373, config->principal), "remctl_open");
ok(remctl_command(r, command_streaming), "remctl_command streaming");
output = remctl_output(r);
ok(output != NULL, "output is not null");
if (output == NULL)
ok_block(4, false, "output is not null");
else {
is_int(REMCTL_OUT_OUTPUT, output->type, "...and is correct type");
is_int(23, output->length, "right length for first line");
if (output->data == NULL)
ok(0, "...right data for first line");
else
ok(memcmp("This is the first line\n", output->data, 23) == 0,
"...right data for first line");
is_int(1, output->stream, "...right stream");
}
output = remctl_output(r);
ok(output != NULL, "second output is not null");
if (output == NULL)
ok_block(4, false, "second output is not null");
else {
is_int(REMCTL_OUT_OUTPUT, output->type, "...and is correct type");
is_int(24, output->length, "right length for second line");
if (output->data == NULL)
ok(0, "...right data for second line");
else
ok(memcmp("This is the second line\n", output->data, 24) == 0,
"...right data for second line");
is_int(2, output->stream, "...right stream");
}
output = remctl_output(r);
ok(output != NULL, "third output is not null");
if (output == NULL)
ok_block(4, false, "third output is not null");
else {
is_int(REMCTL_OUT_OUTPUT, output->type, "...and is correct type");
is_int(23, output->length, "right length for third line");
if (output->data == NULL)
ok(0, "...right data for third line");
else
ok(memcmp("This is the third line\n", output->data, 23) == 0,
"...right data for third line");
is_int(1, output->stream, "...right stream");
}
output = remctl_output(r);
ok(output != NULL, "status is not null");
if (output == NULL)
ok_block(2, false, "status is not null");
else {
is_int(REMCTL_OUT_STATUS, output->type, "...and is right type");
is_int(0, output->status, "...and is right status");
}
/*
* Test again with cat, which tests the interaction between lots of data
* and the child process exiting.
*/
ok(remctl_command(r, command_cat), "remctl_command cat");
output = remctl_output(r);
total = 0;
while (output != NULL) {
if (output->type == REMCTL_OUT_OUTPUT) {
if (output->stream == 1)
total += output->length;
else
diag("%.*s", (int) output->length, output->data);
} else if (output->type == REMCTL_OUT_STATUS) {
is_int(0, output->status, "...correct exit status");
break;
} else {
is_int(REMCTL_OUT_OUTPUT, output->type, "Incorrect output type");
ok(false, "Incorrect output type");
break;
}
output = remctl_output(r);
}
is_int(1728361, total, "...correct total size");
remctl_close(r);
/* Now, version 1. */
r = remctl_new();
ok(r != NULL, "remctl_new protocol version 1");
if (r == NULL)
bail("remctl_new returned NULL");
r->protocol = 1;
ok(remctl_open(r, "localhost", 14373, config->principal), "remctl_open");
ok(remctl_command(r, command_streaming), "remctl_command");
output = remctl_output(r);
ok(output != NULL, "output is not null");
if (output == NULL)
ok_block(4, false, "output is not null");
else {
is_int(REMCTL_OUT_OUTPUT, output->type, "...and is right type");
is_int(70, output->length, "...and right length");
if (output->data == NULL)
ok(0, "...and right data");
else
ok(memcmp("This is the first line\nThis is the second line\n"
"This is the third line\n",
output->data, 70)
== 0,
"...and right data");
is_int(1, output->stream, "...and right stream");
}
output = remctl_output(r);
ok(output != NULL, "status token is not null");
if (output == NULL)
ok_block(2, false, "status token is not null");
else {
is_int(REMCTL_OUT_STATUS, output->type, "...and is right type");
is_int(0, output->status, "...and is right status");
}
remctl_close(r);
/*
* Test with more data than will fit into a single token. Since protocol
* one does not support multiple tokens, this requires truncation, but we
* should still get the correct exit status.
*/
r = remctl_new();
ok(r != NULL, "remctl_new protocol version 1");
if (r == NULL)
bail("remctl_new returned NULL");
r->protocol = 1;
ok(remctl_open(r, "localhost", 14373, config->principal), "remctl_open");
ok(remctl_command(r, command_cat), "remctl_command cat");
output = remctl_output(r);
ok(output != NULL, "output is not null");
if (output == NULL)
ok_block(3, false, "output is not null");
else {
is_int(REMCTL_OUT_OUTPUT, output->type, "...and is right type");
is_int(TOKEN_MAX_OUTPUT_V1, output->length, "...and right length");
is_int(1, output->stream, "...and right stream");
}
output = remctl_output(r);
ok(output != NULL, "status token is not null");
if (output == NULL)
ok_block(2, false, "status token is not null");
else {
is_int(REMCTL_OUT_STATUS, output->type, "...and is right type");
is_int(0, output->status, "...and is right status");
}
remctl_close(r);
return 0;
}
|