From e7f6becf88eaaa9e7f6cff2ca07124c73e72f2e6 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 2 Apr 2019 10:05:44 -0400 Subject: [PATCH] Added framework for smoke tests and few basic tests. Signed-off-by: Michal Mielewczyk --- test/smoke_test/README | 120 +++ test/smoke_test/basic/01 | 31 + test/smoke_test/basic/02 | 46 ++ test/smoke_test/basic/03 | 69 ++ test/smoke_test/basic/04 | 86 +++ test/smoke_test/basic/05 | 50 ++ test/smoke_test/basic/06 | 68 ++ test/smoke_test/basic/07 | 42 ++ test/smoke_test/basic/08 | 169 +++++ test/smoke_test/basic/09 | 38 + test/smoke_test/basic/10 | 38 + test/smoke_test/basic/11 | 48 ++ test/smoke_test/basic/12 | 85 +++ test/smoke_test/cas_config | 124 ++++ test/smoke_test/cas_ex.en.pws | 51 ++ test/smoke_test/cas_functions | 899 +++++++++++++++++++++++ test/smoke_test/cas_lib | 521 +++++++++++++ test/smoke_test/cas_local_config.example | 26 + test/smoke_test/cas_options | 334 +++++++++ test/smoke_test/run_tests | 397 ++++++++++ 20 files changed, 3242 insertions(+) create mode 100644 test/smoke_test/README create mode 100755 test/smoke_test/basic/01 create mode 100755 test/smoke_test/basic/02 create mode 100755 test/smoke_test/basic/03 create mode 100755 test/smoke_test/basic/04 create mode 100755 test/smoke_test/basic/05 create mode 100755 test/smoke_test/basic/06 create mode 100755 test/smoke_test/basic/07 create mode 100755 test/smoke_test/basic/08 create mode 100755 test/smoke_test/basic/09 create mode 100755 test/smoke_test/basic/10 create mode 100755 test/smoke_test/basic/11 create mode 100755 test/smoke_test/basic/12 create mode 100644 test/smoke_test/cas_config create mode 100644 test/smoke_test/cas_ex.en.pws create mode 100644 test/smoke_test/cas_functions create mode 100644 test/smoke_test/cas_lib create mode 100644 test/smoke_test/cas_local_config.example create mode 100644 test/smoke_test/cas_options create mode 100755 test/smoke_test/run_tests diff --git a/test/smoke_test/README b/test/smoke_test/README new file mode 100644 index 0000000..aedf047 --- /dev/null +++ b/test/smoke_test/README @@ -0,0 +1,120 @@ +****************************************************************************** + +Table of Contents: +1) Running tests +2) Framework files +3) Test categories +4) Adding test to BVT +5) Writing tests [basics] +6) Writing tests [advanced] +7) Adding new functions to API + +****************************************************************************** + +1) Running tests + +You can launch the tests in two ways: +a) Manually running a single test, for example "basic/01" +b) Launch a bunch of tests via the "./run_tests" script. + +Both of these have a nice help and detailed output so you should have no +problems testing. + +****************************************************************************** + +2) Framework files + +cas_config - holds default settings for the framework like default cache/core + device, mountpoint etc. +cas_local_config - your local config file, it isn't included in the repository + so that you can override the default settings there +cas_functions - holds all CAS API and system function wrappers used by tests +cas_lib - the main entry point for tests; includes basic environment/test + functions and includes other library files for testing +cas_options - containts options (required and optional) for all functions in + cas_functions so that we can check if the wrapper is called + correctly + +****************************************************************************** + +3) Test categories: + +Tests are separated into several categories using folders. Feel free to add new +tests to existing categories or create new ones - making a new folder is all +you have to do. Right now, the "logs" and hidden (starting with '.') folders +are not considered as categories. + +****************************************************************************** + +4) Adding test to BVT: + +If you want to include any test in the BVT, add the following line in the +beginning of the test (doesn't really matter where you do it): # USE_IN_BVT + +The BVT suite should last no longer than 5 minutes so that the building system +launches all tests fast enough. + +****************************************************************************** + +5) Writing tests [basics] + +When writing tests, you should follow the following rules: +a) All tests should be located in the category folders. +b) Most of the tests in basic category are good templates for tests, so usually + it's best just to copy the file and then edit it so that it fits + you. +c) Make sure the test starts with the appropriate header (including DESCRIPTION, + including cas_lib and "start test $*") and ends with "end_test 0" +d) Use as much of the API and configuration as possible (CACHE_DEVICE, + CORE_DEVICE, MOUNTPOINT etc.). Such things are cleared every test, + so even if something goes wrong, the framework should handle it. +e) If you want to add new API, go to 7). +f) If you want to use a function not included in the API, but you don't really + want it in the API, then use "run_cmd" function. Look up it's + description in cas_lib file. +g) Stick to the naming convention - all params and variables are UPPERCASE, + while functions are lowercase. + +****************************************************************************** + +6) Writing tests [advanced] + +The text in DESCRIPTION header shouldn't be longer than 80 characters - +if it is, characters above 80th will be trimmed. This text is used when printing +the results of tests - if the description is found, we print it - if not, we +just use the test's name. + +****************************************************************************** + +7) Adding new functions to API + +Add new functions to API whenever: +a) It concerns CAS CLI +b) It's a system function and involves repetitive steps which can be reused + using configuration +c) You think it has to be there + +The steps to add new functions are as follows: +a) Write the function's body with: + - "check_options $FUNCNAME" at the very beginning + - "clear_options" at the very end +b) Launch all vital steps via "run_cmd", which checks if the command returned a + correct value. Look up it's description in cas_lib file. You can use + run_cmd any number of times, but the first fail will end the test. +c) Export the function with "export -f [...]", just like all other functions. + +If the function should accept any parameters, then: +a) Do NOT specify them as bash function params, use global variables instead + (see implemented functions for examples). +b) The options should be UPPERCASE and end with "_OPTION" (CACHE_ID_OPTION, for + example) +c) Go to cas_options: + - add your params to the ALL_OPTIONS variable (a new line will probably be + the best place) + - create a variable named [YOUR_FUNCTION'S_NAME_UPPERCASE]_REQUIRED_OPTIONS + (MAKE_PRIMARY_PARTITIONS_REQUIRED_OPTIONS, for example) and put your + required params there + - [optional] create a new entry under the required options section and put + all options there; this is not required, but helps to see which + options are needed and which are not +d) Launch a test using the new function to test its correctness. diff --git a/test/smoke_test/basic/01 b/test/smoke_test/basic/01 new file mode 100755 index 0000000..6799c89 --- /dev/null +++ b/test/smoke_test/basic/01 @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION Verify Open CAS CLI using --version + +# The line below says that this test should be included in BVT - it will be launched, when we use "./run_tests -b" +# USE_IN_BVT +# USE_IN_NIGHTLY + +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +# This is where the real test starts + +# Test if the APP exists, if it has option "--version" and if it returns a correct status +run_cmd "$CAS --version" + +# Always return 0 at the end of the test - if at any point something has failed +# in the API functions, test will end and return a proper result. +# If you need to check other things during the test and end the test earlier, you +# should end the test using "end_test $retval" function +end_test 0 diff --git a/test/smoke_test/basic/02 b/test/smoke_test/basic/02 new file mode 100755 index 0000000..6a65961 --- /dev/null +++ b/test/smoke_test/basic/02 @@ -0,0 +1,46 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION Adding valid & invalid core devices to caches + +# The line below says that this test should be included in BVT - it will be launched, when we use "./run_tests -b" +# USE_IN_BVT +# USE_IN_NIGHTLY + +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +# This is where the real test starts + +# Use CACHE_DEVICE provided by configuration file and remove partitions from this device +TARGET_DEVICE_OPTION="$CACHE_DEVICE" remove_partitions + +# Create one primary partition (ID=1) of size 2000M on CACHE_DEVICE +TARGET_DEVICE_OPTION="$CACHE_DEVICE" PARTITION_SIZE_OPTION="2000M" PARTITION_IDS_OPTION="1" make_primary_partitions + +# Start cache with ID=1 on device ${CACHE_DEVICE}1 (/dev/sda1, for instance) +CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}1" start_cache + +# Use the same device but a different ID - negative test +CACHE_ID_OPTION="2" CACHE_DEVICE_OPTION="${CACHE_DEVICE}1" NEGATIVE_TEST_OPTION="1" start_cache + +# Use the same ID but a different device - another negative test +CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}2" NEGATIVE_TEST_OPTION="1" start_cache + +# Clear up after test +CACHE_ID_OPTION="1" stop_cache + +# Always return 0 at the end of the test - if at any point something has failed +# in the API functions, test will end and return a proper result. +# If you need to check other things during the test and end the test earlier, you +# should end the test using "end_test $retval" function +end_test 0 diff --git a/test/smoke_test/basic/03 b/test/smoke_test/basic/03 new file mode 100755 index 0000000..b9856cb --- /dev/null +++ b/test/smoke_test/basic/03 @@ -0,0 +1,69 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION Create two caches and try to insert invalid cores to them + +# The line below says that this test should be included in BVT - it will be launched, when we use "./run_tests -b" + +# USE_IN_NIGHTLY + +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +# This is where the real test starts + +# Use CACHE_DEVICE and CORE_DEVICE provided by configuration file and remove partitions from those devices +TARGET_DEVICE_OPTION="$CACHE_DEVICE" remove_partitions +TARGET_DEVICE_OPTION="$CORE_DEVICE" remove_partitions + +# Create 2 primary partitions on CACHE_DEVICE, each of 2000M size +TARGET_DEVICE_OPTION="$CACHE_DEVICE" PARTITION_SIZE_OPTION="2000M" PARTITION_IDS_OPTION="1 2" make_primary_partitions +# Create 2 primary partitions on CORE_DEVICE, each of 4000M size +TARGET_DEVICE_OPTION="$CORE_DEVICE" PARTITION_SIZE_OPTION="4000M" PARTITION_IDS_OPTION="1 2" make_primary_partitions + +# Start cache on CACHE_DEVICE1 (/dev/sdd1, for example) with ID=1 and add a core device using CORE_DEVICE1 (/dev/sde1, for example) +CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}1" start_cache +CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="${CORE_DEVICE}1" add_core + +# Start cache on CACHE_DEVICE2 (/dev/sdd2, for example) with ID=2 and add a core device using CORE_DEVICE1 (/dev/sde2, for example) +CACHE_ID_OPTION="2" CACHE_DEVICE_OPTION="${CACHE_DEVICE}2" start_cache +CACHE_ID_OPTION="2" CORE_DEVICE_OPTION="${CORE_DEVICE}2" add_core + +# Try to add already taken CORE device and a non-existing core to cache 1 +NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="${CORE_DEVICE}1" add_core +NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="${CORE_DEVICE}2" add_core +NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="${CORE_DEVICE}3" add_core + +# Try to add already taken CORE device and a non-existing core to cache 2 +NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="2" CORE_DEVICE_OPTION="${CORE_DEVICE}1" add_core +NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="2" CORE_DEVICE_OPTION="${CORE_DEVICE}2" add_core +NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="2" CORE_DEVICE_OPTION="${CORE_DEVICE}3" add_core + +# Remove the core device from cache +CACHE_ID_OPTION="1" CORE_ID_OPTION="1" remove_core +# Try to do it again - this should fail +NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="1" CORE_ID_OPTION="1" remove_core +# Clean up after the test +CACHE_ID_OPTION="1" stop_cache + +# Remove the core device from cache +CACHE_ID_OPTION="2" CORE_ID_OPTION="1" remove_core +# Try to do it again - this should fail +NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="2" CORE_ID_OPTION="1" remove_core +# Clean up after the test +CACHE_ID_OPTION="2" stop_cache + +# Always return 0 at the end of the test - if at any point something has failed +# in the API functions, test will end and return a proper result. +# If you need to check other things during the test and end the test earlier, you +# should end the test using "end_test $retval" function +end_test 0 diff --git a/test/smoke_test/basic/04 b/test/smoke_test/basic/04 new file mode 100755 index 0000000..6496be6 --- /dev/null +++ b/test/smoke_test/basic/04 @@ -0,0 +1,86 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION Test files on core devices with different filesystems after stopping cache + +# USE_IN_BVT +# USE_IN_NIGHTLY + +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +# This is where the real test starts + +# Use CACHE_DEVICE and CORE_DEVICE provided by configuration file and remove partitions from those devices +TARGET_DEVICE_OPTION="$CACHE_DEVICE" remove_partitions +TARGET_DEVICE_OPTION="$CORE_DEVICE" remove_partitions + +# Create 3 primary partitions on CACHE_DEVICE, each of 2000M size +TARGET_DEVICE_OPTION="$CACHE_DEVICE" PARTITION_SIZE_OPTION="2000M" PARTITION_IDS_OPTION="1 2 3" make_primary_partitions +# Create 3 primary partitions on CORE_DEVICE, each of 4000M size +TARGET_DEVICE_OPTION="$CORE_DEVICE" PARTITION_SIZE_OPTION="4000M" PARTITION_IDS_OPTION="1 2 3" make_primary_partitions +run_cmd dd if=/dev/zero of="${CORE_DEVICE}1" bs=1M count=1 oflag=direct +run_cmd dd if=/dev/zero of="${CORE_DEVICE}2" bs=1M count=1 oflag=direct +run_cmd dd if=/dev/zero of="${CORE_DEVICE}3" bs=1M count=1 oflag=direct + +# Start cache on CACHE_DEVICE1 (/dev/sdd1, for example) with ID=1 and add a core device using CORE_DEVICE1 (/dev/sde1, for example) +CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}1" start_cache +CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="${CORE_DEVICE}1" add_core + +# Start cache on CACHE_DEVICE2 (/dev/sdd2, for example) with ID=2 and add a core device using CORE_DEVICE2 (/dev/sde2, for example) +CACHE_ID_OPTION="2" CACHE_DEVICE_OPTION="${CACHE_DEVICE}2" start_cache +CACHE_ID_OPTION="2" CORE_DEVICE_OPTION="${CORE_DEVICE}2" add_core + +# Start cache on CACHE_DEVICE3 (/dev/sdd3, for example) with ID=3 and add a core device using CORE_DEVICE3 (/dev/sde3, for example) +CACHE_ID_OPTION="3" CACHE_DEVICE_OPTION="${CACHE_DEVICE}3" start_cache +CACHE_ID_OPTION="3" CORE_DEVICE_OPTION="${CORE_DEVICE}3" add_core + +# Create filesystems on cached devices - we do this using run_cmd because it is not in the API (and probably won't be). +# The test framework will accept invoking the commands directly (e.g. "mkfs.ext3 [...]" without the "run_cmd"), but the +# results have to be checked manually by the test. +TARGET_DEVICE_OPTION="${DEVICE_NAME}1-1" FILESYSTEM_TYPE="ext3" make_filesystem +TARGET_DEVICE_OPTION="${DEVICE_NAME}2-1" FILESYSTEM_TYPE="ext4" make_filesystem +TARGET_DEVICE_OPTION="${DEVICE_NAME}3-1" FILESYSTEM_TYPE="xfs" make_filesystem + +# Specify a temporary file used for md5sums - note that it resides in $TMP_DIR, which is a special directory defined in cas_config. +# Everytime we use temporary files, they should be placed in that special directory. Its contents are cleared after every test. +MD5_FILE="$TMP_DIR/cas_md5_sum_" + +# Mount the filesystems, then create the example files and save their MD5 sums locally in the temporary place +# Note the usage of ${MOUNTPOINT} - mount_cache always mounts using following formula: ${MOUNTPOINT}-${CACHE_ID_OPTION}-${CORE_ID_OPTION}. +for ID in 1 2 3 ; do + CACHE_ID_OPTION="$ID" CORE_ID_OPTION="1" mount_cache + run_cmd "dd if=/dev/urandom of=${MOUNTPOINT}-${ID}-1/test bs=50M count=1" + run_cmd "md5sum ${MOUNTPOINT}-${ID}-1/test > ${MD5_FILE}${ID}" +done + +# Umount & stop the caches, then mount the core devices +# Note the usage of ${MOUNTPOINT} - mount_cache always mounts using following formula: ${MOUNTPOINT}-${CACHE_ID_OPTION}-${CORE_ID_OPTION}. +for ID in 1 2 3 ; do + run_cmd "umount ${MOUNTPOINT}-${ID}-1" + CACHE_ID_OPTION="$ID" stop_cache + run_cmd "mount ${CORE_DEVICE}${ID} ${MOUNTPOINT}-${ID}-1" +done + +# Now check for files' presence and umount core devices +# Note the usage of ${MOUNTPOINT} - mount_cache always mounts using following formula: ${MOUNTPOINT}-${CACHE_ID_OPTION}-${CORE_ID_OPTION}. +for ID in 1 2 3 ; do + run_cmd "test -f ${MOUNTPOINT}-${ID}-1/test" + run_cmd "md5sum -c ${MD5_FILE}${ID}" + run_cmd "umount ${MOUNTPOINT}-${ID}-1" +done + +# Always return 0 at the end of the test - if at any point something has failed +# in the API functions, test will end and return a proper result. +# If you need to check other things during the test and end the test earlier, you +# should end the test using "end_test $retval" function +end_test 0 diff --git a/test/smoke_test/basic/05 b/test/smoke_test/basic/05 new file mode 100755 index 0000000..cd03ced --- /dev/null +++ b/test/smoke_test/basic/05 @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION Setup CAS with valid and invalid IDs + +# USE_IN_NIGHTLY + +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +# This is where the real test starts + +# Specify "arrays" of IDs used in test +POSITIVE_IDS="1 9238 16384" +NEGATIVE_IDS="-1 abc 16385" + +# Use CACHE_DEVICE provided by configuration file and remove partitions from this device +TARGET_DEVICE_OPTION="$CACHE_DEVICE" remove_partitions +# Create 1 primary partition on CACHE_DEVICE of 2000M size +TARGET_DEVICE_OPTION="$CACHE_DEVICE" PARTITION_SIZE_OPTION="2000M" PARTITION_IDS_OPTION="1" make_primary_partitions + +# Try to start positive caches in loop and later stop them - if any of those operations fails, it +# means the cache ID is invalid +for ID in $POSITIVE_IDS ; do + CACHE_ID_OPTION="$ID" CACHE_DEVICE_OPTION="${CACHE_DEVICE}1" start_cache + CACHE_ID_OPTION="$ID" stop_cache +done + +# Try to start negative caches in loop - if any of those operations succeeds, it +# means the cache ID is valid (and it shouldn't be). Note that we can't provide an empty +# ID, because the framework will treat it as an undefined option and will fail the test +# automatically. +for ID in $NEGATIVE_IDS ; do + NEGATIVE_TEST_OPTION="1" CACHE_ID_OPTION="$ID" CACHE_DEVICE_OPTION="${CACHE_DEVICE}1" start_cache +done + +# Always return 0 at the end of the test - if at any point something has failed +# in the API functions, test will end and return a proper result. +# If you need to check other things during the test and end the test earlier, you +# should end the test using "end_test $retval" function +end_test 0 diff --git a/test/smoke_test/basic/06 b/test/smoke_test/basic/06 new file mode 100755 index 0000000..53ab0ff --- /dev/null +++ b/test/smoke_test/basic/06 @@ -0,0 +1,68 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +#DESCRIPTION --set-param option fuzzing. + +# This tests checks whether CLI accepts correct data and rejects incorrect +# data for "--flush-parameters" option. It tries to invoke CLI using different +# combinations of required options and checks the return code. + +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +# remove all partitions from cache and core +TARGET_DEVICE_OPTION="$CACHE_DEVICE" remove_partitions +TARGET_DEVICE_OPTION="$CORE_DEVICE" remove_partitions + +# Create 1 primary partition on CACHE_DEVICE of 2000M size +TARGET_DEVICE_OPTION="$CACHE_DEVICE" PARTITION_SIZE_OPTION="2000M" PARTITION_IDS_OPTION="1" make_primary_partitions + +# create cache in WT mode and try to change flush-parameters +CACHE_MODE_OPTION="wt" CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}1" CACHE_FORCE_OPTION="1" start_cache + +# changing flush parameters should be prohibited while core is added to cache +CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="$CORE_DEVICE" add_core +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="100" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="5" NEGATIVE_TEST_OPTION="1" set_flush_params + +# remove core +sleep 1 +CACHE_ID_OPTION="1" CORE_ID_OPTION="1" remove_core + +printf "\n============Running negative tests============\n" + +# bunch of negative test checking whether CAS accepts not valid options for flush-parameters command +# test various policy names +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-dummy" WAKE_UP_OPTION="100" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="5" NEGATIVE_TEST_OPTION="1" set_flush_params +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-noop" WAKE_UP_OPTION="100" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="5" NEGATIVE_TEST_OPTION="1" set_flush_params + +# test for negative numeric options +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="-1" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="5" NEGATIVE_TEST_OPTION="1" set_flush_params +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="100" STALE_TIME_OPTION="-1" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="5" NEGATIVE_TEST_OPTION="1" set_flush_params +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="100" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="-1" ACTIVITY_THRESH_OPTION="5" NEGATIVE_TEST_OPTION="1" set_flush_params +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="100" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="-1" NEGATIVE_TEST_OPTION="1" set_flush_params + +# test for 0 wake_up_time and 0 flush buffers +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="0" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="5" NEGATIVE_TEST_OPTION="1" set_flush_params +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="100" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="0" ACTIVITY_THRESH_OPTION="5" NEGATIVE_TEST_OPTION="1" set_flush_params + +printf "\n============Running positive tests============\n" + +# positive test +# test various policy names +CACHE_ID_OPTION="1" CLEAN_POL_OPTION="nop" set_cleaning_policy +CACHE_ID_OPTION="1" CLEAN_POL_OPTION="acp" set_cleaning_policy +CACHE_ID_OPTION="1" CLEAN_POL_OPTION="alru" set_cleaning_policy + +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="100" STALE_TIME_OPTION="1" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="500" set_flush_params +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="100" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="500" set_flush_params + +CACHE_ID_OPTION="1" CLEAN_POL_NS_OPTION="cleaning-alru" WAKE_UP_OPTION="100" STALE_TIME_OPTION="50" FLUSH_BUFFERS_OPTION="100" ACTIVITY_THRESH_OPTION="500" set_flush_params + +# stop cache now +CACHE_ID_OPTION="1" stop_cache + +end_test 0 diff --git a/test/smoke_test/basic/07 b/test/smoke_test/basic/07 new file mode 100755 index 0000000..2f42d85 --- /dev/null +++ b/test/smoke_test/basic/07 @@ -0,0 +1,42 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION Validate spelling of help in CLI + +# USE_IN_NIGHTLY + +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +FAIL=0 + +PERSONAL_DICTIONARY=`pwd`/cas_ex.en.pws + +run_aspell() { + run_cmd "$1 2>&1 | aspell list --lang=en_US --add-extra-dicts=$PERSONAL_DICTIONARY" + for N in $OUTPUT ; do + if [ -n $N ] ; then + FAIL=1 + error "Misspelled word: $N" + fi + done +} + +run_aspell "$CAS -H" + +COMMANDS=`$CAS -H | awk '/Available commands:/{ cmd=1;next } /For detailed help/ { cmd=0 } cmd { print $0 }' | grep -o '\-\-\S*'` + +for CMD in $COMMANDS ; do + run_aspell "$CAS $CMD -H" +done + +end_test $FAIL diff --git a/test/smoke_test/basic/08 b/test/smoke_test/basic/08 new file mode 100755 index 0000000..d1d5d9e --- /dev/null +++ b/test/smoke_test/basic/08 @@ -0,0 +1,169 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# DESCRIPTION Verify if write mode: read only, works as expected and cache only reads and do not cache writes + +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +CACHE_DEVICE_SIZE=1G +CORE_DEVICE_SIZE=2G + +BLOCK_SIZE=4096 +COUNT=100 + +IOSTAT_BLOCK_SIZE=1024 +if [ $POSIXLY_CORRECT ]; then + IOSTAT_BLOCK_SIZE=512 +fi + +L_TEST_STATUS=0 + +# Use CACHE_DEVICE and CORE_DEVICE provided by configuration file and remove partitions from those devices +TARGET_DEVICE_OPTION="$CACHE_DEVICE" remove_partitions +TARGET_DEVICE_OPTION="$CORE_DEVICE" remove_partitions + +# Create 1 primary partitions on CACHE_DEVICE +TARGET_DEVICE_OPTION="$CACHE_DEVICE" PARTITION_SIZE_OPTION=$CACHE_DEVICE_SIZE PARTITION_IDS_OPTION="1" make_primary_partitions + +# Create 1 primary partitions on CORE_DEVICE +TARGET_DEVICE_OPTION="$CORE_DEVICE" PARTITION_SIZE_OPTION=$CORE_DEVICE_SIZE PARTITION_IDS_OPTION="1" make_primary_partitions + +declare -a MODE=("wt" "wa") + +echo "------Test read from cache" + +for mode in "${MODE[@]}" +do + echo "------Start CAS Linux in $mode mode" + +# This is where the real test starts + CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}"1 CACHE_MODE_OPTION="$mode" start_cache + + CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="${CORE_DEVICE}"1 add_core + sleep 2 + +# iostat read + TMP_CACHE_DEVICE=$(echo "${CACHE_DEVICE}" | cut -c6-) + run_cmd "dd if=/dev/cas1-1 of=$TMP_DIR/file001.bin bs=$BLOCK_SIZE count=$COUNT skip=10000 iflag=direct" + READ_CACHE_1=$(iostat "${CACHE_DEVICE}" | grep $TMP_CACHE_DEVICE | awk 'NR==1 {print $5}') + run_cmd "dd if=/dev/cas1-1 of=$TMP_DIR/file001.bin bs=$BLOCK_SIZE count=$COUNT skip=10000 iflag=direct" + READ_CACHE_2=$(iostat "${CACHE_DEVICE}" | grep $TMP_CACHE_DEVICE | awk 'NR==1 {print $5}') + READ_CACHE_DELTA=$((($READ_CACHE_2-$READ_CACHE_1)*IOSTAT_BLOCK_SIZE)) + DATA_READ=$(($COUNT*$BLOCK_SIZE)) + if [ $READ_CACHE_DELTA -eq $DATA_READ ] ; then + echo -n "Blocks read from cache:$READ_CACHE_DELTA == $DATA_READ"; success + else + echo -n "Blocks read from cache:$READ_CACHE_DELTA != $DATA_READ"; error + L_TEST_STATUS=1 + fi + +# Clear up after test + CACHE_ID_OPTION="1" stop_cache +done + +echo "------Test write and than read from cache" + +for mode in "${MODE[@]}" +do + echo "------Start CAS Linux in $mode mode" + +# This is where the real test starts + CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}"1 CACHE_MODE_OPTION="$mode" start_cache + + CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="${CORE_DEVICE}"1 add_core + sleep 2 + +# iostat write and write + TMP_CORE_DEVICE=$(echo "${CORE_DEVICE}" | cut -c6-) + WRITE_CORE_0=$(iostat "${CORE_DEVICE}" | grep $TMP_CORE_DEVICE | awk 'NR==1 {print $6}') + WRITE_CACHE_0=$(iostat "${CACHE_DEVICE}" | grep $TMP_CACHE_DEVICE | awk 'NR==1 {print $6}') + run_cmd "dd if=$TMP_DIR/file001.bin of=/dev/cas1-1 bs=$BLOCK_SIZE count=$COUNT seek=20000 oflag=direct" + WRITE_CORE_1=$(iostat "${CORE_DEVICE}" | grep $TMP_CORE_DEVICE | awk 'NR==1 {print $6}') + WRITE_CACHE_1=$(iostat "${CACHE_DEVICE}" | grep $TMP_CACHE_DEVICE | awk 'NR==1 {print $6}') + READ_CORE_1=$(iostat "${CORE_DEVICE}" | grep $TMP_CORE_DEVICE | awk 'NR==1 {print $5}') + READ_CACHE_1=$(iostat "${CACHE_DEVICE}" | grep $TMP_CACHE_DEVICE | awk 'NR==1 {print $5}') + WRITE_CORE_DELTA_1=$((($WRITE_CORE_1-$WRITE_CORE_0)*IOSTAT_BLOCK_SIZE)) + WRITE_CACHE_DELTA_1=$((($WRITE_CACHE_1-$WRITE_CACHE_0)*IOSTAT_BLOCK_SIZE)) + run_cmd "dd if=/dev/cas1-1 of=$TMP_DIR/file001.bin bs=$BLOCK_SIZE count=$COUNT skip=20000 iflag=direct" + READ_CORE_2=$(iostat "${CORE_DEVICE}" | grep $TMP_CORE_DEVICE | awk 'NR==1 {print $5}') + READ_CACHE_2=$(iostat "${CACHE_DEVICE}" | grep $TMP_CACHE_DEVICE | awk 'NR==1 {print $5}') + READ_CORE_DELTA_2=$((($READ_CORE_2-$READ_CORE_1)*IOSTAT_BLOCK_SIZE)) + READ_CACHE_DELTA_2=$((($READ_CACHE_2-$READ_CACHE_1)*IOSTAT_BLOCK_SIZE)) + DATA_WRITE=$(($COUNT*$BLOCK_SIZE)) + +# Verify writes on both cache and core + if [ "$mode" == "wa" ] ; then + if [ $WRITE_CORE_DELTA_1 -eq $DATA_WRITE ]; then + echo -n "Blocks write to core: $WRITE_CORE_DELTA_1 == $DATA_WRITE"; success + else + echo -n "Blocks write to core: $WRITE_CORE_DELTA_1 != $DATA_WRITE"; error + L_TEST_STATUS=1 + fi + if [ $WRITE_CACHE_DELTA_1 -eq 0 ]; then + echo -n "Blocks write to cache: $WRITE_CACHE_DELTA_1 == 0"; success + else + echo -n "Blocks write to cache: $WRITE_CACHE_DELTA_1 != 0"; error + L_TEST_STATUS=1 + fi + else + if [ $WRITE_CORE_DELTA_1 -eq $DATA_WRITE ]; then + echo -n "Blocks write to core: $WRITE_CORE_DELTA_1 == $DATA_WRITE"; success + else + echo -n "Blocks write to core: $WRITE_CORE_DELTA_1 != $DATA_WRITE"; error + L_TEST_STATUS=1 + fi + if [ $WRITE_CACHE_DELTA_1 -eq $DATA_WRITE ]; then + echo -n "Blocks write to cache: $WRITE_CACHE_DELTA_1 == $DATA_WRITE"; success + else + echo -n "Blocks write to cache: $WRITE_CACHE_DELTA_1 != $DATA_WRITE"; error + L_TEST_STATUS=1 + fi + fi + +# Verify reads on both cache and core + if [ "$mode" == "wa" ] ; then + if [ $READ_CORE_DELTA_2 -eq $DATA_WRITE ]; then + echo -n "Blocks read from core: $READ_CORE_DELTA_2 == $DATA_WRITE"; success + else + echo -n "Blocks read from core: $READ_CORE_DELTA_2 != $DATA_WRITE"; error + L_TEST_STATUS=1 + fi + if [ $READ_CACHE_DELTA_2 -eq 0 ]; then + echo -n "Blocks read from cache: $READ_CACHE_DELTA_2 == 0"; success + else + if [ $READ_CACHE_DELTA_2 -eq 4096 ]; then + echo -n "Blocks read from cache: $READ_CACHE_DELTA_2 == 4096"; success + else + echo -n "Blocks read from cache: $READ_CACHE_DELTA_2 != 0"; error + L_TEST_STATUS=1 + fi + fi + else + if [ $READ_CORE_DELTA_2 -eq 0 ]; then + echo -n "Blocks read from core: $READ_CORE_DELTA_2 == 0"; success + else + echo -n "Blocks read from core: $READ_CORE_DELTA_2 != 0"; error + L_TEST_STATUS=1 + fi + if [ $READ_CACHE_DELTA_2 -ge $DATA_WRITE ]; then + echo -n "Blocks read from cache: $READ_CACHE_DELTA_2 >= $DATA_WRITE"; success + else + echo -n "Blocks read from cache: $READ_CACHE_DELTA_2 != $DATA_WRITE"; error + L_TEST_STATUS=1 + fi + fi + +# Clear up after test + CACHE_ID_OPTION="1" stop_cache +done + +# Always return 0 at the end of the test - if at any point something has failed +# in the API functions, test will end and return a proper result. +# If you need to check other things during the test and end the test earlier, you +# should end the test using "end_test $retval" function +end_test $L_TEST_STATUS diff --git a/test/smoke_test/basic/09 b/test/smoke_test/basic/09 new file mode 100755 index 0000000..752d59f --- /dev/null +++ b/test/smoke_test/basic/09 @@ -0,0 +1,38 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION Validate spelling in manpage + +# USE_IN_NIGHTLY + +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +FAIL=0 + +PERSONAL_DICTIONARY=`pwd`/cas_ex.en.pws + +man --help | grep -- --no-hyphenation 2>&1 > /dev/null +if [ $? -ne 0 ] ; then + warning "option --no-hyphenation not supported by man" + end_test $CAS_TEST_NOT_RUN +fi + +run_cmd "man --no-hyphenation $CAS_MAN_PAGE | head -n -1 | aspell list --lang=en_US --add-extra-dicts=$PERSONAL_DICTIONARY" +for N in $OUTPUT ; do + if [ -n $N ] ; then + FAIL=1 + error "Misspelled word: $N" + fi +done + +end_test $FAIL diff --git a/test/smoke_test/basic/10 b/test/smoke_test/basic/10 new file mode 100755 index 0000000..776d2dc --- /dev/null +++ b/test/smoke_test/basic/10 @@ -0,0 +1,38 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION Verify cache start in different modes + +# The line below says that this test should be included in BVT - it will be launched, when we use "./run_tests -b" +# USE_IN_BVT + +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +# This is where the real test starts +basic_i() { + echo -n "" +} + +# Test if the APP exists, if it has option "--version" and if it returns a correct status +NUMBER_OF_CORE_PARTITIONS="2" +NUMBER_OF_CACHE_PARTITIONS="2" +CACHE_FORCE_OPTION="yes" +CACHE_LINE_SIZE="all" +CACHE_MODE_OPTION="all" +iteration basic_i + +# Always return 0 at the end of the test - if at any point something has failed +# in the API functions, test will end and return a proper result. +# If you need to check other things during the test and end the test earlier, you +# should end the test using "end_test $retval" function +end_test 0 diff --git a/test/smoke_test/basic/11 b/test/smoke_test/basic/11 new file mode 100755 index 0000000..c946a50 --- /dev/null +++ b/test/smoke_test/basic/11 @@ -0,0 +1,48 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION Multi level cache assembly + +# USE_IN_NIGHTLY + +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +# This is where the real test starts + +# Use CACHE_DEVICE provided by configuration file and remove partitions from this device +TARGET_DEVICE_OPTION="$CACHE_DEVICE" remove_partitions + +# Create three primary partitions of size 2000M on CACHE_DEVICE +TARGET_DEVICE_OPTION="$CACHE_DEVICE" PARTITION_SIZE_OPTION="2000M" PARTITION_IDS_OPTION="1 2 3" make_primary_partitions +# Creare one primary partition of size 4000M on CORE DEVICE +TARGET_DEVICE_OPTION="$CORE_DEVICE" PARTITION_SIZE_OPTION="4000M" PARTITION_IDS_OPTION="1" make_primary_partitions + +# Start caches +CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}1" start_cache +CACHE_ID_OPTION="2" CACHE_DEVICE_OPTION="${CACHE_DEVICE}2" start_cache +CACHE_ID_OPTION="3" CACHE_DEVICE_OPTION="${CACHE_DEVICE}3" start_cache + +#Assembly multi-level cache (add cores) +CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="${CORE_DEVICE}1" add_core +CACHE_ID_OPTION="2" CORE_DEVICE_OPTION="${DEVICE_NAME}1-1" add_core +CACHE_ID_OPTION="3" CORE_DEVICE_OPTION="${DEVICE_NAME}2-1" add_core + +# Clear up after test +CACHE_ID_OPTION="3" stop_cache +CACHE_ID_OPTION="2" stop_cache +CACHE_ID_OPTION="1" stop_cache +# Always return 0 at the end of the test - if at any point something has failed +# in the API functions, test will end and return a proper result. +# If you need to check other things during the test and end the test earlier, you +# should end the test using "end_test $retval" function +end_test 0 diff --git a/test/smoke_test/basic/12 b/test/smoke_test/basic/12 new file mode 100755 index 0000000..bd827ba --- /dev/null +++ b/test/smoke_test/basic/12 @@ -0,0 +1,85 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# The line below specified that line under it should be used as the test's short description when launching test via run_tests script. +# The text should not be longer than 80 chars - if it is, the script will strip addititonal characters +# DESCRIPTION WriteBack mode test: Test files on core devices with different filesystems after flushing and stopping cache +# with 'don't flush dirty data on exit' option. + +# USE_IN_NIGHTLY +# USE_IN_BVT +# Standard beginning for every test - get the main tests directory and +# link the cas_lib file for CAS API, then use "start_test $*" to pass params +# and do other necessary checks and setup +TESTS_DIR="$(dirname $0)/../" +. $TESTS_DIR/cas_lib +start_test $* + +# This is where the real test starts + +# Use CACHE_DEVICE and CORE_DEVICE provided by configuration file and remove partitions from those devices +TARGET_DEVICE_OPTION="$CACHE_DEVICE" remove_partitions +TARGET_DEVICE_OPTION="$CORE_DEVICE" remove_partitions + +# Create 3 primary partitions on CACHE_DEVICE, each of 2000M size +TARGET_DEVICE_OPTION="$CACHE_DEVICE" PARTITION_SIZE_OPTION="2000M" PARTITION_IDS_OPTION="1 2 3" make_primary_partitions +# Create 3 primary partitions on CORE_DEVICE, each of 4000M size +TARGET_DEVICE_OPTION="$CORE_DEVICE" PARTITION_SIZE_OPTION="4000M" PARTITION_IDS_OPTION="1 2 3" make_primary_partitions + +# Start cache on CACHE_DEVICE1 (/dev/sdd1, for example) with ID=1 and add a core device using CORE_DEVICE1 (/dev/sde1, for example) +CACHE_ID_OPTION="1" CACHE_DEVICE_OPTION="${CACHE_DEVICE}1" CACHE_FORCE_OPTION="1" CACHE_MODE_OPTION="wb" start_cache +CACHE_ID_OPTION="1" CORE_DEVICE_OPTION="${CORE_DEVICE}1" add_core + +# Start cache on CACHE_DEVICE2 (/dev/sdd2, for example) with ID=2 and add a core device using CORE_DEVICE2 (/dev/sde2, for example) +CACHE_ID_OPTION="2" CACHE_DEVICE_OPTION="${CACHE_DEVICE}2" CACHE_FORCE_OPTION="1" CACHE_MODE_OPTION="wb" start_cache +CACHE_ID_OPTION="2" CORE_DEVICE_OPTION="${CORE_DEVICE}2" add_core + +# Start cache on CACHE_DEVICE3 (/dev/sdd3, for example) with ID=3 and add a core device using CORE_DEVICE3 (/dev/sde3, for example) +CACHE_ID_OPTION="3" CACHE_DEVICE_OPTION="${CACHE_DEVICE}3" CACHE_FORCE_OPTION="1" CACHE_MODE_OPTION="wb" start_cache +CACHE_ID_OPTION="3" CORE_DEVICE_OPTION="${CORE_DEVICE}3" add_core + +# Create filesystems on cached devices - we do this using run_cmd because it is not in the API (and probably won't be). +# The test framework will accept invoking the commands directly (e.g. "mkfs.ext3 [...]" without the "run_cmd"), but the +# results have to be checked manually by the test. +TARGET_DEVICE_OPTION="${DEVICE_NAME}1-1" FILESYSTEM_TYPE="ext3" make_filesystem +TARGET_DEVICE_OPTION="${DEVICE_NAME}2-1" FILESYSTEM_TYPE="ext4" make_filesystem +TARGET_DEVICE_OPTION="${DEVICE_NAME}3-1" FILESYSTEM_TYPE="xfs" make_filesystem + +# Specify a temporary file used for md5sums - note that it resides in $TMP_DIR, which is a special directory defined in cas_config. +# Everytime we use temporary files, they should be placed in that special directory. Its contents are cleared after every test. +MD5_FILE="$TMP_DIR/cas_md5_sum_" + +# Mount the filesystems, then create the example files and save their MD5 sums locally in the temporary place +# Note the usage of ${MOUNTPOINT} - mount_cache always mounts using following formula: ${MOUNTPOINT}-${CACHE_ID_OPTION}-${CORE_ID_OPTION}. +for ID in 1 2 3 ; do + CACHE_ID_OPTION="$ID" CORE_ID_OPTION="1" mount_cache + run_cmd "dd if=/dev/urandom of=${MOUNTPOINT}-${ID}-1/test bs=50M count=1" + run_cmd "md5sum ${MOUNTPOINT}-${ID}-1/test > ${MD5_FILE}_${ID}" +done + +# Umount & stop the caches, then mount the core devices +# Note the usage of ${MOUNTPOINT} - mount_cache always mounts using following formula: ${MOUNTPOINT}-${CACHE_ID_OPTION}-${CORE_ID_OPTION}. +for ID in 1 2 3 ; do + run_cmd "umount ${MOUNTPOINT}-${ID}-1" + CACHE_ID_OPTION="$ID" flush_cache + CACHE_ID_OPTION="$ID" CACHE_DONT_FLUSH_DATA_OPTION="1" stop_cache + run_cmd dd if=/dev/zero of="${CACHE_DEVICE}${ID}" bs=1M count=1 oflag=direct + run_cmd "mount ${CORE_DEVICE}${ID} ${MOUNTPOINT}-${ID}-1" +done + +# Now check for files' presence and umount core devices +# Note the usage of ${MOUNTPOINT} - mount_cache always mounts using following formula: ${MOUNTPOINT}-${CACHE_ID_OPTION}-${CORE_ID_OPTION}. +for ID in 1 2 3 ; do + run_cmd "test -f ${MOUNTPOINT}-${ID}-1/test" + run_cmd "md5sum -c ${MD5_FILE}_${ID}" + run_cmd "umount ${MOUNTPOINT}-${ID}-1" +done + +# Always return 0 at the end of the test - if at any point something has failed +# in the API functions, test will end and return a proper result. +# If you need to check other things during the test and end the test earlier, you +# should end the test using "end_test $retval" function +end_test 0 diff --git a/test/smoke_test/cas_config b/test/smoke_test/cas_config new file mode 100644 index 0000000..dc4c91b --- /dev/null +++ b/test/smoke_test/cas_config @@ -0,0 +1,124 @@ +#!/bin/bash + +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# +# Open CAS Linux Tests configuration +# +# You may override those params either using the CLI or creating a special file cas_local_config +# Default core and cache devices - note that we require whole devices, not partitions. +# Those are now empty to prevent from using default values by mistake, which could lead to +# destroying partitions and data. If you want to setup those, use cas_local_config +export CORE_DEVICE="" +export CACHE_DEVICE="" + +# Default size of partition for cache/core device. This is used only for the DEFAULT_* API functions +export DEFAULT_CACHE_SIZE="3000M" +export DEFAULT_CORE_SIZE="5000M" + +# Available cache mode +export CACHE_MODES="wt wb wa" + +# CLI app's name +export CAS="casadm" +# Config file path +export CAS_CONFIG_PATH="/etc/opencas/opencas.conf" +# Manpage name +export CAS_MAN_PAGE="8 casadm" +# Device name +export DEVICE_NAME="/dev/cas" +# All devices mounted using the test API will be mounted at ${MOUNTPOINT}-${CACHE_ID}-${CORE_ID} +# Use this variable in your tests to use the mounted resource. +export MOUNTPOINT="/mnt/cas" +# TMP_DIR should be a directory where we can store additional data like test files, md5 sums etc. +# We clean up this directory between the tests +export TMP_DIR="/var/tmp/.cas" +# Applications which are usually required by the tests +export REQUIRED_APPS="iostat vdbench aspell mkfs.xfs fio" + +export CAS_CONFIGURATION_LOADED="1" + +export CAS_TEST_NOT_RUN="37" + +check_config() { + if [ -z "$CAS_CONFIG_CHECKED" ] ; then + echo "--- Your configuration ---" + + if [ -n "$CACHE_DEVICE" ] ; then + echo "Cache device: $CACHE_DEVICE" + else + error "Error: cache device not defined!" + exit 1 + fi + + if [ -n "$CORE_DEVICE" ] ; then + echo "Core device: $CORE_DEVICE" + else + error "Error: core device not defined!" + exit 1 + fi + + if [ -n "$MOUNTPOINT" ] ; then + echo "Mount point: $MOUNTPOINT" + else + error "Error: mount point not defined!" + exit 1 + fi + + if [ -n "$TMP_DIR" ] ; then + echo "Temporary directory : $TMP_DIR" + else + error "Error: temporary directory not defined!" + exit 1 + fi + + # Check if core and cache devices are free for us or not + if [ -z $IGNORE_WARNINGS ] && [ -n "$(ls ${CORE_DEVICE}[0-9]* 2> /dev/null)" ] ; then + warning "The core device $CORE_DEVICE is partitioned! Some tests may remove partitions from this device" + warning "Use --ignore | -i flag to force using this core device" + exit 1 + fi + if [ -z $IGNORE_WARNINGS ] && [ -n "$(ls ${CACHE_DEVICE}[0-9]* 2> /dev/null)" ] ; then + warning "The cache device $CACHE_DEVICE is partitioned!" + warning "Use --ignore | -i flag to force using this cache device" + exit 1 + fi + + for DEVICE_TO_UMOUNT in $(mount | grep $CACHE_DEVICE | awk '{print $1}') ; do + umount $DEVICE_TO_UMOUNT + done + + for DEVICE_TO_UMOUNT in $(mount | grep $CORE_DEVICE | awk '{print $1}') ; do + umount $DEVICE_TO_UMOUNT + done + + if [ -n "$(mount | grep $CACHE_DEVICE)" ] ; then + error "The cache device $CACHE_DEVICE or one of its partitions is mounted!" + exit 1 + fi + if [ -n "$(mount | grep $CORE_DEVICE)" ] ; then + error "The core device $CORE_DEVICE or one of its partitions is mounted!" + exit 1 + fi + + for APP in $REQUIRED_APPS ; do + hash $APP 2> /dev/null + if [ $? -ne 0 ] ; then + warning "Many tests use program called $APP and it looks like it's not installed here." + if [ -z $IGNORE_WARNINGS ] ; then + warning "Use --ignore | -i flag to ignore lack of $APP" + exit 1 + fi + fi + done + + if [ ! -d $TMP_DIR ] ; then + mkdir $TMP_DIR + fi + echo "--- Open CAS configuration loaded correctly ---" + export CAS_CONFIG_CHECKED="1" + fi +} + +export -f check_config diff --git a/test/smoke_test/cas_ex.en.pws b/test/smoke_test/cas_ex.en.pws new file mode 100644 index 0000000..80247a4 --- /dev/null +++ b/test/smoke_test/cas_ex.en.pws @@ -0,0 +1,51 @@ +personal_ws-1.1 en 1 +ALRU +CAS +CSV +CentOS +DSS +HDD +KiB +LANG +LBA +MiB +NUM +NVMe +OCF +RHEL +SLES +SSD +SUSE +TERM +TTY +UTF +Ubuntu +acp +alru +async +blk +cas +casadm +casctl +conf +config +csv +dev +io +kibibytes +lru +metadata +namespace +namespaces +nop +nvme +opencas +param +req +reseller +resizing +runtime +sdb +utf +wa +wb diff --git a/test/smoke_test/cas_functions b/test/smoke_test/cas_functions new file mode 100644 index 0000000..5e785fa --- /dev/null +++ b/test/smoke_test/cas_functions @@ -0,0 +1,899 @@ +#!/bin/bash + +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +############################################################ +# CAS API # +############################################################ + +clear_config() { + check_options ${FUNCNAME[0]} + + if [ -n "$STORE_CONFIG_OPTION" ] ; then + cp $CAS_CONFIG_PATH $TMP_DIR/`basename $CAS_CONFIG_PATH` + fi + + echo "version=`$CAS -V -o csv | grep CLI | cut -d, -f2`" > "$CAS_CONFIG_PATH" + + export CAS_CONFIG_VERSION_TAG=`head $CAS_CONFIG_PATH` + + clear_options +} + +restore_config() { + cp $TMP_DIR/`basename $CAS_CONFIG_PATH` $CAS_CONFIG_PATH +} + +start_cache() { + check_options ${FUNCNAME[0]} + + CACHE_DEVICE_NVME_REGEX="(/dev/nvme[0-9]n[0-9])([0-9]*)" + if [ ! -b ${CACHE_DEVICE_OPTION} ] + then + if [[ "${CACHE_DEVICE_OPTION}" =~ ${CACHE_DEVICE_NVME_REGEX} ]] + then + if [ -b ${BASH_REMATCH[1]}p${BASH_REMATCH[2]} ] + then + CACHE_DEVICE_OPTION=${BASH_REMATCH[1]}p${BASH_REMATCH[2]} + fi + fi + fi + + local COMMAND="$CAS --start-cache --cache-device $CACHE_DEVICE_OPTION --cache-id $CACHE_ID_OPTION" + + if [ -n "$CACHE_FORCE_OPTION" ] ; then + COMMAND="$COMMAND --force" + fi + if [ -n "$CACHE_MODE_OPTION" ] ; then + COMMAND="$COMMAND --cache-mode $CACHE_MODE_OPTION" + fi + if [ -n "$CACHE_LOAD_METADATA_OPTION" ] ; then + COMMAND="$COMMAND --load" + fi + if [ -n "$CACHE_LINE_SIZE" ] ; then + COMMAND="$COMMAND --cache-line-size $CACHE_LINE_SIZE" + fi + + run_cmd $COMMAND + clear_options +} + +stop_cache() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --stop-cache --cache-id $CACHE_ID_OPTION" + + if [ -n "$CACHE_DONT_FLUSH_DATA_OPTION" ] ; then + COMMAND="$COMMAND --no-data-flush" + fi + + run_cmd $COMMAND + clear_options +} + +set_cache_mode() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS -Q -c $CACHE_MODE_OPTION --cache-id $CACHE_ID_OPTION" + + if [ -n "$CACHE_MODE_FLUSH_OPTION" ] ; then + COMMAND="$COMMAND --flush-cache yes" + else + COMMAND="$COMMAND --flush-cache no" + fi + + run_cmd $COMMAND + clear_options +} + +try_add_core() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --script --add-core --try-add --cache-id $CACHE_ID_OPTION --core-id $CORE_ID_OPTION --core-device $CORE_DEVICE_OPTION" + + run_cmd $COMMAND +} + +add_core() { + local RETRY=10 + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --add-core --cache-id $CACHE_ID_OPTION --core-device $CORE_DEVICE_OPTION" + + if [ -n "$CORE_TRY_ADD_OPTION" ] ; then + COMMAND="$COMMAND --try-add" + fi + + run_cmd $COMMAND + if [ -n "$NEGATIVE_TEST_OPTION" ]; then + clear_options + return 0 + fi + local i=0 + local CAS_DEV=` casadm -L | egrep "^.core +[0-9]+ +$CORE_DEVICE_OPTION" | awk '{print $NF}'` + clear_options + while [ ! -e $CAS_DEV ]; do + sleep 2 + let i++ + if [ $i -gt $RETRY ]; then + error "Add core timeout" + end_test 1 + fi + done +} + +remove_core() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --remove-core --cache-id $CACHE_ID_OPTION --core-id $CORE_ID_OPTION" + + run_cmd $COMMAND + clear_options +} + +check_device_state() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --list-caches -o csv | grep `readlink -m $DEVICE_ID_OPTION` | cut -d',' -f4 | grep $DEMANDED_STATE_OPTION &> /dev/null" + + run_cmd $COMMAND + + clear_options +} + +get_stats_value() { + check_options ${FUNCNAME[0]} + + if [ -n "$CORE_ID_OPTION" ] ; then + CORE_ID_OPTION="--core-id $CORE_ID_OPTION" + fi + + if [ "$IO_CLASS_ID" = "all" ]; then + PART_ID_OPTION="--io-class-id" + elif [ -n "$IO_CLASS_ID" ] ; then + PART_ID_OPTION="--io-class-id $IO_CLASS_ID" + fi + + SILENT_COMMAND_OPTION="1" run_cmd "$CAS --stats --output-format csv \ + --cache-id $CACHE_ID_OPTION $CORE_ID_OPTION $PART_ID_OPTION | tail -2 | tr \",\" \"\n\"" + + local IFS_DEFAULT=$IFS + IFS=$'\n' + + local STATS_ARRAY=() + local i=0 + for line in $OUTPUT; do + STATS_ARRAY[$i]="$line" + i=$((i+1)) + done + + STATS_VALUES_LENGTH=${#STATS_ARRAY[@]} + STATS_VALUES_OFFSET=$((STATS_VALUES_LENGTH / 2)) + + local hits=0 + for (( i=0; i<$STATS_VALUES_OFFSET; i++ )) + do + echo "${STATS_ARRAY[$i]}" | grep -i "$STAT_NAME_OPTION" | grep -v "%" \ + | grep -i "$STAT_UNIT_OPTION" &> /dev/null + if [ $? -eq 0 ]; then + local value_id=$(( STATS_VALUES_OFFSET + i )) + OUTPUT="${STATS_ARRAY[$value_id]}" + hits=$((hits + 1)) + fi + done + + IFS=$IFS_DEFAULT + + if [[ $hits -gt 1 ]] ; then + error "Given statistic name or unit is ambiguous!" + OUTPUT="" + end_test 1 + fi + + if [[ $hits -eq 0 ]] ; then + error "Given statistic name or unit not found!" + OUTPUT="" + end_test 1 + fi + + clear_options +} + +format_nvme() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --nvme --format $NVME_FORMAT_MODE_OPTION --device $DEVICE_OPTION" + + if [ -n "$NVME_FORMAT_FORCE_OPTION" ] ; then + COMMAND="$COMMAND --force" + fi + + run_cmd $COMMAND + clear_options +} + +init() { + check_options ${FUNCNAME[0]} + + local L_NUMBER_OF_CACHE_PARTITIONS=1 + local L_NUMBER_OF_CORE_PARTITIONS=1 + local L_MAKE_FILE_SYSTEM + local MAX_NUMBER_OF_CORE_PARTITIONS=4 + local L_CACHE_FORCE_OPTION + local L_CACHE_MODE_OPTION + local L_CACHE_LOAD_METADATA_OPTION + local L_CACHE_LINE_SIZE + local L_MAKE_PARTITIONS=${MAKE_PARTITIONS} + + if [ -n "$NUMBER_OF_CACHE_PARTITIONS" ] ; then + L_NUMBER_OF_CACHE_PARTITIONS="$NUMBER_OF_CACHE_PARTITIONS" + fi + if [ -n "$NUMBER_OF_CORE_PARTITIONS" ] ; then + L_NUMBER_OF_CORE_PARTITIONS="$NUMBER_OF_CORE_PARTITIONS" + fi + if [ -n "$MAKE_FILE_SYSTEM" ] ; then + L_MAKE_FILE_SYSTEM="$MAKE_FILE_SYSTEM" + fi + if [ -n "$CACHE_FORCE_OPTION" ] ; then + L_CACHE_FORCE_OPTION="$CACHE_FORCE_OPTION" + fi + if [ -n "$CACHE_MODE_OPTION" ] ; then + L_CACHE_MODE_OPTION="$CACHE_MODE_OPTION" + fi + if [ -n "$CACHE_LOAD_METADATA_OPTION" ] ; then + L_CACHE_LOAD_METADATA_OPTION="$CACHE_LOAD_METADATA_OPTION" + fi + if [ -n "$CACHE_LINE_SIZE" ] ; then + L_CACHE_LINE_SIZE="$CACHE_LINE_SIZE" + fi + + if [ $L_NUMBER_OF_CACHE_PARTITIONS -gt $MAX_NUMBER_OF_CORE_PARTITIONS ] ; then + echo "You are trying start too many cache device!" + echo "Max number of cache device is 4." + L_NUMBER_OF_CACHE_PARTITIONS=4 + fi + + if [ $L_NUMBER_OF_CACHE_PARTITIONS -eq 4 ] || [ $L_NUMBER_OF_CACHE_PARTITIONS -eq 3 ] ; then + MAX_NUMBER_OF_CORE_PARTITIONS=1 + fi + + if [ $L_NUMBER_OF_CACHE_PARTITIONS -eq 2 ] ; then + MAX_NUMBER_OF_CORE_PARTITIONS=2 + fi + + if [ -n "$PARTITION_CORE_SIZE_OPTION" ] ; then + L_PARTITION_CORE_SIZE_OPTION="$PARTITION_CORE_SIZE_OPTION" + else + L_PARTITION_CORE_SIZE_OPTION="$DEFAULT_CORE_SIZE" + fi + + if [ -n "$PARTITION_CACHE_SIZE_OPTION" ] ; then + L_PARTITION_CACHE_SIZE_OPTION="$PARTITION_CACHE_SIZE_OPTION" + else + L_PARTITION_CACHE_SIZE_OPTION="$DEFAULT_CACHE_SIZE" + fi + + if [ "1" == "$L_MAKE_PARTITIONS" ] + then + TARGET_DEVICE_OPTION="$CACHE_DEVICE" remove_partitions + TARGET_DEVICE_OPTION="$CORE_DEVICE" remove_partitions + + local L_PARTITION_NUMBERS=$(seq 1 $L_NUMBER_OF_CACHE_PARTITIONS) + TARGET_DEVICE_OPTION="$CACHE_DEVICE" PARTITION_SIZE_OPTION="$L_PARTITION_CACHE_SIZE_OPTION" PARTITION_IDS_OPTION="$L_PARTITION_NUMBERS" make_primary_partitions + + local L_PARTITION_NUMBERS=$(seq 1 $(( $L_NUMBER_OF_CACHE_PARTITIONS * $L_NUMBER_OF_CORE_PARTITIONS ))) + TARGET_DEVICE_OPTION="$CORE_DEVICE" PARTITION_SIZE_OPTION="$L_PARTITION_CORE_SIZE_OPTION" PARTITION_IDS_OPTION="$L_PARTITION_NUMBERS" make_primary_partitions + fi + + k=1 + for ((i = 1 ; i <= L_NUMBER_OF_CACHE_PARTITIONS; i++)); do + + if [ -n "$L_CACHE_FORCE_OPTION" ] ; then + CACHE_FORCE_OPTION="$L_CACHE_FORCE_OPTION" + fi + if [ -n "$L_CACHE_MODE_OPTION" ] ; then + CACHE_MODE_OPTION="$L_CACHE_MODE_OPTION" + fi + if [ -n "$L_CACHE_LOAD_METADATA_OPTION" ] ; then + CACHE_LOAD_METADATA_OPTION="$L_CACHE_LOAD_METADATA_OPTION" + fi + if [ -n "$L_CACHE_LINE_SIZE" ] ; then + CACHE_LINE_SIZE="$L_CACHE_LINE_SIZE" + fi + + CACHE_ID_OPTION="$i" CACHE_DEVICE_OPTION="${CACHE_DEVICE}$i" start_cache + + for ((j = 1; j <= L_NUMBER_OF_CORE_PARTITIONS && j <= MAX_NUMBER_OF_CORE_PARTITIONS; j++)); do + CACHE_ID_OPTION="$i" CORE_DEVICE_OPTION="${CORE_DEVICE}$k" add_core + k=`expr $k \+ 1` + done + done + + if [ -n "$L_MAKE_FILE_SYSTEM" ] ; then + for ((i=1 ; i <= L_NUMBER_OF_CACHE_PARTITIONS; i++)); do + for ((j=1 ; j <= L_NUMBER_OF_CORE_PARTITIONS && j <= MAX_NUMBER_OF_CORE_PARTITIONS; j++)); do + TARGET_DEVICE_OPTION="${DEVICE_NAME}$i-$j" FILESYSTEM_TYPE="$L_MAKE_FILE_SYSTEM" make_filesystem + run_cmd "mount ${DEVICE_NAME}$i-$j ${MOUNTPOINT}-$i-$j" + done + done + fi + + clear_options +} + +iteration() { + check_options ${FUNCNAME[0]} + + local L_NUMBER_OF_CACHE_PARTITIONS + local L_NUMBER_OF_CORE_PARTITIONS + local L_MAKE_FILE_SYSTEM="off" + local MAX_NUMBER_OF_CORE_PARTITIONS=4 + local L_CACHE_FORCE_OPTION="off" + local L_CACHE_MODE_OPTION="off" + local L_CACHE_LOAD_METADATA_OPTION="off" + local L_CACHE_LINE_SIZE="off" + local L_MAKE_PARTITIONS=1 + + if [ -n "$NUMBER_OF_CACHE_PARTITIONS" ] ; then + L_NUMBER_OF_CACHE_PARTITIONS="$NUMBER_OF_CACHE_PARTITIONS" + fi + if [ -n "$NUMBER_OF_CORE_PARTITIONS" ] ; then + L_NUMBER_OF_CORE_PARTITIONS="$NUMBER_OF_CORE_PARTITIONS" + fi + if [ -n "$MAKE_FILE_SYSTEM" ] ; then + if [ "$MAKE_FILE_SYSTEM" == "all" ] ; then + L_MAKE_FILE_SYSTEM="ext3 ext4 xfs" + else + L_MAKE_FILE_SYSTEM="$MAKE_FILE_SYSTEM" + fi + fi + if [ -n "$CACHE_FORCE_OPTION" ] ; then + if [ "$CACHE_FORCE_OPTION" == "all" ] ; then + L_CACHE_MODE_OPTION="off on" + else + L_CACHE_FORCE_OPTION="$CACHE_FORCE_OPTION" + fi + fi + if [ -n "$CACHE_MODE_OPTION" ] ; then + if [ "$CACHE_MODE_OPTION" == "all" ] ; then + L_CACHE_MODE_OPTION="wa wb wt pt" + else + L_CACHE_MODE_OPTION="$CACHE_MODE_OPTION" + fi + fi + if [ -n "$CACHE_LOAD_METADATA_OPTION" ] ; then + if [ "$CACHE_LOAD_METADATA_OPTION" == "all" ] ; then + L_CACHE_LOAD_METADATA_OPTION="off on" + else + L_CACHE_LOAD_METADATA_OPTION="$CACHE_LOAD_METADATA_OPTION" + fi + fi + if [ -n "$CACHE_LINE_SIZE" ] ; then + if [ "$CACHE_LINE_SIZE" == "all" ] ; then + L_CACHE_LINE_SIZE="4 8 16 32 64" + else + L_CACHE_LINE_SIZE="$CACHE_LINE_SIZE" + fi + fi + + iteration_number=1 + for mode in $L_CACHE_MODE_OPTION; do + for cache_line_size_mode in $L_CACHE_LINE_SIZE; do + for filesystem in $L_MAKE_FILE_SYSTEM; do + for force in $L_CACHE_FORCE_OPTION; do + for load_metadata in $L_CACHE_LOAD_METADATA_OPTION; do + echo "--- Iteration $iteration_number ---" + echo "Configuration in this iteration is:" + + if [ -n "$L_NUMBER_OF_CACHE_PARTITIONS" ] ; then + NUMBER_OF_CACHE_PARTITIONS="$L_NUMBER_OF_CACHE_PARTITIONS" + fi + if [ -n "$L_NUMBER_OF_CORE_PARTITIONS" ] ; then + NUMBER_OF_CORE_PARTITIONS="$L_NUMBER_OF_CORE_PARTITIONS" + fi + if [ "$mode" != "off" ] ; then + CACHE_MODE_OPTION="$mode" + echo "Cache mode : $mode" + fi + if [ "$cache_line_size_mode" != "off" ] ; then + CACHE_LINE_SIZE="$cache_line_size_mode" + echo "Cache_line_size : $cache_line_size_mode" + fi + if [ "$filesystem" != "off" ] ; then + MAKE_FILE_SYSTEM="$filesystem" + echo "Filesystem type : $filesystem" + fi + if [ "$force" == "on" ] ; then + CACHE_FORCE_OPTION="$force" + echo "Force option: on" + fi + if [ "$load_metadata" == "on" ] ; then + CACHE_LOAD_METADATA_OPTION="$load_metadata" + echo "Load metadata option: on" + fi + + MAKE_PARTITIONS=${L_MAKE_PARTITIONS} + init + $1 + if [ $? -ne 0 ] + then + end_test 1 + fi + L_MAKE_PARTITIONS=0 + + if [ -n "$L_NUMBER_OF_CACHE_PARTITIONS" ] ; then + NUMBER_OF_CACHE_PARTITIONS="$L_NUMBER_OF_CACHE_PARTITIONS" + fi + + if [ -n "$L_NUMBER_OF_CORE_PARTITIONS" ] ; then + NUMBER_OF_CORE_PARTITIONS="$L_NUMBER_OF_CORE_PARTITIONS" + fi + + deinit + iteration_number=`expr $iteration_number \+ 1` + done + done + done + done + done + + clear_options +} + +deinit() { + check_options ${FUNCNAME[0]} + + local L_NUMBER_OF_CACHE_PARTITIONS=1 + local L_NUMBER_OF_CORE_PARTITIONS=1 + local MAX_NUMBER_OF_CORE_PARTITIONS=4 + + if [ -n "$NUMBER_OF_CACHE_PARTITIONS" ] ; then + L_NUMBER_OF_CACHE_PARTITIONS="$NUMBER_OF_CACHE_PARTITIONS" + fi + + if [ -n "$NUMBER_OF_CORE_PARTITIONS" ] ; then + L_NUMBER_OF_CORE_PARTITIONS="$NUMBER_OF_CORE_PARTITIONS" + fi + + if [ $L_NUMBER_OF_CACHE_PARTITIONS -gt $MAX_NUMBER_OF_CORE_PARTITIONS ] ; then + echo "You are trying start too many cache device!" + echo "Max number of cache device is 4." + L_NUMBER_OF_CACHE_PARTITIONS=4 + fi + + if [ $L_NUMBER_OF_CACHE_PARTITIONS -eq 4 ] || [ $L_NUMBER_OF_CACHE_PARTITIONS -eq 3 ] ; then + MAX_NUMBER_OF_CORE_PARTITIONS=1 + fi + + if [ $L_NUMBER_OF_CACHE_PARTITIONS -eq 2 ] ; then + MAX_NUMBER_OF_CORE_PARTITIONS=2 + fi + + for ((i=1 ; i <= L_NUMBER_OF_CACHE_PARTITIONS; i++)); do + for ((j=1 ; j <= L_NUMBER_OF_CORE_PARTITIONS && j <= MAX_NUMBER_OF_CORE_PARTITIONS; j++)); do + CHECK_MOUNTPOINT=`mount | grep ${MOUNTPOINT}-$i-$j` + if [ -n "$CHECK_MOUNTPOINT" ] ; then + run_cmd "umount ${MOUNTPOINT}-$i-$j" + fi + done + done + + for ((i=1 ; i <= L_NUMBER_OF_CACHE_PARTITIONS; i++)); do + for ((j=1 ; j <= L_NUMBER_OF_CORE_PARTITIONS && j <= MAX_NUMBER_OF_CORE_PARTITIONS; j++)); do + CACHE_ID_OPTION="$i" CORE_ID_OPTION="$j" remove_core + done + CACHE_ID_OPTION="$i" stop_cache + done + + clear_options +} + +flush_cache() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --flush-cache --cache-id $CACHE_ID_OPTION" + + run_cmd $COMMAND + clear_options +} + +flush_core() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --flush-core --cache-id $CACHE_ID_OPTION --core-id $CORE_ID_OPTION" + + run_cmd $COMMAND + clear_options +} + +set_cleaning_policy() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --set-param --name cleaning --cache-id $CACHE_ID_OPTION \ + --policy $CLEAN_POL_OPTION" + + run_cmd $COMMAND + clear_options +} + +get_cleaning_policy() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --get-param --name cleaning --cache-id $CACHE_ID_OPTION \ + --output-format csv" + + run_cmd $COMMAND + clear_options +} + +set_flush_params() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --set-param --name $CLEAN_POL_NS_OPTION --cache-id $CACHE_ID_OPTION" + + if [ -n "$WAKE_UP_OPTION" ] ; then + COMMAND="$COMMAND --wake-up $WAKE_UP_OPTION" + fi + if [ -n "$STALE_TIME_OPTION" ] ; then + COMMAND="$COMMAND --staleness-time $STALE_TIME_OPTION" + fi + if [ -n "$FLUSH_BUFFERS_OPTION" ] ; then + COMMAND="$COMMAND --flush-max-buffers $FLUSH_BUFFERS_OPTION" + fi + if [ -n "$ACTIVITY_THRESH_OPTION" ] ; then + COMMAND="$COMMAND --activity-threshold $ACTIVITY_THRESH_OPTION" + fi + + run_cmd $COMMAND + clear_options +} + +get_flush_params() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --get-param --name $CLEAN_POL_NS_OPTION \ + --cache-id $CACHE_ID_OPTION --output-format csv" + + run_cmd $COMMAND + clear_options +} + +dirty_stop() { + check_options ${FUNCNAME[0]} + local L_CACHE_DEVICE_OPTION = $CACHE_DEVICE_OPTION + CACHE_DEVICE_OPTION=$L_CACHE_DEVICE_OPTION turn_off_device + + local COMMAND="$CAS --stop-cache --cache-id $CACHE_ID_OPTION" + + sleep 1 + run_cmd $COMMAND + sleep 1 + + CACHE_DEVICE_OPTION=$L_CACHE_DEVICE_OPTION turn_on_device + clear_options +} + +check_no_cache_running() { + run_cmd "$CAS -L | grep 'No caches running'" + clear_options +} + +export -f clear_config +export -f restore_config +export -f start_cache +export -f stop_cache +export -f set_cache_mode +export -f add_core +export -f try_add_core +export -f remove_core +export -f check_device_state +export -f get_stats_value +export -f format_nvme +export -f init +export -f iteration +export -f deinit +export -f flush_core +export -f flush_cache +export -f set_flush_params +export -f get_flush_params +export -f set_cleaning_policy +export -f get_cleaning_policy +export -f dirty_stop +export -f check_no_cache_running + +############################################################ +# SYSTEM FUNCTIONS # +############################################################ + +mount_cache() { + check_options ${FUNCNAME[0]} + + DIR="${MOUNTPOINT}-${CACHE_ID_OPTION}-${CORE_ID_OPTION}" + + if [ ! -d $DIR ] ; then + mkdir $DIR + fi + + if [ -n $(mount | grep "$DIR") ] ; then + umount $DIR 2> /dev/null + fi + + local COMMAND="mount ${DEVICE_NAME}${CACHE_ID_OPTION}-${CORE_ID_OPTION} $DIR" + + run_cmd $COMMAND + clear_options +} + +remove_partitions() { + check_options ${FUNCNAME[0]} + + local DEV_NAME=$(echo $TARGET_DEVICE_OPTION | sed 's/\/.*\///') + local SFDISK_CFG="$TMP_DIR/${DEV_NAME}_sfdisk.cfg" + local COMMAND="dd if=/dev/zero of=$TARGET_DEVICE_OPTION bs=4k count=10" + + yes | rm -r $SFDISK_CFG 2>/dev/null + run_cmd $COMMAND + clear_options +} + +make_primary_partitions() { + check_options ${FUNCNAME[0]} + local RETRY=40 + local DEV_NAME=${TARGET_DEVICE_OPTION} + local SFDISK_CFG="$TMP_DIR/${DEV_NAME}_sfdisk.cfg" + local COMMAND="sfdisk -D -uM $TARGET_DEVICE_OPTION < $SFDISK_CFG" + local MAX_RETRY=4 + local START="2048" + local END="" + local PART_NUM=0 + local RET=1 + local i + + run_cmd parted -s $DEV_NAME mktable gpt + + for PARTITION_ID in $PARTITION_IDS_OPTION ; do + i=0 + + if [[ $PARTITION_SIZE_OPTION == *[^0-9] ]] ; then + local BYTES=$(($(get_bytes $PARTITION_SIZE_OPTION)/512)) + fi + + if [[ $PARTITION_ID -eq 1 ]] ; then + END=$(($BYTES + $START)) + fi + + while [[ $RET -ne 0 && $i -lt $MAX_RETRY ]] ; do + echo -n "parted -s -a optimal $DEV_NAME mkpart primary ${START}s ${END}s " + parted -s -a optimal $DEV_NAME mkpart primary ${START}s ${END}s + RET=$? + if [[ $RET -ne 0 ]] ; then + sleep 2 + let i++ + fi + done + + if [[ $RET -ne 0 ]] ; then + warning "Parted can't inform kernel about changes in partition table" + else + success + RET=1 + fi + + START=$(($END + 2048)) + END=$(($START + $BYTES)) + let PART_NUM++ + done + run_cmd "udevadm settle" + + i=0 + + for ID in `seq 1 $PART_NUM`; do + local i=0 + local TEST_DEV="${TARGET_DEVICE_OPTION}${ID}" + local TEST_DEV_P="${TARGET_DEVICE_OPTION}p${ID}" + while ! [[ -b $TEST_DEV || -b $TEST_DEV_P ]] ; do + # make sure that partition is detected if it was created + partprobe + sleep 1 + let i++ + if [ $i -gt $MAX_RETRY ]; then + clear_options + error "Creating partition ${TEST_DEV} failed" + end_test 1 + fi + done + # Create symlink for NVMe + if [[ $TARGET_DEVICE_OPTION == "/dev/nvme"* ]] ; then + ln -sf "$TEST_DEV_P" "$TEST_DEV" + fi + # partition successfully created., + # erase all filesystem/cas cache metadata that may have existed on it + # before. + + if [ -b $TEST_DEV ] + then + run_cmd dd if=/dev/zero of="${TEST_DEV}" bs=1M count=1 oflag=direct + else + run_cmd dd if=/dev/zero of="${TEST_DEV_P}" bs=1M count=1 oflag=direct + fi + + done + + run_cmd "udevadm settle" + clear_options +} + +make_filesystem() { + check_options ${FUNCNAME[0]} + local L_LABEL="" + + if [ "$FILESYSTEM_LABEL" != "" ]; then + L_LABEL="-L $FILESYSTEM_LABEL" + fi + + case $FILESYSTEM_TYPE in + "ext3" ) + local COMMAND="mkfs.ext3 ${L_LABEL} $TARGET_DEVICE_OPTION" + ;; + "ext4" ) + hash mkfs.ext4 2> /dev/null && [ ! -e /etc/SuSE-release ] #ext4 is not supported on SLES + if [ $? -eq 0 ] ; then + local COMMAND="mkfs.ext4 ${L_LABEL} $TARGET_DEVICE_OPTION" + else + local COMMAND="mkfs.ext3 ${L_LABEL} $TARGET_DEVICE_OPTION" + warning "EXT4 not found or SLES detected , using EXT3 instead" + fi + ;; + "xfs" ) + hash mkfs.xfs 2> /dev/null + if [ $? -eq 0 ] ; then + local COMMAND="mkfs.xfs ${L_LABEL} -f -b size=4096 $TARGET_DEVICE_OPTION" + else + local COMMAND="mkfs.ext3 ${L_LABEL} $TARGET_DEVICE_OPTION" + warning "XFS not found, using EXT3 instead" + fi + ;; + * ) + error "Unrecognized filesystem $FILESYSTEM_TYPE" + esac + + run_cmd $COMMAND + clear_options +} + +# Removes all caches which use the cache device. This should be used in cleanup after each test +# so that if the test fails, it won't make other tests fail. +remove_caches() { + SILENT_COMMAND_OPTION="1" + + CACHE_IDS_TO_REMOVE=$(${CAS} -L | grep $CACHE_DEVICE | awk '{print $2}') + for ID in $CACHE_IDS_TO_REMOVE ; do + # Umount all mounted instances first + DEVICES_TO_UMOUNT="$(mount | grep "/dev/${DEVICE_NAME}${ID}-" | awk '{print $1}')" + for DEVICE_TO_UMOUNT in $DEVICES_TO_UMOUNT ; do + umount $DEVICE_TO_UMOUNT + done + CACHE_ID_OPTION="$ID" + CACHE_DONT_FLUSH_DATA_OPTION="yes" + # Stop the cache! + stop_cache + done + + # Remove detached cores from core pool + CORE_DEVICES_TO_REMOVE=$(${CAS} -L | grep $CORE_DEVICE | awk '{print $3}') + for DEVICE in $CORE_DEVICES_TO_REMOVE ; do + local COMMAND="$CAS --remove-detached -d $DEVICE" + run_cmd $COMMAND + done + + if [ -n "$CACHE_IDS_TO_REMOVE" ] || [ -n "$CORE_DEVICES_TO_REMOVE" ] ; then + warning "Had to remove some caches in cleanup - \ + either the test failed or it doesn't clean up after itself!" + fi + clear_options +} + +turn_on_device() { + check_options ${FUNCNAME[0]} + if [[ $CACHE_DEVICE_OPTION == "/dev/nvme"* ]] ; then + turn_on_nvme_device + else + COMMAND="echo 'running' > /sys/block/${CACHE_DEVICE_OPTION:4}/device/state" + run_cmd $COMMAND + fi + clear_options +} + +turn_off_device() { + check_options ${FUNCNAME[0]} + if [[ $CACHE_DEVICE_OPTION == "/dev/nvme"* ]] ; then + turn_off_nvme_device + else + local COMMAND="echo 'offline' > /sys/block/${CACHE_DEVICE_OPTION:4}/device/state" + run_cmd $COMMAND + fi +} + +turn_off_nvme_device() { + check_options ${FUNCNAME[0]} + COMMAND="echo '1' > /sys/block/${CACHE_DEVICE_OPTION:4}/device/device/remove" + run_cmd $COMMAND + clear_options +} + +turn_on_nvme_device() { + check_options ${FUNCNAME[0]} + local COMMAND="echo '1' > /sys/bus/pci/rescan" + run_cmd $COMMAND + sleep 30 +} + +check_is_nvme_atomic() { + check_options ${FUNCNAME[0]} + nvme id-ns $DEVICE_OPTION | grep "ms:8.*ds:9.*(in use)" &> /dev/null + return $? +} + +io_class_list() { + check_options ${FUNCNAME[0]} + local COMMAND="CASADM_NO_LINE_BREAK='t' LANG='C' $CAS --io-class --list --cache-id $CACHE_ID_OPTION" + + if [ -n "$CSV_FILE" ] ; then + COMMAND="$COMMAND --output-format csv > $CSV_FILE" + fi + + run_cmd $COMMAND + + clear_options +} + +io_class_load() { + check_options ${FUNCNAME[0]} + run_cmd $CAS --io-class --load-config --file $CSV_FILE --cache-id $CACHE_ID_OPTION + clear_options +} + +io_class_stats() { + check_options ${FUNCNAME[0]} + + local COMMAND="$CAS --stats --cache-id $CACHE_ID_OPTION --io-class-id" + + if [ -n "$IO_CLASS_ID" ] ; then + COMMAND="$COMMAND $IO_CLASS_ID" + fi + + if [ -n "$CSV_FILE" ] ; then + COMMAND="$COMMAND --output-format csv > $CSV_FILE" + fi + + run_cmd $COMMAND + clear_options +} + +stats() { + check_options ${FUNCNAME[0]} + run_cmd $CAS --stats --cache-id $CACHE_ID_OPTION + clear_options +} + +export -f mount_cache +export -f remove_partitions +export -f make_primary_partitions +export -f remove_caches +export -f make_filesystem +export -f turn_on_device +export -f turn_off_device +export -f turn_on_nvme_device +export -f turn_off_nvme_device +export -f io_class_list +export -f io_class_load +export -f stats +export -f io_class_stats +export -f check_is_nvme_atomic + +export CAS_FUNCTIONS_LOADED="1" + +echo "--- Open CAS API library loaded ---" diff --git a/test/smoke_test/cas_lib b/test/smoke_test/cas_lib new file mode 100644 index 0000000..eefc48d --- /dev/null +++ b/test/smoke_test/cas_lib @@ -0,0 +1,521 @@ +#!/bin/bash + +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +export NAME=`basename $0` + +export RESTORE='\033[0m' +export RED='\033[00;31m' +export GREEN='\033[00;32m' +export YELLOW='\033[00;33m' + +if [ -z $TESTS_DIR ] ; then + export TESTS_DIR="$(dirname $0)" +fi + +export LOGS_FOLDER="$TESTS_DIR/logs" + +if [ -z "$TEST_LOG_DIR" ] ; then + export TEST_LOG_DIR="$TESTS_DIR/logs" +fi +export TEST_TIME="" + +check_if_root_or_exit() { + if [[ $EUID -ne 0 ]] ; then + echo "You need to have root privileges to launch DVT tests" + exit 1 + fi +} + +parse_args() { + while [ -n "$1" ] ; do + + case $1 in + -a | --all ) export TEST_MODE="all" + ;; + -x | --dir ) shift + export TEST_MODE="dir" + TEST_MODE_DIR="$1" + ;; + -b | --bvt ) export TEST_MODE="bvt" + ;; + -f | --atomic ) export TEST_MODE="atomic" + ;; + -n | --nightly ) export TEST_MODE="nightly" + ;; + -s | --sanity ) export TEST_MODE="sanity" + ;; + -i | --ignore ) export IGNORE_WARNINGS="1" + ;; + -c | --cache ) shift + CACHE_DEVICE="$1" + ;; + -d | --core ) shift + CORE_DEVICE="$1" + ;; + * ) echo "Unrecognized option" + usage + exit 1 + esac + shift + done +} + +usage() { + echo "example: ./${NAME} -b" + echo " -a | --all - run all TESTS" + echo " -b | --bvt - run BVT" + echo " -n | --nightly - run nightly" + echo " -s | --sanity - sanity check" + echo " -i | --ignore - ignore config warnings" + echo " -c | --cache - override cache device from settings file" + echo " -d | --core - override core device from settings file" + echo " -x | --dir - performs tests for specified directory (e.g. --dir basic)" +} + +load_cas_lib() { + if [ -z $CAS_CONFIGURATION_LOADED ] ; then + . $TESTS_DIR/cas_config + fi + if [ -z $CAS_FUNCTIONS_LOADED ] ; then + . $TESTS_DIR/cas_functions + fi + if [ -z $CAS_OPTIONS_LOADED ] ; then + . $TESTS_DIR/cas_options + fi + if [ -f ~/cas_local_config ] ; then + . ~/cas_local_config + echo "--- Using home config file ---" + elif [ -f $TESTS_DIR/cas_local_config ] ; then + . $TESTS_DIR/cas_local_config + echo "--- Using local config file ---" + fi +} + +start_test() { + if [ -z $LOG_FILE ] ; then + load_cas_lib + else + load_cas_lib >> $LOG_FILE + fi + parse_args $* + check_config + + if [ -z $DESCRIPTION ] + then + DESCRIPTION=$(cat $0 | grep "# DESCRIPTION" | sed 's/# DESCRIPTION //g') + export DESCRIPTION="$DESCRIPTION" + fi + + STORE_CONFIG_OPTION=1 clear_config + + clear_options + echo "*** Starting test $0 - $DESCRIPTION ***" + TEST_TIME="$(date +%s)" +} + +end_test() { + TEST_TIME="$(($(date +%s) - TEST_TIME))" + echo "*** Finished test $NAME ***" + echo "*** The test took $TEST_TIME seconds ***" + echo "result : $1" + + restore_config + + if [ $1 -ne 0 ] ; then + # Try to cleanup in case of failure - it might not always work, but could help to + # execute remaining tests + umount ${CORE_DEVICE}* &>/dev/null + remove_caches + test_log_stop + fi + # Delete all temporary files + rm -rf $TMP_DIR/* + # Delete created symlinks for NVMes + if [[ $CACHE_DEVICE != "/dev/nvme"* ]] ; then + exit $1 + fi + + local L_NVME_SYM_LINKS=`ls /dev/ | grep -E -w "${CACHE_DEVICE:5}[1-9][1-9]?"` + + for SYM_LINK in $L_NVME_SYM_LINKS + do + if [ -L "/dev/${SYM_LINK}" ] + then + rm -f "/dev/${SYM_LINK}" + fi + done + + exit $1 +} + +echo_green() { + echo -e "${GREEN}$*${RESTORE}" +} + +echo_red() { + echo -e "${RED}$*${RESTORE}" +} + +echo_yellow() { + echo -e "${YELLOW}$*${RESTORE}" +} + +echo_green_n() { + echo -ne "${GREEN}$*${RESTORE}" +} + +echo_red_n() { + echo -ne "${RED}$*${RESTORE}" +} + +echo_yellow_n() { + echo -ne "${YELLOW}$*${RESTORE}" +} + +success() { + echo -n "$*" + echo_green "[OK]" +} + +error() { + echo -n "$*" + echo_red "[ERROR]" +} + +not_run() { + echo -n "$*" + echo_yellow "[NOT RUN]" +} + +warning() { + echo -n "$*" + echo_yellow "[WARNING]" +} + +# This function should be used by all API wrappers and may be also used +# directly in tests. It runs the command passed to it and checks the return +# code against NEGATIVE_TEST_OPTION. If the NEGATIVE_TEST_OPTION is set, then +# we assume the command should fail - otherwise the command should succeed. +# If the output is correct, the command is printed and the test continues; +# if not, we print an error message and end the test immiedately. +run_cmd() { + export RUN_CMD_OUTPUT="" + local L_RUN_CMD_START=$SECONDS + if [ -z "$SILENT_COMMAND_OPTION" ] ; then + echo -n "$(date +%Y-%m-%d_%H:%M:%S) " + echo -n "Running $* " + fi + OUTPUT=$(eval "$*" 2>&1) + STATUS=$? + export RUN_CMD_OUTPUT="${OUTPUT}" + export RUN_CMD_TIME=$(( $SECONDS - $L_RUN_CMD_START )) + if [ -z "$SILENT_COMMAND_OPTION" ] ; then + if [ -n "$NEGATIVE_TEST_OPTION" ] ; then + echo -n "(negative test) " + if [ $STATUS -ne 0 ] ; then + success + else + error + echo "--- Command output:" + echo "$OUTPUT" + if [ -z $DONT_FAIL_ON_ERROR_OPTION ]; then + end_test 1 + fi + return 1 + fi + else + if [ $STATUS -eq 0 ] ; then + success + else + error + echo "--- Command output:" + echo "$OUTPUT" + if [ -z $DONT_FAIL_ON_ERROR_OPTION ]; then + end_test 1 + fi + return 1 + fi + fi + fi +} + +# This function converts size to bytes amount. It takes one parameter and +# the format of it is: [0-9][b|kB|kiB|k|M|MiB|MB|G|GiB|GB|T|TiB|TB] +# +# example of usage: BYTES=$(get_bytes 128kB) +# return : 128*1024 = 131,072 +# +get_bytes () { + local PARAM + local FACTOR + local BYTES + + if [[ $1 =~ ^([0-9]*)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=1 + elif [[ $1 =~ ^(b)$ ]] ; then + PARAM=1 + FACTOR=512 + elif [[ $1 =~ ^([0-9]*)(b)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=512 + elif [[ $1 =~ ^(kB)$ ]] ; then + PARAM=1 + FACTOR=1000 + elif [[ $1 =~ ^(k|kiB)$ ]] ; then + PARAM=1 + FACTOR=1024 + elif [[ $1 =~ ^([0-9]*)(kB)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=1000 + elif [[ $1 =~ ^([0-9]*)(k|kiB)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=1024 + elif [[ $1 =~ ^(MB)$ ]] ; then + PARAM=1 + FACTOR=1000*1000 + elif [[ $1 =~ ^(M|MiB)$ ]] ; then + PARAM=1 + FACTOR=1024*1024 + elif [[ $1 =~ ^([0-9]*)(MB)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=1000*1000 + elif [[ $1 =~ ^([0-9]*)(M|MiB)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=1024*1024 + elif [[ $1 =~ ^(GB)$ ]] ; then + PARAM=1 + FACTOR=1000*1000*1000 + elif [[ $1 =~ ^(G|GiB)$ ]] ; then + PARAM=1 + FACTOR=1024*1024*1024 + elif [[ $1 =~ ^([0-9]*)(GB)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=1000*1000*1000 + elif [[ $1 =~ ^([0-9]*)(G|GiB)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=1024*1024*1024 + elif [[ $1 =~ ^(T|TiB)$ ]] ; then + PARAM=1 + FACTOR=1024*1024*1024*1024 + elif [[ $1 =~ ^(TB)$ ]] ; then + PARAM=1 + FACTOR=1000*1000*1000*1000 + elif [[ $1 =~ ^([0-9]*)(T|TiB)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=1024*1024*1024*1024 + elif [[ $1 =~ ^([0-9]*)(TB)$ ]] ; then + PARAM=${BASH_REMATCH[1]} + FACTOR=1000*1000*1000*1000 + else + echo "Input parameter error, ($1) is not [0-9](b|kB|kiB|k|M|MiB|MB|G|GiB|GB|T|TiB|TB)" + exit 1 + fi + + let BYTES=$PARAM*$FACTOR + + echo $BYTES +} + +# This function returns pages amount for specified byte size. It takes +# folowing parameters: +# size - size that will be computed to number of pages +# [page_size] - optional, if ommited then page size is 4k +# +# example of usage: PAGES=$(get_bytes 128kB [$PAGE_SIZE=4k]) +# return : 128kB / $PAGE_SIZE = 32 +# +get_pages () { + local PAGES + local PAGE_SIZE + local BYTES + + if [ -z "$2" ] + then + PAGE_SIZE=4096 + else + PAGE_SIZE=$2 + fi + + PAGE_SIZE=$(get_bytes $PAGE_SIZE) + BYTES=$(get_bytes $1) + + let PAGES=$BYTES/$PAGE_SIZE + + echo $PAGES +} + +TEST_LOG_PID="${TEST_LOG_DIR}/.test_log_pid" + +# Start print log to the STD +# +# usage: +# test_log_tail +test_log_tail () { + # + # Check if traicing in progress + # + if [ -f $TEST_LOG_PID ] + then + local L_PID=$(ps | grep tail | grep $(cat $TEST_LOG_PID)) + if [ "" != "$L_PID" ] + then + return 0 + fi + fi + + tail -f $1 & + echo $! > $TEST_LOG_PID + return 0 +} + +# Test Log Utils Function +# It shall be used in following order +# test_log_start() +# +# +# test_log_trace() # Do tracing +# +# +# test_log_stop() +# +# Start trace loging. Function takes following parameters: +# [TEST_LOG_FILE_NAME] File where log will be captured. If omitted log file name +# id "cas_test_log" +# +# example of usage: test_log_start [$TEST_LOG_FILE_NAME] +# +test_log_start() { + if [ -n "$1" ] + then + export TEST_LOG="${TEST_LOG_DIR}/$1" + else + export TEST_LOG="${TEST_LOG_DIR}/cas_test_log_ext" + fi + + if [ ! -d $TEST_LOG_DIR ] ; then + mkdir -p $TEST_LOG_DIR + fi + echo >> $TEST_LOG + echo "********************************************************" >> $TEST_LOG + echo "* Test log start : $(date)" >> $TEST_LOG + echo "* $DESCRIPTION - $TEST_LOG" >> $TEST_LOG + echo "********************************************************" >> $TEST_LOG + + if [ -z $DISABLE_EXTERNAL_LOGGING ] + then + test_log_tail $TEST_LOG + fi +} + +# Stop trace loging +test_log_stop() { + + if [ -n "${TEST_LOG}" ]; then + echo "########################################################" >> $TEST_LOG + echo "* $DESCRIPTION - $TEST_LOG" >> $TEST_LOG + echo "# Test log stop : $(date)" >> $TEST_LOG + echo "########################################################" >> $TEST_LOG + echo >> $TEST_LOG + sleep 1 + fi + + if [ -f $TEST_LOG_PID ] + then + local L_PID=$(ps | grep tail | grep $(cat $TEST_LOG_PID)) + if [ "" != "$L_PID" ] + then + kill $(cat $TEST_LOG_PID) + rm -f $TEST_LOG_PID + fi + fi +} + +# +# Trace log message. +# +# example of usage: test_log_trace "Some message to store in file" +# +test_log_trace() { + if [[ ! -z $1 ]] + then + echo "$DESCRIPTION : $1" >> $TEST_LOG + fi +} + +set_categories() { + if [ "" != "$TEST_MODE_DIR" ] + then + export CATEGORIES=$TEST_MODE_DIR + return 0 + fi + + local TMP_CATEGORIES="$(find $TESTS_DIR -type d | grep -v old | grep -v logs | grep -v ^.$)" + for CATEGORY in $TMP_CATEGORIES ; do + CATEGORIES="$(basename $CATEGORY) $CATEGORIES" + done + export CATEGORIES=$(echo $CATEGORIES | tr ' ' '\n' | sort | tr '\n' ' ' && echo) +} + +# +# Warmup device +# +#param1 - Input +#param2 - Output +#param3 - Block Size +#param4 - Count +#param5 - Seek +#param6 - Skip +warmup() { + local L_IF=$1 + local L_OF=$2 + local L_BS=$3 + local L_COUNT=$4 + local L_SEEK=$5 + local L_SKIP=$6 + local I_SEEK + local I_SKIP + + if [ "$L_OF" = "/dev/null" ] ; then + DD_CONF='if=${L_IF} of=${L_OF} count=1 bs=${L_BS} skip=$I_SKIP iflag=direct' + else + DD_CONF='if=${L_IF} of=${L_OF} count=1 bs=${L_BS} seek=$I_SEEK skip=$I_SKIP oflag=direct iflag=direct conv=notrunc' + fi + + for (( I=0; I<$L_COUNT; I=I+2 )) + do + let I_SEEK=${L_SEEK}+${I} + let I_SKIP=${L_SKIP}+${I} + + eval "dd $DD_CONF &>/dev/null" + if [ $? != 0 ] + then + return 1 + fi + done + + for (( I=1; I<$L_COUNT; I=I+2 )) + do + let I_SEEK=${L_SEEK}+${I} + let I_SKIP=${L_SKIP}+${I} + + eval "dd $DD_CONF &>/dev/null" + if [ $? != 0 ] + then + return 1 + fi + done + + return 0 +} + +cas_version () { + local L_CAS_VERSION=$(LANG=1 casadm -V -o csv 2>/dev/null | grep "CLI" | cut -d ',' -f2) + echo $L_CAS_VERSION +} + +check_if_root_or_exit diff --git a/test/smoke_test/cas_local_config.example b/test/smoke_test/cas_local_config.example new file mode 100644 index 0000000..ec5f0e9 --- /dev/null +++ b/test/smoke_test/cas_local_config.example @@ -0,0 +1,26 @@ +#!/bin/bash + +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +# This is the local config file which may be used to override default settings. +# If you want to use this file, rename it to "cas_local_config". + +# Default core and cache devices - note that we require whole devices, not partitions +export CORE_DEVICE="/dev/sdd" +export CACHE_DEVICE="/dev/sdf" + +# Default size of partition for cache/core device. This is used only for +# the DEFAULT_* API functions +export DEFAULT_CACHE_SIZE="3000M" +export DEFAULT_CORE_SIZE="5000M" + +# All devices mounted using the test API will be mounted at ${MOUNTPOINT}-${CACHE_ID}-${CORE_ID} +# Use this variable in your tests to use the mounted resource. +export MOUNTPOINT="/mnt/cas" + +# TMP_DIR should be a directory where we can store additional data like test files, md5 sums etc. +# We clean up this directory between the tests. +export TMP_DIR="/var/tmp/.cas" diff --git a/test/smoke_test/cas_options b/test/smoke_test/cas_options new file mode 100644 index 0000000..c229215 --- /dev/null +++ b/test/smoke_test/cas_options @@ -0,0 +1,334 @@ +#!/bin/bash + +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# +# Whenever adding new options (required or optional), add them to the variable below. +# Every option might be mentioned more than once - it doesn't really matter at this point +export ALL_OPTIONS=" + CACHE_ID_OPTION CORE_ID_OPTION NEGATIVE_TEST_OPTION SILENT_COMMAND_OPTION DONT_FAIL_ON_ERROR_OPTION + CACHE_DEVICE_OPTION + CACHE_LOAD_METADATA_OPTION CACHE_FORCE_OPTION + CACHE_DONT_FLUSH_DATA_OPTION + CORE_DEVICE_OPTION + NUMBER_OF_CACHE_PARTITIONS NUMBER_OF_CORE_PARTITIONS MAKE_FILE_SYSTEM + PARTITION_ID_OPTION PRIORITY_OPTION MIN_SIZE_OPTION MAX_SIZE_OPTION CLEANING_POLICY_OPTION + CACHE_ID_OPTION CORE_ID_OPTION MOUNTPOINT_ID_OPTION + TARGET_DEVICE_OPTION PARTITION_IDS_OPTION PARTITION_SIZE_OPTION PARTITION_ID_OPTION PARTITIONS_AMOUNT_OPTION + CLEAN_POL_NS_OPTION WAKE_UP_OPTION STALE_TIME_OPTION FLUSH_BUFFERS_OPTION ACTIVITY_THRESH_OPTION + TARGET_DEVICE_OPTION FILESYSTEM_TYPE + IO_CLASS_ID IO_CLASS_PRIORITY IO_CLASS_SIZE_MIN IO_CLASS_SIZE_MAX IO_CLASS_NAME IO_CLASS_CACHE_MODE + FORMAT_NVME_REQUIRED_OPTIONS CHECK_IS_NVME_ATOMIC TURN_OFF_NVME_DEVICE TURN_ON_NVME_DEVICE + DEVICE_ID_OPTION DEMANDED_STATE_OPTION + STAT_UNIT_OPTION STAT_NAME_OPTION + STORE_CONFIG_OPTION + CLEAN_POL_OPTION +" + +# Specify ONLY required options here. The name of the variable should start with +# uppercase function's name + "_REQUIRED_OPTIONS". + +export START_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION CACHE_DEVICE_OPTION" +export STOP_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION" +export ADD_CORE_REQUIRED_OPTIONS="CACHE_ID_OPTION CORE_DEVICE_OPTION" +export TRY_ADD_CORE_REQUIRED_OPTIONS="CACHE_ID_OPTION CORE_ID_OPTION CORE_DEVICE_OPTION" +export CHECK_DEVICE_SATE_REQUIRED_OPTIONS="DEVICE_ID_OPTION DEMANDED_STATE_OPTION" +export REMOVE_CORE_REQUIRED_OPTIONS="CACHE_ID_OPTION CORE_ID_OPTION" +export REMOVE_PARTITIONS_REQUIRED_OPTIONS="TARGET_DEVICE_OPTION" +export FLUSH_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION" +export FLUSH_CORE_REQUIRED_OPTIONS="CACHE_ID_OPTION CORE_ID_OPTION" +export SET_CLEANING_POLICY_REQUIRED_OPTIONS="CACHE_ID_OPTION CLEAN_POL_OPTION" +export GET_CLEANING_POLICY_REQUIRED_OPTIONS="CACHE_ID_OPTION" +export SET_FLUSH_PARAMS_REQUIRED_OPTIONS="CACHE_ID_OPTION CLEAN_POL_NS_OPTION" +export GET_FLUSH_PARAMS_REQUIRED_OPTIONS="CACHE_ID_OPTION CLEAN_POL_NS_OPTION" +export FORMAT_NVME_REQUIRED_OPTIONS="NVME_FORMAT_MODE_OPTION DEVICE_OPTION" +export CHECK_IS_NVME_ATOMIC_REQUIRED_OPTIONS="DEVICE_OPTION" + +export CREATE_PARTITION_REQUIRED_OPTIONS="CACHE_ID_OPTION PARTITION_ID_OPTION PRIORITY_OPTION MIN_SIZE_OPTION MAX_SIZE_OPTION CLEANING_POLICY_OPTION" + +export MOUNT_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION CORE_ID_OPTION" + +export MAKE_PRIMARY_PARTITIONS_REQUIRED_OPTIONS="TARGET_DEVICE_OPTION PARTITION_IDS_OPTION PARTITION_SIZE_OPTION" +export MAKE_EXTENDED_PARTIION_REQUIRED_OPTIONS="TARGET_DEVICE_OPTION PARTITION_ID_OPTION PARTITION_SIZE_OPTION" +export MAKE_LOGICAL_PARTIIONS_REQUIRED_OPTIONS="TARGET_DEVICE_OPTION PARTITIONS_AMOUNT_OPTION PARTITION_SIZE_OPTION" +export MAKE_FILESYSTEM_REQUIRED_OPTIONS="TARGET_DEVICE_OPTION FILESYSTEM_TYPE" +export TURN_OFF_DEVICE_REQUIRED_OPTIONS="CACHE_DEVICE_OPTION" +export TURN_ON_DEVICE_REQUIRED_OPTIONS="CACHE_DEVICE_OPTION" +export TURN_OFF_NVME_DEVICE_REQUIRED_OPTIONS="CACHE_DEVICE_OPTION" +export TURN_ON_NVME_DEVICE_REQUIRED_OPTIONS="CACHE_DEVICE_OPTION" + +export START_DUAL_LEVEL_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION CACHE_DEVICE_OPTION" + +export START_CACHE_REQUIRED_OPTIONS="CACHE_ID_OPTION CACHE_DEVICE_OPTION" + +export IO_CLASS_LIST_REQUIRED_OPTIONS="CACHE_ID_OPTION" +export IO_CLASS_LOAD_REQUIRED_OPTIONS="CACHE_ID_OPTION CSV_FILE" +export IO_CLASS_STATS_CSV_REQUIRED_OPTIONS="CACHE_ID_OPTION CSV_FILE" + +export IO_CLASS_EXT_ADD_REQUIRED_OPTIONS="CACHE_ID_OPTION IO_CLASS_ID IO_CLASS_PRIORITY IO_CLASS_SIZE_MIN IO_CLASS_SIZE_MAX IO_CLASS_NAME IO_CLASS_CACHE_MODE" +export IO_CLASS_EXT_MODIFY_REQUIRED_OPTIONS="CACHE_ID_OPTION IO_CLASS_ID" +export IO_CLASS_EXT_REMOVE_REQUIRED_OPTIONS="CACHE_ID_OPTION IO_CLASS_ID" + +export STATS_REQUIRED_OPTIONS="CACHE_ID_OPTION" +export GET_STATS_VALUE_REQUIRED_OPTIONS="CACHE_ID_OPTION STAT_NAME_OPTION" + +# Clearing the variables below is not really needed, but it makes the whole +# thing much more clear. Unlike the REQUIRED_OPTIONS, we specify all +# possible parameters here for every function. +# Please note that some options are shared between many functions, so +# make sure the option is set to a correct value before invoking one +# function after another. + +############################################################ +# OPTIONS SHARED BETWEEN ALL FUNCTIONS # +############################################################ +NEGATIVE_TEST_OPTION="" +SILENT_COMMAND_OPTION="" +DONT_FAIL_ON_ERROR_OPTION="" +############################################################ +# CLEAR CONFIG # +############################################################ +STORE_CONFIG_OPTION="" +############################################################ +# START CACHE # +############################################################ +CACHE_ID_OPTION="" +CACHE_DEVICE_OPTION="" +# Optional +CACHE_FORCE_OPTION="" +CACHE_LOAD_METADATA_OPTION="" +SEQ_CUTOFF_SIZE="" + +############################################################ +# STOP CACHE # +############################################################ +CACHE_ID_OPTION="" +# Optional +CACHE_DONT_FLUSH_DATA_OPTION="" + +############################################################ +# ADD CORE # +############################################################ +CACHE_ID_OPTION="" +CORE_DEVICE_OPTION="" + +############################################################ +# REMOVE CORE # +############################################################ +CACHE_ID_OPTION="" +CORE_ID_OPTION="" + +############################################################ +# CHECK DEVICE STATE # +############################################################ +DEVICE_ID_OPTION="" +DEMANDED_STATE_OPTION="" + +############################################################ +# FORMAT NVME # +############################################################ +NVME_FORMAT_MODE_OPTION="" +DEVICE_OPTION="" +NVME_FORMAT_FORCE_OPTION="" + +############################################################ +# CHECK_IS_NVME_ATOMIC # +############################################################ +DEVICE_OPTION="" + +############################################################ +# INIT # +############################################################ +NUMBER_OF_CACHE_PARTITIONS="" +NUMBER_OF_CORE_PARTITIONS="" +MAKE_FILE_SYSTEM="" +CACHE_FORCE_OPTION="" +CACHE_MODE_OPTION="" +CACHE_LOAD_METADATA_OPTION="" + +############################################################ +# ITERATION # +############################################################ +NUMBER_OF_CACHE_PARTITIONS="" +NUMBER_OF_CORE_PARTITIONS="" +MAKE_FILE_SYSTEM="" +CACHE_FORCE_OPTION="" +CACHE_MODE_OPTION="" +CACHE_LOAD_METADATA_OPTION="" + +############################################################ +# DEINIT # +############################################################ +NUMBER_OF_CACHE_PARTITIONS="" +NUMBER_OF_CORE_PARTITIONS="" + +############################################################ +# FLUSH CACHE # +############################################################ +CACHE_ID_OPTION="" + +############################################################ +# FLUSH CORE # +############################################################ +CACHE_ID_OPTION="" +CORE_ID_OPTION="" + +############################################################ +# MOUNT CACHE # +############################################################ +CACHE_ID_OPTION="" +CORE_ID_OPTION="" + +############################################################ +# MAKE PRIMARY PARTITIONS # +############################################################ +TARGET_DEVICE_OPTION="" +PARTITION_IDS_OPTION="" +PARTITION_SIZE_OPTION="" + +############################################################ +# MAKE EXTENDED PARTITION # +############################################################ +TARGET_DEVICE_OPTION="" +PARTITION_ID_OPTION="" +PARTITION_SIZE_OPTION="" + +############################################################ +# MAKE LOGICAL PARTITIONS # +############################################################ +TARGET_DEVICE_OPTION="" +PARTITION_SIZE_OPTION="" +PARTITIONS_AMOUNT_OPTION="" + +############################################################ +# MAKE FILESYSTEM # +############################################################ +TARGET_DEVICE_OPTION="" +FILESYSTEM_TYPE="" + +############################################################ +# IO CLASS LIST # +############################################################ +CACHE_ID_OPTION="" +# Optional +CSV_FILE="" + +############################################################ +# IO CLASS LOAD # +############################################################ +CACHE_ID_OPTION="" +CSV_FILE="" + +############################################################ +# IO CLASS EXT ADD # +############################################################ +CACHE_ID_OPTION="" +IO_CLASS_ID="" +IO_CLASS_PRIORITY="" +IO_CLASS_SIZE_MIN="" +IO_CLASS_SIZE_MAX="" +IO_CLASS_NAME="" +IO_CLASS_CACHE_MODE="" + +############################################################ +# IO CLASS EXT MODIFY # +############################################################ +CACHE_ID_OPTION="" +IO_CLASS_ID="" +#Optional +IO_CLASS_PRIORITY="" +IO_CLASS_SIZE_MIN="" +IO_CLASS_SIZE_MAX="" +IO_CLASS_NAME="" +IO_CLASS_CACHE_MODE="" + +############################################################ +# IO CLASS EXT REMOVE # +############################################################ +CACHE_ID_OPTION="" +IO_CLASS_ID="" + +############################################################ +# IO CLASS STATS CSV # +############################################################ +CACHE_ID_OPTION="" +CSV_FILE="" + +############################################################ +# STATS # +############################################################ +CACHE_ID_OPTION="" + +############################################################ +# GET_STATS_VALUE # +############################################################ +DEVICE_ID_OPTION="" +STAT_NAME_OPTION="" +#Optional +STAT_UNIT_OPTION="" +CORE_ID_OPTION="" +IO_CLASS_ID="" + +############################################################ +# SET_CLEANING_POLICY # +############################################################ +DEVICE_ID_OPTION="" +CLEAN_POLICY_OPTION="" + +############################################################ +# GET_CLEANING_POLICY # +############################################################ +DEVICE_ID_OPTION="" + +############################################################ +# SET_FLUSH_PARAMS # +############################################################ +DEVICE_ID_OPTION="" +CLEAN_POLICY_NS_OPTION="" +#Optional +WAKE_UP_OPTION="" +STALE_TIME_OPTION="" +FLUSH_BUFFERS_OPTION="" +ACTIVITY_THRESH_OPTION="" + +############################################################ +# SET_FLUSH_PARAMS # +############################################################ +DEVICE_ID_OPTION="" +CLEAN_POLICY_NS_OPTION="" + +############################################################ +# FUNCTIONS # +############################################################ + +# This function is what exports and sets all the options above. +# All options should be automatically cleared after using them in API. +clear_options() { + for OPTION in $ALL_OPTIONS ; do + export $OPTION="" + done +} + +# This should be used in all API/system functions to check if all required +# options are set. It doesn't check the syntax at all - only if option is set. +check_options() { + FUNCTION_NAME=$(echo $1 | tr [:lower:] [:upper:]) + OPTIONS_NAME="${FUNCTION_NAME}_REQUIRED_OPTIONS" + OPTIONS_TO_CHECK="${!OPTIONS_NAME}" + + for OPTION in $OPTIONS_TO_CHECK ; do + if [ -z "${!OPTION}" ] ; then + echo -n "Required option $OPTION is not set " + echo_red "[ERROR]" + end_test 1 + fi + done +} + +export -f clear_options +export -f check_options + +export CAS_OPTIONS_LOADED="1" + +echo "--- Open CAS options library loaded ---" diff --git a/test/smoke_test/run_tests b/test/smoke_test/run_tests new file mode 100755 index 0000000..56ad1de --- /dev/null +++ b/test/smoke_test/run_tests @@ -0,0 +1,397 @@ +#!/bin/bash +# +# Copyright(c) 2012-2019 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +############################################################ +# GLOBALS # +############################################################ + +export LOG_FILE="" +export LOG_NAME="out" +export RESULT_FILE="result" +export CUMULATIVE_LOG="cumulative_log" +export EXEC_LOG="exec_log" +export TESTS=0 +export PASSED=0 +export FAILED=0 +export NOT_RUN=0 + +# Some tests might use additional logging mechanism - disable them in case we run the tests via this script. +export DISABLE_EXTERNAL_LOGGING=1 + +############################################################ +# FUNCTIONS # +############################################################ + +check_result() { + if [ $1 == 0 ]; then + echo -n " " + echo_green_n "[OK]" + PASSED=$(($PASSED + 1)) + TEST_RESULTS[$TESTS]="Passed" + elif [ "$1" -eq "$CAS_TEST_NOT_RUN" ]; then + echo_yellow_n "[NOT RUN]" + NOT_RUN=$(($NOT_RUN + 1)) + TEST_RESULTS[$TESTS]="Not_run" + else + echo -n " " + echo_red_n "[ERROR]" + FAILED=$(($FAILED+ 1)) + TEST_RESULTS[$TESTS]="Failed" + fi +} + +print_time() { + time=$1 + hours=`expr $time / 3600` + mins=`expr \( $time - $hours \* 3600 \) / 60` + secs=`expr $time - $hours \* 3600 - $mins \* 60` + printf "%5d[s] (%02d:%02d:%02d)" ${time} ${hours} ${mins} ${secs} +} + +run_test() { + TEST_FILE=$1 + TEST_FILE_NAMES[$TESTS]=${TEST_FILE} + TEST_NAMES[$TESTS]="$(basename $TEST_FILE)" + # Ignore tests marked as not-working + if [[ ${TEST_NAMES[$TESTS]} == _* ]] ; then + return + fi + TEST_CATEGORIES[$TESTS]="$(dirname $TEST_FILE | sed 's/.*\///g')" + DESCRIPTION=$(cat $TEST_FILE | grep "# DESCRIPTION" | sed 's/# DESCRIPTION //g') + DESCRIPTION=${DESCRIPTION:0:80} + if [ -z "$DESCRIPTION" ] ; then + DESCRIPTION="${TEST_NAMES[$TESTS]} [NO DESCRIPTION]" + fi + TEST_DESCRIPTIONS[$TESTS]="$DESCRIPTION" + printf "%3d. %-30s% -80s" $((TESTS+1)) "${TEST_FILE}" "$DESCRIPTION" | tee -a ${EXEC_LOG} + # Clear system log + dmesg -c &> /dev/null + + export TEST_LOG_DIR="${LOGS_FOLDER}/$TEST_FILE" + if [ ! -d $TEST_LOG_DIR ] ; then + mkdir -p $TEST_LOG_DIR + fi + export LOG_FILE=$TEST_LOG_DIR/$LOG_NAME + # Execute test and save output to the log file + + TEST_TIME="$(date +%s)" + # Check result and print to stdout + bash $TEST_FILE >> $LOG_FILE + status=$? + check_result $status + + if [ $status == 0 ]; then + echo -n " [OK]" >> ${EXEC_LOG} + elif [ "$status" == "$CAS_TEST_NOT_RUN" ]; then + echo -n "[NOT RUN]" >> ${EXEC_LOG} + else + echo -n " [ERROR]" >> ${EXEC_LOG} + fi + + delta=$(($(date +%s) - TEST_TIME)) + print_time ${delta} | tee -a ${EXEC_LOG} + echo "" | tee -a ${EXEC_LOG} + cat $LOG_FILE >> $LOGS_FOLDER/$CUMULATIVE_LOG + + # Store test time + TEST_TIMES[$TESTS]="${delta}" + # Print the kernel log + echo "--- kernel log ---" | tee -a $LOGS_FOLDER/$CUMULATIVE_LOG >> $LOG_FILE + dmesg | tee -a $LOGS_FOLDER/$CUMULATIVE_LOG >> $LOG_FILE + echo "" | tee -a $LOGS_FOLDER/$CUMULATIVE_LOG >> $LOG_FILE + # Increment the tests counter + TESTS=$(($TESTS + 1)) +} + +start_table() { + printf "

%s tests

\n" ${2} >> ${1} + printf "\n" >> ${1} + printf "\t\n" >> ${1} + printf "\t\t\n" "Test file name" >> ${1} + printf "\t\t\n" "Test description" >> ${1} + printf "\t\t\n" "Exec time" >> ${1} + printf "\t\t\n" "Result" >> ${1} + printf "\t\n" >> ${1} +} + +stop_table() { + printf "
%s%s%s%s

\n" >> ${1} +} + +export_results_to_html() { + HTML_PASSED_LOG="${LOG_FILE}-passed.html" + HTML_FAILED_LOG="${LOG_FILE}-failed.html" + HTML_NOT_RUN_LOG="${LOG_FILE}-not-run.html" + HTML_LOG="${LOG_FILE}.html" + BUILD=$(cas_version) + IF=`route | grep default | tr -s ' ' | cut -d' ' -f8` + IP=`ifconfig ${IF} | grep "inet " | tr -s ' ' | cut -d' ' -f3` + HOSTNAME=`hostname` + + rm -f ${HTML_LOG} ${HTML_PASSED_LOG} ${HTML_FAILED_LOG} ${HTML_NOT_RUN_LOG} + touch ${HTML_LOG} ${HTML_PASSED_LOG} ${HTML_FAILED_LOG} ${HTML_NOT_RUN_LOG} + + printf "

