Unverified Commit b08fd9f9 authored by YaacovHazan's avatar YaacovHazan Committed by GitHub
Browse files

Merge unstable into 8.0 (#13622)

parents 30eb6c32 dd20aa51
...@@ -747,7 +747,7 @@ GetFieldRes hashTypeGetValue(redisDb *db, robj *o, sds field, unsigned char **vs ...@@ -747,7 +747,7 @@ GetFieldRes hashTypeGetValue(redisDb *db, robj *o, sds field, unsigned char **vs
} }
if ((server.loading) || if ((server.loading) ||
(server.lazy_expire_disabled) || (server.allow_access_expired) ||
(hfeFlags & HFE_LAZY_AVOID_FIELD_DEL) || (hfeFlags & HFE_LAZY_AVOID_FIELD_DEL) ||
(isPausedActionsWithUpdate(PAUSE_ACTION_EXPIRE))) (isPausedActionsWithUpdate(PAUSE_ACTION_EXPIRE)))
return GETF_EXPIRED; return GETF_EXPIRED;
...@@ -1929,7 +1929,7 @@ static int hashTypeExpireIfNeeded(redisDb *db, robj *o) { ...@@ -1929,7 +1929,7 @@ static int hashTypeExpireIfNeeded(redisDb *db, robj *o) {
/* Follow expireIfNeeded() conditions of when not lazy-expire */ /* Follow expireIfNeeded() conditions of when not lazy-expire */
if ( (server.loading) || if ( (server.loading) ||
(server.lazy_expire_disabled) || (server.allow_access_expired) ||
(server.masterhost) || /* master-client or user-client, don't delete */ (server.masterhost) || /* master-client or user-client, don't delete */
(isPausedActionsWithUpdate(PAUSE_ACTION_EXPIRE))) (isPausedActionsWithUpdate(PAUSE_ACTION_EXPIRE)))
return 0; return 0;
......
...@@ -56,8 +56,11 @@ ...@@ -56,8 +56,11 @@
/* Glob-style pattern matching. */ /* Glob-style pattern matching. */
static int stringmatchlen_impl(const char *pattern, int patternLen, static int stringmatchlen_impl(const char *pattern, int patternLen,
const char *string, int stringLen, int nocase, int *skipLongerMatches) const char *string, int stringLen, int nocase, int *skipLongerMatches, int nesting)
{ {
/* Protection against abusive patterns. */
if (nesting > 1000) return 0;
while(patternLen && stringLen) { while(patternLen && stringLen) {
switch(pattern[0]) { switch(pattern[0]) {
case '*': case '*':
...@@ -69,7 +72,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen, ...@@ -69,7 +72,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen,
return 1; /* match */ return 1; /* match */
while(stringLen) { while(stringLen) {
if (stringmatchlen_impl(pattern+1, patternLen-1, if (stringmatchlen_impl(pattern+1, patternLen-1,
string, stringLen, nocase, skipLongerMatches)) string, stringLen, nocase, skipLongerMatches, nesting+1))
return 1; /* match */ return 1; /* match */
if (*skipLongerMatches) if (*skipLongerMatches)
return 0; /* no match */ return 0; /* no match */
...@@ -191,7 +194,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen, ...@@ -191,7 +194,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen,
int stringmatchlen(const char *pattern, int patternLen, int stringmatchlen(const char *pattern, int patternLen,
const char *string, int stringLen, int nocase) { const char *string, int stringLen, int nocase) {
int skipLongerMatches = 0; int skipLongerMatches = 0;
return stringmatchlen_impl(pattern,patternLen,string,stringLen,nocase,&skipLongerMatches); return stringmatchlen_impl(pattern,patternLen,string,stringLen,nocase,&skipLongerMatches,0);
} }
int stringmatch(const char *pattern, const char *string, int nocase) { int stringmatch(const char *pattern, const char *string, int nocase) {
......
...@@ -6,6 +6,9 @@ if {$::singledb} { ...@@ -6,6 +6,9 @@ if {$::singledb} {
set ::dbnum 9 set ::dbnum 9
} }
file delete ./.rediscli_history_test
set ::env(REDISCLI_HISTFILE) ".rediscli_history_test"
start_server {tags {"cli"}} { start_server {tags {"cli"}} {
proc open_cli {{opts ""} {infile ""}} { proc open_cli {{opts ""} {infile ""}} {
if { $opts == "" } { if { $opts == "" } {
...@@ -68,10 +71,8 @@ start_server {tags {"cli"}} { ...@@ -68,10 +71,8 @@ start_server {tags {"cli"}} {
set _ [format_output [read_cli $fd]] set _ [format_output [read_cli $fd]]
} }
file delete ./.rediscli_history_test
proc test_interactive_cli_with_prompt {name code} { proc test_interactive_cli_with_prompt {name code} {
set ::env(FAKETTY_WITH_PROMPT) 1 set ::env(FAKETTY_WITH_PROMPT) 1
set ::env(REDISCLI_HISTFILE) ".rediscli_history_test"
test_interactive_cli $name $code test_interactive_cli $name $code
unset ::env(FAKETTY_WITH_PROMPT) unset ::env(FAKETTY_WITH_PROMPT)
} }
...@@ -839,3 +840,4 @@ start_server {tags {"cli external:skip"}} { ...@@ -839,3 +840,4 @@ start_server {tags {"cli external:skip"}} {
} }
} }
file delete ./.rediscli_history_test
...@@ -241,6 +241,11 @@ proc tags_acceptable {tags err_return} { ...@@ -241,6 +241,11 @@ proc tags_acceptable {tags err_return} {
return 0 return 0
} }
if { [lsearch $tags "experimental"] >=0 && [lsearch $::allowtags "experimental"] == -1 } {
set err "experimental test not allowed"
return 0
}
return 1 return 1
} }
......
...@@ -506,7 +506,7 @@ proc the_end {} { ...@@ -506,7 +506,7 @@ proc the_end {} {
} }
} }
# The client is not even driven (the test server is instead) as we just need # The client is not event driven (the test server is instead) as we just need
# to read the command, execute, reply... all this in a loop. # to read the command, execute, reply... all this in a loop.
proc test_client_main server_port { proc test_client_main server_port {
set ::test_server_fd [socket localhost $server_port] set ::test_server_fd [socket localhost $server_port]
......
...@@ -107,3 +107,76 @@ test "DELSLOTSRANGE command with several boundary conditions test suite" { ...@@ -107,3 +107,76 @@ test "DELSLOTSRANGE command with several boundary conditions test suite" {
assert_match "*9829 11000*12001 12100*12201 13104*" [$master4 CLUSTER SLOTS] assert_match "*9829 11000*12001 12100*12201 13104*" [$master4 CLUSTER SLOTS]
} }
} cluster_allocate_with_continuous_slots_local } cluster_allocate_with_continuous_slots_local
start_cluster 2 0 {tags {external:skip cluster experimental}} {
set master1 [srv 0 "client"]
set master2 [srv -1 "client"]
test "SFLUSH - Errors and output validation" {
assert_match "* 0-8191*" [$master1 CLUSTER NODES]
assert_match "* 8192-16383*" [$master2 CLUSTER NODES]
assert_match "*0 8191*" [$master1 CLUSTER SLOTS]
assert_match "*8192 16383*" [$master2 CLUSTER SLOTS]
# make master1 non-continuous slots
$master1 cluster DELSLOTSRANGE 1000 2000
# Test SFLUSH errors validation
assert_error {ERR wrong number of arguments*} {$master1 SFLUSH 4}
assert_error {ERR wrong number of arguments*} {$master1 SFLUSH 4 SYNC}
assert_error {ERR Invalid or out of range slot} {$master1 SFLUSH x 4}
assert_error {ERR Invalid or out of range slot} {$master1 SFLUSH 0 12x}
assert_error {ERR Slot 3 specified multiple times} {$master1 SFLUSH 2 4 3 5}
assert_error {ERR start slot number 8 is greater than*} {$master1 SFLUSH 8 4}
assert_error {ERR wrong number of arguments*} {$master1 SFLUSH 4 8 10}
assert_error {ERR wrong number of arguments*} {$master1 SFLUSH 0 999 2001 8191 ASYNCX}
# Test SFLUSH output validation
assert_match "" [$master1 SFLUSH 2 4]
assert_match "" [$master1 SFLUSH 0 4]
assert_match "" [$master2 SFLUSH 0 4]
assert_match "" [$master1 SFLUSH 1 8191]
assert_match "" [$master1 SFLUSH 0 8190]
assert_match "" [$master1 SFLUSH 0 998 2001 8191]
assert_match "" [$master1 SFLUSH 1 999 2001 8191]
assert_match "" [$master1 SFLUSH 0 999 2001 8190]
assert_match "" [$master1 SFLUSH 0 999 2002 8191]
assert_match "{0 999} {2001 8191}" [$master1 SFLUSH 0 999 2001 8191]
assert_match "{0 999} {2001 8191}" [$master1 SFLUSH 0 8191]
assert_match "{0 999} {2001 8191}" [$master1 SFLUSH 0 4000 4001 8191]
assert_match "" [$master2 SFLUSH 8193 16383]
assert_match "" [$master2 SFLUSH 8192 16382]
assert_match "{8192 16383}" [$master2 SFLUSH 8192 16383]
assert_match "{8192 16383}" [$master2 SFLUSH 8192 16383 SYNC]
assert_match "{8192 16383}" [$master2 SFLUSH 8192 16383 ASYNC]
assert_match "{8192 16383}" [$master2 SFLUSH 8192 9000 9001 16383]
assert_match "{8192 16383}" [$master2 SFLUSH 8192 9000 9001 16383 SYNC]
assert_match "{8192 16383}" [$master2 SFLUSH 8192 9000 9001 16383 ASYNC]
# restore master1 continuous slots
$master1 cluster ADDSLOTSRANGE 1000 2000
}
test "SFLUSH - Deletes the keys with argument <NONE>/SYNC/ASYNC" {
foreach op {"" "SYNC" "ASYNC"} {
for {set i 0} {$i < 100} {incr i} {
catch {$master1 SET key$i val$i}
catch {$master2 SET key$i val$i}
}
assert {[$master1 DBSIZE] > 0}
assert {[$master2 DBSIZE] > 0}
if {$op eq ""} {
assert_match "{0 8191}" [ $master1 SFLUSH 0 8191]
} else {
assert_match "{0 8191}" [ $master1 SFLUSH 0 8191 $op]
}
assert {[$master1 DBSIZE] == 0}
assert {[$master2 DBSIZE] > 0}
assert_match "{8192 16383}" [ $master2 SFLUSH 8192 16383]
assert {[$master2 DBSIZE] == 0}
}
}
}
...@@ -509,6 +509,12 @@ foreach {type large} [array get largevalue] { ...@@ -509,6 +509,12 @@ foreach {type large} [array get largevalue] {
r KEYS "a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*b" r KEYS "a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*b"
} {} } {}
test {Regression for pattern matching very long nested loops} {
r flushdb
r SET [string repeat "a" 50000] 1
r KEYS [string repeat "*?" 50000]
} {}
test {Coverage: basic SWAPDB test and unhappy path} { test {Coverage: basic SWAPDB test and unhappy path} {
r flushall r flushall
r select 0 r select 0
......
...@@ -691,6 +691,12 @@ start_server {tags {"scripting"}} { ...@@ -691,6 +691,12 @@ start_server {tags {"scripting"}} {
set e set e
} {ERR *Attempt to modify a readonly table*} } {ERR *Attempt to modify a readonly table*}
test {lua bit.tohex bug} {
set res [run_script {return bit.tohex(65535, -2147483648)} 0]
r ping
set res
} {0000FFFF}
test {Test an example script DECR_IF_GT} { test {Test an example script DECR_IF_GT} {
set decr_if_gt { set decr_if_gt {
local current local current
......
...@@ -73,7 +73,7 @@ start_server { ...@@ -73,7 +73,7 @@ start_server {
set result [create_random_dataset 16 lpush] set result [create_random_dataset 16 lpush]
test "SORT GET #" { test "SORT GET #" {
assert_equal [lsort -integer $result] [r sort tosort GET #] assert_equal [lsort -integer $result] [r sort tosort GET #]
} {} {cluster:skip} }
foreach command {SORT SORT_RO} { foreach command {SORT SORT_RO} {
test "$command GET <const>" { test "$command GET <const>" {
...@@ -393,6 +393,11 @@ start_cluster 1 0 {tags {"external:skip cluster sort"}} { ...@@ -393,6 +393,11 @@ start_cluster 1 0 {tags {"external:skip cluster sort"}} {
r sort "{a}mylist" by "{a}by*" get "{a}get*" r sort "{a}mylist" by "{a}by*" get "{a}get*"
} {30 200 100} } {30 200 100}
test "sort get # in cluster mode" {
assert_equal [r sort "{a}mylist" by "{a}by*" get # ] {3 1 2}
r sort "{a}mylist" by "{a}by*" get "{a}get*" get #
} {30 3 200 1 100 2}
test "sort_ro by in cluster mode" { test "sort_ro by in cluster mode" {
catch {r sort_ro "{a}mylist" by by*} e catch {r sort_ro "{a}mylist" by by*} e
assert_match {ERR BY option of SORT denied in Cluster mode when *} $e assert_match {ERR BY option of SORT denied in Cluster mode when *} $e
...@@ -404,4 +409,9 @@ start_cluster 1 0 {tags {"external:skip cluster sort"}} { ...@@ -404,4 +409,9 @@ start_cluster 1 0 {tags {"external:skip cluster sort"}} {
assert_match {ERR GET option of SORT denied in Cluster mode when *} $e assert_match {ERR GET option of SORT denied in Cluster mode when *} $e
r sort_ro "{a}mylist" by "{a}by*" get "{a}get*" r sort_ro "{a}mylist" by "{a}by*" get "{a}get*"
} {30 200 100} } {30 200 100}
test "sort_ro get # in cluster mode" {
assert_equal [r sort_ro "{a}mylist" by "{a}by*" get # ] {3 1 2}
r sort_ro "{a}mylist" by "{a}by*" get "{a}get*" get #
} {30 3 200 1 100 2}
} }
...@@ -1454,6 +1454,8 @@ start_server { ...@@ -1454,6 +1454,8 @@ start_server {
assert_equal [dict get $group entries-read] 3 assert_equal [dict get $group entries-read] 3
assert_equal [dict get $group lag] 0 assert_equal [dict get $group lag] 0
wait_for_ofs_sync $master $replica
set reply [$replica XINFO STREAM mystream FULL] set reply [$replica XINFO STREAM mystream FULL]
set group [lindex [dict get $reply groups] 0] set group [lindex [dict get $reply groups] 0]
assert_equal [dict get $group entries-read] 3 assert_equal [dict get $group entries-read] 3
......
...@@ -517,6 +517,11 @@ class Subcommand(Command): ...@@ -517,6 +517,11 @@ class Subcommand(Command):
def create_command(name, desc): def create_command(name, desc):
flags = desc.get("command_flags")
if flags and "EXPERIMENTAL" in flags:
print("Command %s is experimental, skipping..." % name)
return
if desc.get("container"): if desc.get("container"):
cmd = Subcommand(name.upper(), desc) cmd = Subcommand(name.upper(), desc)
subcommands.setdefault(desc["container"].upper(), {})[name] = cmd subcommands.setdefault(desc["container"].upper(), {})[name] = cmd
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment