diff options
Diffstat (limited to 'tests/test_forwarder.sh')
-rw-r--r-- | tests/test_forwarder.sh | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/tests/test_forwarder.sh b/tests/test_forwarder.sh new file mode 100644 index 000000000..aba85d8d8 --- /dev/null +++ b/tests/test_forwarder.sh @@ -0,0 +1,437 @@ +#!/bin/bash + +############################################################################ +# CONSTANTS +############################################################################ +INTERFACE_CMD="ip route get 1 | grep -Po '(?<=(dev )).*(?= src| proto)'" +ADDRESS_CMD="ip route get 1 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}'" +CTRL_CMD="docker exec test-hicn \ + /hicn-build/build/build-root/bin/hicn-light-control" +PING_SERVER_CMD="docker exec -d test-hicn \ + /hicn-build/build/build-root/bin/hicn-ping-server \ + -z hicnlightng_module" +PING_CLIENT_CMD="docker exec test-hicn \ + /hicn-build/build/build-root/bin/hicn-ping-client \ + -z hicnlightng_module" +PING_CLIENT_DETACHED_CMD="docker exec -d test-hicn \ + /hicn-build/build/build-root/bin/hicn-ping-client \ + -z hicnlightng_module" +LISTENER_NAME="udp0" +CONN_NAME="conn0" +PREFIX="c001::/64" +COST=1 +FIVE_SECONDS=5000 + +############################################################################ +# UTILS +############################################################################ +set_up() { + docker build -t hicn-dev . + run_forwarder +} + +tear_down() { + docker stop --time 0 test-hicn +} + +get_address() { + echo $(docker exec test-hicn sh -c "${ADDRESS_CMD}") +} + +get_interface() { + echo $(docker exec test-hicn sh -c "${INTERFACE_CMD}") +} + +#--------------------------------------------------------------------------- +# Exec +#--------------------------------------------------------------------------- +run_forwarder() { + capacity=${1:-"100000"} + loglevel=${2:-"trace"} + config=${3:-""} + + config_file_arg="" + if [[ $config != "" ]]; then + config_file_arg="--config ${config}" + fi + + docker run --rm -d --name test-hicn \ + -v $(pwd)/..:/hicn-build \ + -e LD_LIBRARY_PATH=/hicn-build/build/build-root/lib \ + hicn-dev \ + /hicn-build/build/build-root/bin/hicn-light-daemon \ + --log ${loglevel} --capacity ${capacity} $config_file_arg +} + +exec_controller() { + command=$1 + + # Redirect stderr to stdout + output=$(${CTRL_CMD} ${command} 2>&1) + assert_exit_code + echo ${output} +} + +exec_ping_server() { + data_lifetime=${1:-""} + + lifetime_arg="" + if [[ $data_lifetime != "" ]]; then + lifetime_arg="-l ${data_lifetime}" + fi + + ${PING_SERVER_CMD} ${lifetime_arg} +} + +exec_ping_client() { + num_packets=$1 + + output=$(${PING_CLIENT_CMD} -m ${num_packets}) + assert_exit_code + echo ${output} +} + +exec_ping_client_detached() { + num_packets=$1 + interest_lifetime=$2 + + ${PING_CLIENT_DETACHED_CMD} -m ${num_packets} -l ${interest_lifetime} +} + +#--------------------------------------------------------------------------- +# Asserts +#--------------------------------------------------------------------------- +assert_exit_code() { + if [[ $? -ne 0 ]]; then + exit_with_failure + fi +} + +assert_forwarder() { + # Print forwarder logs for debug info + echo "******** Forwarder Logs ********" + docker logs test-hicn + echo "********************************" + + output=$(docker logs test-hicn) + if [[ $output == "" ]]; then + exit_with_failure + fi + + if [[ "${output}" == *"ERROR"* ]]; then + exit_with_failure + fi + + if [[ "${output}" == *"Aborted (core dumped)"* ]]; then + exit_with_failure + fi +} + +assert_ack() { + # Print controller logs for debug info + echo "******** Controller Logs ********" + echo $1 + echo "********************************" + + output=$1 + + if [[ "$output" == *"Error"* ]]; then + exit_with_failure + fi +} + +assert_nack() { + # Print controller logs for debug info + echo "******** Controller Logs ********" + echo $1 + echo "********************************" + + output=$1 + + if [[ "$output" != *"Error"* ]]; then + exit_with_failure + fi +} + +assert_ping_client() { + # Print ping client logs for debug info + echo "******** Ping Client Logs ********" + echo $1 + echo "********************************" + + ping_client_output=$1 + pkts_sent=$2 + pkts_recv=$3 + pkts_timeout=$4 + + match_str="Sent: ${pkts_sent} Received: ${pkts_recv} Timeouts: ${pkts_timeout}" + if [[ ! ${ping_client_output} == *"${match_str}"* ]]; then + exit_with_failure + fi +} + +assert_forwarder_stats() { + satisfied_from_cs=${1:-""} + no_route_in_fib=${2:-""} + aggregated=${3:-""} + + fwder_stats=$(docker logs test-hicn | grep "Forwarder: received" | tail -n 1) + + if [[ $satisfied_from_cs != "" && + "${fwder_stats}" != *"satisfied_from_cs = ${satisfied_from_cs}"* ]]; then + exit_with_failure + fi + + if [[ $no_route_in_fib != "" && + "${fwder_stats}" != *"no_route_in_fib = ${no_route_in_fib}"* ]]; then + exit_with_failure + fi + + if [[ $aggregated != "" && + "${fwder_stats}" != *"aggregated = ${aggregated}"* ]]; then + exit_with_failure + fi +} + +assert_pkt_cache_stats() { + total_size=${1:-""} + pit_size=${2:-""} + cs_size=${3:-""} + + pkt_cache_stats=$(docker logs test-hicn | grep "Packet cache:" | tail -n 1) + + if [[ $total_size != "" && + "${pkt_cache_stats}" != *"total size = ${total_size}"* ]]; then + exit_with_failure + fi + + if [[ $pit_size != "" && + "${pkt_cache_stats}" != *"PIT size = ${pit_size}"* ]]; then + exit_with_failure + fi + + if [[ $cs_size != "" && + "${pkt_cache_stats}" != *"CS size = ${cs_size}"* ]]; then + exit_with_failure + fi +} + +assert_cs_stats() { + evictions=${1:-""} + + cs_stats=$(docker logs test-hicn | grep "Content store:" | tail -n 1) + + if [[ $evictions != "" && + "${cs_stats}" != *"evictions = ${evictions}"* ]]; then + exit_with_failure + fi +} + +############################################################################ +# TEST SUITE +############################################################################ + +#--------------------------------------------------------------------------- +# Commands +#--------------------------------------------------------------------------- +test_add_listener() { + # Exec hicn-light-control command and capture its output + INTERFACE=$(get_interface) + ADDRESS=$(get_address) + command="add listener udp ${LISTENER_NAME} ${ADDRESS} 9695 ${INTERFACE}" + ctrl_output=$(exec_controller "${command}") + + # Check hicn-light-control and hicn-light-daemon outputs + assert_ack "$ctrl_output" + assert_forwarder +} + +test_remove_listener() { + INTERFACE=$(get_interface) + ADDRESS=$(get_address) + command="add listener udp ${LISTENER_NAME} ${ADDRESS} 9695 ${INTERFACE}" + ctrl_output=$(exec_controller "${command}") + assert_ack "$ctrl_output" + + command="remove listener udp0" + ctrl_output=$(exec_controller "${command}") + + assert_ack "$ctrl_output" + assert_forwarder +} + +test_remove_non_existing_listener() { + command="remove listener udp0" + ctrl_output=$(exec_controller "${command}") + + assert_nack "$ctrl_output" + assert_forwarder +} + +test_add_duplicated_listener() { + # Exec hicn-light-control command and capture its output + INTERFACE=$(get_interface) + ADDRESS=$(get_address) + command="add listener udp ${LISTENER_NAME} ${ADDRESS} 9695 ${INTERFACE}" + exec_controller "${command}" + ctrl_output=$(exec_controller "${command}") + + # Check hicn-light-control and hicn-light-daemon outputs + assert_nack "$ctrl_output" + assert_forwarder +} + +test_list_listeners() { + # Exec hicn-light-control command and capture its output + command="list listener" + ctrl_output=$(exec_controller "${command}") + + # Check hicn-light-control and hicn-light-daemon outputs + assert_forwarder + # Only the local listener should be present + [[ "${ctrl_output}" =~ "inet4://127.0.0.1:9695" ]] && return 0 || exit_with_failure +} + +test_commands_from_config() { + # Create config file + INTERFACE=$(get_interface) + ADDRESS=$(get_address) + echo "# Teset config file + add listener udp $LISTENER_NAME $ADDRESS 9695 ${INTERFACE} + add connection udp $CONN_NAME $ADDRESS 12345 $ADDRESS 9695 ${INTERFACE} + add route $CONN_NAME $PREFIX $COST + set strategy c001::/64 random + " >forwarder.conf + + # Restart the forwarder specifying the config file + tear_down + run_forwarder "" "" "/hicn-build/tests/forwarder.conf" + rm forwarder.conf + + # Check for errors in the output + assert_forwarder +} + +#--------------------------------------------------------------------------- +# Ping +#--------------------------------------------------------------------------- +test_ping_one_packet() { + # Exec hicn-ping-server + exec_ping_server + # Exec hicn-ping-client (w/ 1 packet) and capture its output + output=$(exec_ping_client 1) + + # Check hicn-ping-client (1 pkt sent, 1 pkt received, 0 timeouts) + # and hicn-light-daemon outputs + assert_ping_client "${output}" 1 1 0 + assert_forwarder +} + +test_ping_two_packets() { + exec_ping_server + output=$(exec_ping_client 2) + + assert_ping_client "${output}" 2 2 0 + assert_forwarder +} + +test_ping_using_cs() { + exec_ping_server + exec_ping_client 2 + output=$(exec_ping_client 1) + + assert_ping_client "${output}" 1 1 0 + assert_forwarder + assert_forwarder_stats 1 +} + +test_ping_using_cs_different_order() { + exec_ping_server + exec_ping_client 1 + output=$(exec_ping_client 2) + + assert_ping_client "${output}" 2 2 0 + assert_forwarder + assert_forwarder_stats 1 +} + +test_ping_timeout() { + # Send ping without the ping server being run + output=$(exec_ping_client 1) + + assert_ping_client "${output}" 1 0 1 + assert_forwarder + assert_forwarder_stats 0 1 +} + +test_ping_aggregation() { + # Send ping without server, waiting for a reply + exec_ping_client_detached 1 ${FIVE_SECONDS} + exec_ping_server + # This new ping interest will be aggregated with the previous one + # and the forwarder will reply to both ping clients + output=$(exec_ping_client 1) + + assert_ping_client "${output}" 1 1 0 + assert_forwarder + assert_forwarder_stats "" "" 1 +} + +test_ping_with_cs_store_disabled() { + command="store cache off" + exec_controller "${command}" + + exec_ping_server + exec_ping_client 1 + output=$(exec_ping_client 1) + + assert_ping_client "${output}" 1 1 0 + assert_forwarder + assert_forwarder_stats 0 "" "" + # The packet is not stored in the CS + assert_pkt_cache_stats "" "" 0 +} + +test_ping_with_cs_serve_disabled() { + command="serve cache off" + exec_controller "${command}" + + exec_ping_server + exec_ping_client 1 + output=$(exec_ping_client 1) + + assert_ping_client "${output}" 1 1 0 + assert_forwarder + assert_forwarder_stats 0 "" "" + # The packet is stored in the CS, but CS is not used + assert_pkt_cache_stats "" "" 1 +} + +test_ping_with_eviction() { + # Restart the forwarder with CS capacity = 1 + tear_down + run_forwarder 1 + + exec_ping_server + exec_ping_client 1 + output=$(exec_ping_client 2) + + assert_ping_client "${output}" 2 2 0 + assert_forwarder + # Check if eviction happened + assert_cs_stats 1 + assert_pkt_cache_stats "" "" 1 +} + +test_ping_with_zero_data_lifetime() { + exec_ping_server 0 + exec_ping_client 1 + output=$(exec_ping_client 1) + + assert_ping_client "${output}" 1 1 0 + assert_forwarder + # The data is not taken from the CS because expired + assert_forwarder_stats 0 "" "" +} + +"$@" |