diff --git a/.gitignore b/.gitignore index 265ff40..fddcba6 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,10 @@ GRTAGS GTAGS /config/ar-lib /sysbench/drivers/attachsql/.deps/ +/config/test-driver +*.DS_Store +/tests/*.log +/tests/*.trs +*.gcda +*.gcno +/tests/include/config.sh diff --git a/.travis.yml b/.travis.yml index 72901da..4543239 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,8 @@ language: c +cache: + directories: + - $HOME/.cache/pip + - /usr/local os: - linux @@ -12,14 +16,47 @@ addons: apt: packages: - libmysqlclient-dev + - libpq-dev + - libaio-dev + +services: + - mysql + - postgresql before_install: - > case "${TRAVIS_OS_NAME:-linux}" in osx) + # Workaround for https://github.com/Homebrew/legacy-homebrew/issues/43874 + brew uninstall libtool brew update --quiet - brew install mysql + brew install libtool mysql + # OS X requires servers to be started explicitly + brew services start mysql + pg_ctl -wD /usr/local/var/postgres start + createuser -s postgres; ;; esac -script: ./autogen.sh && ./configure && make +install: + - pip install --user cram cpp-coveralls + - > + case "${TRAVIS_OS_NAME:-linux}" in + osx) + # OS X requires this for user-local pip packages + export PATH=~/Library/Python/2.7/bin:$PATH + ;; + esac + +before_script: + - mysql -u root -e 'CREATE DATABASE sbtest;' + - psql -U postgres -c 'CREATE DATABASE sbtest;' + +script: + - ./autogen.sh && ./configure --enable-coverage --with-mysql --with-pgsql + - make + - make distcheck + - SBTEST_MYSQL_ARGS="--mysql-user=root" SBTEST_PGSQL_ARGS="--pgsql-user=postgres" make test + +after_success: + - coveralls --gcov-options '\-lp' diff --git a/Makefile.am b/Makefile.am index be61b24..e8c6636 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,9 @@ if USE_BUNDLED_LUAJIT LUAJIT_DIR = third_party/luajit endif -SUBDIRS = doc $(LUAJIT_DIR) sysbench +SUBDIRS = doc $(LUAJIT_DIR) sysbench tests EXTRA_DIST = autogen.sh README.md README-WIN.txt ChangeLog + +test: + cd tests && $(MAKE) test diff --git a/README-Oracle.md b/README-Oracle.md new file mode 100644 index 0000000..25b8707 --- /dev/null +++ b/README-Oracle.md @@ -0,0 +1,49 @@ +-------------------------------------------------------------- +Oracle Build steps +-------------------------------------------------------------- + +Using Ubuntu 14.04 - intructions dated for 21/09/2016 (Was built on AWS +in an r3.xlarge These actions were done against 0.5 checkout) + +* Setup Oracle Instant Client - +https://help.ubuntu.com/community/Oracle%20Instant%20Client download +from +http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html. + +The following RPM's and upload them to the server: +- oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm +- oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm + +``` +alien -i oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm +alien -i oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm +``` + +* Install Cuda - http://www.r-tutor.com/gpu-computing/cuda-installation/cuda7.5-ubuntu + +``` +wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64/cuda-repo-ubuntu1404_7.5-18_amd64.deb +sudo dpkg -i cuda-repo-ubuntu1404_7.5-18_amd64.deb +sudo apt-get update +sudo apt-get install cuda +export CUDA_HOME=/usr/local/cuda-7.5 +export LD_LIBRARY_PATH=${CUDA_HOME}/lib64 + +PATH=${CUDA_HOME}/bin:${PATH} +export PATH +echo "/usr/lib/oracle/12.1/client64/lib" > /etc/ld.so.conf.d/oracle-client-12.1.conf +ldconfig +``` + +* Build sysbench +Use the following `configure` option to build with Oracle support: +``` +./configure --with-oracle="/usr/lib/oracle/12.1/client64" +``` + +Run the following commands to allow sysbench use the full number of cores: +``` +sudo sh -c 'for x in /sys/class/net/eth0/queues/rx-*; do echo ffffffff> $x/rps_cpus; done' +sudo sh -c "echo 32768 > /proc/sys/net/core/rps_sock_flow_entries" +sudo sh -c "echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt" +``` diff --git a/README-WIN.txt b/README-WIN.txt index c4a9b48..d8964f1 100644 --- a/README-WIN.txt +++ b/README-WIN.txt @@ -1,8 +1,8 @@ How to build on Windows -You need CMake (download from http://www.cmake.org/) and Visual Studio 2005 or -later (free Express edition should work ok) +You need CMake (download from http://www.cmake.org/) and Visual Studio 2015 or +later. 1.Open Visual Studio command line prompt 2.To build with MySQL support, you will need mysql.h header file and client diff --git a/README.md b/README.md index ba81c64..914d761 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Coverage Status](https://coveralls.io/repos/github/akopytov/sysbench/badge.svg?branch=1.0)](https://coveralls.io/github/akopytov/sysbench?branch=1.0) [![Build Status](https://travis-ci.org/akopytov/sysbench.svg?branch=1.0)](https://travis-ci.org/akopytov/sysbench) About @@ -39,6 +40,12 @@ To compile SysBench without MySQL support, use `--without-mysql`. In this case all database-related tests will not work, but other tests will be functional. +See [README-WIN.txt](README-WIN.txt) for instructions on Windows builds. + +See [README-Oracle.md](README-Oracle.md) for instructions on building +with Oracle client libraries. + + Usage ===== @@ -82,7 +89,5 @@ The table below lists the supported common options, their descriptions and defau | `--help` | Print help on general syntax or on a test mode specified with --test, and exit | off | | `--verbosity` | Verbosity level (0 - only critical messages, 5 - debug) | 4 | | `--percentile` | SysBench measures execution times for all processed requests to display statistical information like minimal, average and maximum execution time. For most benchmarks it is also useful to know a request execution time value matching some percentile (e.g. 95% percentile means we should drop 5% of the most long requests and choose the maximal value from the remaining ones). This option allows to specify a percentile rank of query execution times to count | 95 | -| `--validate` | Perform validation of test results where possible | off | Note that numerical values for all *size* options (like `--thread-stack-size` in this table) may be specified by appending the corresponding multiplicative suffix (K for kilobytes, M for megabytes, G for gigabytes and T for terabytes). - diff --git a/configure.ac b/configure.ac index f03552f..9fd96fe 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) -AC_INIT([sysbench],[0.9],[https://github.com/akopytov/sysbench/issues], +AC_INIT([sysbench],[1.0],[https://github.com/akopytov/sysbench/issues], [sysbench], [https://github.com/akopytov/sysbench]) AC_CONFIG_AUX_DIR([config]) # Setting CFLAGS here prevents AC_CANONICAL_TARGET from injecting them @@ -70,6 +70,7 @@ then CFLAGS="-ggdb3 ${CFLAGS}" DEBUG_CFLAGS="-O0" OPTIMIZE_CFLAGS="-O2" + GCOV_CFLAGS="-O0 --coverage" fi if test "$SUNCC" = "yes" then @@ -91,6 +92,7 @@ then CFLAGS="-g -mt ${IS_64} ${MEMALIGN_FLAGS} ${CFLAGS}" DEBUG_CFLAGS="-xO0" OPTIMIZE_CFLAGS="-xO2 -xlibmil -xdepend -Xa -mt -xstrconst" +# TODO: Set flags for Gcov-enabled builds, if supported by Sun Studio fi @@ -235,7 +237,7 @@ AM_CONDITIONAL(USE_ATTACHSQL, test x$ac_cv_libattachsql = xyes) AS_IF([test x$with_oracle != xno], [ AC_DEFINE(USE_ORACLE,1,[Define to 1 if you want to compile with Oracle support]) ORA_LIBS="-L${sb_with_oracle}/lib -lclntsh" - ORA_CFLAGS="-I${with_oracle}/rdbms/demo -I${with_oracle}/rdbms/public" + ORA_CFLAGS="-I${with_oracle}/include -I${with_oracle}/rdbms/demo -I${with_oracle}/rdbms/public" AC_SUBST([ORA_LIBS]) AC_SUBST([ORA_CFLAGS]) ]) @@ -290,6 +292,10 @@ AX_TLS([], AC_MSG_ERROR([Thread-local storage is not suppored by the target platform!]) ) +# Define HAVE_FUNC_ATTRIBUTE_FORMAT if compiler supports the +# __attribute__((format...)) function attribute +AX_GCC_FUNC_ATTRIBUTE(format) + if test "$enable_largefile" = yes; then AC_SYS_LARGEFILE fi @@ -348,14 +354,6 @@ AC_ARG_WITH([debug], [Add debug code/turns off optimizations (yes|no) @<:@default=no@:>@])], [with_debug=$withval], [with_debug=no]) -if test "$with_debug" = "yes" -then - # Debugging. No optimization. - CFLAGS="${DEBUG_CFLAGS} -DDEBUG ${CFLAGS}" -else - # Optimized version. No debug - CFLAGS="${OPTIMIZE_CFLAGS} ${CFLAGS}" -fi AC_ARG_ENABLE([profiling], [AS_HELP_STRING([--enable-profiling], @@ -400,6 +398,19 @@ AC_ARG_ENABLE([go-crazy], [ac_warn_go_crazy="$enableval"], [ac_warn_go_crazy="no"]) +if test "$with_debug" = "yes" +then + # Debugging. No optimization. + CFLAGS="${DEBUG_CFLAGS} -DDEBUG ${CFLAGS}" +elif test "$ac_coverage" = "yes" +then + # Gcov-enabled build. No optimization. + CFLAGS="${GCOV_CFLAGS} ${CFLAGS}" +else + # Optimized version. No debug + CFLAGS="${OPTIMIZE_CFLAGS} ${CFLAGS}" +fi + if test "$GCC" = "yes" then if test "$ac_warn_fail" = "yes" @@ -419,7 +430,7 @@ then if test "$ac_coverage" = "yes" then - GPROF_COVERAGE="-fprofile-arcs -ftest-coverage" + GPROF_COVERAGE="--coverage" else GPROF_COVERAGE=" " fi @@ -444,7 +455,7 @@ then W_CRAZY="-Wshadow -Wconversion" fi - CC_WARNINGS="${BASE_WARNINGS} ${W_PEDANTIC} ${W_UNREACHABLE} ${GPROF_PROFILING} ${GPROF_COVERAGE} ${W_CRAZY}" + CC_WARNINGS="${BASE_WARNINGS} ${W_PEDANTIC} ${W_UNREACHABLE} ${W_CRAZY}" NO_REDUNDANT_DECLS="-Wno-redundant-decls" CPPFLAGS="${CPPFLAGS}" @@ -454,7 +465,7 @@ then CC_WARNINGS="-v -errtags=yes -errwarn=%all -erroff=E_INTEGER_OVERFLOW_DETECTED" fi -AM_CFLAGS="${CC_WARNINGS} ${AM_CFLAGS} ${PTHREAD_CFLAGS}" +AM_CFLAGS="${CC_WARNINGS} ${GPROF_PROFILING} ${GPROF_COVERAGE} ${AM_CFLAGS} ${PTHREAD_CFLAGS}" AM_CPPFLAGS="${AM_CPPFLAGS} -I\$(top_srcdir)/sysbench ${LUAJIT_CFLAGS}" @@ -485,6 +496,8 @@ sysbench/tests/threads/Makefile sysbench/tests/mutex/Makefile sysbench/tests/db/Makefile sysbench/scripting/Makefile +tests/Makefile +tests/include/config.sh ]) AC_OUTPUT diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..f24a9f7 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +sysbench (1.0-1) unstable; urgency=low + + * Initial release + + -- Alexey Kopytov Wed, 10 Aug 2016 18:04:53 +0300 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +7 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..96c7ae2 --- /dev/null +++ b/debian/control @@ -0,0 +1,27 @@ +Source: sysbench +Section: misc +Priority: extra +Maintainer: Alexey Kopytov +Build-Depends: debhelper, autoconf, automake, libtool, libmysqlclient-dev +Standards-Version: 3.9.5 +Homepage: https://github.com/akopytov/sysbench + +Package: sysbench +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Cross-platform and multi-threaded benchmark tool + SysBench is a modular, cross-platform and multi-threaded benchmark tool for + evaluating OS parameters that are important for a system running a database + under intensive load. + . + The idea of this benchmark suite is to quickly get an impression about system + performance without setting up complex database benchmarks or even without + installing a database at all. + . + Current features allow to test the following system parameters: + . + * file I/O performance + * scheduler performance + * memory allocation and transfer speed + * POSIX threads implementation performance + * database server performance (OLTP benchmark) diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..8d4bf50 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,15 @@ +Format-Specification: http://wiki.debian.org/Proposals/CopyrightFormat +Upstream-Name: sysbench +Upstream-Maintainer: Alexey Kopytov +Upstream-Source: https://github.com/akopytov/sysbench + +Files: * +Copyright: 2016 Alexey Kopytov +License: GPL-2 + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + . + On Debian systems, the complete text of the GNU General + Public License can be found in `/usr/share/common-licenses/GPL-2'. + diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..e772481 --- /dev/null +++ b/debian/dirs @@ -0,0 +1 @@ +usr/bin diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..b43bf86 --- /dev/null +++ b/debian/docs @@ -0,0 +1 @@ +README.md diff --git a/debian/install b/debian/install new file mode 100644 index 0000000..f3f2de5 --- /dev/null +++ b/debian/install @@ -0,0 +1 @@ +sysbench/tests/db/*.lua usr/lib/sysbench/tests/db diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..8a36405 --- /dev/null +++ b/debian/rules @@ -0,0 +1,13 @@ +#!/usr/bin/make -f +#export DH_VERBOSE=1 + +%: + dh $@ + +override_dh_auto_configure: + dh_testdir + autoreconf -vif + dh_auto_configure + +override_dh_compress: + dh_compress -X.lua diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/m4/ac_check_mysqlr.m4 b/m4/ac_check_mysqlr.m4 index 67715d1..fbf819a 100644 --- a/m4/ac_check_mysqlr.m4 +++ b/m4/ac_check_mysqlr.m4 @@ -1,9 +1,9 @@ dnl --------------------------------------------------------------------------- dnl Macro: AC_CHECK_MYSQLR -dnl First check for custom MySQL paths in --with-mysql-* options. -dnl If some paths are missing, check if mysql_config exists. -dnl Then check for the libraries and replace -lmysqlclient with -dnl -lmysqlclient_r, to enable threaded client library. +dnl First check if the MySQL root directory is specified with --with-mysql. +dnl Otherwise check for custom MySQL paths in --with-mysql-includes and +dnl --with-mysql-libs. If some paths are not specified explicitly, try to get +dnl them from mysql_config. dnl --------------------------------------------------------------------------- AC_DEFUN([AC_CHECK_MYSQLR],[ @@ -51,7 +51,20 @@ then ac_cv_mysql_libs=`echo ${ac_cv_mysql_libs} | sed -e 's/.libs$//' \ -e 's+.libs/$++'` AC_CACHE_CHECK([MySQL libraries], [ac_cv_mysql_libs], [ac_cv_mysql_libs=""]) - MYSQL_LIBS="-L$ac_cv_mysql_libs -lmysqlclient_r" + save_LDFLAGS="$LDFLAGS" + save_LIBS="$LIBS" + LDFLAGS="-L$ac_cv_mysql_libs" + LIBS="" + + # libmysqlclient_r has been removed in MySQL 5.7 + AC_SEARCH_LIBS([mysql_real_connect], + [mysqlclient_r mysqlclient], + [], + AC_MSG_ERROR([cannot find MySQL client libraries in $ac_cv_mysql_libs])) + + MYSQL_LIBS="$LDFLAGS $LIBS" + LIBS="$save_LIBS" + LDFLAGS="$save_LDFLAGS" fi # If some path is missing, try to autodetermine with mysql_config diff --git a/m4/ax_gcc_func_attribute.m4 b/m4/ax_gcc_func_attribute.m4 new file mode 100644 index 0000000..c788ca9 --- /dev/null +++ b/m4/ax_gcc_func_attribute.m4 @@ -0,0 +1,223 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE) +# +# DESCRIPTION +# +# This macro checks if the compiler supports one of GCC's function +# attributes; many other compilers also provide function attributes with +# the same syntax. Compiler warnings are used to detect supported +# attributes as unsupported ones are ignored by default so quieting +# warnings when using this macro will yield false positives. +# +# The ATTRIBUTE parameter holds the name of the attribute to be checked. +# +# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_. +# +# The macro caches its result in the ax_cv_have_func_attribute_ +# variable. +# +# The macro currently supports the following function attributes: +# +# alias +# aligned +# alloc_size +# always_inline +# artificial +# cold +# const +# constructor +# constructor_priority for constructor attribute with priority +# deprecated +# destructor +# dllexport +# dllimport +# error +# externally_visible +# flatten +# format +# format_arg +# gnu_inline +# hot +# ifunc +# leaf +# malloc +# noclone +# noinline +# nonnull +# noreturn +# nothrow +# optimize +# pure +# unused +# used +# visibility +# warning +# warn_unused_result +# weak +# weakref +# +# Unsuppored function attributes will be tested with a prototype returning +# an int and not accepting any arguments and the result of the check might +# be wrong or meaningless so use with care. +# +# LICENSE +# +# Copyright (c) 2013 Gabriele Svelto +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ + AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1]) + + AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + m4_case([$1], + [alias], [ + int foo( void ) { return 0; } + int bar( void ) __attribute__(($1("foo"))); + ], + [aligned], [ + int foo( void ) __attribute__(($1(32))); + ], + [alloc_size], [ + void *foo(int a) __attribute__(($1(1))); + ], + [always_inline], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [artificial], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [cold], [ + int foo( void ) __attribute__(($1)); + ], + [const], [ + int foo( void ) __attribute__(($1)); + ], + [constructor_priority], [ + int foo( void ) __attribute__((__constructor__(65535/2))); + ], + [constructor], [ + int foo( void ) __attribute__(($1)); + ], + [deprecated], [ + int foo( void ) __attribute__(($1(""))); + ], + [destructor], [ + int foo( void ) __attribute__(($1)); + ], + [dllexport], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [dllimport], [ + int foo( void ) __attribute__(($1)); + ], + [error], [ + int foo( void ) __attribute__(($1(""))); + ], + [externally_visible], [ + int foo( void ) __attribute__(($1)); + ], + [flatten], [ + int foo( void ) __attribute__(($1)); + ], + [format], [ + int foo(const char *p, ...) __attribute__(($1(printf, 1, 2))); + ], + [format_arg], [ + char *foo(const char *p) __attribute__(($1(1))); + ], + [gnu_inline], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [hot], [ + int foo( void ) __attribute__(($1)); + ], + [ifunc], [ + int my_foo( void ) { return 0; } + static int (*resolve_foo(void))(void) { return my_foo; } + int foo( void ) __attribute__(($1("resolve_foo"))); + ], + [leaf], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [malloc], [ + void *foo( void ) __attribute__(($1)); + ], + [noclone], [ + int foo( void ) __attribute__(($1)); + ], + [noinline], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [nonnull], [ + int foo(char *p) __attribute__(($1(1))); + ], + [noreturn], [ + void foo( void ) __attribute__(($1)); + ], + [nothrow], [ + int foo( void ) __attribute__(($1)); + ], + [optimize], [ + __attribute__(($1(3))) int foo( void ) { return 0; } + ], + [pure], [ + int foo( void ) __attribute__(($1)); + ], + [unused], [ + int foo( void ) __attribute__(($1)); + ], + [used], [ + int foo( void ) __attribute__(($1)); + ], + [visibility], [ + int foo_def( void ) __attribute__(($1("default"))); + int foo_hid( void ) __attribute__(($1("hidden"))); + int foo_int( void ) __attribute__(($1("internal"))); + int foo_pro( void ) __attribute__(($1("protected"))); + ], + [warning], [ + int foo( void ) __attribute__(($1(""))); + ], + [warn_unused_result], [ + int foo( void ) __attribute__(($1)); + ], + [weak], [ + int foo( void ) __attribute__(($1)); + ], + [weakref], [ + static int foo( void ) { return 0; } + static int bar( void ) __attribute__(($1("foo"))); + ], + [ + m4_warn([syntax], [Unsupported attribute $1, the test may fail]) + int foo( void ) __attribute__(($1)); + ] + )], []) + ], + dnl GCC doesn't exit with an error if an unknown attribute is + dnl provided but only outputs a warning, so accept the attribute + dnl only if no warning were issued. + [AS_IF([test -s conftest.err], + [AS_VAR_SET([ac_var], [no])], + [AS_VAR_SET([ac_var], [yes])])], + [AS_VAR_SET([ac_var], [no])]) + ]) + + AS_IF([test yes = AS_VAR_GET([ac_var])], + [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1, + [Define to 1 if the system has the `$1' function attribute])], []) + + AS_VAR_POPDEF([ac_var]) +]) diff --git a/sysbench/Makefile.am b/sysbench/Makefile.am index b1186de..29277d1 100644 --- a/sysbench/Makefile.am +++ b/sysbench/Makefile.am @@ -47,7 +47,7 @@ luajit_ldadd = $(LUAJIT_LIBS) sysbench_SOURCES = sysbench.c sysbench.h sb_timer.c sb_timer.h \ sb_options.c sb_options.h sb_logger.c sb_logger.h sb_list.h db_driver.h \ db_driver.c sb_percentile.c sb_percentile.h sb_rnd.c sb_rnd.h \ -sb_thread.c sb_thread.h sb_barrier.c sb_barrier.h +sb_thread.c sb_thread.h sb_barrier.c sb_barrier.h sb_global.h sysbench_LDADD = tests/fileio/libsbfileio.a tests/threads/libsbthreads.a \ tests/memory/libsbmemory.a tests/cpu/libsbcpu.a \ diff --git a/sysbench/db_driver.c b/sysbench/db_driver.c index 8fdc438..3ec9b97 100644 --- a/sysbench/db_driver.c +++ b/sysbench/db_driver.c @@ -892,24 +892,24 @@ void db_print_stats(sb_stat_t type) log_text(LOG_NOTICE, "OLTP test statistics:"); log_text(LOG_NOTICE, " queries performed:"); - log_text(LOG_NOTICE, " read: %d", + log_text(LOG_NOTICE, " read: %lu", read_ops); - log_text(LOG_NOTICE, " write: %d", + log_text(LOG_NOTICE, " write: %lu", write_ops); - log_text(LOG_NOTICE, " other: %d", + log_text(LOG_NOTICE, " other: %lu", other_ops); - log_text(LOG_NOTICE, " total: %d", + log_text(LOG_NOTICE, " total: %lu", read_ops + write_ops + other_ops); - log_text(LOG_NOTICE, " transactions: %-6d" + log_text(LOG_NOTICE, " transactions: %-6lu" " (%.2f per sec.)", transactions, transactions / seconds); - log_text(LOG_NOTICE, " read/write requests: %-6d" + log_text(LOG_NOTICE, " read/write requests: %-6lu" " (%.2f per sec.)", read_ops + write_ops, (read_ops + write_ops) / seconds); - log_text(LOG_NOTICE, " other operations: %-6d" + log_text(LOG_NOTICE, " other operations: %-6lu" " (%.2f per sec.)", other_ops, other_ops / seconds); - log_text(LOG_NOTICE, " ignored errors: %-6d" + log_text(LOG_NOTICE, " ignored errors: %-6lu" " (%.2f per sec.)", errors, errors / seconds); - log_text(LOG_NOTICE, " reconnects: %-6d" + log_text(LOG_NOTICE, " reconnects: %-6lu" " (%.2f per sec.)", reconnects, reconnects / seconds); if (db_globals.debug) diff --git a/sysbench/drivers/mysql/drv_mysql.c b/sysbench/drivers/mysql/drv_mysql.c index 90b011e..02e0374 100644 --- a/sysbench/drivers/mysql/drv_mysql.c +++ b/sysbench/drivers/mysql/drv_mysql.c @@ -481,7 +481,8 @@ int mysql_drv_prepare(db_stmt_t *stmt, const char *query) return 1; } stmt->ptr = (void *)mystmt; - DEBUG("mysql_stmt_prepare(%p, \"%s\", %d) = %p", mystmt, query, strlen(query), stmt->ptr); + DEBUG("mysql_stmt_prepare(%p, \"%s\", %u) = %p", mystmt, query, + (unsigned int) strlen(query), stmt->ptr); if (mysql_stmt_prepare(mystmt, query, strlen(query))) { /* Check if this statement in not supported */ @@ -842,7 +843,8 @@ int mysql_drv_query(db_conn_t *sb_conn, const char *query, con = db_mysql_con->mysql; rc = (unsigned int)mysql_real_query(con, query, strlen(query)); - DEBUG("mysql_real_query(%p, \"%s\", %u) = %u", con, query, strlen(query), rc); + DEBUG("mysql_real_query(%p, \"%s\", %u) = %u", con, query, + (unsigned int) strlen(query), rc); if (rc) return check_error(sb_conn, "mysql_drv_query()", query); @@ -924,7 +926,7 @@ int mysql_drv_store_results(db_result_set_t *rs) return check_error(rs->connection, "mysql_stmt_store_result()", NULL); } rs->nrows = mysql_stmt_num_rows(rs->statement->ptr); - DEBUG("mysql_stmt_num_rows(%p) = %d", rs->statement->ptr, rs->nrows); + DEBUG("mysql_stmt_num_rows(%p) = %llu", rs->statement->ptr, rs->nrows); do { rc = (unsigned int)mysql_stmt_fetch(rs->statement->ptr); DEBUG("mysql_stmt_fetch(%p) = %d", rs->statement->ptr, rc); @@ -950,7 +952,7 @@ int mysql_drv_store_results(db_result_set_t *rs) rs->ptr = (void *)res; rs->nrows = mysql_num_rows(res); - DEBUG("mysql_num_rows(%p) = %u", res, rs->nrows); + DEBUG("mysql_num_rows(%p) = %llu", res, rs->nrows); /* just fetch result */ while((row = mysql_fetch_row(res))) diff --git a/sysbench/drivers/pgsql/drv_pgsql.c b/sysbench/drivers/pgsql/drv_pgsql.c index eab7755..2b6b7ca 100644 --- a/sysbench/drivers/pgsql/drv_pgsql.c +++ b/sysbench/drivers/pgsql/drv_pgsql.c @@ -31,6 +31,7 @@ #include "sb_options.h" #include "db_driver.h" +#include "sb_rnd.h" /* Maximum length of text representation of bind parameters */ #define MAX_PARAM_LENGTH 256 @@ -518,7 +519,7 @@ int pgsql_drv_execute(db_stmt_t *stmt, db_result_set_t *rs) /* Convert SysBench bind structures to PgSQL data */ for (i = 0; i < (unsigned)pgstmt->nparams; i++) { - if (stmt->bound_param[i].is_null) + if (stmt->bound_param[i].is_null && *(stmt->bound_param[i].is_null)) continue; switch (stmt->bound_param[i].type) { diff --git a/sysbench/sb_global.h b/sysbench/sb_global.h new file mode 100644 index 0000000..edf855f --- /dev/null +++ b/sysbench/sb_global.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2016 Alexey Kopytov + + 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 +*/ + +/* Global and portability-related macros */ + +#ifndef SB_GLOBAL_H +#define SB_GLOBAL_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_FUNC_ATTRIBUTE_FORMAT +# define SB_ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n))) +#else +# define SB_ATTRIBUTE_FORMAT(style, m, n) +#endif + +#endif /* SB_GLOBAL_H */ diff --git a/sysbench/sb_list.h b/sysbench/sb_list.h index 5c2a456..2cc7368 100644 --- a/sysbench/sb_list.h +++ b/sysbench/sb_list.h @@ -22,7 +22,6 @@ typedef struct sb_list_item_t { -// char c; struct sb_list_item_t *next_p; struct sb_list_item_t *prev_p; } diff --git a/sysbench/sb_logger.c b/sysbench/sb_logger.c index 59d0af6..785d669 100644 --- a/sysbench/sb_logger.c +++ b/sysbench/sb_logger.c @@ -105,7 +105,8 @@ static log_handler_t text_handler = { static sb_arg_t oper_handler_args[] = { - {"percentile", "percentile rank of query response times to count", + {"percentile", "percentile rank of query response times to count. " + "Use the special value of 0 to disable percentile statistics.", SB_ARG_TYPE_INT, "95"}, {NULL, NULL, SB_ARG_TYPE_NULL, NULL} @@ -485,7 +486,7 @@ int oper_handler_init(void) unsigned int i, tmp; tmp = sb_get_value_int("percentile"); - if (tmp < 1 || tmp > 100) + if (tmp < 0 || tmp > 100) { log_text(LOG_FATAL, "Invalid value for percentile option: %d", tmp); @@ -641,7 +642,7 @@ int print_global_stats(void) NS2MS(get_max_time(&t))); /* Print approx. percentile value for event execution times */ - if (t.events > 0) + if (t.events > 0 && sb_globals.percentile_rank > 0) { log_text(LOG_NOTICE, " approx. %3d percentile: %10.2fms", sb_globals.percentile_rank, NS2MS(percentile_val)); diff --git a/sysbench/sb_logger.h b/sysbench/sb_logger.h index eec2ac4..2d0644b 100644 --- a/sysbench/sb_logger.h +++ b/sysbench/sb_logger.h @@ -23,6 +23,7 @@ # include "config.h" #endif +#include "sb_global.h" #include "sb_options.h" #include "sb_timer.h" @@ -144,7 +145,8 @@ void log_msg(log_msg_t *); /* printf-like wrapper to log text messages */ -void log_text(log_msg_priority_t priority, const char *fmt, ...); +void log_text(log_msg_priority_t priority, const char *fmt, ...) + SB_ATTRIBUTE_FORMAT(printf, 2, 3); /* variant of log_text() which prepends log lines with a elapsed time of the @@ -152,11 +154,13 @@ void log_text(log_msg_priority_t priority, const char *fmt, ...); */ void log_timestamp(log_msg_priority_t priority, const sb_timer_t *timer, - const char *fmt, ...); + const char *fmt, ...) + SB_ATTRIBUTE_FORMAT(printf, 3, 4); /* printf-like wrapper to log system error messages */ -void log_errno(log_msg_priority_t priority, const char *fmt, ...); +void log_errno(log_msg_priority_t priority, const char *fmt, ...) + SB_ATTRIBUTE_FORMAT(printf, 2, 3); /* Uninitialize logger */ diff --git a/sysbench/sb_options.c b/sysbench/sb_options.c index bc541fc..6a18c0a 100644 --- a/sysbench/sb_options.c +++ b/sysbench/sb_options.c @@ -396,7 +396,7 @@ char *sb_print_value_size(char *buf, unsigned int buflen, double value) /* empty */ ; if (i > 0) - snprintf(buf, buflen, "%.5g%c", value, sizemods[i-1]); + snprintf(buf, buflen, "%.5g%ci", value, sizemods[i-1]); else snprintf(buf, buflen, "%.5g", value); diff --git a/sysbench/sb_percentile.c b/sysbench/sb_percentile.c index def2d6d..72dff63 100644 --- a/sysbench/sb_percentile.c +++ b/sysbench/sb_percentile.c @@ -32,12 +32,16 @@ # include #endif +#include "sysbench.h" #include "sb_percentile.h" #include "sb_logger.h" int sb_percentile_init(sb_percentile_t *percentile, unsigned int size, double range_min, double range_max) { + if (sb_globals.percentile_rank == 0) + return 0; + percentile->values = (unsigned long long *) calloc(size, sizeof(unsigned long long)); percentile->tmp = (unsigned long long *) @@ -65,6 +69,9 @@ void sb_percentile_update(sb_percentile_t *percentile, double value) { unsigned int n; + if (sb_globals.percentile_rank == 0) + return; + if (value < percentile->range_min) value= percentile->range_min; else if (value > percentile->range_max) @@ -84,6 +91,9 @@ double sb_percentile_calculate(sb_percentile_t *percentile, double percent) unsigned long long ncur, nmax; unsigned int i; + if (sb_globals.percentile_rank == 0) + return 0.0; + pthread_mutex_lock(&percentile->mutex); if (percentile->total == 0) @@ -111,6 +121,9 @@ double sb_percentile_calculate(sb_percentile_t *percentile, double percent) void sb_percentile_reset(sb_percentile_t *percentile) { + if (sb_globals.percentile_rank == 0) + return; + pthread_mutex_lock(&percentile->mutex); percentile->total = 0; memset(percentile->values, 0, percentile->size * sizeof(unsigned long long)); @@ -119,6 +132,9 @@ void sb_percentile_reset(sb_percentile_t *percentile) void sb_percentile_done(sb_percentile_t *percentile) { + if (sb_globals.percentile_rank == 0) + return; + pthread_mutex_destroy(&percentile->mutex); free(percentile->values); free(percentile->tmp); diff --git a/sysbench/sb_timer.c b/sysbench/sb_timer.c index 9054c28..ecca91b 100644 --- a/sysbench/sb_timer.c +++ b/sysbench/sb_timer.c @@ -130,11 +130,16 @@ void sb_timer_stop(sb_timer_t *t) } -/* get the current timer value in nanoseconds */ +/* + get the current timer value in nanoseconds without affecting is state, i.e. + is safe to be used concurrently on a shared timer. +*/ unsigned long long sb_timer_value(sb_timer_t *t) { + struct timespec ts; + switch (t->state) { case TIMER_INITIALIZED: log_text(LOG_WARNING, "timer was never started"); @@ -148,9 +153,8 @@ unsigned long long sb_timer_value(sb_timer_t *t) abort(); } - sb_timer_update(t); - - return t->elapsed; + SB_GETTIME(&ts); + return TIMESPEC_DIFF(ts, t->time_start) + t->queue_time; } diff --git a/sysbench/sb_win.h b/sysbench/sb_win.h index 24618cf..b481b9b 100644 --- a/sysbench/sb_win.h +++ b/sysbench/sb_win.h @@ -20,8 +20,6 @@ #define PACKAGE_VERSION "0.5" #endif -#define snprintf(buffer, count, format,...) \ - _snprintf_s(buffer,count, _TRUNCATE,format, __VA_ARGS__) #define strcasecmp _stricmp #define strncasecmp _strnicmp #define srandom(seed) srand(seed) @@ -39,11 +37,6 @@ typedef intptr_t ssize_t; #endif #endif -struct timespec -{ - time_t tv_sec; - long long tv_nsec; -}; typedef HANDLE pthread_t; typedef CRITICAL_SECTION pthread_mutex_t; diff --git a/sysbench/scripting/Makefile.am b/sysbench/scripting/Makefile.am index 0f8a9c5..0c2862a 100644 --- a/sysbench/scripting/Makefile.am +++ b/sysbench/scripting/Makefile.am @@ -15,6 +15,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +AM_CPPFLAGS += -DDATA_PATH=\"$(pkgdatadir)\" + noinst_LIBRARIES = libsbscript.a libsbscript_a_SOURCES = sb_script.c sb_script.h script_lua.c script_lua.h diff --git a/sysbench/scripting/script_lua.c b/sysbench/scripting/script_lua.c index ef7e701..7b71064 100644 --- a/sysbench/scripting/script_lua.c +++ b/sysbench/scripting/script_lua.c @@ -29,6 +29,8 @@ #include "db_driver.h" #include "sb_rnd.h" +#include + #define EVENT_FUNC "event" #define PREPARE_FUNC "prepare" #define CLEANUP_FUNC "cleanup" @@ -169,6 +171,8 @@ int script_load_lua(const char *testname, sb_test_t *test) { unsigned int i; + setenv("LUA_PATH", DATA_PATH LUA_DIRSEP "?.lua", 0); + /* Initialize global interpreter state */ gstate = sb_lua_new_state(testname, -1); if (gstate == NULL) @@ -241,15 +245,21 @@ sb_request_t sb_lua_get_request(int thread_id) (void) thread_id; /* unused */ - if (sb_globals.max_requests != 0 && nevents >= sb_globals.max_requests) + if (sb_globals.max_requests > 0) { - req.type = SB_REQ_TYPE_NULL; - return req; + SB_THREAD_MUTEX_LOCK(); + if (nevents >= sb_globals.max_requests) + { + req.type = SB_REQ_TYPE_NULL; + SB_THREAD_MUTEX_UNLOCK(); + return req; + } + nevents++; + SB_THREAD_MUTEX_UNLOCK(); } req.type = SB_REQ_TYPE_SCRIPT; - nevents++; - + return req; } @@ -482,8 +492,27 @@ lua_State *sb_lua_new_state(const char *scriptname, int thread_id) luaL_newmetatable(state, "sysbench.stmt"); luaL_newmetatable(state, "sysbench.rs"); - - if (luaL_loadfile(state, scriptname) || lua_pcall(state, 0, 0, 0)) + + if (luaL_loadfile(state, scriptname)) + { + /* first location failed - look in DATA_PATH */ + char p[PATH_MAX + 1]; + strncpy(p, DATA_PATH LUA_DIRSEP, sizeof(p)); + strncat(p, scriptname, sizeof(p)-strlen(p)-1); + if (!strrchr(scriptname, '.')) + { + /* add .lua extension if there isn't one */ + strncat(p, ".lua", sizeof(p)-strlen(p)-1); + } + + if (luaL_loadfile(state, p)) + { + lua_error(state); + return NULL; + } + } + + if (lua_pcall(state, 0, 0, 0)) { lua_error(state); return NULL; diff --git a/sysbench/sysbench.c b/sysbench/sysbench.c index 2de432a..6ee56b4 100644 --- a/sysbench/sysbench.c +++ b/sysbench/sysbench.c @@ -451,13 +451,13 @@ void print_run_mode(sb_test_t *test) if (rand_seed) { log_text(LOG_NOTICE, "Initializing random number generator from seed (%d).\n", rand_seed); - sb_srnd(rand_seed); + srandom(rand_seed); } else { log_text(LOG_NOTICE, "Initializing random number generator from current time\n"); - sb_srnd(time(NULL)); + srandom(time(NULL)); } if (sb_globals.force_shutdown) @@ -489,9 +489,9 @@ static void *worker_thread(void *arg) thread_id = ctxt->id; /* Initialize thread-local RNG state */ - sb_srnd(thread_id); + sb_srnd(random()); - log_text(LOG_DEBUG, "Worker thread started (%d)!", thread_id); + log_text(LOG_DEBUG, "Worker thread (#%d) started", thread_id); if (test->ops.thread_init != NULL && test->ops.thread_init(thread_id) != 0) { @@ -502,7 +502,7 @@ static void *worker_thread(void *arg) return NULL; } - log_text(LOG_DEBUG, "Worker thread (#%d) started!", thread_id); + log_text(LOG_DEBUG, "Worker thread (#%d) initialized", thread_id); /* Wait for other threads to initialize */ if (sb_barrier_wait(&thread_start_barrier) < 0) @@ -609,15 +609,16 @@ static void *eventgen_thread_proc(void *arg) next_ns = next_ns + intr_ns*1000; if (next_ns > curr_ns) + { pause_ns = next_ns - curr_ns; + usleep(pause_ns / 1000); + } else { - pause_ns = 1000; log_timestamp(LOG_DEBUG, &sb_globals.exec_timer, "Event generation thread is too slow"); } - usleep(pause_ns / 1000); queue_array[i].event_time = sb_timer_value(&sb_globals.exec_timer); pthread_mutex_lock(&event_queue_mutex); @@ -662,7 +663,7 @@ static void *report_thread_proc(void *arg) if (current_test->ops.print_stats == NULL) { - log_text(LOG_DEBUG, "Reporting not supported by the current test, ", + log_text(LOG_DEBUG, "Reporting not supported by the current test, " "terminating the reporting thread"); return NULL; } @@ -712,7 +713,7 @@ static void *checkpoints_thread_proc(void *arg) if (current_test->ops.print_stats == NULL) { - log_text(LOG_DEBUG, "Reporting not supported by the current test, ", + log_text(LOG_DEBUG, "Reporting not supported by the current test, " "terminating the checkpoints thread"); return NULL; } @@ -1224,9 +1225,6 @@ int main(int argc, char *argv[]) } if (test->cmds.help != NULL) test->cmds.help(); - else - fprintf(stderr, "No help available for test '%s'.\n", - test->sname); } exit(0); } diff --git a/sysbench/sysbench.h b/sysbench/sysbench.h index a26a3f0..2ba5f96 100644 --- a/sysbench/sysbench.h +++ b/sysbench/sysbench.h @@ -19,10 +19,6 @@ #ifndef SYSBENCH_H #define SYSBENCH_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #ifdef STDC_HEADERS # include # include diff --git a/sysbench/tests/cpu/sb_cpu.c b/sysbench/tests/cpu/sb_cpu.c index 970b1a4..b2e665e 100644 --- a/sysbench/tests/cpu/sb_cpu.c +++ b/sysbench/tests/cpu/sb_cpu.c @@ -70,8 +70,6 @@ static sb_test_t cpu_test = static unsigned int max_prime; /* Request counter */ static unsigned int req_performed; -/* Counter mutex */ -static pthread_mutex_t request_mutex; int register_test_cpu(sb_list_t * tests) { @@ -92,8 +90,6 @@ int cpu_init(void) req_performed = 0; - pthread_mutex_init(&request_mutex, NULL); - return 0; } @@ -104,15 +100,20 @@ sb_request_t cpu_get_request(int thread_id) (void) thread_id; /* unused */ - if (sb_globals.max_requests > 0 && req_performed >= sb_globals.max_requests) + if (sb_globals.max_requests > 0) { - req.type = SB_REQ_TYPE_NULL; - return req; + SB_THREAD_MUTEX_LOCK(); + if (req_performed >= sb_globals.max_requests) + { + req.type = SB_REQ_TYPE_NULL; + SB_THREAD_MUTEX_UNLOCK(); + return req; + } + req_performed++; + SB_THREAD_MUTEX_UNLOCK(); } + req.type = SB_REQ_TYPE_CPU; - pthread_mutex_lock(&request_mutex); - req_performed++; - pthread_mutex_unlock(&request_mutex); return req; } @@ -158,7 +159,5 @@ void cpu_print_mode(void) int cpu_done(void) { - pthread_mutex_destroy(&request_mutex); - return 0; } diff --git a/sysbench/tests/db/Makefile.am b/sysbench/tests/db/Makefile.am index e7647ac..3d6a7e4 100644 --- a/sysbench/tests/db/Makefile.am +++ b/sysbench/tests/db/Makefile.am @@ -15,7 +15,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -EXTRA_DIST = delete.lua insert.lua oltp.lua \ +dist_pkgdata_DATA = common.lua delete.lua insert.lua bulk_insert.lua \ + oltp.lua \ oltp_simple.lua \ parallel_prepare.lua \ select_random_points.lua \ diff --git a/sysbench/tests/db/common.lua b/sysbench/tests/db/common.lua index 6aabecd..f9c0e19 100644 --- a/sysbench/tests/db/common.lua +++ b/sysbench/tests/db/common.lua @@ -59,8 +59,6 @@ pad CHAR(60) DEFAULT '' NOT NULL, db_query(query) - db_query("CREATE INDEX k_" .. i .. " on sbtest" .. i .. "(k)") - print("Inserting " .. oltp_table_size .. " records into 'sbtest" .. i .. "'") if (oltp_auto_inc) then @@ -89,6 +87,8 @@ pad CHAR(60) DEFAULT '' NOT NULL, db_bulk_insert_done() + print("Creating secondary indexes on 'sbtest" .. i .. "'...") + db_query("CREATE INDEX k_" .. i .. " on sbtest" .. i .. "(k)") end @@ -132,6 +132,13 @@ function set_vars() oltp_distinct_ranges = oltp_distinct_ranges or 1 oltp_index_updates = oltp_index_updates or 1 oltp_non_index_updates = oltp_non_index_updates or 1 + oltp_delete_inserts = oltp_delete_inserts or 1 + + if (oltp_range_selects == 'off') then + oltp_range_selects = false + else + oltp_range_selects = true + end if (oltp_auto_inc == 'off') then oltp_auto_inc = false @@ -145,6 +152,16 @@ function set_vars() oltp_read_only = false end + if (oltp_write_only == 'on') then + oltp_write_only = true + else + oltp_write_only = false + end + + if (oltp_read_only and oltp_write_only) then + error("--oltp-read-only and --oltp-write-only are mutually exclusive") + end + if (oltp_skip_trx == 'on') then oltp_skip_trx = true else diff --git a/sysbench/tests/db/delete.lua b/sysbench/tests/db/delete.lua index b4e4dc7..85c9c94 100644 --- a/sysbench/tests/db/delete.lua +++ b/sysbench/tests/db/delete.lua @@ -1,6 +1,10 @@ -pathtest = string.match(test, "(.*/)") or "" +pathtest = string.match(test, "(.*/)") -dofile(pathtest .. "common.lua") +if pathtest then + dofile(pathtest .. "common.lua") +else + require("common") +end function thread_init(thread_id) set_vars() diff --git a/sysbench/tests/db/insert.lua b/sysbench/tests/db/insert.lua index d206609..60e9567 100644 --- a/sysbench/tests/db/insert.lua +++ b/sysbench/tests/db/insert.lua @@ -1,6 +1,10 @@ -pathtest = string.match(test, "(.*/)") or "" +pathtest = string.match(test, "(.*/)") -dofile(pathtest .. "common.lua") +if pathtest then + dofile(pathtest .. "common.lua") +else + require("common") +end function thread_init(thread_id) set_vars() diff --git a/sysbench/tests/db/oltp.lua b/sysbench/tests/db/oltp.lua index c72cf69..209f5a9 100644 --- a/sysbench/tests/db/oltp.lua +++ b/sysbench/tests/db/oltp.lua @@ -1,12 +1,21 @@ -pathtest = string.match(test, "(.*/)") or "" +pathtest = string.match(test, "(.*/)") -dofile(pathtest .. "common.lua") +if pathtest then + dofile(pathtest .. "common.lua") +else + require("common") +end function thread_init(thread_id) set_vars() if (((db_driver == "mysql") or (db_driver == "attachsql")) and mysql_table_engine == "myisam") then - begin_query = "LOCK TABLES sbtest WRITE" + local i + local tables = {} + for i=1, oltp_tables_count do + tables[i] = string.format("sbtest%i WRITE", i) + end + begin_query = "LOCK TABLES " .. table.concat(tables, " ,") commit_query = "UNLOCK TABLES" else begin_query = "BEGIN" @@ -15,11 +24,16 @@ function thread_init(thread_id) end +function get_range_str() + local start = sb_rand(1, oltp_table_size) + return string.format(" WHERE id BETWEEN %u AND %u", + start, start + oltp_range_size - 1) +end + function event(thread_id) local rs local i local table_name - local range_start local c_val local pad_val local query @@ -29,30 +43,37 @@ function event(thread_id) db_query(begin_query) end + if not oltp_write_only then + for i=1, oltp_point_selects do - rs = db_query("SELECT c FROM ".. table_name .." WHERE id=" .. sb_rand(1, oltp_table_size)) + rs = db_query("SELECT c FROM ".. table_name .." WHERE id=" .. + sb_rand(1, oltp_table_size)) end + if oltp_range_selects then + for i=1, oltp_simple_ranges do - range_start = sb_rand(1, oltp_table_size) - rs = db_query("SELECT c FROM ".. table_name .." WHERE id BETWEEN " .. range_start .. " AND " .. range_start .. "+" .. oltp_range_size - 1) + rs = db_query("SELECT c FROM ".. table_name .. get_range_str()) end - + for i=1, oltp_sum_ranges do - range_start = sb_rand(1, oltp_table_size) - rs = db_query("SELECT SUM(K) FROM ".. table_name .." WHERE id BETWEEN " .. range_start .. " AND " .. range_start .. "+" .. oltp_range_size - 1) + rs = db_query("SELECT SUM(K) FROM ".. table_name .. get_range_str()) end - + for i=1, oltp_order_ranges do - range_start = sb_rand(1, oltp_table_size) - rs = db_query("SELECT c FROM ".. table_name .." WHERE id BETWEEN " .. range_start .. " AND " .. range_start .. "+" .. oltp_range_size - 1 .. " ORDER BY c") + rs = db_query("SELECT c FROM ".. table_name .. get_range_str() .. + " ORDER BY c") end for i=1, oltp_distinct_ranges do - range_start = sb_rand(1, oltp_table_size) - rs = db_query("SELECT DISTINCT c FROM ".. table_name .." WHERE id BETWEEN " .. range_start .. " AND " .. range_start .. "+" .. oltp_range_size - 1 .. " ORDER BY c") + rs = db_query("SELECT DISTINCT c FROM ".. table_name .. get_range_str() .. + " ORDER BY c") end + end + + end + if not oltp_read_only then for i=1, oltp_index_updates do @@ -68,6 +89,8 @@ function event(thread_id) end end + for i=1, oltp_delete_inserts do + i = sb_rand(1, oltp_table_size) rs = db_query("DELETE FROM " .. table_name .. " WHERE id=" .. i) @@ -79,6 +102,8 @@ function event(thread_id) rs = db_query("INSERT INTO " .. table_name .. " (id, k, c, pad) VALUES " .. string.format("(%d, %d, '%s', '%s')",i, sb_rand(1, oltp_table_size) , c_val, pad_val)) + end + end -- oltp_read_only if not oltp_skip_trx then diff --git a/sysbench/tests/db/oltp_simple.lua b/sysbench/tests/db/oltp_simple.lua index 13da9b1..c55cc57 100644 --- a/sysbench/tests/db/oltp_simple.lua +++ b/sysbench/tests/db/oltp_simple.lua @@ -1,6 +1,10 @@ -pathtest = string.match(test, "(.*/)") or "" +pathtest = string.match(test, "(.*/)") -dofile(pathtest .. "common.lua") +if pathtest then + dofile(pathtest .. "common.lua") +else + require("common") +end function thread_init(thread_id) set_vars() diff --git a/sysbench/tests/db/parallel_prepare.lua b/sysbench/tests/db/parallel_prepare.lua index a28af58..d001310 100644 --- a/sysbench/tests/db/parallel_prepare.lua +++ b/sysbench/tests/db/parallel_prepare.lua @@ -1,12 +1,20 @@ -pathtest = string.match(test, "(.*/)") or "" +-- for proper initialization use --max-requests = N, where N is --num-threads +-- +pathtest = string.match(test, "(.*/)") -dofile(pathtest .. "common.lua") +if pathtest then + dofile(pathtest .. "common.lua") +else + require("common") +end function thread_init(thread_id) + set_vars() +end + +function event(thread_id) local index_name local i - set_vars() - print("thread prepare"..thread_id) if (oltp_secondary) then @@ -20,7 +28,3 @@ function thread_init(thread_id) end end - -function event(thread_id) - -end diff --git a/sysbench/tests/db/select.lua b/sysbench/tests/db/select.lua index a43f7b7..b2a75f6 100644 --- a/sysbench/tests/db/select.lua +++ b/sysbench/tests/db/select.lua @@ -1,6 +1,10 @@ -pathtest = string.match(test, "(.*/)") or "" +pathtest = string.match(test, "(.*/)") -dofile(pathtest .. "common.lua") +if pathtest then + dofile(pathtest .. "common.lua") +else + require("common") +end function thread_init(thread_id) set_vars() diff --git a/sysbench/tests/db/update_index.lua b/sysbench/tests/db/update_index.lua index e74027f..077240c 100644 --- a/sysbench/tests/db/update_index.lua +++ b/sysbench/tests/db/update_index.lua @@ -1,6 +1,10 @@ -pathtest = string.match(test, "(.*/)") or "" +pathtest = string.match(test, "(.*/)") -dofile(pathtest .. "common.lua") +if pathtest then + dofile(pathtest .. "common.lua") +else + require("common") +end function thread_init(thread_id) set_vars() diff --git a/sysbench/tests/db/update_non_index.lua b/sysbench/tests/db/update_non_index.lua index bb17dad..1a6a502 100644 --- a/sysbench/tests/db/update_non_index.lua +++ b/sysbench/tests/db/update_non_index.lua @@ -1,6 +1,10 @@ -pathtest = string.match(test, "(.*/)") or "" +pathtest = string.match(test, "(.*/)") -dofile(pathtest .. "common.lua") +if pathtest then + dofile(pathtest .. "common.lua") +else + require("common") +end function thread_init(thread_id) set_vars() diff --git a/sysbench/tests/fileio/sb_fileio.c b/sysbench/tests/fileio/sb_fileio.c index 4fe5857..0946081 100644 --- a/sysbench/tests/fileio/sb_fileio.c +++ b/sysbench/tests/fileio/sb_fileio.c @@ -309,7 +309,8 @@ static unsigned long sb_getpagesize(void); static unsigned long sb_get_allocation_granularity(void); static void *sb_memalign(size_t size); static void sb_free_memaligned(void *buf); -static FILE_DESCRIPTOR sb_open(const char *name); +static FILE_DESCRIPTOR sb_open(const char *); +static int sb_create(const char *); int register_test_fileio(sb_list_t *tests) { @@ -355,14 +356,21 @@ int file_prepare(void) { snprintf(file_name, sizeof(file_name), "test_file.%d",i); /* remove test files for creation test if they exist */ - if (test_mode == MODE_WRITE) + if (test_mode == MODE_WRITE) + { unlink(file_name); + if (sb_create(file_name)) + { + log_errno(LOG_FATAL, "Cannot create file '%s'", file_name); + return 1; + } + } log_text(LOG_DEBUG, "Opening file: %s", file_name); files[i] = sb_open(file_name); if (!VALID_FILE(files[i])) { - log_errno(LOG_FATAL, "Cannot open file"); + log_errno(LOG_FATAL, "Cannot open file '%s'", file_name); return 1; } } @@ -743,8 +751,8 @@ int file_execute_request(sb_request_t *sb_req, int thread_id) file_validate_buffer(per_thread[thread_id].buffer, file_req->size, file_req->pos)) { log_text(LOG_FATAL, - "Validation failed on file " FD_FMT ", block offset 0x%x, exiting...", - file_req->file_id, file_req->pos); + "Validation failed on file " FD_FMT ", block offset %lld, exiting...", + file_req->file_id, (long long) file_req->pos); return 1; } @@ -793,15 +801,15 @@ void file_print_mode(void) char sizestr[16]; log_text(LOG_NOTICE, "Extra file open flags: %x", file_extra_flags); - log_text(LOG_NOTICE, "%d files, %sb each", num_files, + log_text(LOG_NOTICE, "%d files, %sB each", num_files, sb_print_value_size(sizestr, sizeof(sizestr), file_size)); - log_text(LOG_NOTICE, "%sb total file size", + log_text(LOG_NOTICE, "%sB total file size", sb_print_value_size(sizestr, sizeof(sizestr), file_size * num_files)); - log_text(LOG_NOTICE, "Block size %sb", + log_text(LOG_NOTICE, "Block size %sB", sb_print_value_size(sizestr, sizeof(sizestr), file_block_size)); if (file_merged_requests > 0) - log_text(LOG_NOTICE, "Merging requests up to %sb for sequential IO.", + log_text(LOG_NOTICE, "Merging requests up to %sB for sequential IO.", sb_print_value_size(sizestr, sizeof(sizestr), file_max_request_size)); @@ -846,7 +854,6 @@ void file_print_mode(void) void file_print_stats(sb_stat_t type) { double seconds; - char s1[16], s2[16], s3[16], s4[16]; unsigned long long diff_read; unsigned long long diff_written; unsigned long long diff_other_ops; @@ -869,8 +876,8 @@ void file_print_stats(sb_stat_t type) SB_THREAD_MUTEX_UNLOCK(); log_timestamp(LOG_NOTICE, &sb_globals.exec_timer, - "reads: %4.2f MB/s writes: %4.2f MB/s fsyncs: %4.2f/s " - "response time: %4.3fms (%u%%)", + "reads: %4.2f MiB/s writes: %4.2f MiB/s fsyncs: %4.2f/s " + "latency: %4.3f ms (%uth pct.)", diff_read / megabyte / seconds, diff_written / megabyte / seconds, diff_other_ops / seconds, @@ -886,18 +893,19 @@ void file_print_stats(sb_stat_t type) case SB_STAT_CUMULATIVE: seconds = NS2SEC(sb_timer_split(&sb_globals.cumulative_timer1)); - log_text(LOG_NOTICE, - "Operations performed: %d reads, %d writes, %d Other = %d Total", - read_ops, write_ops, other_ops, read_ops + write_ops + other_ops); - log_text(LOG_NOTICE, "Read %sb Written %sb Total transferred %sb " - "(%sb/sec)", - sb_print_value_size(s1, sizeof(s1), bytes_read), - sb_print_value_size(s2, sizeof(s2), bytes_written), - sb_print_value_size(s3, sizeof(s3), bytes_read + bytes_written), - sb_print_value_size(s4, sizeof(s4), - (bytes_read + bytes_written) / seconds)); - log_text(LOG_NOTICE, "%8.2f Requests/sec executed", - (read_ops + write_ops) / seconds); + log_text(LOG_NOTICE, "\n" + "File operations:\n" + " reads/s: %4.2f\n" + " writes/s: %4.2f\n" + " fsyncs/s: %4.2f\n" + "\n" + "Throughput:\n" + " read, MiB/s: %4.2f\n" + " written, MiB/s: %4.2f", + read_ops / seconds, write_ops / seconds, other_ops / seconds, + bytes_read / megabyte / seconds, + bytes_written / megabyte / seconds); + clear_stats(); break; @@ -1084,7 +1092,7 @@ int create_files(void) seconds = NS2SEC(sb_timer_value(&t)); if (written > 0) - log_text(LOG_NOTICE, "%llu bytes written in %.2f seconds (%.2f MB/sec).", + log_text(LOG_NOTICE, "%llu bytes written in %.2f seconds (%.2f MiB/sec).", written, seconds, (double) (written / megabyte) / seconds); else @@ -1918,7 +1926,7 @@ int parse_arguments(void) file_rw_ratio = sb_get_value_float("file-rw-ratio"); if (file_rw_ratio < 0) { - log_text(LOG_FATAL, "Invalid value file file-rw-ratio: %f.", file_rw_ratio); + log_text(LOG_FATAL, "Invalid value for --file-rw-ratio: %f.", file_rw_ratio); return 1; } @@ -1926,6 +1934,12 @@ int parse_arguments(void) for (i = 0; i < sb_globals.num_threads; i++) { per_thread[i].buffer = sb_memalign(file_max_request_size); + if (per_thread[i].buffer == NULL) + { + log_text(LOG_FATAL, "Failed to allocate a memory buffer"); + return 1; + } + memset(per_thread[i].buffer, 0, file_max_request_size); } return 0; @@ -2055,11 +2069,10 @@ static FILE_DESCRIPTOR sb_open(const char *name) return SB_INVALID_FILE; #ifndef _WIN32 - file = open(name, O_CREAT | O_RDWR | flags, - S_IRUSR | S_IWUSR); + file = open(name, O_RDWR | flags, S_IRUSR | S_IWUSR); #else - file = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, - OPEN_ALWAYS, flags, NULL); + file = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + flags, NULL); #endif #ifdef HAVE_DIRECTIO @@ -2074,6 +2087,30 @@ static FILE_DESCRIPTOR sb_open(const char *name) return file; } +/* + Create a file with a given path. Signal an error if the file already + exists. Return a non-zero value on error. +*/ + +static int sb_create(const char *path) +{ + FILE_DESCRIPTOR file; + int res; + +#ifndef _WIN32 + file = open(path, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + res = !VALID_FILE(file); + close(file); +#else + file = CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, + 0, NULL); + res = !VALID_FILE(file); + CloseHandle(file); +#endif + + return res; +} + /* Fill buffer with random values and write checksum */ @@ -2108,7 +2145,8 @@ int file_validate_buffer(unsigned char *buf, unsigned int len, size_t offset) if (checksum != *(unsigned int *)(void *)(buf + cs_offset)) { - log_text(LOG_FATAL, "Checksum mismatch in block: ", offset); + log_text(LOG_FATAL, "Checksum mismatch in block with offset: %lld", + (long long) offset); log_text(LOG_FATAL, " Calculated value: 0x%x Stored value: 0x%x", checksum, *(unsigned int *)(void *)(buf + cs_offset)); return 1; diff --git a/sysbench/tests/memory/sb_memory.c b/sysbench/tests/memory/sb_memory.c index 50f042c..3f28591 100644 --- a/sysbench/tests/memory/sb_memory.c +++ b/sysbench/tests/memory/sb_memory.c @@ -247,7 +247,7 @@ sb_request_t memory_get_request(int thread_id) int memory_execute_request(sb_request_t *sb_req, int thread_id) { sb_mem_request_t *mem_req = &sb_req->u.mem_request; - int tmp = 0; + volatile int tmp = 0; int idx; int *buf, *end; log_msg_t msg; @@ -322,9 +322,9 @@ void memory_print_mode(void) char *str; log_text(LOG_INFO, "Doing memory operations speed test"); - log_text(LOG_INFO, "Memory block size: %ldK\n", + log_text(LOG_INFO, "Memory block size: %ldKiB\n", (long)(memory_block_size / 1024)); - log_text(LOG_INFO, "Memory transfer size: %ldM\n", + log_text(LOG_INFO, "Memory transfer size: %ldMiB\n", (long)(memory_total_size / 1024 / 1024)); switch (memory_oper) { @@ -369,7 +369,7 @@ void memory_print_stats(sb_stat_t type) seconds = NS2SEC(sb_timer_split(&sb_globals.exec_timer)); log_timestamp(LOG_NOTICE, &sb_globals.exec_timer, - "%4.2f MB/sec,", + "%4.2f MiB/sec,", (double)(total_bytes - last_bytes) / megabyte / seconds); last_bytes = total_bytes; SB_THREAD_MUTEX_UNLOCK(); @@ -382,7 +382,7 @@ void memory_print_stats(sb_stat_t type) log_text(LOG_NOTICE, "Operations performed: %d (%8.2f ops/sec)\n", total_ops, total_ops / seconds); if (memory_oper != SB_MEM_OP_NONE) - log_text(LOG_NOTICE, "%4.2f MB transferred (%4.2f MB/sec)\n", + log_text(LOG_NOTICE, "%4.2f MiB transferred (%4.2f MiB/sec)\n", total_bytes / megabyte, total_bytes / megabyte / seconds); total_ops = 0; @@ -415,7 +415,7 @@ void * hugetlb_alloc(size_t size) if (shmid < 0) { log_errno(LOG_FATAL, - "Failed to allocate %d bytes from HugeTLB memory.", size); + "Failed to allocate %zd bytes from HugeTLB memory.", size); return NULL; } diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..3279762 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,55 @@ +# Copyright (C) 2016 Alexey Kopytov +# +# 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 + +TESTS = test_run.sh + +test_SCRIPTS = test_run.sh + +EXTRA_DIST = $(test_SCRIPTS) \ + README.md + +testroot = $(datadir) +testdir = $(testroot)/sysbench/tests +test_dirs= t + +# Used by dist-hook and install-data-local to copy all +# test files into either dist or install directory +install_test_files: + @if test -z "$(INSTALL_TO_DIR)"; then \ + echo "Set INSTALL_TO_DIR!" && exit 1; \ + fi + @for dir in $(test_dirs); do \ + from_dir="$(srcdir)/$$dir"; \ + to_dir="$(INSTALL_TO_DIR)/$$dir"; \ + $(mkinstalldirs) "$$to_dir"; \ + for f in `(cd $$from_dir && ls *.t)`; do \ + if test -f "$$from_dir/$$f"; then \ + $(INSTALL_DATA) "$$from_dir/$$f" "$$to_dir/$$f" ; \ + fi; \ + done \ + done + +dist-hook: + $(MAKE) INSTALL_TO_DIR="$(distdir)" install_test_files + +install-data-local: + $(MAKE) INSTALL_TO_DIR="$(DESTDIR)$(testdir)" install_test_files + +uninstall-local: + rm -f -r $(DESTDIR)$(testdir) + +test: + ./test_run.sh diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..760b38e --- /dev/null +++ b/tests/README.md @@ -0,0 +1,52 @@ +sysbench Test Suite +=================== + +sysbench uses the [Cram](https://bitheap.org/cram/) framework for +functional and regression testing. If your system has Python 2.7.9 or +later, or Python 3.4 or later, installing Cram is as simple as executing +`pip install cram`. + +If you use an older Python version, you may need to [install +pip](https://pip.pypa.io/en/latest/installing/) first: + +``` {.example} +curl https://bootstrap.pypa.io/get-pip.py | python +``` + +To run the sysbench test suite, invoke the `test_run.sh` script in the +`tests` directory as follows: + +``` {.example} +./test_run.sh [test_name]... +``` + +Each `test_name` argument is a name of a test case file. Functional and +regression tests are located in the `t` subdirectory in files with the +`.t` suffix. + +If no tests are named on the `test_run.sh` command line, it will execute +all files with the `.t` suffix in the `t` subdirectory. + +Some tests require external servers (MySQL, PostgreSQL, etc). One should +use environment variables to specify connection related arguments that +sysbench can use to connect to such external server(s). The currently +recognized variables are: + +- `SBTEST_MYSQL_ARGS` -- MySQL connection options: `--mysql-host`, + `--mysql-port`, `--mysql-socket` `--mysql-user`, `--mysql-password` + and `--mysql-db`; + +- `SBTEST_PGSQL_ARGS` -- PostgreSQL connection options: `--pgsql-host`, + `--pgsql-port`, `--pgsql-user`, `--pgsql-password` and `--pgsql-db`. + +For example: +``` {.example} +export SBTEST_MYSQL_ARGS="--mysql-host=localhost --mysql-user=sbtest --mysql-password=secret --mysql-db=sbtest" +export SBTEST_PGSQL_ARGS="--pgsql-host=localhost --pgsql-user=postgres --pgsql-password=secret --pgsql-db=sbtest" +./test_run.sh +``` + +sysbench assumes that server(s) are pre-configured so that the specified +database exists and the user connecting with the specified credentials +has all privileges on the database. In particular, sysbench must have +enough privileges to create/drop/read/modify tables in that database. diff --git a/tests/include/config.sh.in b/tests/include/config.sh.in new file mode 100644 index 0000000..e6f2a14 --- /dev/null +++ b/tests/include/config.sh.in @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# Configuration file used by the sysbench test suite. + +# Copyright (C) 2016 Alexey Kopytov +# +# 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 + +SBTEST_VERSION=@PACKAGE_VERSION@ diff --git a/tests/include/drv_common.sh b/tests/include/drv_common.sh new file mode 100644 index 0000000..2f414bf --- /dev/null +++ b/tests/include/drv_common.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# +######################################################################### +# Common code for DB driver tests +# Variables: +# DB_DRIVER_ARGS -- extra driver-specific arguments to pass to sysbench +######################################################################### + +set -eu + +cat >test.lua </dev/null 2>&1 diff --git a/tests/t/cleanup.t b/tests/t/cleanup.t new file mode 100644 index 0000000..9629cbd --- /dev/null +++ b/tests/t/cleanup.t @@ -0,0 +1,3 @@ + $ sysbench cleanup | grep Missing + Missing required argument: --test. + [1] diff --git a/tests/t/commands.t b/tests/t/commands.t new file mode 100644 index 0000000..1dbc621 --- /dev/null +++ b/tests/t/commands.t @@ -0,0 +1,8 @@ + $ commands=$(sysbench help | grep 'Commands:' | cut -d ' ' -f 2-) + $ for cmd in $commands; do + > if [ ! -r ${SBTEST_SUITEDIR}/${cmd}.t ] + > then + > echo "Cannot find test(s) for 'sysbench $cmd'!" + > exit 1 + > fi + > done diff --git a/tests/t/drivers.t b/tests/t/drivers.t new file mode 100644 index 0000000..cfc4d4b --- /dev/null +++ b/tests/t/drivers.t @@ -0,0 +1,13 @@ +######################################################################## +Make sure all available DB drivers are covered +######################################################################## + + $ drivers=$(sysbench help | sed -n '/Compiled-in database drivers:/,/^$/p' | tail -n +2 | cut -d ' ' -f 3) + $ for drv in $drivers + > do + > if [ ! -r ${SBTEST_SUITEDIR}/drv_${drv}.t ] + > then + > echo "Cannot find test(s) for the $drv driver!" + > exit 1 + > fi + > done diff --git a/tests/t/drv_mysql.t b/tests/t/drv_mysql.t new file mode 100644 index 0000000..f3255fd --- /dev/null +++ b/tests/t/drv_mysql.t @@ -0,0 +1,47 @@ +######################################################################## +MySQL driver tests +######################################################################## + + $ if [ -z "${SBTEST_MYSQL_ARGS:-}" ] + > then + > exit 80 + > fi + $ DB_DRIVER_ARGS="--db-driver=mysql $SBTEST_MYSQL_ARGS" + $ . $SBTEST_INCDIR/drv_common.sh + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 2 + Initializing random number generator from current time + + + Initializing worker threads... + + Threads started! + + OLTP test statistics: + queries performed: + read: 10 + write: 0 + other: 0 + total: 10 + transactions: 0 (0.00 per sec.) + read/write requests: 10 (*.* per sec.) (glob) + other operations: 0 (0.00 per sec.) + ignored errors: 0 (0.00 per sec.) + reconnects: 0 (0.00 per sec.) + + General statistics: + total time: *.*s (glob) + total number of events: 10 + total time taken by event execution: *.*s (glob) + response time: + min: *.*ms (glob) + avg: *.*ms (glob) + max: *.*ms (glob) + approx. 95 percentile: *.*ms (glob) + + Threads fairness: + events (avg/stddev): *.*/*.* (glob) + execution time (avg/stddev): *.*/*.* (glob) + diff --git a/tests/t/drv_pgsql.t b/tests/t/drv_pgsql.t new file mode 100644 index 0000000..94c04ea --- /dev/null +++ b/tests/t/drv_pgsql.t @@ -0,0 +1,47 @@ +######################################################################## +PostgreSQL driver tests +######################################################################## + + $ if [ -z "${SBTEST_PGSQL_ARGS:-}" ] + > then + > exit 80 + > fi + $ DB_DRIVER_ARGS="--db-driver=pgsql $SBTEST_PGSQL_ARGS" + $ . $SBTEST_INCDIR/drv_common.sh + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 2 + Initializing random number generator from current time + + + Initializing worker threads... + + Threads started! + + OLTP test statistics: + queries performed: + read: 10 + write: 0 + other: 0 + total: 10 + transactions: 0 (0.00 per sec.) + read/write requests: 10 (*.* per sec.) (glob) + other operations: 0 (0.00 per sec.) + ignored errors: 0 (0.00 per sec.) + reconnects: 0 (0.00 per sec.) + + General statistics: + total time: *.*s (glob) + total number of events: 10 + total time taken by event execution: *.*s (glob) + response time: + min: *.*ms (glob) + avg: *.*ms (glob) + max: *.*ms (glob) + approx. 95 percentile: *.*ms (glob) + + Threads fairness: + events (avg/stddev): *.*/*.* (glob) + execution time (avg/stddev): *.*/*.* (glob) + diff --git a/tests/t/help.t b/tests/t/help.t new file mode 100644 index 0000000..f778d22 --- /dev/null +++ b/tests/t/help.t @@ -0,0 +1,70 @@ +######################################################################## +Skip everything between "Compiled-in database drivers:" and +"Compiled-in tests:" as that part depends on available database +drivers and thus, build options. Driver-specific options is tested +separately. +######################################################################## + + $ sysbench help | sed '/Compiled-in database drivers:/,/Compiled-in tests:/d' + sysbench 1.0: multi-threaded system evaluation benchmark + + Usage: + sysbench --test= [options]... + + Commands: prepare run cleanup help version + + General options: + --num-threads=N number of threads to use [1] + --max-requests=N limit for total number of requests [10000] + --max-time=N limit for total execution time in seconds [0] + --forced-shutdown=STRING amount of time to wait after --max-time before forcing shutdown [off] + --thread-stack-size=SIZE size of stack per thread [64K] + --tx-rate=N target transaction rate (tps) [0] + --report-interval=N periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0] + --report-checkpoints=[LIST,...]dump full statistics and reset all counters at specified points in time. The argument is a list of comma-separated values representing the amount of time in seconds elapsed from start of test when report checkpoint(s) must be performed. Report checkpoints are off by default. [] + --test=STRING test to run + --debug=[on|off] print more debugging info [off] + --validate=[on|off] perform validation checks where possible [off] + --help=[on|off] print help and exit + --version=[on|off] print version and exit [off] + --rand-type=STRING random numbers distribution {uniform,gaussian,special,pareto} [special] + --rand-spec-iter=N number of iterations used for numbers generation [12] + --rand-spec-pct=N percentage of values to be treated as 'special' (for special distribution) [1] + --rand-spec-res=N percentage of 'special' values to use (for special distribution) [75] + --rand-seed=N seed for random number generator, ignored when 0 [0] + --rand-pareto-h=N parameter h for pareto distibution [0.2] + --config-file=FILENAME File containing command line options + + Log options: + --verbosity=N verbosity level {5 - debug, 0 - only critical messages} [3] + + --percentile=N percentile rank of query response times to count. Use the special value of 0 to disable percentile statistics. [95] + + General database options: + + --db-driver=STRING specifies database driver to use ('help' to get list of available drivers) + --db-ps-mode=STRING prepared statements usage mode {auto, disable} [auto] + --db-debug=[on|off] print database-specific debug information [off] + + + fileio - File I/O test + cpu - CPU performance test + memory - Memory functions speed test + threads - Threads subsystem performance test + mutex - Mutex performance test + + See 'sysbench --test= help' for a list of options for each test. + + +######################################################################## +Test driver-specific options +######################################################################## + $ drivers=$(sysbench help | sed -n '/Compiled-in database drivers:/,/^$/p' | tail -n +2 | cut -d ' ' -f 3) + $ for drv in $drivers + > do + > if [ ! -r ${SBTEST_SUITEDIR}/help_drv_${drv}.t ] + > then + > echo "Cannot find test(s) for $drv driver options!" + > exit 1 + > fi + > done diff --git a/tests/t/help_drv_mysql.t b/tests/t/help_drv_mysql.t new file mode 100644 index 0000000..c5631d3 --- /dev/null +++ b/tests/t/help_drv_mysql.t @@ -0,0 +1,24 @@ +Skip test if the MySQL driver is not available. + + $ if ! sysbench help | sed -n '/Compiled-in database drivers:/,/^$/p' | grep mysql > /dev/null 2>&1 + > then + > exit 80 + > fi + + $ sysbench help | sed -n '/mysql options:/,/^$/p' + mysql options: + --mysql-host=[LIST,...] MySQL server host [localhost] + --mysql-port=[LIST,...] MySQL server port [3306] + --mysql-socket=[LIST,...] MySQL socket + --mysql-user=STRING MySQL user [sbtest] + --mysql-password=STRING MySQL password [] + --mysql-db=STRING MySQL database name [sbtest] + --mysql-table-engine=STRING storage engine to use for the test table {myisam,innodb,bdb,heap,ndbcluster,federated} [innodb] + --mysql-engine-trx=STRING whether storage engine used is transactional or not {yes,no,auto} [auto] + --mysql-ssl=[on|off] use SSL connections, if available in the client library [off] + --mysql-compression=[on|off] use compression, if available in the client library [off] + --myisam-max-rows=N max-rows parameter for MyISAM tables [1000000] + --mysql-debug=[on|off] dump all client library calls [off] + --mysql-ignore-errors=[LIST,...]list of errors to ignore, or "all" [1213,1020,1205] + --mysql-dry-run=[on|off] Dry run, pretent that all MySQL client API calls are successful without executing them [off] + diff --git a/tests/t/help_drv_pgsql.t b/tests/t/help_drv_pgsql.t new file mode 100644 index 0000000..b4d788c --- /dev/null +++ b/tests/t/help_drv_pgsql.t @@ -0,0 +1,15 @@ +Skip test if the PostgreSQL driver is not available. + + $ if ! sysbench help | sed -n '/Compiled-in database drivers:/,/^$/p' | grep pgsql > /dev/null 2>&1 + > then + > exit 80 + > fi + + $ sysbench help | sed -n '/pgsql options:/,/^$/p' + pgsql options: + --pgsql-host=STRING PostgreSQL server host [localhost] + --pgsql-port=N PostgreSQL server port [5432] + --pgsql-user=STRING PostgreSQL user [sbtest] + --pgsql-password=STRING PostgreSQL password [] + --pgsql-db=STRING PostgreSQL database name [sbtest] + diff --git a/tests/t/prepare.t b/tests/t/prepare.t new file mode 100644 index 0000000..b583012 --- /dev/null +++ b/tests/t/prepare.t @@ -0,0 +1,3 @@ + $ sysbench prepare | grep Missing + Missing required argument: --test. + [1] diff --git a/tests/t/run.t b/tests/t/run.t new file mode 100644 index 0000000..e706b09 --- /dev/null +++ b/tests/t/run.t @@ -0,0 +1,3 @@ + $ sysbench run | grep Missing + Missing required argument: --test. + [1] diff --git a/tests/t/script_oltp_mysql.t b/tests/t/script_oltp_mysql.t new file mode 100644 index 0000000..145f52d --- /dev/null +++ b/tests/t/script_oltp_mysql.t @@ -0,0 +1,160 @@ +######################################################################## +oltp.lua + MySQL tests +######################################################################## + + $ if [ -z "${SBTEST_MYSQL_ARGS:-}" ] + > then + > exit 80 + > fi + + $ DB_DRIVER_ARGS="--db-driver=mysql --mysql-table-engine=myisam $SBTEST_MYSQL_ARGS" + $ . $SBTEST_INCDIR/script_oltp_common.sh + sysbench *: multi-threaded system evaluation benchmark (glob) + + Creating table 'sbtest1'... + Inserting 10000 records into 'sbtest1' + Creating secondary indexes on 'sbtest1'... + Creating table 'sbtest2'... + Inserting 10000 records into 'sbtest2' + Creating secondary indexes on 'sbtest2'... + Creating table 'sbtest3'... + Inserting 10000 records into 'sbtest3' + Creating secondary indexes on 'sbtest3'... + Creating table 'sbtest4'... + Inserting 10000 records into 'sbtest4' + Creating secondary indexes on 'sbtest4'... + Creating table 'sbtest5'... + Inserting 10000 records into 'sbtest5' + Creating secondary indexes on 'sbtest5'... + Creating table 'sbtest6'... + Inserting 10000 records into 'sbtest6' + Creating secondary indexes on 'sbtest6'... + Creating table 'sbtest7'... + Inserting 10000 records into 'sbtest7' + Creating secondary indexes on 'sbtest7'... + Creating table 'sbtest8'... + Inserting 10000 records into 'sbtest8' + Creating secondary indexes on 'sbtest8'... + sysbench *: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 1 + Initializing random number generator from current time + + + Initializing worker threads... + + Threads started! + + OLTP test statistics: + queries performed: + read: 1400 + write: 400 + other: 200 + total: 2000 + transactions: 100 (* per sec.) (glob) + read/write requests: 1800 (* per sec.) (glob) + other operations: 200 (* per sec.) (glob) + ignored errors: 0 (* per sec.) (glob) + reconnects: 0 (* per sec.) (glob) + + General statistics: + total time: *s (glob) + total number of events: 100 + total time taken by event execution: *s (glob) + response time: + min: *ms (glob) + avg: *ms (glob) + max: *ms (glob) + approx. 95 percentile: *ms (glob) + + Threads fairness: + events (avg/stddev): */* (glob) + execution time (avg/stddev): */* (glob) + + sysbench *: multi-threaded system evaluation benchmark (glob) + + Dropping table 'sbtest1'... + Dropping table 'sbtest2'... + Dropping table 'sbtest3'... + Dropping table 'sbtest4'... + Dropping table 'sbtest5'... + Dropping table 'sbtest6'... + Dropping table 'sbtest7'... + Dropping table 'sbtest8'... + + $ DB_DRIVER_ARGS="--db-driver=mysql --mysql-table-engine=innodb $SBTEST_MYSQL_ARGS" + $ . $SBTEST_INCDIR/script_oltp_common.sh + sysbench *: multi-threaded system evaluation benchmark (glob) + + Creating table 'sbtest1'... + Inserting 10000 records into 'sbtest1' + Creating secondary indexes on 'sbtest1'... + Creating table 'sbtest2'... + Inserting 10000 records into 'sbtest2' + Creating secondary indexes on 'sbtest2'... + Creating table 'sbtest3'... + Inserting 10000 records into 'sbtest3' + Creating secondary indexes on 'sbtest3'... + Creating table 'sbtest4'... + Inserting 10000 records into 'sbtest4' + Creating secondary indexes on 'sbtest4'... + Creating table 'sbtest5'... + Inserting 10000 records into 'sbtest5' + Creating secondary indexes on 'sbtest5'... + Creating table 'sbtest6'... + Inserting 10000 records into 'sbtest6' + Creating secondary indexes on 'sbtest6'... + Creating table 'sbtest7'... + Inserting 10000 records into 'sbtest7' + Creating secondary indexes on 'sbtest7'... + Creating table 'sbtest8'... + Inserting 10000 records into 'sbtest8' + Creating secondary indexes on 'sbtest8'... + sysbench *: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 1 + Initializing random number generator from current time + + + Initializing worker threads... + + Threads started! + + OLTP test statistics: + queries performed: + read: 1400 + write: 400 + other: 200 + total: 2000 + transactions: 100 (* per sec.) (glob) + read/write requests: 1800 (* per sec.) (glob) + other operations: 200 (* per sec.) (glob) + ignored errors: 0 (* per sec.) (glob) + reconnects: 0 (* per sec.) (glob) + + General statistics: + total time: *s (glob) + total number of events: 100 + total time taken by event execution: *s (glob) + response time: + min: *ms (glob) + avg: *ms (glob) + max: *ms (glob) + approx. 95 percentile: *ms (glob) + + Threads fairness: + events (avg/stddev): */* (glob) + execution time (avg/stddev): */* (glob) + + sysbench *: multi-threaded system evaluation benchmark (glob) + + Dropping table 'sbtest1'... + Dropping table 'sbtest2'... + Dropping table 'sbtest3'... + Dropping table 'sbtest4'... + Dropping table 'sbtest5'... + Dropping table 'sbtest6'... + Dropping table 'sbtest7'... + Dropping table 'sbtest8'... diff --git a/tests/t/script_oltp_pgsql.t b/tests/t/script_oltp_pgsql.t new file mode 100644 index 0000000..09930db --- /dev/null +++ b/tests/t/script_oltp_pgsql.t @@ -0,0 +1,85 @@ +######################################################################## +oltp.lua + PostgreSQL tests +######################################################################## + + $ if [ -z "${SBTEST_PGSQL_ARGS:-}" ] + > then + > exit 80 + > fi + + $ DB_DRIVER_ARGS="--db-driver=pgsql $SBTEST_PGSQL_ARGS" + $ . $SBTEST_INCDIR/script_oltp_common.sh + sysbench *: multi-threaded system evaluation benchmark (glob) + + Creating table 'sbtest1'... + Inserting 10000 records into 'sbtest1' + Creating secondary indexes on 'sbtest1'... + Creating table 'sbtest2'... + Inserting 10000 records into 'sbtest2' + Creating secondary indexes on 'sbtest2'... + Creating table 'sbtest3'... + Inserting 10000 records into 'sbtest3' + Creating secondary indexes on 'sbtest3'... + Creating table 'sbtest4'... + Inserting 10000 records into 'sbtest4' + Creating secondary indexes on 'sbtest4'... + Creating table 'sbtest5'... + Inserting 10000 records into 'sbtest5' + Creating secondary indexes on 'sbtest5'... + Creating table 'sbtest6'... + Inserting 10000 records into 'sbtest6' + Creating secondary indexes on 'sbtest6'... + Creating table 'sbtest7'... + Inserting 10000 records into 'sbtest7' + Creating secondary indexes on 'sbtest7'... + Creating table 'sbtest8'... + Inserting 10000 records into 'sbtest8' + Creating secondary indexes on 'sbtest8'... + sysbench *: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 1 + Initializing random number generator from current time + + + Initializing worker threads... + + Threads started! + + OLTP test statistics: + queries performed: + read: 1400 + write: 400 + other: 200 + total: 2000 + transactions: 100 (* per sec.) (glob) + read/write requests: 1800 (* per sec.) (glob) + other operations: 200 (* per sec.) (glob) + ignored errors: 0 (* per sec.) (glob) + reconnects: 0 (* per sec.) (glob) + + General statistics: + total time: *s (glob) + total number of events: 100 + total time taken by event execution: *s (glob) + response time: + min: *ms (glob) + avg: *ms (glob) + max: *ms (glob) + approx. 95 percentile: *ms (glob) + + Threads fairness: + events (avg/stddev): */* (glob) + execution time (avg/stddev): */* (glob) + + sysbench *: multi-threaded system evaluation benchmark (glob) + + Dropping table 'sbtest1'... + Dropping table 'sbtest2'... + Dropping table 'sbtest3'... + Dropping table 'sbtest4'... + Dropping table 'sbtest5'... + Dropping table 'sbtest6'... + Dropping table 'sbtest7'... + Dropping table 'sbtest8'... + diff --git a/tests/t/test_cpu.t b/tests/t/test_cpu.t new file mode 100644 index 0000000..871f10c --- /dev/null +++ b/tests/t/test_cpu.t @@ -0,0 +1,49 @@ +######################################################################## +cpu benchmark tests +######################################################################## + $ args="--test=cpu --cpu-max-prime=1000 --max-requests=100 --num-threads=2" + $ sysbench $args help + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + cpu options: + --cpu-max-prime=N upper limit for primes generator [10000] + + $ sysbench $args prepare + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + 'cpu' test does not have the 'prepare' command. + [1] + $ sysbench $args run + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 2 + Initializing random number generator from current time + + + Prime numbers limit: 1000 + + Initializing worker threads... + + Threads started! + + + General statistics: + total time: *s (glob) + total number of events: 100 + total time taken by event execution: *s (glob) + response time: + min: *ms (glob) + avg: *ms (glob) + max: *ms (glob) + approx. 95 percentile: *ms (glob) + + Threads fairness: + events (avg/stddev): 50.0000/* (glob) + execution time (avg/stddev): */* (glob) + + $ sysbench $args cleanup + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + 'cpu' test does not have the 'cleanup' command. + [1] diff --git a/tests/t/test_fileio.t b/tests/t/test_fileio.t new file mode 100644 index 0000000..88b1420 --- /dev/null +++ b/tests/t/test_fileio.t @@ -0,0 +1,231 @@ +######################################################################## +fileio benchmark tests +######################################################################## + + $ fileio_args="--test=fileio --file-num=4 --file-total-size=32M" + + $ sysbench $fileio_args prepare + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + 4 files, 8192Kb each, 32Mb total + Creating files for the test... + Extra file open flags: 0 + Creating file test_file.0 + Creating file test_file.1 + Creating file test_file.2 + Creating file test_file.3 + 33554432 bytes written in * seconds (*.* MiB/sec). (glob) + + $ ls test_file.* + test_file.0 + test_file.1 + test_file.2 + test_file.3 + $ for i in $(seq 0 3) + > do + > echo -n "test_file.$i: " + > echo $(wc -c < test_file.$i) + > done + test_file.0: 8388608 + test_file.1: 8388608 + test_file.2: 8388608 + test_file.3: 8388608 + + $ sysbench $fileio_args run | grep FATAL + FATAL: Missing required argument: --file-test-mode + + $ sysbench $fileio_args --max-requests=150 --file-test-mode=rndrw run + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 1 + Initializing random number generator from current time + + + Extra file open flags: 0 + 4 files, 8MiB each + 32MiB total file size + Block size 16KiB + Number of IO requests: 150 + Read/Write ratio for combined random IO test: 1.50 + Periodic FSYNC enabled, calling fsync() each 100 requests. + Calling fsync() at the end of test, Enabled. + Using synchronous I/O mode + Doing random r/w test + Initializing worker threads... + + Threads started! + + + File operations: + reads/s: *.* (glob) + writes/s: *.* (glob) + fsyncs/s: *.* (glob) + + Throughput: + read, MiB/s: *.* (glob) + written, MiB/s: *.* (glob) + + General statistics: + total time: *.*s (glob) + total number of events: 150 + total time taken by event execution: *.*s (glob) + response time: + min: *.*ms (glob) + avg: *.*ms (glob) + max: *.*ms (glob) + approx. 95 percentile: *.*ms (glob) + + Threads fairness: + events (avg/stddev): 150.0000/0.00 + execution time (avg/stddev): *.*/0.00 (glob) + + $ sysbench $fileio_args --max-requests=150 --file-test-mode=rndrd run + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 1 + Initializing random number generator from current time + + + Extra file open flags: 0 + 4 files, 8MiB each + 32MiB total file size + Block size 16KiB + Number of IO requests: 150 + Read/Write ratio for combined random IO test: 1.50 + Periodic FSYNC enabled, calling fsync() each 100 requests. + Calling fsync() at the end of test, Enabled. + Using synchronous I/O mode + Doing random read test + Initializing worker threads... + + Threads started! + + + File operations: + reads/s: *.* (glob) + writes/s: 0.00 + fsyncs/s: 0.00 + + Throughput: + read, MiB/s: *.* (glob) + written, MiB/s: 0.00 + + General statistics: + total time: *.*s (glob) + total number of events: 150 + total time taken by event execution: *.*s (glob) + response time: + min: *.*ms (glob) + avg: *.*ms (glob) + max: *.*ms (glob) + approx. 95 percentile: *.*ms (glob) + + Threads fairness: + events (avg/stddev): 150.0000/0.00 + execution time (avg/stddev): *.*/0.00 (glob) + + + $ sysbench $fileio_args --max-requests=150 --file-test-mode=seqrd run + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 1 + Initializing random number generator from current time + + + Extra file open flags: 0 + 4 files, 8MiB each + 32MiB total file size + Block size 16KiB + Periodic FSYNC enabled, calling fsync() each 100 requests. + Calling fsync() at the end of test, Enabled. + Using synchronous I/O mode + Doing sequential read test + Initializing worker threads... + + Threads started! + + + File operations: + reads/s: *.* (glob) + writes/s: 0.00 + fsyncs/s: 0.00 + + Throughput: + read, MiB/s: *.* (glob) + written, MiB/s: 0.00 + + General statistics: + total time: *.*s (glob) + total number of events: 150 + total time taken by event execution: *.*s (glob) + response time: + min: *.*ms (glob) + avg: *.*ms (glob) + max: *.*ms (glob) + approx. 95 percentile: *.*ms (glob) + + Threads fairness: + events (avg/stddev): 150.0000/0.00 + execution time (avg/stddev): *.*/0.00 (glob) + + + $ sysbench $fileio_args --max-requests=150 --file-test-mode=rndwr run + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 1 + Initializing random number generator from current time + + + Extra file open flags: 0 + 4 files, 8MiB each + 32MiB total file size + Block size 16KiB + Number of IO requests: 150 + Read/Write ratio for combined random IO test: 1.50 + Periodic FSYNC enabled, calling fsync() each 100 requests. + Calling fsync() at the end of test, Enabled. + Using synchronous I/O mode + Doing random write test + Initializing worker threads... + + Threads started! + + + File operations: + reads/s: 0.00 + writes/s: *.* (glob) + fsyncs/s: *.* (glob) + + Throughput: + read, MiB/s: 0.00 + written, MiB/s: *.* (glob) + + General statistics: + total time: *.*s (glob) + total number of events: 150 + total time taken by event execution: *.*s (glob) + response time: + min: *.*ms (glob) + avg: *.*ms (glob) + max: *.*ms (glob) + approx. 95 percentile: *.*ms (glob) + + Threads fairness: + events (avg/stddev): 150.0000/0.00 + execution time (avg/stddev): *.*/0.00 (glob) + + + $ sysbench $fileio_args --max-requests=150 --file-test-mode=foo run + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + FATAL: Invalid IO operations mode: foo. + [1] + $ sysbench $fileio_args cleanup + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Removing test files... + $ ls diff --git a/tests/t/test_memory.t b/tests/t/test_memory.t new file mode 100644 index 0000000..7b8e8ff --- /dev/null +++ b/tests/t/test_memory.t @@ -0,0 +1,68 @@ +######################################################################## +memory benchmark tests +######################################################################## + + $ args="--test=memory --memory-block-size=4K --memory-total-size=1G --max-requests=100 --num-threads=2" + +The --memory-hugetlb option is supported and printed by 'sysbench +help' only on Linux. + + $ if [ "$(uname -s)" = "Linux" ] + > then + > sysbench $args help | grep hugetlb + > else + > echo " --memory-hugetlb=[on|off] allocate memory from HugeTLB pool [off]" + > fi + --memory-hugetlb=[on|off] allocate memory from HugeTLB pool [off] + + $ sysbench $args help | grep -v hugetlb + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + memory options: + --memory-block-size=SIZE size of memory block for test [1K] + --memory-total-size=SIZE total size of data to transfer [100G] + --memory-scope=STRING memory access scope {global,local} [global] + --memory-oper=STRING type of memory operations {read, write, none} [write] + --memory-access-mode=STRING memory access mode {seq,rnd} [seq] + + $ sysbench $args prepare + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + 'memory' test does not have the 'prepare' command. + [1] + $ sysbench $args run + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 2 + Initializing random number generator from current time + + + Initializing worker threads... + + Threads started! + + Operations performed: 262144 (* ops/sec) (glob) + + 1024.00 MiB transferred (* MiB/sec) (glob) + + + General statistics: + total time: *s (glob) + total number of events: 262144 (glob) + total time taken by event execution: *s (glob) + response time: + min: *ms (glob) + avg: *ms (glob) + max: *ms (glob) + approx. 95 percentile: *ms (glob) + + Threads fairness: + events (avg/stddev): */* (glob) + execution time (avg/stddev): */* (glob) + + $ sysbench $args cleanup + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + 'memory' test does not have the 'cleanup' command. + [1] diff --git a/tests/t/test_mutex.t b/tests/t/test_mutex.t new file mode 100644 index 0000000..c8c58c0 --- /dev/null +++ b/tests/t/test_mutex.t @@ -0,0 +1,49 @@ +######################################################################## +mutex benchmark tests +######################################################################## + $ args="--test=mutex --max-requests=10 --num-threads=2" + $ sysbench $args help + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + mutex options: + --mutex-num=N total size of mutex array [4096] + --mutex-locks=N number of mutex locks to do per thread [50000] + --mutex-loops=N number of empty loops to do inside mutex lock [10000] + + $ sysbench $args prepare + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + 'mutex' test does not have the 'prepare' command. + [1] + $ sysbench $args run + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 2 + Initializing random number generator from current time + + + Initializing worker threads... + + Threads started! + + + General statistics: + total time: *s (glob) + total number of events: 2 + total time taken by event execution: *s (glob) + response time: + min: *ms (glob) + avg: *ms (glob) + max: *ms (glob) + approx. 95 percentile: *ms (glob) + + Threads fairness: + events (avg/stddev): */* (glob) + execution time (avg/stddev): */* (glob) + + $ sysbench $args cleanup + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + 'mutex' test does not have the 'cleanup' command. + [1] diff --git a/tests/t/test_threads.t b/tests/t/test_threads.t new file mode 100644 index 0000000..65ab9e0 --- /dev/null +++ b/tests/t/test_threads.t @@ -0,0 +1,49 @@ +######################################################################## +threads benchmark tests +######################################################################## + + $ args="--test=threads --max-requests=100 --num-threads=2" + $ sysbench $args help + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + threads options: + --thread-yields=N number of yields to do per request [1000] + --thread-locks=N number of locks per thread [8] + + $ sysbench $args prepare + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + 'threads' test does not have the 'prepare' command. + [1] + $ sysbench $args run + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + Running the test with following options: + Number of threads: 2 + Initializing random number generator from current time + + + Initializing worker threads... + + Threads started! + + + General statistics: + total time: *s (glob) + total number of events: 100 + total time taken by event execution: *s (glob) + response time: + min: *ms (glob) + avg: *ms (glob) + max: *ms (glob) + approx. 95 percentile: *ms (glob) + + Threads fairness: + events (avg/stddev): */* (glob) + execution time (avg/stddev): */* (glob) + + $ sysbench $args cleanup + sysbench *.*: multi-threaded system evaluation benchmark (glob) + + 'threads' test does not have the 'cleanup' command. + [1] diff --git a/tests/t/tests.t b/tests/t/tests.t new file mode 100644 index 0000000..bd4c65f --- /dev/null +++ b/tests/t/tests.t @@ -0,0 +1,13 @@ +######################################################################## +Make sure all built-in tests are covered +######################################################################## + + $ tests=$(sysbench help | sed -n '/Compiled-in tests:/,/^$/p' | tail -n +2 | cut -d ' ' -f 3) + $ for t in $tests + > do + > if [ ! -r ${SBTEST_SUITEDIR}/test_${t}.t ] + > then + > echo "Cannot find test(s) for 'sysbench --test=$t'!" + > exit 1 + > fi + > done diff --git a/tests/t/version.t b/tests/t/version.t new file mode 100644 index 0000000..8f22cd2 --- /dev/null +++ b/tests/t/version.t @@ -0,0 +1,7 @@ + $ . $SBTEST_CONFIG + + $ sysbench --version + sysbench [.0-9]* (re) + + $ version=$(sysbench --version | cut -d ' ' -f 2) + $ test "$version" = "$SBTEST_VERSION" diff --git a/tests/test_run.sh b/tests/test_run.sh new file mode 100755 index 0000000..8703bd9 --- /dev/null +++ b/tests/test_run.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# Copyright (C) 2016 Alexey Kopytov +# +# 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 + +set -eu + +testroot=$(cd $(dirname "$0"); echo $PWD) + +# Find the sysbench binary to use +if [ -x "$testroot/../sysbench/sysbench" ] +then + # Invoked from a source directory? + PATH="$testroot/../sysbench:$PATH" +elif [ -x "$testroot/../bin" ] +then + # Invoked from a standalone install root directory? + PATH="$testroot/../bin:$PATH" +elif [ -x "$testroot/../../../bin/sysbench" ] +then + # Invoked from a system-wide install (e.g. /usr/local/share/sysbench/tests)? + PATH="$testroot/../../../bin:$PATH" +elif [ -x "$PWD/../sysbench/sysbench" ] +then + # Invoked from the build directory by 'make distcheck'? + PATH="$PWD/../sysbench:$PATH" +fi + +if ! which sysbench >/dev/null 2>&1 +then + echo "Cannot find sysbench in PATH=$PATH" + echo "testroot=$testroot" + echo "PWD=$PWD" + ls -l $PWD + ls -l $PWD/../sysbench + ls -l $testroot + ls -l $testroot/.. + ls -l $testroot/../sysbench + exit 1 +fi + +if [ $# -lt 1 ] +then + if [ -z ${srcdir+x} ] + then + tests="t/*.t" + else + tests="$srcdir/t/*.t" + fi +else + tests="$*" +fi + +export SBTEST_ROOTDIR="$testroot" +export SBTEST_SCRIPTDIR="$testroot/../sysbench/tests/db" +export SBTEST_SUITEDIR="$testroot/t" +export SBTEST_INCDIR="$PWD/include" +export SBTEST_CONFIG="$SBTEST_INCDIR/config.sh" + +cram --shell=/bin/bash --verbose $tests