mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-20 05:37:57 +00:00
Improve test framework: create_file()
New executable in Makefile 'all' target: tfw_createfile. New str.h function: str_to_ll_scaled().
This commit is contained in:
parent
aba7e417c4
commit
d38ce66c95
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,6 +19,7 @@ nacl/nacllib.txt
|
||||
serval.c
|
||||
/servald
|
||||
/directory_service
|
||||
/tfw_createfile
|
||||
*.so
|
||||
test.*.log
|
||||
testlog
|
||||
|
@ -54,7 +54,7 @@ CFLAGS+=-D_DARWIN_C_SOURCE
|
||||
|
||||
DEFS= @DEFS@
|
||||
|
||||
all: servald libmonitorclient.so libmonitorclient.a
|
||||
all: servald libmonitorclient.so libmonitorclient.a tfw_createfile
|
||||
|
||||
sqlite-amalgamation-3070900/sqlite3.o: sqlite-amalgamation-3070900/sqlite3.c
|
||||
@echo CC $<
|
||||
@ -72,6 +72,10 @@ directory_service: $(MDPCLIENTOBJS) directory_service.o
|
||||
@echo LINK $@
|
||||
@$(CC) $(CFLAGS) -Wall -o $@ $(MDPCLIENTOBJS) directory_service.o $(LDFLAGS)
|
||||
|
||||
tfw_createfile: tfw_createfile.o str.o
|
||||
@echo LINK $@
|
||||
@$(CC) $(CFLAGS) -Wall -o $@ tfw_createfile.o str.o
|
||||
|
||||
# This does not build on 64 bit elf platforms as NaCL isn't built with -fPIC
|
||||
# DOC 20120615
|
||||
libservald.so: $(OBJS)
|
||||
|
27
str.c
27
str.c
@ -17,6 +17,7 @@
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
@ -76,3 +77,29 @@ char *str_str(char *haystack, const char *needle, int haystack_len)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int str_to_ll_scaled(const char *str, int base, long long *result, char **afterp)
|
||||
{
|
||||
if (!(isdigit(*str) || *str == '-' || *str == '+'))
|
||||
return 0;
|
||||
char *end;
|
||||
long long value = strtoll(str, &end, base);
|
||||
if (end == str)
|
||||
return 0;
|
||||
switch (*end) {
|
||||
case '\0': break;
|
||||
case 'k': value *= 1000LL; ++end; break;
|
||||
case 'K': value *= 1024LL; ++end; break;
|
||||
case 'm': value *= 1000LL * 1000LL; ++end; break;
|
||||
case 'M': value *= 1024LL * 1024LL; ++end; break;
|
||||
case 'g': value *= 1000LL * 1000LL * 1000LL; ++end; break;
|
||||
case 'G': value *= 1024LL * 1024LL * 1024LL; ++end; break;
|
||||
default: return 0;
|
||||
}
|
||||
if (afterp)
|
||||
*afterp = end;
|
||||
else if (*end)
|
||||
return 0;
|
||||
*result = value;
|
||||
return 1;
|
||||
}
|
||||
|
44
str.h
44
str.h
@ -21,15 +21,17 @@
|
||||
#define __STR_H__
|
||||
|
||||
/* Check if a given string starts with a given sub-string. If so, return 1 and, if afterp is not
|
||||
NULL, set *afterp to point to the character immediately following the substring. Otherwise
|
||||
return 0.
|
||||
This function is used to parse HTTP headers and responses, which are typically not
|
||||
nul-terminated, but are held in a buffer which has an associated length. To avoid this function
|
||||
running past the end of the buffer, the caller must ensure that the buffer contains a sub-string
|
||||
that is not part of the sub-string being sought, eg, "\r\n\r\n" as detected by
|
||||
http_header_complete(). This guarantees that this function will return nonzero before running
|
||||
past the end of the buffer.
|
||||
@author Andrew Bettison <andrew@servalproject.com>
|
||||
* NULL, set *afterp to point to the character immediately following the substring. Otherwise
|
||||
* return 0.
|
||||
*
|
||||
* This function is used to parse HTTP headers and responses, which are typically not
|
||||
* nul-terminated, but are held in a buffer which has an associated length. To avoid this function
|
||||
* running past the end of the buffer, the caller must ensure that the buffer contains a sub-string
|
||||
* that is not part of the sub-string being sought, eg, "\r\n\r\n" as detected by
|
||||
* http_header_complete(). This guarantees that this function will return nonzero before running
|
||||
* past the end of the buffer.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int str_startswith(char *str, const char *substring, char **afterp);
|
||||
|
||||
@ -37,12 +39,30 @@ int str_startswith(char *str, const char *substring, char **afterp);
|
||||
*/
|
||||
int strcase_startswith(char *str, const char *substring, char **afterp);
|
||||
|
||||
/* like strstr(), but doesn't depend on null termination.
|
||||
@author Paul Gardner-Stephen <paul@servalproject.org>
|
||||
@author Andrew Bettison <andrew@servalproject.com>
|
||||
/* like strstr(3), but doesn't depend on null termination.
|
||||
*
|
||||
* @author Paul Gardner-Stephen <paul@servalproject.org>
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
char *str_str(char *haystack, const char *needle, int haystack_len);
|
||||
|
||||
/* Parse a string as an integer in ASCII radix notation in the given 'base' (eg, base=10 means
|
||||
* decimal) and scale the result by a factor given by an optional suffix "scaling" character in the
|
||||
* set {kKmMgG}: 'k' = 1e3, 'K' = 1<<10, 'm' = 1e6, 'M' = 1<<20, 'g' = 1e9, 'G' = * 1<<30.
|
||||
*
|
||||
* Return 1 if a valid scaled integer was parsed, storing the value in *result (unless result is
|
||||
* NULL) and storing a pointer to the immediately succeeding character in *afterp (unless afterp is
|
||||
* NULL, in which case returns 1 only if the immediately succeeding character is a nul '\0').
|
||||
* Returns 0 otherwise, leaving *result and *afterp unchanged.
|
||||
*
|
||||
* NOTE: an argument base > 16 will cause any trailing 'g' or 'G' character to be parsed as part of
|
||||
* the integer, not as a scale suffix. Ditto for base > 20 and 'k' 'K', and base > 22 and 'm' 'M'.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
int str_to_ll_scaled(const char *str, int base, long long *result, char **afterp);
|
||||
|
||||
|
||||
int parse_argv(char *cmdline, char delim, char **argv, int max_argv);
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Serval Project testing framework for Bash shell
|
||||
# Copyright 2012 Paul Gardner-Stephen
|
||||
# Copyright 2012 Serval Project, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
@ -62,7 +62,6 @@ TSFMT='+%Y-%m-%d %H:%M:%S'
|
||||
SYSTYPE=`uname -s`
|
||||
if [ $SYSTYPE = "SunOS" ]; then
|
||||
abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; }
|
||||
|
||||
AWK=gawk
|
||||
SED=gsed
|
||||
GREP=ggrep
|
||||
@ -133,7 +132,9 @@ runTests() {
|
||||
_tfw_stdout=1
|
||||
_tfw_stderr=2
|
||||
_tfw_checkBashVersion
|
||||
export PATH="$(_tfw_abspath "${BASH_SOURCE%/*}"):$PATH"
|
||||
_tfw_checkTerminfo
|
||||
_tfw_checkCommandInPATH tfw_createfile
|
||||
_tfw_invoking_script=$(abspath "${BASH_SOURCE[1]}")
|
||||
_tfw_suite_name="${_tfw_invoking_script##*/}"
|
||||
_tfw_cwd=$(abspath "$PWD")
|
||||
@ -484,6 +485,15 @@ matches_rexp() {
|
||||
_tfw_matches_rexp "$@"
|
||||
}
|
||||
|
||||
# Create a file with the given size (default 0).
|
||||
# Usage: create_file <path> [<size>]
|
||||
# where: <size> is of the form Nu
|
||||
# N is decimal integer
|
||||
# u is one of kKmMgG (k=10^3, K=2^10, m=10^6, M=2^20, g=10^9, G=2^30)
|
||||
create_file() {
|
||||
tfw_createfile --label="$1" ${2:+--size=$2} >"$1" || error "failed command: create_file $@"
|
||||
}
|
||||
|
||||
# Executes its arguments as a command:
|
||||
# - captures the standard output and error in temporary files for later
|
||||
# examination
|
||||
@ -1214,6 +1224,13 @@ _tfw_checkTerminfo() {
|
||||
esac
|
||||
}
|
||||
|
||||
_tfw_checkCommandInPATH() {
|
||||
case $(type -p "$1") in
|
||||
*/"${1##*/}") ;;
|
||||
*) _tfw_fatal "command not found: $1 (PATH=$PATH)"
|
||||
esac
|
||||
}
|
||||
|
||||
# Return a list of test names in the _tfw_tests array variable, in the order
|
||||
# that the test_TestName functions were defined. Test names must start with
|
||||
# an alphabetic character (not numeric or '_').
|
||||
|
105
tfw_createfile.c
Normal file
105
tfw_createfile.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
Serval Project testing framework utility - create fixture file
|
||||
Copyright (C) 2012 Serval Project, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "str.h"
|
||||
|
||||
static const char *argv0 = "test_createfile";
|
||||
|
||||
static void fatal(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
char buf[1024];
|
||||
setbuffer(stderr, buf, sizeof buf);
|
||||
fprintf(stderr, "%s: ", argv0);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fputc('\n', stderr);
|
||||
va_end(ap);
|
||||
fflush(stderr);
|
||||
setbuf(stderr, NULL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static inline char stripe(int i)
|
||||
{
|
||||
return (i >= ' ' && i <= '~') ? i : '.';
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
argv0 = argv[0];
|
||||
long long size = 0;
|
||||
const char *label = "";
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
char *arg = argv[i];
|
||||
if (str_startswith(arg, "--size=", &arg)) {
|
||||
if (!str_to_ll_scaled(arg, 10, &size, NULL) || size < 0)
|
||||
fatal("illegal --size= argument: %s", arg);
|
||||
}
|
||||
else if (str_startswith(arg, "--label=", &arg))
|
||||
label = arg;
|
||||
else
|
||||
fatal("unrecognised argument: %s", arg);
|
||||
}
|
||||
long long offset = 0;
|
||||
char buf[127];
|
||||
for (i = 0; i != sizeof buf; ++i)
|
||||
buf[i] = stripe(i);
|
||||
const size_t labellen = strlen(label);
|
||||
int bouncemax = sizeof buf - labellen;
|
||||
if (bouncemax < 0)
|
||||
bouncemax = sizeof buf;
|
||||
int bounce = 3;
|
||||
int bouncedelta = 1;
|
||||
while (!ferror(stdout) && offset < size) {
|
||||
int n = sprintf(buf, "%lld", offset);
|
||||
buf[n] = stripe(n);
|
||||
size_t labelsiz = labellen;
|
||||
if (labelsiz && bounce < sizeof buf) {
|
||||
if (labelsiz > sizeof buf - bounce)
|
||||
labelsiz = sizeof buf - bounce;
|
||||
memcpy(buf + bounce, label, labelsiz);
|
||||
}
|
||||
int remain = size - offset - 1;
|
||||
if (remain > sizeof buf)
|
||||
remain = sizeof buf;
|
||||
fwrite(buf, remain, 1, stdout);
|
||||
fputc('\n', stdout);
|
||||
offset += remain + 1;
|
||||
if (bounce <= n || bounce >= bouncemax)
|
||||
bouncedelta *= -1;
|
||||
if (labelsiz) {
|
||||
if (bouncedelta > 0)
|
||||
buf[bounce] = stripe(bounce);
|
||||
else
|
||||
buf[bounce + labelsiz - 1] = stripe(bounce + labelsiz - 1);
|
||||
}
|
||||
bounce += bouncedelta;
|
||||
}
|
||||
fflush(stdout);
|
||||
if (ferror(stdout))
|
||||
fatal("write error: %s [errno=%d]", strerror(errno), errno);
|
||||
exit(0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user