diff --git a/tests/console/redis.pm b/tests/console/redis.pm index cd9d78faea5b..a746c87463d6 100644 --- a/tests/console/redis.pm +++ b/tests/console/redis.pm @@ -20,196 +20,166 @@ use serial_terminal 'select_serial_terminal'; use utils qw(zypper_call script_retry validate_script_output_retry); use registration qw(add_suseconnect_product get_addon_fullname); -my $default_redis_version = "redis"; -my @redis_versions = ($default_redis_version, "redis7"); -my $default_redis_port = "6379"; -my $default_redis_replica_port = "6380"; -my $killall_redis_server_cmd = "killall redis-server"; -my $remove_test_db_file_cmd = "rm -f movies.redis"; - -sub get_redis_version { - my $output = script_output('redis-server --version'); - my $version = ""; - - if ($output =~ /v=(.+?)\s/) { - $version = $1; # Capture the first match +my @redis_versions = ("redis", "redis7"); + +my %ROLES = ( + MASTER => 'MASTER', + REPLICA => 'REPLICA', +); + +# Dynamically generate ports starting at 6379 +my $base_port = 6379; +my %PORTS = map { $ROLES{$_} => $base_port++ } keys %ROLES; + +my %REDIS_CLI_CMD = map { + $_ => "redis-cli -p " . $PORTS{$ROLES{$_}} +} keys %ROLES; + +my $logfile_prefix = "/var/log/redis/redis-server_"; +my $logfile_postfix = ".log"; +# Build a mapping of log file locations +my %logfile_locations = map { + my $version = $_; # Capture the Redis version + $version => { + map { + $ROLES{$_} => $logfile_prefix . $version . "_${\lc($ROLES{$_})}" . $logfile_postfix + } keys %ROLES } +} @redis_versions; - die "Failed to extract Redis version!" if $version eq ""; - - return $version; -} +my $killall_redis_server_cmd = "killall redis-server"; +my $remove_test_db_file_cmd = "rm -f movies.redis"; sub test_ping { my (%args) = @_; - $args{port} //= $default_redis_port; - my $redis_cli_cmd = "redis-cli -p $args{port}"; + $args{target} //= $ROLES{MASTER}; + record_info("Test ping to target: " . $args{target}); + die("Invalid target: " . $args{target}) unless exists $REDIS_CLI_CMD{$args{target}}; + + my $cmd = $REDIS_CLI_CMD{$args{target}}; - script_retry("$redis_cli_cmd ping", delay => 5, retry => 12); - validate_script_output_retry("$redis_cli_cmd ping", sub { m/PONG/ }, delay => 5, retry => 12); + script_retry("$cmd ping", delay => 5, retry => 12); + validate_script_output_retry("$cmd ping", sub { m/PONG/ }, delay => 5, retry => 12); } sub test_crud { - my (%args) = @_; - $args{port} //= $default_redis_port; - my $redis_cli_cmd = "redis-cli -p $args{port}"; + record_info("Test Create Read Update Delete"); # Perform CRUD operations - validate_script_output("$redis_cli_cmd set foo bar", sub { m/OK/ }); - validate_script_output("$redis_cli_cmd get foo", sub { m/bar/ }); - validate_script_output("$redis_cli_cmd pfselftest", sub { m/OK/ }); - validate_script_output("$redis_cli_cmd flushdb", sub { m/OK/ }); - validate_script_output("$redis_cli_cmd get foo", sub { !m/bar/ }); + validate_script_output($REDIS_CLI_CMD{$ROLES{MASTER}} . " set foo bar", sub { m/OK/ }); + validate_script_output($REDIS_CLI_CMD{$ROLES{MASTER}} . " get foo", sub { m/bar/ }); + validate_script_output($REDIS_CLI_CMD{$ROLES{MASTER}} . " pfselftest", sub { m/OK/ }); + validate_script_output($REDIS_CLI_CMD{$ROLES{MASTER}} . " flushdb", sub { m/OK/ }); + validate_script_output($REDIS_CLI_CMD{$ROLES{MASTER}} . " get foo", sub { !m/bar/ }); } sub load_test_db_and_validate { - my (%args) = @_; - $args{port} //= $default_redis_port; - my $redis_cli_cmd = "redis-cli -p $args{port}"; + record_info("Load test database and validate data"); # Load test DB and validate data assert_script_run 'curl -O ' . data_url('console/movies.redis'); - assert_script_run("$redis_cli_cmd < ./movies.redis"); - validate_script_output("$redis_cli_cmd HMGET \"movie:343\" title", sub { m/Spider-Man/ }); + assert_script_run($REDIS_CLI_CMD{$ROLES{MASTER}} . " < ./movies.redis"); + validate_script_output($REDIS_CLI_CMD{$ROLES{MASTER}} . " HMGET \"movie:343\" title", sub { m/Spider-Man/ }); } sub verify_replication_status { - my (%args) = @_; - $args{port} //= $default_redis_port; - $args{replica_port} //= $default_redis_replica_port; - - my $redis_cli_cmd = "redis-cli -p $args{port}"; - my $redis_replica_cli_cmd = "redis-cli -p $args{replica_port}"; + record_info("Verify replication status"); # Verify replication status - validate_script_output_retry("$redis_cli_cmd info replication", sub { m/connected_slaves:1/ }, delay => 5, retry => 12); - validate_script_output("$redis_replica_cli_cmd info replication", sub { m/role:slave/ }); - validate_script_output_retry("$redis_replica_cli_cmd info replication", sub { m/master_link_status:up/ }, delay => 5, retry => 12); + validate_script_output_retry($REDIS_CLI_CMD{$ROLES{MASTER}} . " info replication", sub { m/connected_slaves:1/ }, delay => 5, retry => 12); + validate_script_output($REDIS_CLI_CMD{$ROLES{REPLICA}} . " info replication", sub { m/role:slave/ }); + validate_script_output_retry($REDIS_CLI_CMD{$ROLES{REPLICA}} . " info replication", sub { m/master_link_status:up/ }, delay => 5, retry => 12); } sub configure_and_test_master { - my (%args) = @_; - $args{port} //= $default_redis_port; + record_info("Configure and test master"); - test_ping(port => $args{port}); - test_crud(port => $args{port}); - load_test_db_and_validate(port => $args{port}); + test_ping(target => $ROLES{MASTER}); + test_crud(); + load_test_db_and_validate(); } sub configure_and_test_replica { - my (%args) = @_; - $args{port} //= $default_redis_port; - $args{replica_port} //= $default_redis_replica_port; - - my $redis_replica_cli_cmd = "redis-cli -p $args{replica_port}"; + record_info("Configure and test replica"); - test_ping(port => $args{replica_port}); + test_ping(target => $ROLES{REPLICA}); # Configure replication - assert_script_run("$redis_replica_cli_cmd replicaof localhost $args{port}"); + assert_script_run($REDIS_CLI_CMD{$ROLES{REPLICA}} . " replicaof localhost " . $PORTS{$ROLES{MASTER}}); verify_replication_status(); # Validate data from the replica - validate_script_output("$redis_replica_cli_cmd HMGET \"movie:343\" title", sub { m/Spider-Man/ }); + validate_script_output($REDIS_CLI_CMD{$ROLES{REPLICA}} . " HMGET \"movie:343\" title", sub { m/Spider-Man/ }); } sub cleanup_redis { - my (%args) = @_; - $args{redis_version} //= $default_redis_version; - $args{port} //= $default_redis_port; - $args{replica_port} //= $default_redis_replica_port; - - my $redis_cli_cmd_prefix = "redis-cli -p "; - my $redis_cli_cmd_postfix = " flushall"; - - my $redis_cli_cmd = $redis_cli_cmd_prefix . $args{port} . $redis_cli_cmd_postfix; - my $redis_replica_cli_cmd = $redis_cli_cmd_prefix . $args{replica_port} . $redis_cli_cmd_postfix; + record_info("Cleanup after testing"); # Clean up after testing - assert_script_run($redis_cli_cmd); - assert_script_run($redis_replica_cli_cmd); + foreach my $role (values %ROLES) { + assert_script_run($REDIS_CLI_CMD{$role} . " flushall"); + } assert_script_run($killall_redis_server_cmd); assert_script_run($remove_test_db_file_cmd); assert_script_run("find / -type f -name 'dump.rdb' -print -exec rm -f {} + || true"); } -sub log_location { - my (%args) = @_; - $args{redis_version} //= $default_redis_version; - $args{port} //= $default_redis_port; - my $logfile_prefix = "/var/log/redis/redis-server_" . $args{redis_version} . "_"; - my $logfile_postfix = ".log"; - - return $logfile_prefix . $args{port} . $logfile_postfix; -} - sub upload_redis_logs { my (%args) = @_; - $args{redis_version} //= $default_redis_version; - $args{port} //= $default_redis_port; - $args{replica_port} //= $default_redis_replica_port; - - my $logfile = log_location(redis_version => $args{redis_version}, port => $args{port}); - my $replica_logfile = log_location(redis_version => $args{redis_version}, port => $args{replica_port}); - - # Upload logs - upload_logs($logfile) if -e $logfile; - upload_logs($replica_logfile) if -e $replica_logfile; -} - -sub print_redis_logs { - my (%args) = @_; - $args{redis_version} //= $default_redis_version; - $args{port} //= $default_redis_port; - $args{replica_port} //= $default_redis_replica_port; - - my $logfile = log_location(redis_version => $args{redis_version}, port => $args{port}); - my $replica_logfile = log_location(redis_version => $args{redis_version}, port => $args{replica_port}); + $args{redis_version} //= $redis_versions[0]; # Default to the first Redis version + record_info("Upload logs for " . $args{redis_version}); - # Print logs - record_info("Redis version " . $args{redis_version}, script_output("cat " . $logfile)); - record_info("Redis version " . $args{redis_version}, script_output("cat " . $replica_logfile)); + # Iterate through roles and upload logs if they exist + foreach my $role (values %ROLES) { + my $logfile = $logfile_locations{$args{redis_version}}{$role}; + upload_logs($logfile) if -e $logfile; + } } sub test_redis { my (%args) = @_; - $args{redis_version} //= $default_redis_version; - $args{port} //= $default_redis_port; - $args{replica_port} //= $default_redis_replica_port; + $args{redis_version} //= $redis_versions[0]; # Default to the first Redis version + # Install the Redis package zypper_call('in --force-resolution --solver-focus Update ' . $args{redis_version}); - my $version = get_redis_version(); - - record_info("Testing " . $args{redis_version} . " v=" . $version); - - my $logfile = log_location(redis_version => $args{redis_version}, port => $args{port}); - my $replica_logfile = log_location(redis_version => $args{redis_version}, port => $args{replica_port}); + # Get the installed Redis version + record_info("Testing " . $args{redis_version}); - my $redis_server_cmd_prefix = "redis-server --daemonize yes --port "; - my $redis_server_cmd = $redis_server_cmd_prefix . $args{port} . " --logfile " . $logfile; - my $redis_server_replica_cmd = $redis_server_cmd_prefix . $args{replica_port} . " --logfile " . $replica_logfile; + # Start Redis servers for each role + foreach my $role (values %ROLES) { + my $port = $PORTS{$role}; + my $logfile = $logfile_locations{$args{redis_version}}{$role}; + my $redis_server_cmd = "redis-server --daemonize yes --port $port --logfile $logfile"; - # Start the primary redis server - assert_script_run($redis_server_cmd); - configure_and_test_master(port => $args{port}); + assert_script_run($redis_server_cmd); # Start the Redis server for this role + } + # Configure and test the master + configure_and_test_master(); - # Start the replica redis server - assert_script_run($redis_server_replica_cmd); - configure_and_test_replica(port => $args{port}, replica_port => $args{replica_port}); + # Configure and test the replica + configure_and_test_replica(); - cleanup_redis(redis_version => $args{redis_version}, port => $args{port}, replica_port => $args{replica_port}); + # Clean up Redis servers + cleanup_redis(); - upload_redis_logs(redis_version => $args{redis_version}, port => $args{port}, replica_port => $args{replica_port}); + # Upload logs + upload_redis_logs(redis_version => $args{redis_version}); } + sub run { my $self = shift; select_serial_terminal; + record_info("DEBUG", "ROLES: " . join(", ", map { "$_ => $ROLES{$_}" } keys %ROLES)); + record_info("DEBUG", "PORTS: " . join(", ", map { "$_ => $PORTS{$_}" } keys %PORTS)); + record_info("DEBUG", "REDIS_CLI_CMD: " . join(", ", map { "$_ => $REDIS_CLI_CMD{$_}" } keys %REDIS_CLI_CMD)); + + foreach my $redis_version (@redis_versions) { test_redis(redis_version => $redis_version); } @@ -217,14 +187,10 @@ sub run { sub post_fail_hook { my $self = shift; + script_run($killall_redis_server_cmd); + script_run($remove_test_db_file_cmd); foreach my $redis_version (@redis_versions) { - print_redis_logs(redis_version => $redis_version, port => $default_redis_port, replica_port => $default_redis_replica_port); - } - my $proceed_on_fail_cmd = " || true"; - script_run($killall_redis_server_cmd . $proceed_on_fail_cmd); - script_run($remove_test_db_file_cmd . $proceed_on_fail_cmd); - foreach my $redis_version (@redis_versions) { - upload_redis_logs(redis_version => $redis_version, port => $default_redis_port, replica_port => $default_redis_replica_port); + upload_redis_logs(redis_version => $redis_version); } $self->SUPER::post_fail_hook; }