diff --git a/tests/console/redis.pm b/tests/console/redis.pm index 172d29778be6..9d79e239065e 100644 --- a/tests/console/redis.pm +++ b/tests/console/redis.pm @@ -20,65 +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); -sub run { - my $self = shift; - select_serial_terminal; +my $default_redis_version = "redis"; +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"; - # install redis package - zypper_call 'in redis'; - assert_script_run('redis-server --version'); +sub test_ping { + my (%args) = @_; + $args{port} //= $default_redis_port; + my $redis_cli_cmd = "redis-cli -p $args{port}"; - # start redis server on port 6379 and test that it works - assert_script_run('redis-server --daemonize yes --logfile /var/log/redis/redis-server_6379.log'); - script_retry('redis-cli ping', delay => 5, retry => 12); - validate_script_output_retry('redis-cli ping', sub { m/PONG/ }, delay => 5, retry => 12); + 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); +} + +sub test_crud { + my (%args) = @_; + $args{port} //= $default_redis_port; + my $redis_cli_cmd = "redis-cli -p $args{port}"; - # test some redis cli commands - validate_script_output('redis-cli set foo bar', sub { m/OK/ }); - validate_script_output('redis-cli get foo', sub { m/bar/ }); - validate_script_output('redis-cli pfselftest', sub { m/OK/ }); - validate_script_output('redis-cli flushdb', sub { m/OK/ }); - validate_script_output('redis-cli get foo', sub { !m/bar/ }); + # 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/ }); +} +sub load_test_db_and_validate { + my (%args) = @_; + $args{port} //= $default_redis_port; + my $redis_cli_cmd = "redis-cli -p $args{port}"; + + # Load test DB and validate data assert_script_run 'curl -O ' . data_url('console/movies.redis'); - assert_script_run('redis-cli -h localhost -p 6379 < ./movies.redis'); + assert_script_run("$redis_cli_cmd < ./movies.redis"); + validate_script_output("$redis_cli_cmd 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}"; + + # 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); +} + +sub configure_and_test_master { + my (%args) = @_; + $args{port} //= $default_redis_port; + + test_ping(port => $args{port}); + test_crud(port => $args{port}); + load_test_db_and_validate(port => $args{port}); +} + +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}"; + + test_ping(port => $args{replica_port}); + + # Configure replication + assert_script_run("$redis_replica_cli_cmd replicaof localhost $args{port}"); + + 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 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; - # start redis server on port 6380 and test that it works - assert_script_run('redis-server --daemonize yes --port 6380 --logfile /var/log/redis/redis-server_6380.log'); - validate_script_output_retry('redis-cli -p 6380 ping', sub { m/PONG/ }, delay => 5, retry => 12); + my $redis_cli_cmd_prefix = "redis-cli -p "; + my $redis_cli_cmd_postfix = " flushall"; - # make 6380 instance a replica of redis instance running on port 6379 - assert_script_run('redis-cli -p 6380 replicaof localhost 6379'); + 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; - # test master knows about the slave and vice versa - validate_script_output_retry('redis-cli info replication', sub { m/connected_slaves:1/ }, delay => 5, retry => 12); - validate_script_output('redis-cli -p 6380 info replication', sub { m/role:slave/ }); + # Clean up after testing + assert_script_run($redis_cli_cmd); + assert_script_run($redis_replica_cli_cmd); - # test that the synchronization finished and the data are reachable from slave - validate_script_output_retry('redis-cli info replication', sub { m/state=online/ }, delay => 5, retry => 12); - validate_script_output('redis-cli -p 6380 HMGET "movie:343" title', sub { m/Spider-Man/ }); + assert_script_run($killall_redis_server_cmd); + assert_script_run($remove_test_db_file_cmd); + zypper_call('rm -u ' . $args{redis_version}); +} + +sub test_redis { + my (%args) = @_; + $args{redis_version} //= $default_redis_version; + $args{port} //= $default_redis_port; + $args{replica_port} //= $default_redis_replica_port; + + zypper_call('in --force-resolution --solver-focus Update ' . $args{redis_version}); + + my ($version) = script_output('redis-server --version') =~ (/v=(.+?)\s/)[0] || ""; + + record_info("Testing " . $version); + + my $logfile_prefix = "/var/log/redis/redis-server_${version}_"; + my $logfile_postfix = ".log"; + my $logfile = $logfile_prefix . $args{port} . $logfile_postfix; + my $replica_logfile = $logfile_prefix . $args{replica_port} . $logfile_postfix; + + 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 the primary redis server + assert_script_run($redis_server_cmd); + configure_and_test_master(port => $args{port}); + + + # Start the replica redis server + assert_script_run($redis_server_replica_cmd); + configure_and_test_replica(port => $args{port}, replica_port => $args{replica_port}); + + cleanup_redis(redis_version => $args{redis_version}, port => $args{port}, replica_port => $args{replica_port}); + + # Upload logs + upload_logs($logfile) if -e $logfile; + upload_logs($replica_logfile) if -e $replica_logfile; +} + +sub run { + my $self = shift; + select_serial_terminal; + + my @redis_versions = ($default_redis_version, "redis7"); + + foreach my $redis_version (@redis_versions) { + test_redis(redis_version => $redis_version); + } } sub post_fail_hook { my $self = shift; - $self->cleanup(); + 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); $self->SUPER::post_fail_hook; } sub post_run_hook { my $self = shift; - $self->cleanup(); $self->SUPER::post_run_hook; } -sub cleanup { - upload_logs('/var/log/redis/redis-server_6379.log'); - upload_logs('/var/log/redis/redis-server_6380.log'); - assert_script_run('redis-cli -h localhost flushall'); - assert_script_run('killall redis-server'); - assert_script_run('rm -f movies.redis'); -} - 1;