Skip to content

Commit e2fe8a1

Browse files
authored
Merge branch 'main' into lettuce-connection-validation
2 parents d7bd9da + 9dd83b1 commit e2fe8a1

13 files changed

+375
-14
lines changed

.github/workflows/integration.yml

+25-12
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,35 @@ on:
1515
schedule:
1616
- cron: '0 1 * * *' # nightly build
1717
workflow_dispatch:
18-
inputs:
19-
redis_version:
20-
description: "Redis stack version to use for testing"
21-
required: false
22-
default: "8.0-M02"
23-
type: choice
24-
options:
25-
- "8.0-M02"
26-
- "rs-7.4.0-v1"
27-
- "rs-7.2.0-v13"
2818

2919
jobs:
30-
3120
build:
3221
name: Build and Test
3322
runs-on: ubuntu-24.04
23+
strategy:
24+
fail-fast: false
25+
matrix:
26+
redis_version:
27+
- "unstable"
28+
- "8.0"
29+
- "7.4"
30+
- "7.2"
31+
3432
steps:
33+
- name: Test Redis Server Version
34+
id: map-tags
35+
run: |
36+
# Map requested version to github or tag
37+
case "${{ matrix.redis_version }}" in
38+
"unstable") redis_branch="unstable" stack_version="8.0-M04-pre" ;;
39+
"8.0") redis_branch="8.0" stack_version="8.0-M04-pre" ;;
40+
"7.4") redis_branch="7.4" stack_version="rs-7.4.0-v2" ;;
41+
"7.2") redis_branch="7.2" stack_version="rs-7.2.0-v14" ;;
42+
*) echo "Unsupported version: ${{ matrix.redis_version }}" && exit 1 ;;
43+
esac
44+
# Save them as outputs for later use
45+
echo "redis_branch=$redis_branch" >> $GITHUB_OUTPUT
46+
echo "redis_stack_version=$stack_version" >> $GITHUB_OUTPUT
3547
- name: Checkout project
3648
uses: actions/checkout@v4
3749
- name: Set Java up in the runner
@@ -61,7 +73,8 @@ jobs:
6173
run: |
6274
make test-coverage
6375
env:
64-
REDIS_STACK_VERSION: ${{ inputs.redis_version || '8.0-M02' }}
76+
REDIS: ${{ steps.map-tags.outputs.redis_branch }}
77+
REDIS_STACK_VERSION: ${{ steps.map-tags.outputs.redis_stack_version }}
6578
JVM_OPTS: -Xmx3200m
6679
TERM: dumb
6780
- name: Upload coverage reports to Codecov

src/main/java/io/lettuce/core/AclCategory.java

+41-1
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,45 @@ public enum AclCategory {
111111
/**
112112
* scripting command
113113
*/
114-
SCRIPTING
114+
SCRIPTING,
115+
116+
/**
117+
* bloom command
118+
*/
119+
BLOOM,
120+
121+
/**
122+
* cuckoo command
123+
*/
124+
CUCKOO,
125+
126+
/**
127+
* count-min-sketch command
128+
*/
129+
CMS,
130+
131+
/**
132+
* top-k command
133+
*/
134+
TOPK,
135+
136+
/**
137+
* t-digest command
138+
*/
139+
TDIGEST,
140+
141+
/**
142+
* search command
143+
*/
144+
SEARCH,
145+
146+
/**
147+
* timeseries command
148+
*/
149+
TIMESERIES,
150+
151+
/**
152+
* json command
153+
*/
154+
JSON
115155
}

src/main/java/io/lettuce/core/models/command/CommandDetailParser.java

+9
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ public class CommandDetailParser {
9595
aclCategoriesMap.put("@connection", AclCategory.CONNECTION);
9696
aclCategoriesMap.put("@transaction", AclCategory.TRANSACTION);
9797
aclCategoriesMap.put("@scripting", AclCategory.SCRIPTING);
98+
aclCategoriesMap.put("@bloom", AclCategory.BLOOM);
99+
aclCategoriesMap.put("@cuckoo", AclCategory.CUCKOO);
100+
aclCategoriesMap.put("@cms", AclCategory.CMS);
101+
aclCategoriesMap.put("@topk", AclCategory.TOPK);
102+
aclCategoriesMap.put("@tdigest", AclCategory.TDIGEST);
103+
aclCategoriesMap.put("@search", AclCategory.SEARCH);
104+
aclCategoriesMap.put("@timeseries", AclCategory.TIMESERIES);
105+
aclCategoriesMap.put("@json", AclCategory.JSON);
106+
98107
ACL_CATEGORY_MAPPING = Collections.unmodifiableMap(aclCategoriesMap);
99108
}
100109

