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%s | \n" "Test file name" >> ${1}
+ printf "\t\t%s | \n" "Test description" >> ${1}
+ printf "\t\t%s | \n" "Exec time" >> ${1}
+ printf "\t\t%s | \n" "Result" >> ${1}
+ printf "\t
\n" >> ${1}
+}
+
+stop_table() {
+ printf "
\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\tName | \n" >> ${HTML_LOG}
+ printf "\t\tTime | \n" >> ${HTML_LOG}
+ printf "\tNumber | \n" >> ${HTML_LOG}
+ printf "\t
\n" >> ${HTML_LOG}
+
+ printf "\t\n" >> ${HTML_LOG}
+ time=`print_time ${total_passed}`
+ printf "\t\tPassed | \n" >> ${HTML_LOG}
+ printf "\t\t%s | \n" "${time}" >> ${HTML_LOG}
+ printf "\t\t%d | \n" ${PASSED} >> ${HTML_LOG}
+ printf "\t
\n" >> ${HTML_LOG}
+
+ printf "\t\n" >> ${HTML_LOG}
+ time=`print_time ${total_failed}`
+ printf "\t\tFailed | \n" >> ${HTML_LOG}
+ printf "\t\t%s | \n" "${time}" >> ${HTML_LOG}
+ printf "\t\t%d | \n" ${FAILED} >> ${HTML_LOG}
+ printf "\t
\n" >> ${HTML_LOG}
+
+ printf "\t\n" >> ${HTML_LOG}
+ time=`print_time ${total_not_run}`
+ printf "\t\tNot run | \n" >> ${HTML_LOG}
+ printf "\t\t%s | \n" "${time}" >> ${HTML_LOG}
+ printf "\t\t%d | \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\tTotal | \n" >> ${HTML_LOG}
+ printf "\t\t%s | \n" "${time}" >> ${HTML_LOG}
+ printf "\t\t%d | \n" ${TESTS} >> ${HTML_LOG}
+ printf "\t
\n" >> ${HTML_LOG}
+
+ printf "
\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}