Summary for Open-CAS-%s

\n" "${BUILD}" >> ${HTML_LOG} + printf "

Test mode: %s

\n" "${TEST_MODE}" >> ${HTML_LOG} + printf "

HOST: %s (%s)

\n" "${IP}" "${HOSTNAME}" >> ${HTML_LOG} + + start_table ${HTML_PASSED_LOG} "PASSED" + start_table ${HTML_FAILED_LOG} "FAILED" + start_table ${HTML_NOT_RUN_LOG} "NOT_RUN" + + total_passed=0 + total_failed=0 + total_not_run=0 + + for ((I = 0; I < $TESTS; I++)) ; do + if [ "${TEST_RESULTS[$I]}" == "Passed" ]; then + COLOR="green" + file=${HTML_PASSED_LOG} + total_passed=$((${total_passed}+${TEST_TIMES[I]})) + elif [ "${TEST_RESULTS[$I]}" == "Failed" ]; then + COLOR="red" + file=${HTML_FAILED_LOG} + total_failed=$((${total_failed}+${TEST_TIMES[$I]})) + else + COLOR="yellow" + file=${HTML_NOT_RUN_LOG} + total_not_run=$((${total_not_run}+${TEST_TIMES[I]})) + fi + + printf "\t\n" >> ${file} + printf "\t\t%s\n" "${TEST_FILE_NAMES[$I]}" >> ${file} + printf "\t\t%s\n" "${TEST_DESCRIPTIONS[$I]}" >> ${file} + printf "\t\t%s\n" "`print_time ${TEST_TIMES[$I]}`" >> ${file} + printf "\t\t%s\n" "${TEST_RESULTS[$I]}" >> ${file} + printf "\t\n" >> ${file} + done + + stop_table ${HTML_PASSED_LOG} + stop_table ${HTML_FAILED_LOG} + stop_table ${HTML_NOT_RUN_LOG} + + if [ ${PASSED} -gt 0 ]; then + cat ${HTML_PASSED_LOG} >> ${HTML_LOG} + fi + + if [ ${FAILED} -gt 0 ]; then + cat ${HTML_FAILED_LOG} >> ${HTML_LOG} + fi + + if [ ${NOT_RUN} -gt 0 ]; then + cat ${HTML_NOT_RUN_LOG} >> ${HTML_LOG} + fi + + printf "
\n" >> ${HTML_LOG} + + printf "

