@@ -1032,6 +1032,58 @@ var streamTests = func(t *testing.T, configs util.KvrocksServerConfigs) {
10321032 require .Equal (t , "2-0" , msgs [0 ].ID )
10331033 require .NoError (t , rdb .Del (ctx , streamName ).Err ())
10341034 })
1035+
1036+ t .Run ("XDELEX KEEPREF delete last entry with consumer groups recalculates boundary" , func (t * testing.T ) {
1037+ streamName := "xdelex_boundary_last_" + strconv .Itoa (rand .Int ())
1038+ require .NoError (t , rdb .XAdd (ctx , & redis.XAddArgs {
1039+ Stream : streamName , ID : "1-0" , Values : []string {"f" , "v" },
1040+ }).Err ())
1041+ require .NoError (t , rdb .XAdd (ctx , & redis.XAddArgs {
1042+ Stream : streamName , ID : "2-0" , Values : []string {"f" , "v" },
1043+ }).Err ())
1044+ require .NoError (t , rdb .XAdd (ctx , & redis.XAddArgs {
1045+ Stream : streamName , ID : "3-0" , Values : []string {"f" , "v" },
1046+ }).Err ())
1047+ // Group/PEL keys sort after entry keys; SeekToLast must filter them out.
1048+ require .NoError (t , rdb .XGroupCreateMkStream (ctx , streamName , "g1" , "0" ).Err ())
1049+ r , err := rdb .Do (ctx , "XDELEX" , streamName , "KEEPREF" , "IDS" , "1" , "3-0" ).Result ()
1050+ require .NoError (t , err )
1051+ require .Equal (t , []interface {}{int64 (1 )}, r )
1052+ require .Equal (t , int64 (2 ), rdb .XLen (ctx , streamName ).Val ())
1053+ // XRANGE should end at 2-0 now, not parse garbage from group keys
1054+ msgs , err := rdb .XRange (ctx , streamName , "-" , "+" ).Result ()
1055+ require .NoError (t , err )
1056+ require .Equal (t , 2 , len (msgs ))
1057+ require .Equal (t , "2-0" , msgs [1 ].ID )
1058+ require .NoError (t , rdb .Del (ctx , streamName ).Err ())
1059+ })
1060+
1061+ t .Run ("XDELEX DELREF delete last entry with consumer groups recalculates boundary" , func (t * testing.T ) {
1062+ streamName := "xdelex_boundary_last_delref_" + strconv .Itoa (rand .Int ())
1063+ require .NoError (t , rdb .XAdd (ctx , & redis.XAddArgs {
1064+ Stream : streamName , ID : "1-0" , Values : []string {"f" , "v" },
1065+ }).Err ())
1066+ require .NoError (t , rdb .XAdd (ctx , & redis.XAddArgs {
1067+ Stream : streamName , ID : "2-0" , Values : []string {"f" , "v" },
1068+ }).Err ())
1069+ require .NoError (t , rdb .XAdd (ctx , & redis.XAddArgs {
1070+ Stream : streamName , ID : "3-0" , Values : []string {"f" , "v" },
1071+ }).Err ())
1072+ require .NoError (t , rdb .XGroupCreateMkStream (ctx , streamName , "g1" , "0" ).Err ())
1073+ _ , err := rdb .XReadGroup (ctx , & redis.XReadGroupArgs {
1074+ Group : "g1" , Consumer : "c1" , Streams : []string {streamName , ">" }, Count : 1 ,
1075+ }).Result ()
1076+ require .NoError (t , err )
1077+ r , err := rdb .Do (ctx , "XDELEX" , streamName , "DELREF" , "IDS" , "1" , "3-0" ).Result ()
1078+ require .NoError (t , err )
1079+ require .Equal (t , []interface {}{int64 (1 )}, r )
1080+ require .Equal (t , int64 (2 ), rdb .XLen (ctx , streamName ).Val ())
1081+ msgs , err := rdb .XRange (ctx , streamName , "-" , "+" ).Result ()
1082+ require .NoError (t , err )
1083+ require .Equal (t , 2 , len (msgs ))
1084+ require .Equal (t , "2-0" , msgs [1 ].ID )
1085+ require .NoError (t , rdb .Del (ctx , streamName ).Err ())
1086+ })
10351087}
10361088
10371089// streamSimulateXRANGE simulates Redis XRANGE implementation in Golang.
0 commit comments