diff --git a/.gitignore b/.gitignore index ddfa296e0b..0c19632157 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ daemon/version.go parser/lex.yy.c parser/y.tab.h parser/y.tab.c +parser/test_memory_leaks protocol/protocol.pb.go build/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 772e1750f4..0370e60f1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ ### Bugfixes +- [Issue #978](https://github.com/influxdb/influxdb/issues/978). Check + for valgrind and mercurial in the configure script - [Issue #671](https://github.com/influxdb/influxdb/issues/671). Fix the Makefile package target for Mac OSX - [Issue #925](https://github.com/influxdb/influxdb/issues/925). Don't diff --git a/Makefile.in b/Makefile.in index f9d7f1dc45..9459270589 100644 --- a/Makefile.in +++ b/Makefile.in @@ -70,8 +70,10 @@ uname_S = $(shell sh -c "uname -s 2>/dev/null || echo not") valgrind: ifeq ($(uname_S),Linux) +ifneq ($(VALGRIND),notfound) $(MAKE) -C parser valgrind endif +endif # packages test_packages = $(shell sh -c "go list github.com/influxdb/influxdb/... | egrep -v 'integration|tools'") diff --git a/configure b/configure index 91712d6e60..df4db7ec57 100755 --- a/configure +++ b/configure @@ -593,6 +593,9 @@ CPPFLAGS LDFLAGS CFLAGS CC +HG +VALGRIND +sed_i ROCKSDB_LIB LRT_LDFLAG with_flex @@ -1807,6 +1810,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking sed -i" >&5 $as_echo_n "checking sed -i... " >&6; } if ${ac_cv_influxdb_sed_i+:} false; then : @@ -1884,6 +1889,48 @@ if test x"${PROTOC}" == x"notfound"; then as_fn_error $? "Please install protobuf before trying to build InfluxDB" "$LINENO" 5 fi +# Extract the first word of "valgrind", so it can be a program name with args. +set dummy valgrind; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_VALGRIND+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $VALGRIND in + [\\/]* | ?:[\\/]*) + ac_cv_path_VALGRIND="$VALGRIND" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_VALGRIND="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_VALGRIND" && ac_cv_path_VALGRIND=""notfound"" + ;; +esac +fi +VALGRIND=$ac_cv_path_VALGRIND +if test -n "$VALGRIND"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $VALGRIND" >&5 +$as_echo "$VALGRIND" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + # Check whether --with-goroot was given. if test "${with_goroot+set}" = set; then : @@ -1981,6 +2028,51 @@ if test x"${GOFMT}" == x"notfound"; then as_fn_error $? "Please install GO (or make sure it's on your path) before trying to build InfluxDB" "$LINENO" 5 fi +# Extract the first word of "hg", so it can be a program name with args. +set dummy hg; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_HG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $HG in + [\\/]* | ?:[\\/]*) + ac_cv_path_HG="$HG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_HG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_HG" && ac_cv_path_HG=""notfound"" + ;; +esac +fi +HG=$ac_cv_path_HG +if test -n "$HG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HG" >&5 +$as_echo "$HG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test x"${HG}" == x"notfound"; then + as_fn_error $? "Please install mercurial before trying to build InfluxDB" "$LINENO" 5 +fi + # Check whether --with-flex was given. if test "${with_flex+set}" = set; then : diff --git a/configure.ac b/configure.ac index 8fdea6fdfd..3973643786 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,7 @@ AC_SUBST(with_flex) AC_SUBST(LRT_LDFLAG) AC_SUBST(ROCKSDB_LIB) AC_SUBST(sed_i) +AC_SUBST(VALGRIND) AC_DEFUN([INFLUXDB_SED], [ AC_MSG_CHECKING([sed -i]) @@ -42,6 +43,8 @@ if test x"${PROTOC}" == x"notfound"; then AC_MSG_ERROR([Please install protobuf before trying to build InfluxDB]) fi +AC_PATH_PROG(VALGRIND, valgrind, "notfound") + AC_ARG_WITH([goroot], [AS_HELP_STRING([--with-goroot], [Set goroot to use])], @@ -58,6 +61,11 @@ if test x"${GOFMT}" == x"notfound"; then AC_MSG_ERROR([Please install GO (or make sure it's on your path) before trying to build InfluxDB]) fi +AC_PATH_PROG(HG, hg, "notfound") +if test x"${HG}" == x"notfound"; then + AC_MSG_ERROR([Please install mercurial before trying to build InfluxDB]) +fi + AC_ARG_WITH([flex], [AS_HELP_STRING([--with-flex], [Use flex given at that path])], diff --git a/parser/Makefile.in b/parser/Makefile.in index ccc9426195..038e4189e6 100644 --- a/parser/Makefile.in +++ b/parser/Makefile.in @@ -1,3 +1,5 @@ +VALGRIND = @VALGRIND@ + BISON = @with_bison@ FLEX = @with_flex@ @@ -7,7 +9,7 @@ files = y.tab.c y.tab.h lex.yy.c all: $(files) clean: - rm -f y.tab.c y.tab.h lex.yy.c + rm -f y.tab.c y.tab.h lex.yy.c test_memory_leaks y.tab.c y.tab.h: query.yacc $(BISON) -t -d query.yacc -o y.tab.c --defines=y.tab.h @@ -16,4 +18,6 @@ lex.yy.c: query.lex $(FLEX) -o lex.yy.c -i query.lex valgrind: all - ./test_memory_leaks.sh + gcc -g y.tab.c lex.yy.c frees.c test_memory_leaks.c -o a.out + $(VALGRIND) --error-exitcode=1 --leak-check=full ./a.out + rm a.out diff --git a/parser/test_memory_leaks.c b/parser/test_memory_leaks.c new file mode 100644 index 0000000000..ca74159301 --- /dev/null +++ b/parser/test_memory_leaks.c @@ -0,0 +1,44 @@ +// +build ignore + +#include "query_types.h" +#include + +int +main(int argc, char **argv) +{ + char *qs[] = { + "select count(*) from users.events group_by user_email,time(1h) where time>now()-1d;", + "explain select users.events group_by user_email,time(1h) where time>now()-1d;", + "select * from foo where time < -1s", + "select * from merge(/.*/) where time < -1s", + "list series /", + "select count(*) from users.events group_by user_email,time(1h) where time >> now()-1d;", + "select value from t where c == 5 and b == 6;", + "select value from t where c == '5';", + "select value from cpu.idle where value > 90 and (time > now() - 1d or value > 80) and time < now() - 1w;", + "select email from users.events where email =~ /gmail\\\\.com/i and time>now()-2d;", + "select email from users.events where email in ('jvshahid@gmail.com')", + "select * from foobar limit", + "list continuous queries;", + "list series /foo/ bar", + "select -1 * value from t where c == 5 and b == 6;", + "select value from cpu.idle where value > 90 and (time > now() - 1d or value > 80) and time < now() - 1w last 10;", + "drop series foobar", + "drop continuous query 5;", + "select count(bar) as the_count from users.events group_by user_email,time(1h);", + "select email from users.events as events where email === /gmail\\\\.com/i and time>now()-2d;", + "select value from t where c = '5';", + "select * from foo into bar;", + }; + + int i; + for (i = 0; i < sizeof(qs) / sizeof(char*); i++) { + // test freeing on close for different types of queries + queries q = parse_query(qs[i]); + close_queries(&q); + } + + printf("Checked %d queries for memory leak\n", i); + + return 0; +} diff --git a/parser/test_memory_leaks.sh b/parser/test_memory_leaks.sh deleted file mode 100755 index a3b8754572..0000000000 --- a/parser/test_memory_leaks.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env bash - -cat > test_memory.c <now()-1d;"); - close_queries(&q); - - q = parse_query("explain select users.events group_by user_email,time(1h) where time>now()-1d;"); - close_queries(&q); - - q = parse_query("select * from foo where time < -1s"); - close_queries(&q); - - q = parse_query("select * from merge(/.*/) where time < -1s"); - close_queries(&q); - - // test partial regex - q = parse_query("list series /"); - close_queries(&q); - - // test freeing list series query - q = parse_query("list series /foo/ bar"); - close_queries(&q); - - // test freeing on error - q = parse_query("select count(*) from users.events group_by user_email,time(1h) where time >> now()-1d;"); - close_queries(&q); - - // test freeing alias - q = parse_query("select count(bar) as the_count from users.events group_by user_email,time(1h);"); - close_queries(&q); - - // test freeing where conditions - q = parse_query("select value from t where c == 5 and b == 6;"); - close_queries(&q); - - // test freeing where conditions - q = parse_query("select -1 * value from t where c == 5 and b == 6;"); - close_queries(&q); - - // test freeing simple query - q = parse_query("select value from t where c == '5';"); - close_queries(&q); - - // test freeing on error - q = parse_query("select value from t where c = '5';"); - close_queries(&q); - - q = parse_query("select value from cpu.idle where value > 90 and (time > now() - 1d or value > 80) and time < now() - 1w;"); - close_queries(&q); - - q = parse_query("select value from cpu.idle where value > 90 and (time > now() - 1d or value > 80) and time < now() - 1w last 10;"); - close_queries(&q); - - q = parse_query("select email from users.events where email =~ /gmail\\\\.com/i and time>now()-2d;"); - close_queries(&q); - - q = parse_query("select email from users.events as events where email === /gmail\\\\.com/i and time>now()-2d;"); - close_queries(&q); - - q = parse_query("select email from users.events where email in ('jvshahid@gmail.com')"); - close_queries(&q); - - q = parse_query("drop series foobar"); - close_queries(&q); - - q = parse_query("select * from foobar limit"); - close_queries(&q); - - // test continuous queries - q = parse_query("select * from foo into bar;"); - close_queries(&q); - - q = parse_query("list continuous queries;"); - close_queries(&q); - - q = parse_query("drop continuous query 5;"); - close_queries(&q); - - return 0; -} -EOF -gcc -g *.c -valgrind --error-exitcode=1 --leak-check=full ./a.out -valgrind_result=$? -rm ./a.out test_memory.c -exit $valgrind_result