Skip to content

Commit

Permalink
Add sample examples to test redis.io build (#3051)
Browse files Browse the repository at this point in the history
* Add sample examples to test redis.io build

* Reformat testable examples

* Add doctest profile and fix testable examples

Co-authored-by: Tihomir Mateev <tihomir.mateev@gmail.com>

* Add doctests workflow

* Add maven cache

* Run workflow on main branch

---------

Co-authored-by: Tihomir Mateev <tihomir.mateev@gmail.com>
  • Loading branch information
uglide and tishun authored Jan 17, 2025
1 parent 68f2a1d commit 6a05e17
Show file tree
Hide file tree
Showing 4 changed files with 290 additions and 0 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/doctests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Documentation Tests

on:
push:
tags-ignore:
- '*'
branches:
- 'main'
pull_request:
workflow_dispatch:

jobs:
doctests:
runs-on: ubuntu-latest
services:
redis-stack:
image: redis/redis-stack-server:latest
options: >-
--health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
ports:
- 6379:6379

steps:
- name: Checkout project
uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'temurin'
- name: Cache local Maven repository
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Run doctests
run: |
mvn -Pdoctests test
19 changes: 19 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,25 @@
</build>
</profile>

<profile>
<id>doctests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/examples/reactive/*Example.java</include>
<include>**/examples/async/*Example.java</include>
</includes>
<failIfNoTests>true</failIfNoTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>

</profiles>

</project>
127 changes: 127 additions & 0 deletions src/test/java/io/redis/examples/async/StringExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// EXAMPLE: set_tutorial
package io.redis.examples.async;

import io.lettuce.core.*;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.api.StatefulRedisConnection;

// REMOVE_START
import org.junit.jupiter.api.Test;
// REMOVE_END

import java.util.*;
import java.util.concurrent.CompletableFuture;

// REMOVE_START
import static org.assertj.core.api.Assertions.assertThat;
// REMOVE_END

public class StringExample {

// REMOVE_START
@Test
// REMOVE_END
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");

try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisAsyncCommands<String, String> asyncCommands = connection.async();

// STEP_START set_get
CompletableFuture<Void> setAndGet = asyncCommands.set("bike:1", "Deimos").thenCompose(v -> {
System.out.println(v); // OK
// REMOVE_START
assertThat(v).isEqualTo("OK");
// REMOVE_END
return asyncCommands.get("bike:1");
})
// REMOVE_START
.thenApply(res -> {
assertThat(res).isEqualTo("Deimos");
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // Deimos
.toCompletableFuture();
// STEP_END

// STEP_START setnx_xx
CompletableFuture<Void> setnx = asyncCommands.setnx("bike:1", "bike").thenCompose(v -> {
System.out.println(v); // false (because key already exists)
// REMOVE_START
assertThat(v).isFalse();
// REMOVE_END
return asyncCommands.get("bike:1");
})
// REMOVE_START
.thenApply(res -> {
assertThat(res).isEqualTo("Deimos");
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // Deimos (value is unchanged)
.toCompletableFuture();

// set the value to "bike" if it already exists
CompletableFuture<Void> setxx = asyncCommands.set("bike:1", "bike", SetArgs.Builder.xx())
// REMOVE_START
.thenApply(res -> {
assertThat(res).isEqualTo("OK");
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // OK
.toCompletableFuture();
// STEP_END

// STEP_START mset
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");

CompletableFuture<Void> mset = asyncCommands.mset(bikeMap).thenCompose(v -> {
System.out.println(v); // OK
return asyncCommands.mget("bike:1", "bike:2", "bike:3");
})
// REMOVE_START
.thenApply(res -> {
List<KeyValue<String, String>> expected = new ArrayList<>(
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
KeyValue.just("bike:3", "Vanth")));
assertThat(res).isEqualTo(expected);
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3,
// Vanth]]
.toCompletableFuture();
// STEP_END

// STEP_START incr
CompletableFuture<Void> incrby = asyncCommands.set("total_crashes", "0")
.thenCompose(v -> asyncCommands.incr("total_crashes")).thenCompose(v -> {
System.out.println(v); // 1
// REMOVE_START
assertThat(v).isEqualTo(1L);
// REMOVE_END
return asyncCommands.incrby("total_crashes", 10);
})
// REMOVE_START
.thenApply(res -> {
assertThat(res).isEqualTo(11L);
return res;
})
// REMOVE_END
.thenAccept(System.out::println) // 11
.toCompletableFuture();
// STEP_END

CompletableFuture.allOf(setAndGet, setnx, setxx, mset, incrby).join();

} finally {
redisClient.shutdown();
}
}

}
104 changes: 104 additions & 0 deletions src/test/java/io/redis/examples/reactive/StringExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// EXAMPLE: set_tutorial
package io.redis.examples.reactive;

import io.lettuce.core.*;
import io.lettuce.core.api.reactive.RedisReactiveCommands;
import io.lettuce.core.api.StatefulRedisConnection;
// REMOVE_START
import org.junit.jupiter.api.Test;
// REMOVE_END
import reactor.core.publisher.Mono;

import java.util.*;

// REMOVE_START
import static org.assertj.core.api.Assertions.assertThat;
// REMOVE_END

public class StringExample {

// REMOVE_START
@Test
// REMOVE_END
public void run() {
RedisClient redisClient = RedisClient.create("redis://localhost:6379");

try (StatefulRedisConnection<String, String> connection = redisClient.connect()) {
RedisReactiveCommands<String, String> reactiveCommands = connection.reactive();

// STEP_START set_get
Mono<Void> setAndGet = reactiveCommands.set("bike:1", "Deimos").doOnNext(v -> {
System.out.println(v); // OK
// REMOVE_START
assertThat(v).isEqualTo("OK");
// REMOVE_END
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
// REMOVE_START
assertThat(res).isEqualTo("Deimos");
// REMOVE_END
System.out.println(res); // Deimos
}).then();
// STEP_END

// STEP_START setnx_xx
Mono<Void> setnx = reactiveCommands.setnx("bike:1", "bike").doOnNext(v -> {
System.out.println(v); // false (because key already exists)
// REMOVE_START
assertThat(v).isFalse();
// REMOVE_END
}).flatMap(v -> reactiveCommands.get("bike:1")).doOnNext(res -> {
// REMOVE_START
assertThat(res).isEqualTo("Deimos");
// REMOVE_END
System.out.println(res); // Deimos (value is unchanged)
}).then();

Mono<Void> setxx = reactiveCommands.set("bike:1", "bike", SetArgs.Builder.xx()).doOnNext(res -> {
// REMOVE_START
assertThat(res).isEqualTo("OK");
// REMOVE_END
System.out.println(res); // OK
}).then();
// STEP_END

// STEP_START mset
Map<String, String> bikeMap = new HashMap<>();
bikeMap.put("bike:1", "Deimos");
bikeMap.put("bike:2", "Ares");
bikeMap.put("bike:3", "Vanth");

Mono<Void> mset = reactiveCommands.mset(bikeMap).doOnNext(System.out::println) // OK
.flatMap(v -> reactiveCommands.mget("bike:1", "bike:2", "bike:3").collectList()).doOnNext(res -> {
List<KeyValue<String, String>> expected = new ArrayList<>(
Arrays.asList(KeyValue.just("bike:1", "Deimos"), KeyValue.just("bike:2", "Ares"),
KeyValue.just("bike:3", "Vanth")));
// REMOVE_START
assertThat(res).isEqualTo(expected);
// REMOVE_END
System.out.println(res); // [KeyValue[bike:1, Deimos], KeyValue[bike:2, Ares], KeyValue[bike:3, Vanth]]
}).then();
// STEP_END

// STEP_START incr
Mono<Void> incrby = reactiveCommands.set("total_crashes", "0").flatMap(v -> reactiveCommands.incr("total_crashes"))
.doOnNext(v -> {
System.out.println(v); // 1
// REMOVE_START
assertThat(v).isEqualTo(1L);
// REMOVE_END
}).flatMap(v -> reactiveCommands.incrby("total_crashes", 10)).doOnNext(res -> {
// REMOVE_START
assertThat(res).isEqualTo(11L);
// REMOVE_END
System.out.println(res); // 11
}).then();
// STEP_END

Mono.when(setAndGet, setnx, setxx, mset, incrby).block();

} finally {
redisClient.shutdown();
}
}

}

0 comments on commit 6a05e17

Please sign in to comment.