src/test/java/io/lettuce/core/RedisContainerIntegrationTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class RedisContainerIntegrationTests {
2626

2727
private static final String REDIS_STACK_CLUSTER = "clustered-stack";
2828

29-
private static final String REDIS_STACK_VERSION = System.getProperty("REDIS_STACK_VERSION", "8.0-M02");;
29+
private static final String REDIS_STACK_VERSION = System.getProperty("REDIS_STACK_VERSION", "8.0-M04-pre");;
3030

3131
private static Exception initializationException;
3232

src/test/java/io/lettuce/core/ScanIteratorIntegrationTests.java

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static io.lettuce.TestTags.INTEGRATION_TEST;
2323
import static org.assertj.core.api.AssertionsForClassTypes.*;
2424
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
25+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
2526

2627
import java.util.ArrayList;
2728
import java.util.List;
@@ -30,6 +31,7 @@
3031

3132
import javax.inject.Inject;
3233

34+
import io.lettuce.test.condition.RedisConditions;
3335
import org.junit.jupiter.api.BeforeEach;
3436
import org.junit.jupiter.api.Tag;
3537
import org.junit.jupiter.api.Test;
@@ -161,6 +163,8 @@ void hashSinglePass() {
161163

162164
@Test
163165
void hashNoValuesSinglePass() {
166+
// NOVALUES flag (since Redis 7.4)
167+
assumeTrue(RedisConditions.of(redis).hasVersionGreaterOrEqualsTo("7.4"));
164168

165169
redis.hmset(key, KeysAndValues.MAP);
166170

@@ -194,6 +198,8 @@ void hashMultiPass() {
194198

195199
@Test
196200
void hashNoValuesMultiPass() {
201+
// NOVALUES flag (since Redis 7.4)
202+
assumeTrue(RedisConditions.of(redis).hasVersionGreaterOrEqualsTo("7.4"));
197203

198204
redis.hmset(key, KeysAndValues.MAP);
199205

src/test/java/io/lettuce/core/ScanStreamIntegrationTests.java

+6
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121

2222
import static io.lettuce.TestTags.INTEGRATION_TEST;
2323
import static org.assertj.core.api.Assertions.*;
24+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
2425

2526
import java.util.List;
2627
import java.util.stream.IntStream;
2728

2829
import javax.inject.Inject;
2930

31+
import io.lettuce.test.condition.RedisConditions;
3032
import org.junit.jupiter.api.BeforeEach;
3133
import org.junit.jupiter.api.Tag;
3234
import org.junit.jupiter.api.Test;
@@ -95,6 +97,8 @@ void shouldHscanIteratively() {
9597

9698
@Test
9799
void shouldHscanNovaluesIteratively() {
100+
// NOVALUES flag (since Redis 7.4)
101+
assumeTrue(RedisConditions.of(redis).hasVersionGreaterOrEqualsTo("7.4"));
98102

99103
for (int i = 0; i < 1000; i++) {
100104
redis.hset(key, "field-" + i, "value-" + i);
@@ -160,6 +164,8 @@ void shouldCorrectlyEmitItemsWithConcurrentPoll() {
160164

161165
@Test
162166
void shouldCorrectlyEmitKeysWithConcurrentPoll() {
167+
// NOVALUES flag (since Redis 7.4)
168+
assumeTrue(RedisConditions.of(redis).hasVersionGreaterOrEqualsTo("7.4"));
163169

164170
RedisReactiveCommands<String, String> commands = connection.reactive();
165171

src/test/java/io/lettuce/core/cluster/ScanIteratorIntegrationTests.java

+6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static io.lettuce.TestTags.INTEGRATION_TEST;
2323
import static org.assertj.core.api.AssertionsForClassTypes.*;
2424
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
25+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
2526

2627
import java.util.ArrayList;
2728
import java.util.List;
@@ -30,6 +31,7 @@
3031

3132
import javax.inject.Inject;
3233

34+
import io.lettuce.test.condition.RedisConditions;
3335
import org.junit.jupiter.api.BeforeEach;
3436
import org.junit.jupiter.api.Tag;
3537
import org.junit.jupiter.api.Test;
@@ -185,6 +187,8 @@ void hashSinglePass() {
185187

186188
@Test
187189
void hashNovaluesSinglePass() {
190+
// NOVALUES flag (since Redis 7.4)
191+
assumeTrue(RedisConditions.of(redis).hasVersionGreaterOrEqualsTo("7.4"));
188192

189193
redis.hmset(key, KeysAndValues.MAP);
190194

@@ -215,6 +219,8 @@ void hashMultiPass() {
215219

216220
@Test
217221
void hashNovaluesMultiPass() {
222+
// NOVALUES flag (since Redis 7.4)
223+
assumeTrue(RedisConditions.of(redis).hasVersionGreaterOrEqualsTo("7.4"));
218224

219225
redis.hmset(key, KeysAndValues.MAP);
220226

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* Copyright 2011-Present, Redis Ltd. and Contributors
3+
* All rights reserved.
4+
*
5+
* Licensed under the MIT License.
6+
*
7+
* This file contains contributions from third-party contributors
8+
* licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* https://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
package io.lettuce.core.commands;
21+
22+
import io.lettuce.core.*;
23+
import io.lettuce.core.api.sync.RedisCommands;
24+
25+
import io.lettuce.test.condition.RedisConditions;
26+
import org.junit.jupiter.api.*;
27+
28+
import java.util.Arrays;
29+
30+
import static io.lettuce.TestTags.INTEGRATION_TEST;
31+
import static org.assertj.core.api.Assertions.assertThat;
32+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
33+
34+
/**
35+
* Integration tests for ACL commands with Redis modules since Redis 8.0.
36+
*
37+
* @author M Sazzadul Hoque
38+
*/
39+
@Tag(INTEGRATION_TEST)
40+
public class ConsolidatedAclCommandIntegrationTests extends RedisContainerIntegrationTests {
41+
42+
private static RedisClient client;
43+
44+
private static RedisCommands<String, String> redis;
45+
46+
@BeforeAll
47+
public static void setup() {
48+
RedisURI redisURI = RedisURI.Builder.redis("127.0.0.1").withPort(16379).build();
49+
50+
client = RedisClient.create(redisURI);
51+
redis = client.connect().sync();
52+
assumeTrue(RedisConditions.of(redis).hasVersionGreaterOrEqualsTo("7.9"));
53+
}
54+
55+
@AfterAll
56+
static void teardown() {
57+
if (client != null) {
58+
client.shutdown();
59+
}
60+
}
61+
62+
@BeforeEach
63+
void setUp() {
64+
redis.flushall();
65+
redis.aclUsers().stream().filter(o -> !"default".equals(o)).forEach(redis::aclDeluser);
66+
redis.aclLogReset();
67+
}
68+
69+
@Test
70+
public void listACLCategoriesTest() {
71+
assertThat(redis.aclCat()).containsAll(Arrays.asList(AclCategory.BLOOM, AclCategory.CUCKOO, AclCategory.CMS,
72+
AclCategory.TOPK, AclCategory.TDIGEST, AclCategory.SEARCH, AclCategory.TIMESERIES, AclCategory.JSON));
73+
}
74+
75+
@Test
76+
void grantBloomCommandCatTest() {
77+
grantModuleCommandCatTest(AclCategory.BLOOM, "bloom");
78+
}
79+
80+
@Test
81+
void grantCuckooCommandCatTest() {
82+
grantModuleCommandCatTest(AclCategory.CUCKOO, "cuckoo");
83+
}
84+
85+
@Test
86+
void grantCmsCommandCatTest() {
87+
grantModuleCommandCatTest(AclCategory.CMS, "cms");
88+
}
89+
90+
@Test
91+
void grantTopkCommandCatTest() {
92+
grantModuleCommandCatTest(AclCategory.TOPK, "topk");
93+
}
94+
95+
@Test
96+
void grantTdigestCommandCatTest() {
97+
grantModuleCommandCatTest(AclCategory.TDIGEST, "tdigest");
98+
}
99+
100+
@Test
101+
void grantSearchCommandCatTest() {
102+
grantModuleCommandCatTest(AclCategory.SEARCH, "search");
103+
}
104+
105+
@Test
106+
void grantTimeseriesCommandCatTest() {
107+
grantModuleCommandCatTest(AclCategory.TIMESERIES, "timeseries");
108+
}
109+
110+
@Test
111+
void grantJsonCommandCatTest() {
112+
grantModuleCommandCatTest(AclCategory.JSON, "json");
113+
}
114+
115+
private void grantModuleCommandCatTest(AclCategory category, String categoryStr) {
116+
assertThat(redis.aclDeluser("foo")).isNotNull();
117+
AclSetuserArgs args = AclSetuserArgs.Builder.on().addCategory(category);
118+
assertThat(redis.aclSetuser("foo", args)).isEqualTo("OK");
119+
assertThat(redis.aclGetuser("foo")).contains("-@all +@" + categoryStr);
120+
assertThat(redis.aclDeluser("foo")).isNotNull();
121+
}
122+
123+
}

0 commit comments

Comments
 (0)