Time stats

\n" >> ${HTML_LOG} + printf "\n" >> ${HTML_LOG} + + printf "\t\n" >> ${HTML_LOG} + printf "\t\t\n" >> ${HTML_LOG} + printf "\t\t\n" >> ${HTML_LOG} + printf "\t\n" >> ${HTML_LOG} + printf "\t\n" >> ${HTML_LOG} + + printf "\t\n" >> ${HTML_LOG} + time=`print_time ${total_passed}` + printf "\t\t\n" >> ${HTML_LOG} + printf "\t\t\n" "${time}" >> ${HTML_LOG} + printf "\t\t\n" ${PASSED} >> ${HTML_LOG} + printf "\t\n" >> ${HTML_LOG} + + printf "\t\n" >> ${HTML_LOG} + time=`print_time ${total_failed}` + printf "\t\t\n" >> ${HTML_LOG} + printf "\t\t\n" "${time}" >> ${HTML_LOG} + printf "\t\t\n" ${FAILED} >> ${HTML_LOG} + printf "\t\n" >> ${HTML_LOG} + + printf "\t\n" >> ${HTML_LOG} + time=`print_time ${total_not_run}` + printf "\t\t\n" >> ${HTML_LOG} + printf "\t\t\n" "${time}" >> ${HTML_LOG} + printf "\t\t\n" ${NOT_RUN} >> ${HTML_LOG} + printf "\t\n" >> ${HTML_LOG} + + printf "\t\n" >> ${HTML_LOG} + time=`print_time $((total_passed+total_failed+total_not_run))` + printf "\t\t\n" >> ${HTML_LOG} + printf "\t\t\n" "${time}" >> ${HTML_LOG} + printf "\t\t\n" ${TESTS} >> ${HTML_LOG} + printf "\t\n" >> ${HTML_LOG} + + printf "
NameTimeNumber
Passed%s%d
Failed%s%d
Not run%s%d
Total%s%d
\n" >> ${HTML_LOG} + + printf "

