Skip to content

Commit 6a05e17

Browse files
uglidetishun
andauthored
Add sample examples to test redis.io build (#3051)
* Add sample examples to test redis.io build * Reformat testable examples * Add doctest profile and fix testable examples Co-authored-by: Tihomir Mateev <[email protected]> * Add doctests workflow * Add maven cache * Run workflow on main branch --------- Co-authored-by: Tihomir Mateev <[email protected]>
1 parent 68f2a1d commit 6a05e17

File tree

4 files changed

+290
-0
lines changed

4 files changed

+290
-0
lines changed

.github/workflows/doctests.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Documentation Tests
2+
3+
on:
4+
push:
5+
tags-ignore:
6+
- '*'
7+
branches:
8+
- 'main'
9+
pull_request:
10+
workflow_dispatch:
11+
12+
jobs:
13+
doctests:
14+
runs-on: ubuntu-latest
15+
services:
16+
redis-stack:
17+
image: redis/redis-stack-server:latest
18+
options: >-
19+
--health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
20+
ports:
21+
- 6379:6379
22+
23+
steps:
24+
- name: Checkout project
25+
uses: actions/checkout@v4
26+
- name: Set up Java
27+
uses: actions/setup-java@v2
28+
with:
29+
java-version: '11'
30+
distribution: 'temurin'
31+
- name: Cache local Maven repository
32+
uses: actions/cache@v4
33+
with:
34+
path: ~/.m2/repository
35+
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
36+
restore-keys: |
37+
${{ runner.os }}-maven-
38+
- name: Run doctests
39+
run: |
40+
mvn -Pdoctests test

pom.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,25 @@
13681368
</build>
13691369
</profile>
13701370

1371+
<profile>
1372+
<id>doctests</id>
1373+
<build>
1374+
<plugins>
1375+
<plugin>
1376+
<groupId>org.apache.maven.plugins</groupId>
1377+
<artifactId>maven-surefire-plugin</artifactId>
1378+
<configuration>
1379+
<includes>
1380+
<include>**/examples/reactive/*Example.java</include>
1381+
<include>**/examples/async/*Example.java</include>
1382+
</includes>
1383+
<failIfNoTests>true</failIfNoTests>
1384+
</configuration>
1385+
</plugin>
1386+
</plugins>
1387+
</build>
1388+
</profile>
1389+
13711390
</profiles>
13721391

13731392
</project>
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// EXAMPLE: set_tutorial
2+
package io.redis.examples.async;
3+
4+
import io.lettuce.core.*;
5+
import io.lettuce.core.api.async.RedisAsyncCommands;
6+
import io.lettuce.core.api.StatefulRedisConnection;
7+
8+
// REMOVE_START
9+
import org.junit.jupiter.api.Test;
10+
// REMOVE_END
11+
12+
import java.util.*;
13+
import java.util.concurrent.CompletableFuture;
14+
15+
// REMOVE_START
16+
import static org.assertj.core.api.Assertions.assertThat;
17+
// REMOVE_END
18+
19+
public class StringExample {
20+
21+
// REMOVE_START
22+
@Test
23+
// REMOVE_END
24+
public void run() {
25+
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
26+
27+
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
28+
RedisAsyncCommands<String, String> asyncCommands = connection.async();
29+
30+
// STEP_START set_get
31+
CompletableFuture<Void> setAndGet = asyncCommands.set("bike:1", "Deimos").thenCompose(v -> {
32+
System.out.println(v); // OK
33+
// REMOVE_START
34+
assertThat(v).isEqualTo("OK");
35+
// REMOVE_END
36+
return asyncCommands.get("bike:1");
37+
})
38+
// REMOVE_START
39+
.thenApply(res -> {
40+
assertThat(res).isEqualTo("Deimos");
41+
return res;
42+
})
43+
// REMOVE_END
44+
.thenAccept(System.out::println) // Deimos
45+
.toCompletableFuture();
46+
// STEP_END
47+
48+
// STEP_START setnx_xx
49+
CompletableFuture<Void> setnx = asyncCommands.setnx("bike:1", "bike").thenCompose(v -> {
50+
System.out.println(v); // false (because key already exists)
51+
// REMOVE_START
52+
assertThat(v).isFalse();
53+
// REMOVE_END
54+
return asyncCommands.get("bike:1");
55+
})
56+
// REMOVE_START
57+
.thenApply(res -> {
58+
assertThat(res).isEqualTo("Deimos");
59+
return res;
60+
})
61+
// REMOVE_END
62+
.thenAccept(System.out::println) // Deimos (value is unchanged)
63+
.toCompletableFuture();
64+
65+
// set the value to "bike" if it already exists
66+
CompletableFuture<Void> setxx = asyncCommands.set("bike:1", "bike", SetArgs.Builder.xx())
67+
// REMOVE_START
68+
.thenApply(res -> {
69+
assertThat(res).isEqualTo("OK");
70+
return res;
71+
})
72+
// REMOVE_END
73+
.thenAccept(System.out::println) // OK
74+
.toCompletableFuture();
75+
// STEP_END
76+
77+
// STEP_START mset
78+
Map<String, String> bikeMap = new HashMap<>();
79+
bikeMap.put("bike:1", "Deimos");
80+
bikeMap.put("bike:2", "Ares");
81+
bikeMap.put("bike:3", "Vanth");
82+
83+
CompletableFuture<Void> mset = asyncCommands.mset(bikeMap).thenCompose(v -> {
84+
System.out.println(v); // OK
85+
return asyncCommands.mget("bike:1", "bike:2", "bike:3");
86+
})
87+
// REMOVE_START
88+
.thenApply(res -> {
89+
List<KeyValue<String, String>> expected = new ArrayList<>(
90+
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
91+
KeyValue.just("bike:3", "Vanth")));
92+
assertThat(res).isEqualTo(expected);
93+
return res;
94+
})
95+
// REMOVE_END
96+
.thenAccept(System.out::println) // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3,
97+
// Vanth]]
98+
.toCompletableFuture();
99+
// STEP_END
100+
101+
// STEP_START incr
102+
CompletableFuture<Void> incrby = asyncCommands.set("total_crashes", "0")
103+
.thenCompose(v -> asyncCommands.incr("total_crashes")).thenCompose(v -> {
104+
System.out.println(v); // 1
105+
// REMOVE_START
106+
assertThat(v).isEqualTo(1L);
107+
// REMOVE_END
108+
return asyncCommands.incrby("total_crashes", 10);
109+
})
110+
// REMOVE_START
111+
.thenApply(res -> {
112+
assertThat(res).isEqualTo(11L);
113+
return res;
114+
})
115+
// REMOVE_END
116+
.thenAccept(System.out::println) // 11
117+
.toCompletableFuture();
118+
// STEP_END
119+
120+
CompletableFuture.allOf(setAndGet, setnx, setxx, mset, incrby).join();
121+
122+
} finally {
123+
redisClient.shutdown();
124+
}
125+
}
126+
127+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// EXAMPLE: set_tutorial
2+
package io.redis.examples.reactive;
3+
4+
import io.lettuce.core.*;
5+
import io.lettuce.core.api.reactive.RedisReactiveCommands;
6+
import io.lettuce.core.api.StatefulRedisConnection;
7+
// REMOVE_START
8+
import org.junit.jupiter.api.Test;
9+
// REMOVE_END
10+
import reactor.core.publisher.Mono;
11+
12+
import java.util.*;
13+
14+
// REMOVE_START
15+
import static org.assertj.core.api.Assertions.assertThat;
16+
// REMOVE_END
17+
18+
public class StringExample {
19+
20+
// REMOVE_START
21+
@Test
22+
// REMOVE_END
23+
public void run() {
24+
RedisClient redisClient = RedisClient.create("redis://localhost:6379");
25+
26+
try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
27+
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();
28+
29+
// STEP_START set_get
30+
Mono<Void> setAndGet = reactiveCommands.set("bike:1", "Deimos").doOnNext(v -> {
31+
System.out.println(v); // OK
32+
// REMOVE_START
33+
assertThat(v).isEqualTo("OK");
34+
// REMOVE_END
35+
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
36+
// REMOVE_START
37+
assertThat(res).isEqualTo("Deimos");
38+
// REMOVE_END
39+
System.out.println(res); // Deimos
40+
}).then();
41+
// STEP_END
42+
43+
// STEP_START setnx_xx
44+
Mono<Void> setnx = reactiveCommands.setnx("bike:1", "bike").doOnNext(v -> {
45+
System.out.println(v); // false (because key already exists)
46+
// REMOVE_START
47+
assertThat(v).isFalse();
48+
// REMOVE_END
49+
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
50+
// REMOVE_START
51+
assertThat(res).isEqualTo("Deimos");
52+
// REMOVE_END
53+
System.out.println(res); // Deimos (value is unchanged)
54+
}).then();
55+
56+
Mono<Void> setxx = reactiveCommands.set("bike:1", "bike", SetArgs.Builder.xx()).doOnNext(res -> {
57+
// REMOVE_START
58+
assertThat(res).isEqualTo("OK");
59+
// REMOVE_END
60+
System.out.println(res); // OK
61+
}).then();
62+
// STEP_END
63+
64+
// STEP_START mset
65+
Map<String, String> bikeMap = new HashMap<>();
66+
bikeMap.put("bike:1", "Deimos");
67+
bikeMap.put("bike:2", "Ares");
68+
bikeMap.put("bike:3", "Vanth");
69+
70+
Mono<Void> mset = reactiveCommands.mset(bikeMap).doOnNext(System.out::println) // OK
71+
.flatMap(v -> reactiveCommands.mget("bike:1", "bike:2", "bike:3").collectList()).doOnNext(res -> {
72+
List<KeyValue<String, String>> expected = new ArrayList<>(
73+
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
74+
KeyValue.just("bike:3", "Vanth")));
75+
// REMOVE_START
76+
assertThat(res).isEqualTo(expected);
77+
// REMOVE_END
78+
System.out.println(res); // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3, Vanth]]
79+
}).then();
80+
// STEP_END
81+
82+
// STEP_START incr
83+
Mono<Void> incrby = reactiveCommands.set("total_crashes", "0").flatMap(v -> reactiveCommands.incr("total_crashes"))
84+
.doOnNext(v -> {
85+
System.out.println(v); // 1
86+
// REMOVE_START
87+
assertThat(v).isEqualTo(1L);
88+
// REMOVE_END
89+
}).flatMap(v -> reactiveCommands.incrby("total_crashes", 10)).doOnNext(res -> {
90+
// REMOVE_START
91+
assertThat(res).isEqualTo(11L);
92+
// REMOVE_END
93+
System.out.println(res); // 11
94+
}).then();
95+
// STEP_END
96+
97+
Mono.when(setAndGet, setnx, setxx, mset, incrby).block();
98+
99+
} finally {
100+
redisClient.shutdown();
101+
}
102+
}
103+
104+
}

0 commit comments

Comments
 (0)