4
* Copyright Ericsson AB 2001-2009. All Rights Reserved.
6
* The contents of this file are subject to the Erlang Public License,
7
* Version 1.1, (the "License"); you may not use this file except in
8
* compliance with the License. You should have received a copy of the
9
* Erlang Public License along with this software. If not, it can be
10
* retrieved online at http://www.erlang.org/.
12
* Software distributed under the License is distributed on an "AS IS"
13
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
* the License for the specific language governing rights and limitations
22
#include <sys/types.h>
30
#include "ei_runner.h"
34
#define _setmode(fd, mode)
39
static char* progname; /* Name of this program (from argv[0]). */
40
static int fd_from_erl; /* File descriptor from Erlang. */
41
static int fd_to_erl; /* File descriptor to Erlang. */
43
static int packet_loop();
44
static void ensure_buf_big_enough();
46
static void reply(char* buf, unsigned size);
50
run_tests(char* argv0, TestCase test_cases[], unsigned number)
57
_setmode(0, _O_BINARY);
58
_setmode(1, _O_BINARY);
62
packet = read_packet(&n);
65
* Dispatch to the appropriate test function.
68
i = packet[0] * 256 + packet[1];
70
fprintf(stderr, "%s: bad test case number %d",
81
/***********************************************************************
83
* R e a d i n g p a c k e t s
85
************************************************************************/
88
* Reads an Erlang term.
90
* Only accepts 't' (term) or 'e' (end of test),
91
* exits program on error
92
* returns 1 on 'e', 0 on 't'
94
int get_bin_term(ei_x_buff* x, ei_term* term)
99
x->buff = read_packet(&len);
102
switch (x->buff[x->index++]) {
106
if (ei_decode_version(x->buff, &x->index, &version) < 0
107
|| ei_decode_ei_term(x->buff, &x->index, term) < 0) {
108
fail("Failed to decode term");
113
fprintf(stderr, "Garbage received: ");
114
dump(x->buff, len, 16);
116
fail("C program received garbage");
123
* Reads a packet from Erlang. The packet must be a standard {packet, 2}
124
* packet. This function aborts if any error is detected (including EOF).
126
* Returns: The number of bytes in the packet.
129
char *read_packet(int *len)
132
unsigned char* io_buf = NULL; /* Buffer for file i/o. */
134
unsigned char header[HEADER_SIZE];
135
unsigned packet_length; /* Length of current packet. */
139
* Read the packet header.
142
bytes_read = readn(fd_from_erl, header, HEADER_SIZE);
144
if (bytes_read == 0) {
145
fprintf(stderr, "%s: Unexpected end of file\n", progname);
148
if (bytes_read != HEADER_SIZE) {
149
fprintf(stderr, "%s: Failed to read packet header\n", progname);
154
* Get the length of this packet.
159
for (i = 0; i < HEADER_SIZE; i++)
160
packet_length = (packet_length << 8) | header[i];
162
if (len) *len=packet_length; /* report length only if caller requested it */
164
if ((io_buf = (char *) malloc(packet_length)) == NULL) {
165
fprintf(stderr, "%s: insufficient memory for i/o buffer of size %d\n",
166
progname, packet_length);
171
* Read the packet itself.
174
bytes_read = readn(fd_from_erl, io_buf, packet_length);
175
if (bytes_read != packet_length) {
176
fprintf(stderr, "%s: couldn't read packet of length %d\r\n",
177
progname, packet_length);
186
/***********************************************************************
187
* S e n d i n g r e p l i e s
189
* The functions below send various types of replies back to Erlang.
190
* Each reply start with a letter indicating the type of reply.
192
* Reply Translated to on Erlang side
193
* ----- ----------------------------
194
* [$b|Bytes] {bytes, Bytes}
196
* [$f] test_server:fail()
197
* [$f|Reason] test_server:fail(Reason)
198
* [$t|EncodedTerm] {term, Term}
200
* [$m|Message] io:format("~s", [Message]) (otherwise ignored)
202
***********************************************************************/
205
* This function reports the outcome of a test fail. It is useful if
206
* you implement a test case entirely in C code.
208
* If the ok argument is zero, a [$f] reply will be sent to the
209
* Erlang side (causing test_server:fail() to be called); otherwise,
210
* the atom 'eot' will be sent to Erlang.
212
* If you need to provide more details on a failure, use the fail() function.
216
do_report(file, line, ok)
219
int ok; /* Zero if failed; non-zero otherwise. */
225
reason = ok ? 'e' : 'f';
228
do_fail(file, line, "Generic failure");
230
/* release all unallocated blocks */
231
/*erl_eterm_release();*/
232
/* check mem usage stats */
233
/*erl_eterm_statistics(&ab, &fb);*/
234
/*if ((ab == 0) && (fb == 0) ) {*/
240
sprintf(sbuf, "still %lu terms allocated,"
241
" %lu on freelist at end of test", ab, fb);
242
do_fail(file, line, sbuf);
249
* This function causes a call to test_server:fail(Reason) on the
253
void do_fail(char* file, int line, char* reason)
258
sprintf(sbuf+1, "%s, line %d: %s", file, line, reason);
259
reply(sbuf, 1+strlen(sbuf+1));
263
* This function sends a message to the Erlang side.
264
* The message will be written to the test servers log file,
265
* but will otherwise be completly ignored.
268
void message(char* format, ...)
274
va_start(ap, format);
275
vsprintf(sbuf+1, format, ap);
278
reply(sbuf, 1+strlen(sbuf+1));
282
* This function sends the given binary term to the Erlang side,
283
* where it will be received as {term, Term} (prefix 't').
285
void send_bin_term(ei_x_buff* x)
289
x2.buff[x2.index++] = 't';
291
reply(x2.buff, x2.index);
296
* This function sends a raw buffer of data to the
297
* Erlang side, where it will be received as {bytes, Bytes} (prefix 'b').
299
void send_buffer(char* buf, int size)
303
send_buf = (char *) malloc(size+1);
305
memcpy(send_buf+1, buf, size);
306
reply(send_buf, size+1);
310
/***********************************************************************
312
* P r i v a t e h e l p e r s
314
***********************************************************************/
317
* Sends a packet back to Erlang.
319
static void reply(char* reply_buf, unsigned size)
321
int n; /* Temporary to hold size. */
322
int i; /* Loop counter. */
326
buf = (char *) malloc(size+HEADER_SIZE);
327
memcpy(buf+HEADER_SIZE, reply_buf, size);
330
* Fill the header starting with the least significant byte.
333
for (i = HEADER_SIZE-1; i >= 0; i--) {
334
buf[i] = (char) n; /* Store least significant byte. */
339
write(fd_to_erl, buf, size);
345
* Reads len number of bytes.
350
int fd; /* File descriptor to read from. */
351
unsigned char *buf; /* Store in this buffer. */
352
int len; /* Number of bytes to read. */
354
int n; /* Byte count in last read call. */
355
int sofar = 0; /* Bytes read so far. */
358
if ((n = read(fd, buf+sofar, len-sofar)) <= 0)
359
/* error or EOF in read */
362
} while (sofar < len);
382
for (i=0; i<imax; i++) {
385
strcpy(comma, ",...");
390
fprintf(stderr, "%u%s", (int)(buf[i]), comma);
392
if (isalpha(buf[i])) {
393
fprintf(stderr, "%c%s", buf[i], comma);
396
fprintf(stderr, "%u%s", (int)(buf[i]), comma);