Detailed execution with order

\n" >> ${HTML_LOG} + + printf "
\n" >> ${HTML_LOG}
+    cat ${EXEC_LOG} >> ${HTML_LOG}
+    rm -f ${EXEC_LOG}
+    printf "
\n" >> ${HTML_LOG} + + printf "
\n" >> ${HTML_LOG} + + printf "More details in %s\n" ${LOGS_FOLDER} >> ${HTML_LOG} + + cp ${HTML_LOG} ${LOGS_FOLDER}/results.html + rm -f ${HTML_LOG} ${HTML_PASSED_LOG} ${HTML_FAILED_LOG} ${HTML_NOT_RUN_LOG} +} + +add_header() { + echo "" >> $1 + echo "--- ${2} tests ---" >> $1 + printf "%-16s %-10s %-80s %20s %10s\n" "Test group" "Name" "Test description" "Exec time" "Result" >> $1 + for I in {0..139}; do + echo -n '-' >> $1 + done + echo "" >> $1 +} + +sum_up_and_exit() { + TMP_PASSED="/tmp/cas_passed.txt" + TMP_FAILED="/tmp/cas_failed.txt" + TMP_NOT_RUN="/tmp/cas_not_run.txt" + + rm -f ${TMP_PASSED} ${TMP_FAILED} ${TMP_NOT_RUN} + touch ${TMP_PASSED} ${TMP_FAILED} ${TMP_NOT_RUN} + + add_header ${TMP_PASSED} "PASSED" + add_header ${TMP_FAILED} "FAILED" + add_header ${TMP_NOT_RUN} "NOT_RUN" + + total_passed=0 + total_failed=0 + total_not_run=0 + + for ((I = 0; I < $TESTS; I++)) ; do + if [ "${TEST_RESULTS[$I]}" == "Passed" ]; then + file=${TMP_PASSED} + total_passed=$((${total_passed}+${TEST_TIMES[I]})) + elif [ "${TEST_RESULTS[$I]}" == "Failed" ]; then + file=${TMP_FAILED} + total_failed=$((${total_failed}+${TEST_TIMES[$I]})) + else + file=${TMP_NOT_RUN} + total_not_run=$((${total_not_run}+${TEST_TIMES[$I]})) + fi + printf "%-16s %-10s %-80s %20s %10s\n" "${TEST_CATEGORIES[$I]}" "${TEST_NAMES[$I]}" "${TEST_DESCRIPTIONS[$I]}" "`print_time ${TEST_TIMES[$I]}`" "${TEST_RESULTS[$I]}" >> ${file} + done + + if [ ${PASSED} -gt 0 ]; then + cat ${TMP_PASSED} + fi + + if [ ${FAILED} -gt 0 ]; then + cat ${TMP_FAILED} + fi + + if [ ${NOT_RUN} -gt 0 ]; then + cat ${TMP_NOT_RUN} + fi + + rm -f ${TMP_PASSED} ${TMP_FAILED} ${TMP_NOT_RUN} + + echo "" + time=`print_time $((total_passed+total_failed))` + tests_no=`printf "%3d" $TESTS` + echo "Tests number: ${tests_no} ${time}" + + tests_no=`printf "%3d" $PASSED` + echo_green_n "Passed: ${tests_no} " + print_time ${total_passed} + echo "" + + tests_no=`printf "%3d" $FAILED` + echo_red_n "Failed: ${tests_no} " + print_time ${total_failed} + echo "" + + tests_no=`printf "%3d" $NOT_RUN` + echo_yellow_n "Not run: ${tests_no} " + print_time ${total_not_run} + echo "" + echo "" + + echo "More details in $LOGS_FOLDER" + export_results_to_html + if [ $PASSED == $TESTS ] ; then + exit 0 + else + exit 1 + fi +} + +############################################################ +# MAIN # +############################################################ + +BVT_TEST_HEADER="# USE_IN_BVT" +NIGHTLY_TEST_HEADER="# USE_IN_NIGHTLY" +ATOMIC_TEST_HEADER="# USE_IN_ATOMIC" +TEST_FILE_PATTERN="[0-9*]*" +TEST_MODE="" +TEST_FILES="" +TEST_NAMES="" +TEST_DESCRIPTIONS="" +TEST_RESULTS="" + +TESTS_DIR="$(dirname $0)" +. $TESTS_DIR/cas_lib + +if [ $# -eq 0 ] ; then + usage + exit 1 +fi + +load_cas_lib +parse_args $* +check_config +set_categories + +case $TEST_MODE in + "all" | "dir" ) + for CATEGORY in $CATEGORIES ; do + TEST_FILES="$(find $CATEGORY -type f -name "$TEST_FILE_PATTERN" | sort) $TEST_FILES" + done + ;; + "sanity" ) + TEST_FILES=$(find $TESTS_DIR/sandbox -type f -name "$TEST_FILE_PATTERN" | sort) + ;; + "bvt" ) + for CATEGORY in $CATEGORIES ; do + TEST_FILES="$TEST_FILES $(find $CATEGORY -type f -name "$TEST_FILE_PATTERN" | xargs grep -l "$BVT_TEST_HEADER" | sort)" + done + ;; + "nightly" ) + for CATEGORY in $CATEGORIES ; do + TEST_FILES="$TEST_FILES $(find $CATEGORY -type f -name "$TEST_FILE_PATTERN" | xargs grep -l "$NIGHTLY_TEST_HEADER" | sort)" + done + ;; + * ) + echo "Unsupported test mode $TEST_MODE" + exit 1 +esac + +export LOGS_FOLDER="${LOGS_FOLDER}/${TEST_MODE}_$(date +%Y-%m-%d_%H:%M:%S)/" + +echo "--- Starting test mode $TEST_MODE ---" +echo "" + +rm -f ${EXEC_LOG} +touch ${EXEC_LOG} +for TEST in $TEST_FILES ; do + logger "[CAS][DVT] ~~~ $TEST ~~~ [START]" &>/dev/null + run_test $TEST + logger "[CAS][DVT] ~~~ $TEST ~~~ [END]" &>/dev/null +done + +sum_up_and_exit | tee -a $LOGS_FOLDER/$RESULT_FILE +exec_result=${PIPESTATUS[0]} + +rm -f ${EXEC_LOG} + +exit ${exec_result}