From 2390ed72c5f65d21f44d7d49db59e4e88da1acb1 Mon Sep 17 00:00:00 2001 From: adarovadya Date: Sun, 15 Sep 2024 16:10:39 +0300 Subject: [PATCH 01/18] Node: fix getting the right EVENT_NAME for release candidate (#2293) * change packages name to Valkey, fix ENV variables Signed-off-by: Adar Ovadia --------- Signed-off-by: Adar Ovadia Co-authored-by: Adar Ovadia --- .github/workflows/npm-cd.yml | 17 +++++++++++++--- utils/release-candidate-testing/node/index.js | 20 +++++++++---------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/.github/workflows/npm-cd.yml b/.github/workflows/npm-cd.yml index 25db537ab5..3788d87e04 100644 --- a/.github/workflows/npm-cd.yml +++ b/.github/workflows/npm-cd.yml @@ -108,6 +108,7 @@ jobs: if ${{ env.EVENT_NAME == 'pull_request' }}; then R_VERSION="255.255.255" elif ${{ env.EVENT_NAME == 'workflow_dispatch' }}; then + echo "${{env.EVENT_NAME}}" R_VERSION="${{ env.INPUT_VERSION }}" else R_VERSION=${GITHUB_REF:11} @@ -229,8 +230,16 @@ jobs: working-directory: ./node/npm/glide run: | export pkg_name=valkey-glide - echo "${GITHUB_REF:11}" - export package_version=${GITHUB_REF:11} + + echo "The workflow is: ${{env.EVENT_NAME}}" + if ${{ env.EVENT_NAME == 'workflow_dispatch' }}; then + R_VERSION="${{ env.INPUT_VERSION }}" + else + R_VERSION=${GITHUB_REF:11} + fi + echo "RELEASE_VERSION=${R_VERSION}" >> $GITHUB_ENV + + export package_version=${R_VERSION} export scope=`if [ "$NPM_SCOPE" != '' ]; then echo "$NPM_SCOPE/"; fi` mv package.json package.json.tmpl envsubst < package.json.tmpl > "package.json" @@ -239,6 +248,8 @@ jobs: sed -i "s|@scope/|${scope}|g" index.ts env: NPM_SCOPE: ${{ vars.NPM_SCOPE }} + EVENT_NAME: ${{ github.event_name }} + INPUT_VERSION: ${{ github.event.inputs.version }} - name: Build Node wrapper uses: ./.github/workflows/build-node-wrapper @@ -251,7 +262,7 @@ jobs: - name: Check if RC and set a distribution tag for the package shell: bash run: | - if [[ "${GITHUB_REF:11}" == *"rc"* ]] + if [[ ${{ env.RELEASE_VERSION }} == *"rc"* ]] then echo "This is a release candidate" export npm_tag="next" diff --git a/utils/release-candidate-testing/node/index.js b/utils/release-candidate-testing/node/index.js index 257f40ea05..40f5b86f12 100644 --- a/utils/release-candidate-testing/node/index.js +++ b/utils/release-candidate-testing/node/index.js @@ -1,5 +1,5 @@ -import { RedisClient, RedisClusterClient } from "@valkey/valkey-glide"; -import { RedisCluster } from "../../TestUtils.js"; +import { GlideClient, GlideClusterClient } from "@valkey/valkey-glide"; +import { ValkeyCluster } from "../../TestUtils.js"; async function runCommands(client) { @@ -66,20 +66,20 @@ async function clusterTests() { try { console.log("Testing cluster"); console.log("Creating cluster"); - let redisCluster = await RedisCluster.createCluster(true, + let valkeyCluster = await ValkeyCluster.createCluster(true, 3, 1, ); console.log("Cluster created"); console.log("Connecting to cluster"); - let addresses = redisCluster.getAddresses().map((address) => { return { host: address[0], port: address[1] } }); - const client = await RedisClusterClient.createClient({ addresses: addresses }); + let addresses = valkeyCluster.getAddresses().map((address) => { return { host: address[0], port: address[1] } }); + const client = await GlideClusterClient.createClient({ addresses: addresses }); console.log("Connected to cluster"); await runCommands(client); - await closeClientAndCluster(client, redisCluster); + await closeClientAndCluster(client, valkeyCluster); console.log("Done"); } catch (error) { // Need this part just when running in our self-hosted runner, so if the test fails before closing Clusters we still kill them and clean up @@ -96,18 +96,18 @@ async function standaloneTests() { try { console.log("Testing standalone Cluster") console.log("Creating Cluster"); - let redisCluster = await RedisCluster.createCluster(false, + let valkeyCluster = await ValkeyCluster.createCluster(false, 1, 1, ); console.log("Cluster created"); console.log("Connecting to Cluster"); - let addresses = redisCluster.getAddresses().map((address) => { return { host: address[0], port: address[1] } }); - const client = await RedisClient.createClient({ addresses: addresses }); + let addresses = valkeyCluster.getAddresses().map((address) => { return { host: address[0], port: address[1] } }); + const client = await GlideClient.createClient({ addresses: addresses }); console.log("Connected to Cluster"); - await closeClientAndCluster(client, redisCluster); + await closeClientAndCluster(client, valkeyCluster); console.log("Done"); } catch (error) { From aa00b227397bd8940eec4dc4b1dce3a99640e631 Mon Sep 17 00:00:00 2001 From: adarovadya Date: Mon, 16 Sep 2024 18:13:08 +0300 Subject: [PATCH 02/18] Node: change createCluster args call (#2297) * fix create cluster call Signed-off-by: Adar Ovadia --------- Signed-off-by: Adar Ovadia Signed-off-by: adarovadya Co-authored-by: Adar Ovadia --- utils/release-candidate-testing/node/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/release-candidate-testing/node/index.js b/utils/release-candidate-testing/node/index.js index 40f5b86f12..2e36f65539 100644 --- a/utils/release-candidate-testing/node/index.js +++ b/utils/release-candidate-testing/node/index.js @@ -1,4 +1,5 @@ import { GlideClient, GlideClusterClient } from "@valkey/valkey-glide"; +import { getServerVersion } from "../../TestUtilities.js"; import { ValkeyCluster } from "../../TestUtils.js"; @@ -69,6 +70,7 @@ async function clusterTests() { let valkeyCluster = await ValkeyCluster.createCluster(true, 3, 1, + getServerVersion, ); console.log("Cluster created"); @@ -99,6 +101,7 @@ async function standaloneTests() { let valkeyCluster = await ValkeyCluster.createCluster(false, 1, 1, + getServerVersion, ); console.log("Cluster created"); From 891698d782609901e35b25d85c01fac89166a9fd Mon Sep 17 00:00:00 2001 From: adarovadya Date: Wed, 18 Sep 2024 14:13:00 +0300 Subject: [PATCH 03/18] Node: added the serverVersion parameter to createCluster call (#2311) * create getServerVersion func Signed-off-by: Adar Ovadia --------- Signed-off-by: Adar Ovadia Signed-off-by: adarovadya Co-authored-by: Adar Ovadia --- utils/release-candidate-testing/node/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/utils/release-candidate-testing/node/index.js b/utils/release-candidate-testing/node/index.js index 2e36f65539..51862c65c4 100644 --- a/utils/release-candidate-testing/node/index.js +++ b/utils/release-candidate-testing/node/index.js @@ -63,6 +63,11 @@ async function closeClientAndCluster(client, Cluster) { console.log("Clusters closed"); } +async function getServerVersion(addresses, clusterMode) { + // General version for those tests + return "255.255.255"; +} + async function clusterTests() { try { console.log("Testing cluster"); From 71d804ae2d8b116828411c40acb85fac94a91055 Mon Sep 17 00:00:00 2001 From: adarovadya Date: Wed, 18 Sep 2024 14:32:00 +0300 Subject: [PATCH 04/18] Node: remove unnecessary import (#2312) * create getServerVersion func Signed-off-by: Adar Ovadia --------- Signed-off-by: Adar Ovadia Co-authored-by: Adar Ovadia --- utils/release-candidate-testing/node/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/utils/release-candidate-testing/node/index.js b/utils/release-candidate-testing/node/index.js index 51862c65c4..b537c25468 100644 --- a/utils/release-candidate-testing/node/index.js +++ b/utils/release-candidate-testing/node/index.js @@ -1,5 +1,4 @@ import { GlideClient, GlideClusterClient } from "@valkey/valkey-glide"; -import { getServerVersion } from "../../TestUtilities.js"; import { ValkeyCluster } from "../../TestUtils.js"; From 59cfa7f9b5aa031a16dcc13b3d64460b22f81c20 Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Wed, 18 Sep 2024 08:45:39 -0700 Subject: [PATCH 05/18] Python: fix CD (#2302) * Fix python CD Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Install python 3.8 Signed-off-by: Yury-Fridlyand --------- Signed-off-by: Yury-Fridlyand --- .../install-shared-dependencies/action.yml | 1 - .github/workflows/pypi-cd.yml | 14 +++++++------- .github/workflows/python.yml | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/install-shared-dependencies/action.yml b/.github/workflows/install-shared-dependencies/action.yml index 0a134eecc9..abca1966cd 100644 --- a/.github/workflows/install-shared-dependencies/action.yml +++ b/.github/workflows/install-shared-dependencies/action.yml @@ -40,7 +40,6 @@ runs: if: "${{ inputs.os == 'macos' }}" run: | brew update - brew upgrade || true brew install git gcc pkgconfig openssl coreutils - name: Install software dependencies for Ubuntu GNU diff --git a/.github/workflows/pypi-cd.yml b/.github/workflows/pypi-cd.yml index b30810c233..9e0e3d1240 100644 --- a/.github/workflows/pypi-cd.yml +++ b/.github/workflows/pypi-cd.yml @@ -63,11 +63,11 @@ jobs: if: github.repository_owner == 'valkey-io' name: Publish packages to PyPi runs-on: ${{ matrix.build.RUNNER }} - timeout-minutes: 25 + timeout-minutes: 35 strategy: fail-fast: false matrix: - build: ${{fromJson( needs.load-platform-matrix.outputs.PLATFORM_MATRIX )}} + build: ${{ fromJson(needs.load-platform-matrix.outputs.PLATFORM_MATRIX) }} steps: - name: Setup self-hosted runner access if: ${{ contains(matrix.build.RUNNER, 'self-hosted') }} @@ -118,8 +118,7 @@ jobs: if: startsWith(matrix.build.NAMED_OS, 'darwin') run: | brew update - brew upgrade || true - brew install python@3.9 + brew install python@3.8 python@3.9 - name: Setup Python for self-hosted Ubuntu runners if: contains(matrix.build.OS, 'ubuntu') && contains(matrix.build.RUNNER, 'self-hosted') @@ -191,9 +190,9 @@ jobs: - name: Upload Python wheels if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: wheels + name: wheels-${{ matrix.build.TARGET }} path: python/wheels if-no-files-found: error @@ -206,7 +205,8 @@ jobs: - uses: actions/download-artifact@v4 with: path: python/wheels - name: wheels + merge-multiple: true + - name: Publish to PyPI uses: PyO3/maturin-action@v1 env: diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 2511c8c1f4..a1b5a16721 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -358,6 +358,6 @@ jobs: continue-on-error: true uses: actions/upload-artifact@v4 with: - name: smoke-test-report-amazon-linux + name: modules-test-report-${{ matrix.host.TARGET }}-python-${{ matrix.python }}-server-${{ matrix.engine.version }} path: | python/python/tests/pytest_report.html From c672c628b1b32552ce0af8ac1be5fdd3b48097b3 Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Wed, 18 Sep 2024 10:11:52 -0700 Subject: [PATCH 06/18] Java: fix pubsub IT for valkey 8 (#2300) * Signed-off-by: Yury-Fridlyand --- .../src/test/java/glide/PubSubTests.java | 141 ++++++++++-------- 1 file changed, 80 insertions(+), 61 deletions(-) diff --git a/java/integTest/src/test/java/glide/PubSubTests.java b/java/integTest/src/test/java/glide/PubSubTests.java index ff2220c0dd..e4eeab6cad 100644 --- a/java/integTest/src/test/java/glide/PubSubTests.java +++ b/java/integTest/src/test/java/glide/PubSubTests.java @@ -7,7 +7,6 @@ import static glide.TestUtilities.commonClusterClientConfig; import static glide.api.BaseClient.OK; import static glide.api.models.GlideString.gs; -import static glide.api.models.configuration.RequestRoutingConfiguration.SimpleMultiNodeRoute.ALL_NODES; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; @@ -36,6 +35,7 @@ import glide.api.models.exceptions.RequestException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -83,12 +83,15 @@ private BaseClient createClientWithSubscriptions( if (callback.isPresent()) { subConfigBuilder.callback(callback.get(), context.get()); } - return GlideClient.createClient( - commonClientConfig() - .requestTimeout(5000) - .subscriptionConfiguration(subConfigBuilder.build()) - .build()) - .get(); + var client = + GlideClient.createClient( + commonClientConfig() + .requestTimeout(5000) + .subscriptionConfiguration(subConfigBuilder.build()) + .build()) + .get(); + listeners.put(client, subscriptions); + return client; } else { var subConfigBuilder = ClusterSubscriptionConfiguration.builder() @@ -98,26 +101,35 @@ private BaseClient createClientWithSubscriptions( subConfigBuilder.callback(callback.get(), context.get()); } - return GlideClusterClient.createClient( - commonClusterClientConfig() - .requestTimeout(5000) - .subscriptionConfiguration(subConfigBuilder.build()) - .build()) - .get(); + var client = + GlideClusterClient.createClient( + commonClusterClientConfig() + .requestTimeout(5000) + .subscriptionConfiguration(subConfigBuilder.build()) + .build()) + .get(); + listeners.put(client, subscriptions); + return client; } } private BaseClient createClientWithSubscriptions( boolean standalone, Map> subscriptions) { - return createClientWithSubscriptions( - standalone, subscriptions, Optional.empty(), Optional.empty()); + var client = + createClientWithSubscriptions( + standalone, subscriptions, Optional.empty(), Optional.empty()); + listeners.put(client, subscriptions); + return client; } @SneakyThrows private BaseClient createClient(boolean standalone) { - return standalone - ? GlideClient.createClient(commonClientConfig().build()).get() - : GlideClusterClient.createClient(commonClusterClientConfig().build()).get(); + var client = + standalone + ? GlideClient.createClient(commonClientConfig().build()).get() + : GlideClusterClient.createClient(commonClusterClientConfig().build()).get(); + senders.add(client); + return client; } /** @@ -126,32 +138,67 @@ private BaseClient createClient(boolean standalone) { private final ConcurrentLinkedDeque> pubsubMessageQueue = new ConcurrentLinkedDeque<>(); - /** Clients used in a test. */ - private final List clients = new ArrayList<>(); + /** Subscribed clients used in a test. */ + private final Map>> listeners = + new HashMap<>(); + + /** Other clients used in a test. */ + private final List senders = new ArrayList<>(); private static final int MESSAGE_DELIVERY_DELAY = 500; // ms @AfterEach @SneakyThrows public void cleanup() { - for (var client : clients) { + for (var pair : listeners.entrySet()) { + var client = pair.getKey(); + var subscriptionTypes = pair.getValue(); if (client instanceof GlideClusterClient) { - ((GlideClusterClient) client) - .customCommand(new GlideString[] {gs("unsubscribe")}, ALL_NODES) - .get(); - ((GlideClusterClient) client) - .customCommand(new GlideString[] {gs("punsubscribe")}, ALL_NODES) - .get(); - ((GlideClusterClient) client) - .customCommand(new GlideString[] {gs("sunsubscribe")}, ALL_NODES) - .get(); + for (var subscription : subscriptionTypes.entrySet()) { + var channels = subscription.getValue().toArray(GlideString[]::new); + for (GlideString channel : channels) { + switch ((PubSubClusterChannelMode) subscription.getKey()) { + case EXACT: + ((GlideClusterClient) client) + .customCommand(new GlideString[] {gs("unsubscribe"), channel}) + .get(); + break; + case PATTERN: + ((GlideClusterClient) client) + .customCommand(new GlideString[] {gs("punsubscribe"), channel}) + .get(); + break; + case SHARDED: + ((GlideClusterClient) client) + .customCommand(new GlideString[] {gs("sunsubscribe"), channel}) + .get(); + break; + } + } + } } else { - ((GlideClient) client).customCommand(new GlideString[] {gs("unsubscribe")}).get(); - ((GlideClient) client).customCommand(new GlideString[] {gs("punsubscribe")}).get(); + for (var subscription : subscriptionTypes.entrySet()) { + var channels = subscription.getValue().toArray(GlideString[]::new); + switch ((PubSubChannelMode) subscription.getKey()) { + case EXACT: + ((GlideClient) client) + .customCommand(ArrayUtils.addFirst(channels, gs("unsubscribe"))) + .get(); + break; + case PATTERN: + ((GlideClient) client) + .customCommand(ArrayUtils.addFirst(channels, gs("punsubscribe"))) + .get(); + break; + } + } } + } + listeners.clear(); + for (var client : senders) { client.close(); } - clients.clear(); + senders.clear(); pubsubMessageQueue.clear(); } @@ -246,7 +293,6 @@ public void exact_happy_path(boolean standalone, MessageReadMethod method) { var listener = createListener(standalone, method == MessageReadMethod.Callback, 1, subscriptions); var sender = createClient(standalone); - clients.addAll(List.of(listener, sender)); sender.publish(message, channel).get(); Thread.sleep(MESSAGE_DELIVERY_DELAY); // deliver the message @@ -279,7 +325,6 @@ public void exact_happy_path_many_channels(boolean standalone, MessageReadMethod var listener = createListener(standalone, method == MessageReadMethod.Callback, 1, subscriptions); var sender = createClient(standalone); - clients.addAll(List.of(listener, sender)); for (var pubsubMessage : messages) { sender.publish(pubsubMessage.getMessage(), pubsubMessage.getChannel()).get(); @@ -305,7 +350,6 @@ public void sharded_pubsub(MessageReadMethod method) { var listener = createListener(false, method == MessageReadMethod.Callback, 1, subscriptions); var sender = (GlideClusterClient) createClient(false); - clients.addAll(List.of(listener, sender)); sender.publish(pubsubMessage, channel, true).get(); Thread.sleep(MESSAGE_DELIVERY_DELAY); // deliver the message @@ -339,7 +383,6 @@ public void sharded_pubsub_many_channels(MessageReadMethod method) { var listener = createListener(false, method == MessageReadMethod.Callback, 1, subscriptions); var sender = (GlideClusterClient) createClient(false); - clients.addAll(List.of(listener, sender)); for (var pubsubMessage : pubsubMessages) { sender.publish(pubsubMessage.getMessage(), pubsubMessage.getChannel(), true).get(); @@ -376,7 +419,6 @@ public void pattern(boolean standalone, MessageReadMethod method) { var listener = createListener(standalone, method == MessageReadMethod.Callback, 1, subscriptions); var sender = createClient(standalone); - clients.addAll(List.of(listener, sender)); Thread.sleep(MESSAGE_DELIVERY_DELAY); // need some time to propagate subscriptions - why? @@ -419,7 +461,6 @@ public void pattern_many_channels(boolean standalone, MessageReadMethod method) var listener = createListener(standalone, method == MessageReadMethod.Callback, 1, subscriptions); var sender = createClient(standalone); - clients.addAll(List.of(listener, sender)); Thread.sleep(MESSAGE_DELIVERY_DELAY); // need some time to propagate subscriptions - why? @@ -470,7 +511,6 @@ public void combined_exact_and_pattern_one_client(boolean standalone, MessageRea var listener = createListener(standalone, method == MessageReadMethod.Callback, 1, subscriptions); var sender = createClient(standalone); - clients.addAll(List.of(listener, sender)); for (var pubsubMessage : messages) { sender.publish(pubsubMessage.getMessage(), pubsubMessage.getChannel()).get(); @@ -519,7 +559,6 @@ public void combined_exact_and_pattern_multiple_clients( createListener(standalone, method == MessageReadMethod.Callback, 2, subscriptions); var sender = createClient(standalone); - clients.addAll(List.of(listenerExactSub, listenerPatternSub, sender)); for (var pubsubMessage : messages) { sender.publish(pubsubMessage.getMessage(), pubsubMessage.getChannel()).get(); @@ -596,7 +635,6 @@ public void combined_exact_pattern_and_sharded_one_client(MessageReadMethod meth var listener = createListener(false, method == MessageReadMethod.Callback, 1, subscriptions); var sender = (GlideClusterClient) createClient(false); - clients.addAll(List.of(listener, sender)); for (var pubsubMessage : messages) { sender.publish(pubsubMessage.getMessage(), pubsubMessage.getChannel()).get(); @@ -653,7 +691,6 @@ public void coexistense_of_sync_and_async_read() { var listener = createListener(false, false, 1, subscriptions); var sender = (GlideClusterClient) createClient(false); - clients.addAll(List.of(listener, sender)); for (var pubsubMessage : messages) { sender.publish(pubsubMessage.getMessage(), pubsubMessage.getChannel()).get(); @@ -756,7 +793,6 @@ public void combined_exact_pattern_and_sharded_multi_client(MessageReadMethod me subscriptionsSharded); var sender = (GlideClusterClient) createClient(false); - clients.addAll(List.of(listenerExact, listenerPattern, listenerSharded, sender)); for (var pubsubMessage : exactMessages) { sender.publish(pubsubMessage.getMessage(), pubsubMessage.getChannel()).get(); @@ -849,8 +885,6 @@ public void three_publishing_clients_same_name_with_sharded(MessageReadMethod me false, true, PubSubClusterChannelMode.SHARDED.ordinal(), subscriptionsSharded) : (GlideClusterClient) createClientWithSubscriptions(false, subscriptionsSharded); - clients.addAll(List.of(listenerExact, listenerPattern, listenerSharded)); - listenerPattern.publish(exactMessage.getMessage(), channel).get(); listenerSharded.publish(patternMessage.getMessage(), channel).get(); listenerExact.publish(shardedMessage.getMessage(), channel, true).get(); @@ -961,7 +995,6 @@ public void transaction_with_all_types_of_messages(boolean standalone, MessageRe var listener = createListener(standalone, method == MessageReadMethod.Callback, 1, subscriptions); var sender = createClient(standalone); - clients.addAll(List.of(listener, sender)); if (standalone) { var transaction = @@ -1004,7 +1037,6 @@ public void pubsub_exact_max_size_message(boolean standalone) { : Map.of(PubSubClusterChannelMode.EXACT, Set.of(channel)); var listener = createClientWithSubscriptions(standalone, subscriptions); var sender = createClient(standalone); - clients.addAll(Arrays.asList(listener, sender)); assertEquals(OK, sender.publish(message, channel).get()); assertEquals(OK, sender.publish(message2, channel).get()); @@ -1044,7 +1076,6 @@ public void pubsub_sharded_max_size_message(boolean standalone) { Map.of(PubSubClusterChannelMode.SHARDED, Set.of(channel)); var listener = createClientWithSubscriptions(standalone, subscriptions); var sender = createClient(standalone); - clients.addAll(Arrays.asList(listener, sender)); assertEquals(OK, sender.publish(message, channel).get()); assertEquals(OK, ((GlideClusterClient) sender).publish(message2, channel, true).get()); @@ -1101,7 +1132,6 @@ public void pubsub_exact_max_size_message_callback(boolean standalone) { Optional.ofNullable(callback), Optional.of(callbackMessages)); var sender = createClient(standalone); - clients.addAll(Arrays.asList(listener, sender)); assertEquals(OK, sender.publish(message, channel).get()); @@ -1143,7 +1173,6 @@ public void pubsub_sharded_max_size_message_callback(boolean standalone) { Optional.ofNullable(callback), Optional.of(callbackMessages)); var sender = createClient(standalone); - clients.addAll(Arrays.asList(listener, sender)); assertEquals(OK, ((GlideClusterClient) sender).publish(message, channel, true).get()); @@ -1188,7 +1217,6 @@ public void pubsub_test_callback_exception(boolean standalone) { Optional.ofNullable(callback), Optional.of(callbackMessages)); var sender = createClient(standalone); - clients.addAll(Arrays.asList(listener, sender)); assertEquals(OK, sender.publish(message1, channel).get()); assertEquals(OK, sender.publish(message2, channel).get()); @@ -1241,7 +1269,6 @@ public void pubsub_with_binary(boolean standalone) { createClientWithSubscriptions( standalone, subscriptions, Optional.of(callback), Optional.of(callbackMessages)); var sender = createClient(standalone); - clients.addAll(List.of(listener, listener2, sender)); assertEquals(OK, sender.publish(message.getMessage(), channel).get()); Thread.sleep(MESSAGE_DELIVERY_DELAY); // deliver the messages @@ -1277,7 +1304,6 @@ public void pubsub_channels(boolean standalone) { channels.stream().map(GlideString::gs).collect(Collectors.toSet())); var listener = createClientWithSubscriptions(standalone, subscriptions); - clients.addAll(List.of(client, listener)); // test without pattern assertEquals(channels, Set.of(client.pubsubChannels().get())); @@ -1330,7 +1356,6 @@ public void pubsub_numpat(boolean standalone) { patterns.stream().map(GlideString::gs).collect(Collectors.toSet())); var listener = createClientWithSubscriptions(standalone, subscriptions); - clients.addAll(List.of(client, listener)); assertEquals(2, client.pubsubNumPat().get()); assertEquals(2, listener.pubsubNumPat().get()); @@ -1376,8 +1401,6 @@ public void pubsub_numsub(boolean standalone) { : Map.of(PubSubClusterChannelMode.PATTERN, Set.of(gs("channel*"))); var listener4 = createClientWithSubscriptions(standalone, subscriptions4); - clients.addAll(List.of(client, listener1, listener2, listener3, listener4)); - var expected = Map.of("channel1", 1L, "channel2", 2L, "channel3", 3L, "channel4", 0L); assertEquals(expected, client.pubsubNumSub(ArrayUtils.addFirst(channels, "channel4")).get()); assertEquals(expected, listener1.pubsubNumSub(ArrayUtils.addFirst(channels, "channel4")).get()); @@ -1447,7 +1470,6 @@ public void pubsub_channels_and_numpat_and_numsub_in_transaction(boolean standal patterns.stream().map(GlideString::gs).collect(Collectors.toSet())); var listener = createClientWithSubscriptions(standalone, subscriptions); - clients.addAll(List.of(client, listener)); result = standalone @@ -1491,7 +1513,6 @@ public void pubsub_shard_channels() { GlideClusterClient listener = (GlideClusterClient) createClientWithSubscriptions(false, subscriptions); - clients.addAll(List.of(client, listener)); // test without pattern assertEquals(channels, Set.of(client.pubsubShardChannels().get())); @@ -1553,8 +1574,6 @@ public void pubsub_shardnumsub() { GlideClusterClient listener3 = (GlideClusterClient) createClientWithSubscriptions(false, subscriptions3); - clients.addAll(List.of(client, listener1, listener2, listener3)); - var expected = Map.of("channel1", 1L, "channel2", 2L, "channel3", 3L, "channel4", 0L); assertEquals( expected, client.pubsubShardNumSub(ArrayUtils.addFirst(channels, "channel4")).get()); From e37308dc4b85bb5a4ccfd323ae9145fc839f9cd1 Mon Sep 17 00:00:00 2001 From: Yi-Pin Chen Date: Wed, 18 Sep 2024 23:27:25 -0700 Subject: [PATCH 07/18] Node: Fixed missing exports (#2301) Node: include missing exports in the npm release Signed-off-by: Yi-Pin Chen Signed-off-by: Andrew Carbonetto --- CHANGELOG.md | 1 + examples/node/index.ts | 2 +- examples/node/package.json | 2 +- node/npm/glide/index.ts | 12 ++++++++++++ node/src/Logger.ts | 2 +- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5a454a708..f8809ae7af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ #### Changes +* Node: Fixed missing exports ([#2301](https://github.com/valkey-io/valkey-glide/pull/2301)) * Node: Use `options` struct for all optional arguments ([#2287](https://github.com/valkey-io/valkey-glide/pull/2287)) * Node: Added `invokeScript` API with routing for cluster client ([#2284](https://github.com/valkey-io/valkey-glide/pull/2284)) * Java: Expanded tests for converting non UTF-8 bytes to Strings ([#2286](https://github.com/valkey-io/valkey-glide/pull/2286)) diff --git a/examples/node/index.ts b/examples/node/index.ts index 49fa9a531d..a72180b17c 100644 --- a/examples/node/index.ts +++ b/examples/node/index.ts @@ -49,7 +49,7 @@ async function sendPingToRandomNodeInCluster() { clientName: "test_cluster_client", }); // The empty array signifies that there are no additional arguments. - const pong = await client.customCommand(["PING"], "randomNode"); + const pong = await client.customCommand(["PING"], { route: "randomNode" }); console.log(pong); await send_set_and_get(client); client.close(); diff --git a/examples/node/package.json b/examples/node/package.json index 1521a6d8c4..712ae76e02 100644 --- a/examples/node/package.json +++ b/examples/node/package.json @@ -1,7 +1,7 @@ { "type": "module", "dependencies": { - "@valkey/valkey-glide": "^1.0.0", + "@valkey/valkey-glide": "^1.1.0", "@types/node": "^20.4.8" }, "devDependencies": { diff --git a/node/npm/glide/index.ts b/node/npm/glide/index.ts index 546f3ebe83..7d307b3c0c 100644 --- a/node/npm/glide/index.ts +++ b/node/npm/glide/index.ts @@ -192,6 +192,12 @@ function initialize() { createLeakedMap, createLeakedString, parseInfoResponse, + Script, + ObjectType, + ClusterScanCursor, + BaseClientConfiguration, + GlideClusterClientConfiguration, + LevelOptions, } = nativeBinding; module.exports = { @@ -305,6 +311,12 @@ function initialize() { createLeakedMap, createLeakedString, parseInfoResponse, + Script, + ObjectType, + ClusterScanCursor, + BaseClientConfiguration, + GlideClusterClientConfiguration, + LevelOptions, }; globalObject = Object.assign(global, nativeBinding); diff --git a/node/src/Logger.ts b/node/src/Logger.ts index f5f09d269d..df38c77994 100644 --- a/node/src/Logger.ts +++ b/node/src/Logger.ts @@ -12,7 +12,7 @@ const LEVEL = new Map([ ["trace", Level.Trace], [undefined, undefined], ]); -type LevelOptions = "error" | "warn" | "info" | "debug" | "trace"; +export type LevelOptions = "error" | "warn" | "info" | "debug" | "trace"; /* * A singleton class that allows logging which is consistent with logs from the internal rust core. From 1c3aa0d4aded532c7474e74663dd0d72a42c5e55 Mon Sep 17 00:00:00 2001 From: Yury-Fridlyand Date: Thu, 19 Sep 2024 01:38:07 -0700 Subject: [PATCH 08/18] Node: fix pubsub IT by making sure cluster mode tests run only with cluster mode enabled flag (#2317) * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand --- node/tests/PubSub.test.ts | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/node/tests/PubSub.test.ts b/node/tests/PubSub.test.ts index 82aec7f826..5e8d40207a 100644 --- a/node/tests/PubSub.test.ts +++ b/node/tests/PubSub.test.ts @@ -4018,7 +4018,7 @@ describe("PubSub", () => { * * @param clusterMode - Indicates if the test should be run in cluster mode. */ - it.each([true, false])( + it.each([true])( "test pubsub numsub and shardnumsub separation_%p", async (clusterMode) => { //const clusterMode = false; @@ -4070,17 +4070,13 @@ describe("PubSub", () => { }); // Test pubsubShardnumsub - if (clusterMode) { - const shardSubscribers = await ( - client2 as GlideClusterClient - ).pubsubShardNumSub([regularChannel, shardChannel]); - expect( - convertGlideRecordToRecord(shardSubscribers), - ).toEqual({ - [regularChannel]: 0, - [shardChannel]: 2, - }); - } + const shardSubscribers = await ( + client2 as GlideClusterClient + ).pubsubShardNumSub([regularChannel, shardChannel]); + expect(convertGlideRecordToRecord(shardSubscribers)).toEqual({ + [regularChannel]: 0, + [shardChannel]: 2, + }); } finally { if (client1) { await clientCleanup(client1, pubSub!); From 1c334fd85beba25838c23bdb917eee46c26626f5 Mon Sep 17 00:00:00 2001 From: Shoham Elias <116083498+shohamazon@users.noreply.github.com> Date: Thu, 19 Sep 2024 13:07:38 +0300 Subject: [PATCH 09/18] Update Valkey version to 8.0.0 in test matrix and version checks (#2296) Signed-off-by: Shoham Elias --- .github/json_matrices/engine-matrix.json | 2 +- .../test/java/glide/SharedCommandTests.java | 44 ++++++++----------- .../java/glide/TransactionTestUtilities.java | 12 ++--- .../cluster/ClusterTransactionTests.java | 4 +- .../test/java/glide/cluster/CommandTests.java | 6 +-- .../java/glide/standalone/CommandTests.java | 8 ++-- node/tests/SharedTests.ts | 25 +++++------ node/tests/TestUtilities.ts | 6 +-- python/python/tests/test_async_client.py | 25 +++++------ python/python/tests/test_transaction.py | 8 ++-- 10 files changed, 61 insertions(+), 79 deletions(-) diff --git a/.github/json_matrices/engine-matrix.json b/.github/json_matrices/engine-matrix.json index bf755b782e..464aedf31a 100644 --- a/.github/json_matrices/engine-matrix.json +++ b/.github/json_matrices/engine-matrix.json @@ -5,6 +5,6 @@ }, { "type": "valkey", - "version": "8.0.0-rc1" + "version": "8.0.0" } ] diff --git a/java/integTest/src/test/java/glide/SharedCommandTests.java b/java/integTest/src/test/java/glide/SharedCommandTests.java index c3e600d5c9..3224f45c5c 100644 --- a/java/integTest/src/test/java/glide/SharedCommandTests.java +++ b/java/integTest/src/test/java/glide/SharedCommandTests.java @@ -918,14 +918,10 @@ public void getrange(BaseClient client) { assertEquals("", client.getrange(stringKey, -1, -3).get()); // a redis bug, fixed in version 8: https://github.com/redis/redis/issues/13207 - assertEquals( - SERVER_VERSION.isLowerThan("8.0.0") ? "T" : "", - client.getrange(stringKey, -200, -100).get()); + assertEquals("T", client.getrange(stringKey, -200, -100).get()); // empty key (returning null isn't implemented) - assertEquals( - SERVER_VERSION.isLowerThan("8.0.0") ? "" : null, - client.getrange(nonStringKey, 0, -1).get()); + assertEquals("", client.getrange(nonStringKey, 0, -1).get()); // non-string key assertEquals(1, client.lpush(nonStringKey, new String[] {"_"}).get()); @@ -955,14 +951,10 @@ public void getrange_binary(BaseClient client) { assertEquals(gs(""), client.getrange(stringKey, -1, -3).get()); // a redis bug, fixed in version 8: https://github.com/redis/redis/issues/13207 - assertEquals( - gs(SERVER_VERSION.isLowerThan("8.0.0") ? "T" : ""), - client.getrange(stringKey, -200, -100).get()); + assertEquals(gs("T"), client.getrange(stringKey, -200, -100).get()); // empty key (returning null isn't implemented) - assertEquals( - gs(SERVER_VERSION.isLowerThan("8.0.0") ? "" : null), - client.getrange(nonStringKey, 0, -1).get()); + assertEquals(gs(""), client.getrange(nonStringKey, 0, -1).get()); // non-string key assertEquals(1, client.lpush(nonStringKey, new GlideString[] {gs("_")}).get()); @@ -3279,7 +3271,7 @@ public void persist_on_existing_and_non_existing_key(BaseClient client) { @ParameterizedTest(autoCloseArguments = false) @MethodSource("getClients") public void scriptShow_test(BaseClient client) { - assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")); + assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")); String code = "return '" + UUID.randomUUID().toString().substring(0, 5) + "'"; Script script = new Script(code, false); @@ -10423,7 +10415,7 @@ public void bitcount(BaseClient client) { () -> client.bitcount(key1, 5, 30, BitmapIndexType.BIT).get()); assertTrue(executionException.getCause() instanceof RequestException); } - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { assertEquals(26L, client.bitcount(key1, 0).get()); assertEquals(4L, client.bitcount(key1, 5).get()); assertEquals(0L, client.bitcount(key1, 80).get()); @@ -12557,7 +12549,7 @@ public void sort_binary(BaseClient client) { @MethodSource("getClients") public void sort_with_pattern(BaseClient client) { if (client instanceof GlideClusterClient) { - assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0"), "This feature added in version 8"); + assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0"), "This feature added in version 8"); } String setKey1 = "{setKey}1"; String setKey2 = "{setKey}2"; @@ -12739,7 +12731,7 @@ public void sort_with_pattern(BaseClient client) { @MethodSource("getClients") public void sort_with_pattern_binary(BaseClient client) { if (client instanceof GlideClusterClient) { - assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0"), "This feature added in version 8"); + assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0"), "This feature added in version 8"); } GlideString setKey1 = gs("{setKeyGs}1"); @@ -14291,7 +14283,7 @@ public void sscan(BaseClient client) { assertDeepEquals(new String[] {}, result[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { ExecutionException executionException = assertThrows(ExecutionException.class, () -> client.sscan(key1, "-1").get()); } else { @@ -14432,7 +14424,7 @@ public void sscan_binary(BaseClient client) { assertDeepEquals(new GlideString[] {}, result[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { ExecutionException executionException = assertThrows(ExecutionException.class, () -> client.sscan(key1, gs("-1")).get()); } else { @@ -14586,7 +14578,7 @@ public void zscan(BaseClient client) { assertDeepEquals(new String[] {}, result[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { ExecutionException executionException = assertThrows(ExecutionException.class, () -> client.zscan(key1, "-1").get()); } else { @@ -14710,7 +14702,7 @@ public void zscan(BaseClient client) { assertTrue(Long.parseLong(result[resultCursorIndex].toString()) >= 0); assertTrue(ArrayUtils.getLength(result[resultCollectionIndex]) >= 0); - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { result = client.zscan(key1, initialCursor, ZScanOptions.builder().noScores(true).build()).get(); assertTrue(Long.parseLong(result[resultCursorIndex].toString()) >= 0); @@ -14788,7 +14780,7 @@ public void zscan_binary(BaseClient client) { assertDeepEquals(new GlideString[] {}, result[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { ExecutionException executionException = assertThrows(ExecutionException.class, () -> client.zscan(key1, gs("-1")).get()); } else { @@ -14917,7 +14909,7 @@ public void zscan_binary(BaseClient client) { assertTrue(Long.parseLong(result[resultCursorIndex].toString()) >= 0); assertTrue(ArrayUtils.getLength(result[resultCollectionIndex]) >= 0); - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { result = client .zscan(key1, initialCursor, ZScanOptionsBinary.builder().noScores(true).build()) @@ -14993,7 +14985,7 @@ public void hscan(BaseClient client) { assertDeepEquals(new String[] {}, result[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { ExecutionException executionException = assertThrows(ExecutionException.class, () -> client.hscan(key1, "-1").get()); } else { @@ -15104,7 +15096,7 @@ public void hscan(BaseClient client) { assertTrue(Long.parseLong(result[resultCursorIndex].toString()) >= 0); assertTrue(ArrayUtils.getLength(result[resultCollectionIndex]) >= 0); - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { result = client.hscan(key1, initialCursor, HScanOptions.builder().noValues(true).build()).get(); assertTrue(Long.parseLong(result[resultCursorIndex].toString()) >= 0); @@ -15175,7 +15167,7 @@ public void hscan_binary(BaseClient client) { assertDeepEquals(new GlideString[] {}, result[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { ExecutionException executionException = assertThrows(ExecutionException.class, () -> client.hscan(key1, gs("-1")).get()); } else { @@ -15293,7 +15285,7 @@ public void hscan_binary(BaseClient client) { assertTrue(Long.parseLong(result[resultCursorIndex].toString()) >= 0); assertTrue(ArrayUtils.getLength(result[resultCollectionIndex]) >= 0); - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { result = client .hscan(key1, initialCursor, HScanOptionsBinary.builder().noValues(true).build()) diff --git a/java/integTest/src/test/java/glide/TransactionTestUtilities.java b/java/integTest/src/test/java/glide/TransactionTestUtilities.java index 30675fcc56..46545f786a 100644 --- a/java/integTest/src/test/java/glide/TransactionTestUtilities.java +++ b/java/integTest/src/test/java/glide/TransactionTestUtilities.java @@ -382,7 +382,7 @@ private static Object[] hashCommands(BaseTransaction transaction) { .hscan(hashKey2, "0") .hscan(hashKey2, "0", HScanOptions.builder().count(20L).build()); - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { transaction .hscan(hashKey2, "0", HScanOptions.builder().count(20L).noValues(false).build()) .hscan(hashKey2, "0", HScanOptions.builder().count(20L).noValues(true).build()); @@ -417,7 +417,7 @@ private static Object[] hashCommands(BaseTransaction transaction) { }, // hscan(hashKey2, "0", HScanOptions.builder().count(20L).build()); }; - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { result = concatenateArrays( result, @@ -670,7 +670,7 @@ private static Object[] sortedSetCommands(BaseTransaction transaction) { .zrandmemberWithCountWithScores(zSetKey2, 1) .zscan(zSetKey2, "0") .zscan(zSetKey2, "0", ZScanOptions.builder().count(20L).build()); - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { transaction .zscan(zSetKey2, 0, ZScanOptions.builder().count(20L).noScores(false).build()) .zscan(zSetKey2, 0, ZScanOptions.builder().count(20L).noScores(true).build()); @@ -741,7 +741,7 @@ private static Object[] sortedSetCommands(BaseTransaction transaction) { }, // zscan(zSetKey2, 0, ZScanOptions.builder().count(20L).build()) }; - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { expectedResults = concatenateArrays( expectedResults, @@ -1288,7 +1288,7 @@ private static Object[] bitmapCommands(BaseTransaction transaction) { .bitpos(key3, 1, 44, 50, BitmapIndexType.BIT); } - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { transaction.set(key4, "foobar").bitcount(key4, 0); } @@ -1321,7 +1321,7 @@ private static Object[] bitmapCommands(BaseTransaction transaction) { }); } - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { expectedResults = concatenateArrays( expectedResults, diff --git a/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java b/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java index faf13c2ecd..4f5c2a7918 100644 --- a/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java +++ b/java/integTest/src/test/java/glide/cluster/ClusterTransactionTests.java @@ -311,7 +311,7 @@ public void sort() { transaction.sortReadOnly(key1, SortOptions.builder().orderBy(DESC).build()); } - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { transaction .hset(key3, Map.of("name", "Alice", "age", "30")) .hset(key4, Map.of("name", "Bob", "age", "25")) @@ -358,7 +358,7 @@ public void sort() { ); } - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { expectedResult = concatenateArrays( expectedResult, diff --git a/java/integTest/src/test/java/glide/cluster/CommandTests.java b/java/integTest/src/test/java/glide/cluster/CommandTests.java index bd893a7693..cadd37a707 100644 --- a/java/integTest/src/test/java/glide/cluster/CommandTests.java +++ b/java/integTest/src/test/java/glide/cluster/CommandTests.java @@ -1055,7 +1055,7 @@ public void flushall() { assertEquals(OK, clusterClient.flushall(ASYNC, route).get()); var replicaRoute = new SlotKeyRoute("key", REPLICA); - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { // Since Valkey 8.0.0 flushall can run on replicas assertEquals(OK, clusterClient.flushall(route).get()); } else { @@ -1650,7 +1650,7 @@ public void fcall_binary_with_keys(String prefix) { public void fcall_readonly_function() { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assumeTrue( - !SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0"), + !SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0"), "Temporary disabeling this test on valkey 8"); String libName = "fcall_readonly_function"; @@ -1708,7 +1708,7 @@ public void fcall_readonly_function() { public void fcall_readonly_binary_function() { assumeTrue(SERVER_VERSION.isGreaterThanOrEqualTo("7.0.0"), "This feature added in version 7"); assumeTrue( - !SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0"), + !SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0"), "Temporary disabeling this test on valkey 8"); String libName = "fcall_readonly_function"; diff --git a/java/integTest/src/test/java/glide/standalone/CommandTests.java b/java/integTest/src/test/java/glide/standalone/CommandTests.java index 34abf7861e..5e558a0273 100644 --- a/java/integTest/src/test/java/glide/standalone/CommandTests.java +++ b/java/integTest/src/test/java/glide/standalone/CommandTests.java @@ -1176,7 +1176,7 @@ public void scan() { assertDeepEquals(new String[] {}, emptyResult[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { ExecutionException executionException = assertThrows(ExecutionException.class, () -> regularClient.scan("-1").get()); } else { @@ -1235,7 +1235,7 @@ public void scan_binary() { assertDeepEquals(new String[] {}, emptyResult[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { ExecutionException executionException = assertThrows(ExecutionException.class, () -> regularClient.scan(gs("-1")).get()); } else { @@ -1303,7 +1303,7 @@ public void scan_with_options() { assertDeepEquals(new String[] {}, emptyResult[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { final ScanOptions finalOptions = options; ExecutionException executionException = assertThrows( @@ -1392,7 +1392,7 @@ public void scan_binary_with_options() { assertDeepEquals(new String[] {}, emptyResult[resultCollectionIndex]); // Negative cursor - if (SERVER_VERSION.isGreaterThanOrEqualTo("7.9.0")) { + if (SERVER_VERSION.isGreaterThanOrEqualTo("8.0.0")) { final ScanOptions finalOptions = options; ExecutionException executionException = assertThrows( diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index 75d37cd316..04f589c0ae 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -1297,7 +1297,7 @@ export function runBaseTests(config: { it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])( `getrange test_%p`, async (protocol) => { - await runTest(async (client: BaseClient, cluster) => { + await runTest(async (client: BaseClient) => { const key = uuidv4(); const nonStringKey = uuidv4(); const valueEncoded = Buffer.from("This is a string"); @@ -1337,15 +1337,10 @@ export function runBaseTests(config: { // incorrect range expect(await client.getrange(key, -1, -3)).toEqual(""); - // a bug fixed in version 8: https://github.com/redis/redis/issues/13207 - expect(await client.getrange(key, -200, -100)).toEqual( - cluster.checkIfServerVersionLessThan("8.0.0") ? "T" : "", - ); + expect(await client.getrange(key, -200, -100)).toEqual("T"); // empty key (returning null isn't implemented) - expect(await client.getrange(nonStringKey, 0, -1)).toEqual( - cluster.checkIfServerVersionLessThan("8.0.0") ? "" : null, - ); + expect(await client.getrange(nonStringKey, 0, -1)).toEqual(""); // non-string key expect(await client.lpush(nonStringKey, ["_"])).toEqual(1); @@ -1604,7 +1599,7 @@ export function runBaseTests(config: { expect(result[resultCursorIndex]).not.toEqual(initialCursor); expect(result[resultCollectionIndex].length).toBeGreaterThan(0); - if (!cluster.checkIfServerVersionLessThan("7.9.0")) { + if (!cluster.checkIfServerVersionLessThan("8.0.0")) { const result = await client.hscan(key1, initialCursor, { noValues: true, }); @@ -1645,7 +1640,7 @@ export function runBaseTests(config: { expect(result2[resultCollectionIndex]).toEqual([]); // Negative cursor - if (cluster.checkIfServerVersionLessThan("7.9.0")) { + if (cluster.checkIfServerVersionLessThan("8.0.0")) { result = await client.hscan(key1, "-1"); expect(result[resultCursorIndex]).toEqual( initialCursor, @@ -4194,7 +4189,7 @@ export function runBaseTests(config: { `script show test_%p`, async (protocol) => { await runTest(async (client: BaseClient, cluster) => { - if (cluster.checkIfServerVersionLessThan("7.9.0")) { + if (cluster.checkIfServerVersionLessThan("8.0.0")) { return; } @@ -8921,7 +8916,7 @@ export function runBaseTests(config: { ).rejects.toThrow(RequestError); } - if (cluster.checkIfServerVersionLessThan("7.9.0")) { + if (cluster.checkIfServerVersionLessThan("8.0.0")) { await expect( client.bitcount(key1, { start: 2, @@ -9755,7 +9750,7 @@ export function runBaseTests(config: { expect(result[resultCollectionIndex]).toEqual([]); // Negative cursor - if (cluster.checkIfServerVersionLessThan("7.9.0")) { + if (cluster.checkIfServerVersionLessThan("8.0.0")) { result = await client.zscan(key1, "-1"); expect(result[resultCursorIndex]).toEqual( initialCursor, @@ -9869,7 +9864,7 @@ export function runBaseTests(config: { result[resultCollectionIndex].length, ).toBeGreaterThan(0); - if (!cluster.checkIfServerVersionLessThan("7.9.0")) { + if (!cluster.checkIfServerVersionLessThan("8.0.0")) { const result = await client.zscan(key1, initialCursor, { noScores: true, }); @@ -12079,7 +12074,7 @@ export function runBaseTests(config: { await runTest( async (client: BaseClient, cluster: ValkeyCluster) => { if ( - cluster.checkIfServerVersionLessThan("7.9.0") && + cluster.checkIfServerVersionLessThan("8.0.0") && client instanceof GlideClusterClient ) { return; diff --git a/node/tests/TestUtilities.ts b/node/tests/TestUtilities.ts index b79259c01d..6da0a39f00 100644 --- a/node/tests/TestUtilities.ts +++ b/node/tests/TestUtilities.ts @@ -812,7 +812,7 @@ export async function transactionTest( baseTransaction.hscan(key4, "0"); responseData.push(['hscan(key4, "0")', ["0", [field, value]]]); - if (gte(version, "7.9.0")) { + if (gte(version, "8.0.0")) { baseTransaction.hscan(key4, "0", { noValues: false }); responseData.push([ 'hscan(key4, "0", {noValues: false})', @@ -1081,7 +1081,7 @@ export async function transactionTest( baseTransaction.zscan(key12, "0"); responseData.push(['zscan(key12, "0")', ["0", ["one", "1", "two", "2"]]]); - if (gte(version, "7.9.0")) { + if (gte(version, "8.0.0")) { baseTransaction.zscan(key12, "0", { noScores: false }); responseData.push([ 'zscan(key12, "0", {noScores: false})', @@ -1463,7 +1463,7 @@ export async function transactionTest( ]); } - if (gte(version, "7.9.0")) { + if (gte(version, "8.0.0")) { baseTransaction.set(key17, "foobar"); responseData.push(['set(key17, "foobar")', "OK"]); baseTransaction.bitcount(key17, { diff --git a/python/python/tests/test_async_client.py b/python/python/tests/test_async_client.py index 7febd0e2c9..e9897c7b2d 100644 --- a/python/python/tests/test_async_client.py +++ b/python/python/tests/test_async_client.py @@ -539,14 +539,9 @@ async def test_getrange(self, glide_client: TGlideClient): # incorrect range assert await glide_client.getrange(key, -1, -3) == b"" - # a redis bug, fixed in version 8: https://github.com/redis/redis/issues/13207 - if await check_if_server_version_lt(glide_client, "8.0.0"): - assert await glide_client.getrange(key, -200, -100) == value[0].encode() - else: - assert await glide_client.getrange(key, -200, -100) == b"" + assert await glide_client.getrange(key, -200, -100) == value[0].encode() - if await check_if_server_version_lt(glide_client, "8.0.0"): - assert await glide_client.getrange(non_string_key, 0, -1) == b"" + assert await glide_client.getrange(non_string_key, 0, -1) == b"" # non-string key assert await glide_client.lpush(non_string_key, ["_"]) == 1 @@ -4720,7 +4715,7 @@ async def test_sort_and_sort_store_with_get_or_by_args( ): if isinstance( glide_client, GlideClusterClient - ) and await check_if_server_version_lt(glide_client, "7.9.0"): + ) and await check_if_server_version_lt(glide_client, "8.0.0"): return pytest.mark.skip( reason=f"Valkey version required in cluster mode>= 8.0.0" ) @@ -7133,7 +7128,7 @@ async def test_bitcount(self, glide_client: TGlideClient): set_key, OffsetOptions(1, 1, BitmapIndexType.BIT) ) - if await check_if_server_version_lt(glide_client, "7.9.0"): + if await check_if_server_version_lt(glide_client, "8.0.0"): # exception thrown optional end was implemented after 8.0.0 with pytest.raises(RequestError): await glide_client.bitcount( @@ -9835,7 +9830,7 @@ async def test_sscan(self, glide_client: GlideClusterClient): assert result[result_collection_index] == [] # Negative cursor - if await check_if_server_version_lt(glide_client, "7.9.0"): + if await check_if_server_version_lt(glide_client, "8.0.0"): result = await glide_client.sscan(key1, "-1") assert result[result_cursor_index] == initial_cursor.encode() assert result[result_collection_index] == [] @@ -9949,7 +9944,7 @@ async def test_zscan(self, glide_client: GlideClusterClient): assert result[result_collection_index] == [] # Negative cursor - if await check_if_server_version_lt(glide_client, "7.9.0"): + if await check_if_server_version_lt(glide_client, "8.0.0"): result = await glide_client.zscan(key1, "-1") assert result[result_cursor_index] == initial_cursor.encode() assert result[result_collection_index] == [] @@ -10025,7 +10020,7 @@ async def test_zscan(self, glide_client: GlideClusterClient): assert len(result[result_collection_index]) >= 0 # Test no_scores option - if not await check_if_server_version_lt(glide_client, "7.9.0"): + if not await check_if_server_version_lt(glide_client, "8.0.0"): result = await glide_client.zscan(key1, initial_cursor, no_scores=True) assert result[result_cursor_index] != b"0" values_array = cast(List[bytes], result[result_collection_index]) @@ -10076,7 +10071,7 @@ async def test_hscan(self, glide_client: GlideClusterClient): assert result[result_collection_index] == [] # Negative cursor - if await check_if_server_version_lt(glide_client, "7.9.0"): + if await check_if_server_version_lt(glide_client, "8.0.0"): result = await glide_client.hscan(key1, "-1") assert result[result_cursor_index] == initial_cursor.encode() assert result[result_collection_index] == [] @@ -10152,7 +10147,7 @@ async def test_hscan(self, glide_client: GlideClusterClient): assert len(result[result_collection_index]) >= 0 # Test no_values option - if not await check_if_server_version_lt(glide_client, "7.9.0"): + if not await check_if_server_version_lt(glide_client, "8.0.0"): result = await glide_client.hscan(key1, initial_cursor, no_values=True) assert result[result_cursor_index] != b"0" values_array = cast(List[bytes], result[result_collection_index]) @@ -10487,7 +10482,7 @@ async def attempt_kill_writing_script(): @pytest.mark.parametrize("cluster_mode", [True, False]) @pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3]) async def test_script_show(self, glide_client: TGlideClient): - min_version = "7.9.0" + min_version = "8.0.0" if await check_if_server_version_lt(glide_client, min_version): return pytest.mark.skip(reason=f"Valkey version required >= {min_version}") diff --git a/python/python/tests/test_transaction.py b/python/python/tests/test_transaction.py index 526c70681e..dadef84200 100644 --- a/python/python/tests/test_transaction.py +++ b/python/python/tests/test_transaction.py @@ -308,7 +308,7 @@ async def transaction_test( args.append([b"0", [key3.encode(), b"10.5"]]) transaction.hscan(key4, "0", match="*", count=10) args.append([b"0", [key3.encode(), b"10.5"]]) - if not await check_if_server_version_lt(glide_client, "7.9.0"): + if not await check_if_server_version_lt(glide_client, "8.0.0"): transaction.hscan(key4, "0", match="*", count=10, no_values=True) args.append([b"0", [key3.encode()]]) transaction.hrandfield(key4) @@ -463,7 +463,7 @@ async def transaction_test( args.append([b"0", [b"three", b"3"]]) transaction.zscan(key8, "0", match="*", count=20) args.append([b"0", [b"three", b"3"]]) - if not await check_if_server_version_lt(glide_client, "7.9.0"): + if not await check_if_server_version_lt(glide_client, "8.0.0"): transaction.zscan(key8, "0", match="*", count=20, no_scores=True) args.append([b"0", [b"three"]]) transaction.zpopmax(key8) @@ -561,7 +561,7 @@ async def transaction_test( transaction.bitpos_interval(key20, 1, 44, 50, BitmapIndexType.BIT) args.append(46) - if not await check_if_server_version_lt(glide_client, "7.9.0"): + if not await check_if_server_version_lt(glide_client, "8.0.0"): transaction.set(key20, "foobar") args.append(OK) transaction.bitcount(key20, OffsetOptions(0)) @@ -720,7 +720,7 @@ async def transaction_test( alpha=True, ) args.append(4) - if not await check_if_server_version_lt(glide_client, "7.9.0"): + if not await check_if_server_version_lt(glide_client, "8.0.0"): transaction.hset(f"{{{keyslot}}}:1", {"name": "Alice", "age": "30"}) args.append(2) transaction.hset(f"{{{keyslot}}}:2", {"name": "Bob", "age": "25"}) From ae861539123732d36b64c5cb8a958bd0c4317648 Mon Sep 17 00:00:00 2001 From: Andrew Carbonetto Date: Thu, 19 Sep 2024 15:06:38 -0700 Subject: [PATCH 10/18] Node: fix xinfogroups; fix lrem (#2324) * Node: fix xinfogroups; fix lrem Signed-off-by: Andrew Carbonetto --- CHANGELOG.md | 1 + node/src/BaseClient.ts | 2 +- node/src/Commands.ts | 2 +- node/src/Transaction.ts | 4 ++-- node/tests/SharedTests.ts | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8809ae7af..e5bf8a0405 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ #### Changes +* Node: Fix binary variant for xinfogroups and lrem ([#2324](https://github.com/valkey-io/valkey-glide/pull/2324)) * Node: Fixed missing exports ([#2301](https://github.com/valkey-io/valkey-glide/pull/2301)) * Node: Use `options` struct for all optional arguments ([#2287](https://github.com/valkey-io/valkey-glide/pull/2287)) * Node: Added `invokeScript` API with routing for cluster client ([#2284](https://github.com/valkey-io/valkey-glide/pull/2284)) diff --git a/node/src/BaseClient.ts b/node/src/BaseClient.ts index 1c31078305..2bfb9a3bbd 100644 --- a/node/src/BaseClient.ts +++ b/node/src/BaseClient.ts @@ -5523,7 +5523,7 @@ export class BaseClient { * ``` */ public async xinfoGroups( - key: string, + key: GlideString, options?: DecoderOption, ): Promise[]> { return this.createWritePromise< diff --git a/node/src/Commands.ts b/node/src/Commands.ts index fea676c01a..811504301c 100644 --- a/node/src/Commands.ts +++ b/node/src/Commands.ts @@ -2694,7 +2694,7 @@ export function createXInfoStream( } /** @internal */ -export function createXInfoGroups(key: string): command_request.Command { +export function createXInfoGroups(key: GlideString): command_request.Command { return createCommand(RequestType.XInfoGroups, [key]); } diff --git a/node/src/Transaction.ts b/node/src/Transaction.ts index 4a3fe802d4..485d7f06d0 100644 --- a/node/src/Transaction.ts +++ b/node/src/Transaction.ts @@ -1252,7 +1252,7 @@ export class BaseTransaction> { * Command Response - the number of the removed elements. * If `key` does not exist, 0 is returned. */ - public lrem(key: GlideString, count: number, element: string): T { + public lrem(key: GlideString, count: number, element: GlideString): T { return this.addAndReturn(createLRem(key, count, element)); } @@ -2651,7 +2651,7 @@ export class BaseTransaction> { * attributes of a consumer group for the stream at `key`. * The response comes in format `GlideRecord[]`, see {@link GlideRecord}. */ - public xinfoGroups(key: string): T { + public xinfoGroups(key: GlideString): T { return this.addAndReturn(createXInfoGroups(key)); } diff --git a/node/tests/SharedTests.ts b/node/tests/SharedTests.ts index 04f589c0ae..eea277241a 100644 --- a/node/tests/SharedTests.ts +++ b/node/tests/SharedTests.ts @@ -10752,7 +10752,7 @@ export function runBaseTests(config: { ).toEqual("OK"); // one empty group exists - expect(await client.xinfoGroups(key)).toEqual( + expect(await client.xinfoGroups(Buffer.from(key))).toEqual( cluster.checkIfServerVersionLessThan("7.0.0") ? [ { From 3846ac3a3b1d65ba0efc2d6ba7525ef14551e023 Mon Sep 17 00:00:00 2001 From: Guian Gumpac Date: Fri, 20 Sep 2024 11:30:20 -0700 Subject: [PATCH 11/18] Java: fix CI job for testing Maven Deployment (#2319) Fix testing deployment Signed-off-by: Guian Gumpac --- .github/workflows/java-cd.yml | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/java-cd.yml b/.github/workflows/java-cd.yml index 26efa0cfb7..e9df283c50 100644 --- a/.github/workflows/java-cd.yml +++ b/.github/workflows/java-cd.yml @@ -221,16 +221,10 @@ jobs: fail-fast: false matrix: host: ${{ fromJson(needs.load-platform-matrix.outputs.PLATFORM_MATRIX) }} - runs-on: ${{ matrix.host.RUNNER }} steps: - - name: Start Valkey server - uses: ./.github/actions/install-valkey - with: - engine-version: "7.2.5" - target: ${{ matrix.host.TARGET }} - - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 with: submodules: recursive @@ -244,6 +238,7 @@ jobs: uses: ./.github/workflows/install-shared-dependencies with: os: ${{ matrix.host.OS }} + engine-version: "7.2.5" target: ${{ matrix.host.TARGET }} github-token: ${{ secrets.GITHUB_TOKEN }} @@ -253,17 +248,26 @@ jobs: version: "26.1" repo-token: ${{ secrets.GITHUB_TOKEN }} + - name: Start standalone Valkey server + working-directory: utils + id: port + run: | + PORT=$(python3 ./cluster_manager.py start -r 0 2>&1 | grep CLUSTER_NODES | cut -d = -f 2 | cut -d , -f 1 | cut -d : -f 2) + echo "PORT=$PORT" >> $GITHUB_OUTPUT + - name: Test deployment working-directory: java + env: + PORT: ${{ steps.port.outputs.PORT }} run: | export ORG_GRADLE_PROJECT_centralManualTestingAuthHeaderName="Authorization" export ORG_GRADLE_PROJECT_centralManualTestingAuthHeaderValue="Bearer $(echo "${{ secrets.CENTRAL_TOKEN_USERNAME }}:${{ secrets.CENTRAL_TOKEN_PASSWORD }}" | base64)" export GLIDE_RELEASE_VERSION=${{ env.RELEASE_VERSION }} - ./gradlew :benchmarks:run --args="--minimal --clients glide" + ./gradlew :benchmarks:run --args="--minimal --clients glide --port ${{ env.PORT }}" publish-release-to-maven: if: ${{ inputs.maven_publish == true || github.event_name == 'push' }} - needs: [test-deployment-on-all-architectures] + needs: [publish-to-maven-central-deployment, test-deployment-on-all-architectures] runs-on: ubuntu-latest environment: AWS_ACTIONS env: @@ -287,4 +291,3 @@ jobs: curl --request DELETE \ -u "${{ secrets.CENTRAL_TOKEN_USERNAME }}:${{ secrets.CENTRAL_TOKEN_PASSWORD }}" \ "https://central.sonatype.com/api/v1/publisher/deployment/${{ env.DEPLOYMENT_ID }}" - From 4e484c0226c60e64611bdd25ebc5b2e326ea7071 Mon Sep 17 00:00:00 2001 From: James Xin Date: Sat, 21 Sep 2024 09:30:28 -0700 Subject: [PATCH 12/18] Java : Fix ExamplesApp (#2326) Fix Java ExamplesApp Signed-off-by: James Xin --- .../java/src/main/java/glide/examples/ClusterExample.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/java/src/main/java/glide/examples/ClusterExample.java b/examples/java/src/main/java/glide/examples/ClusterExample.java index cc598b632a..5fce398f7a 100644 --- a/examples/java/src/main/java/glide/examples/ClusterExample.java +++ b/examples/java/src/main/java/glide/examples/ClusterExample.java @@ -10,7 +10,7 @@ import glide.api.GlideClusterClient; import glide.api.logging.Logger; import glide.api.models.ClusterValue; -import glide.api.models.commands.InfoOptions; +import glide.api.models.commands.InfoOptions.Section; import glide.api.models.configuration.GlideClusterClientConfiguration; import glide.api.models.configuration.NodeAddress; import glide.api.models.exceptions.ClosingException; @@ -76,7 +76,7 @@ public static void appLogic(GlideClusterClient client) // Send INFO REPLICATION with routing option to all nodes ClusterValue infoResponse = client - .info(InfoOptions.builder().section(InfoOptions.Section.REPLICATION).build(), ALL_NODES) + .info(new Section[] {Section.REPLICATION}, ALL_NODES) .get(); log( INFO, From c8b2b5031c9d1a80fcdf1bbf0a7b2710fcc3c85e Mon Sep 17 00:00:00 2001 From: Shoham Elias <116083498+shohamazon@users.noreply.github.com> Date: Mon, 23 Sep 2024 10:50:39 +0300 Subject: [PATCH 13/18] Bump redis-rs (#2338) Signed-off-by: Shoham Elias --- submodules/redis-rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/redis-rs b/submodules/redis-rs index 426bb99d0e..8e89ad8f3d 160000 --- a/submodules/redis-rs +++ b/submodules/redis-rs @@ -1 +1 @@ -Subproject commit 426bb99d0e2d02a3fcb35c28d8d8dd6beae252ef +Subproject commit 8e89ad8f3d4a872ceb9bd87027e55ea7f1477b83 From 48c385e0bc5bd5387294c5707819b37f7f2f80df Mon Sep 17 00:00:00 2001 From: Shoham Elias <116083498+shohamazon@users.noreply.github.com> Date: Mon, 23 Sep 2024 12:39:51 +0300 Subject: [PATCH 14/18] Python: add missing exports (#2341) * Add missing python exports. Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Revert: benchmark update Signed-off-by: Andrew Carbonetto * Revert "Revert: benchmark update" This reverts commit a26ca32688339f433f82b74002e15d6de50282a5. Signed-off-by: Andrew Carbonetto * remove json Signed-off-by: Shoham Elias --------- Signed-off-by: Yury-Fridlyand Signed-off-by: Andrew Carbonetto Signed-off-by: Shoham Elias Co-authored-by: Yury-Fridlyand Co-authored-by: Andrew Carbonetto --- CHANGELOG.md | 5 ++-- benchmarks/python/python_benchmark.py | 7 +++-- python/python/glide/__init__.py | 41 +++++++++++++++++++++++---- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5bf8a0405..551d0653c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -140,9 +140,10 @@ * Node: Fix ZADD bug where command could not be called with only the `changed` optional parameter ([#1995](https://github.com/valkey-io/valkey-glide/pull/1995)) * Java: `XRange`/`XRevRange` should return `null` instead of `GlideException` when given a negative count ([#1920](https://github.com/valkey-io/valkey-glide/pull/1920)) * Python: Fix `XClaim` return type to `List[bytes]` instead of `List[TEncodable]` ([#2075](https://github.com/valkey-io/valkey-glide/pull/2075)) +* Python: Add missing exports ([2321](https://github.com/valkey-io/valkey-glide/pull/2321)) ### Operational Enhancements -* CI/CD: Create Workflow to deploy artifacts for all platforms ([#2285](https://github.com/valkey-io/valkey-glide/pull/2285) +* CI/CD: Create Workflow to deploy artifacts for all platforms ([#2285](https://github.com/valkey-io/valkey-glide/pull/2285)) * Node: Get valkey/redis version using client's info command ([#2276](https://github.com/valkey-io/valkey-glide/pull/2276)) * Java: Fetch server version using client's info command ([#2258](https://github.com/valkey-io/valkey-glide/pull/2258)) * CI/CD: Add workflow for automating Maven release ([#2128](https://github.com/valkey-io/valkey-glide/pull/2128)) @@ -303,7 +304,7 @@ * Python: Added SETRANGE command ([#1453](https://github.com/valkey-io/valkey-glide/pull/1453)) #### Fixes -* Python: Fix typing error "‘type’ object is not subscriptable" ([#1203](https://github.com/valkey-io/valkey-glide/pull/1203)) +* Python: Fix typing error "'type' object is not subscriptable" ([#1203](https://github.com/valkey-io/valkey-glide/pull/1203)) * Core: Fixed blocking commands to use the specified timeout from the command argument ([#1283](https://github.com/valkey-io/valkey-glide/pull/1283)) ### Breaking Changes diff --git a/benchmarks/python/python_benchmark.py b/benchmarks/python/python_benchmark.py index 1da52f9941..580ac8a41d 100644 --- a/benchmarks/python/python_benchmark.py +++ b/benchmarks/python/python_benchmark.py @@ -16,7 +16,8 @@ import numpy as np import redis.asyncio as redispy # type: ignore from glide import ( - BaseClientConfiguration, + GlideClientConfiguration, + GlideClusterClientConfiguration, GlideClient, GlideClusterClient, Logger, @@ -289,7 +290,9 @@ async def main( if clients_to_run == "all" or clients_to_run == "glide": # Glide Socket client_class = GlideClusterClient if is_cluster else GlideClient - config = BaseClientConfiguration( + config = GlideClusterClientConfiguration( + [NodeAddress(host=host, port=port)], use_tls=use_tls + ) if is_cluster else GlideClientConfiguration( [NodeAddress(host=host, port=port)], use_tls=use_tls ) clients = await create_clients( diff --git a/python/python/glide/__init__.py b/python/python/glide/__init__.py index 50caeb5f4a..cf817c128a 100644 --- a/python/python/glide/__init__.py +++ b/python/python/glide/__init__.py @@ -17,7 +17,7 @@ SignedEncoding, UnsignedEncoding, ) -from glide.async_commands.command_args import Limit, ListDirection, OrderBy +from glide.async_commands.command_args import Limit, ListDirection, ObjectType, OrderBy from glide.async_commands.core import ( ConditionalChange, CoreCommands, @@ -64,10 +64,13 @@ TrimByMaxLen, TrimByMinId, ) -from glide.async_commands.transaction import ClusterTransaction, Transaction +from glide.async_commands.transaction import ( + ClusterTransaction, + Transaction, + TTransaction, +) from glide.config import ( BackoffStrategy, - BaseClientConfiguration, GlideClientConfiguration, GlideClusterClientConfiguration, NodeAddress, @@ -77,7 +80,19 @@ ReadFrom, ServerCredentials, ) -from glide.constants import OK +from glide.constants import ( + OK, + TOK, + TClusterResponse, + TEncodable, + TFunctionListResponse, + TFunctionStatsFullResponse, + TFunctionStatsSingleNodeResponse, + TResult, + TSingleNodeRoute, + TXInfoStreamFullResponse, + TXInfoStreamResponse, +) from glide.exceptions import ( ClosingError, ConfigurationError, @@ -87,7 +102,7 @@ RequestError, TimeoutError, ) -from glide.glide_client import GlideClient, GlideClusterClient +from glide.glide_client import GlideClient, GlideClusterClient, TGlideClient from glide.logger import Level as LogLevel from glide.logger import Logger from glide.routes import ( @@ -95,6 +110,7 @@ AllPrimaries, ByAddressRoute, RandomNode, + Route, SlotIdRoute, SlotKeyRoute, SlotType, @@ -110,8 +126,9 @@ "GlideClusterClient", "Transaction", "ClusterTransaction", + "TGlideClient", + "TTransaction", # Config - "BaseClientConfiguration", "GlideClientConfiguration", "GlideClusterClientConfiguration", "BackoffStrategy", @@ -123,6 +140,15 @@ "PeriodicChecksStatus", # Response "OK", + "TClusterResponse", + "TEncodable", + "TFunctionListResponse", + "TFunctionStatsFullResponse", + "TFunctionStatsSingleNodeResponse", + "TOK", + "TResult", + "TXInfoStreamFullResponse", + "TXInfoStreamResponse", # Commands "BitEncoding", "BitFieldGet", @@ -166,6 +192,7 @@ "RangeByLex", "RangeByScore", "ScoreFilter", + "ObjectType", "OrderBy", "ExclusiveIdBound", "IdBound", @@ -189,6 +216,7 @@ "Logger", "LogLevel", # Routes + "Route", "SlotType", "AllNodes", "AllPrimaries", @@ -196,6 +224,7 @@ "RandomNode", "SlotKeyRoute", "SlotIdRoute", + "TSingleNodeRoute", # Exceptions "ClosingError", "ConfigurationError", From 589f4ee66df748e45d9fd276bcc8d6575d3e0990 Mon Sep 17 00:00:00 2001 From: adarovadya Date: Mon, 23 Sep 2024 14:53:14 +0300 Subject: [PATCH 15/18] Node: fix missing exports (#2342) Signed-off-by: Adar Ovadia Co-authored-by: Adar Ovadia --- CHANGELOG.md | 3 ++- node/npm/glide/index.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 551d0653c7..9bdaa961c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -140,7 +140,8 @@ * Node: Fix ZADD bug where command could not be called with only the `changed` optional parameter ([#1995](https://github.com/valkey-io/valkey-glide/pull/1995)) * Java: `XRange`/`XRevRange` should return `null` instead of `GlideException` when given a negative count ([#1920](https://github.com/valkey-io/valkey-glide/pull/1920)) * Python: Fix `XClaim` return type to `List[bytes]` instead of `List[TEncodable]` ([#2075](https://github.com/valkey-io/valkey-glide/pull/2075)) -* Python: Add missing exports ([2321](https://github.com/valkey-io/valkey-glide/pull/2321)) +* Python: Add missing exports ([#2341](https://github.com/valkey-io/valkey-glide/pull/2341)) +* Node: Add missing exports ([#2342](https://github.com/valkey-io/valkey-glide/pull/2342)) ### Operational Enhancements * CI/CD: Create Workflow to deploy artifacts for all platforms ([#2285](https://github.com/valkey-io/valkey-glide/pull/2285)) diff --git a/node/npm/glide/index.ts b/node/npm/glide/index.ts index 7d307b3c0c..98171bfef4 100644 --- a/node/npm/glide/index.ts +++ b/node/npm/glide/index.ts @@ -198,6 +198,10 @@ function initialize() { BaseClientConfiguration, GlideClusterClientConfiguration, LevelOptions, + ReturnTypeRecord, + ReturnTypeMap, + ClusterResponse, + ReturnTypeAttribute, } = nativeBinding; module.exports = { @@ -317,6 +321,10 @@ function initialize() { BaseClientConfiguration, GlideClusterClientConfiguration, LevelOptions, + ReturnTypeRecord, + ReturnTypeMap, + ClusterResponse, + ReturnTypeAttribute, }; globalObject = Object.assign(global, nativeBinding); From aae64fb70d139240e22a618dc61f6a3371bf092c Mon Sep 17 00:00:00 2001 From: ikolomi <152477505+ikolomi@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:26:32 +0300 Subject: [PATCH 16/18] Fix node examples (#2345) Fix node example: 1. Use the latest version from npm. 2. Clear up the doc. 3. Comment out the cluster mode in the example, leaving standalone mode by default. Signed-off-by: ikolomi --- examples/node/README.MD | 25 +++---------------------- examples/node/index.ts | 9 ++++++--- examples/node/package.json | 2 +- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/examples/node/README.MD b/examples/node/README.MD index adea1790ed..4bac2015c4 100644 --- a/examples/node/README.MD +++ b/examples/node/README.MD @@ -1,38 +1,19 @@ -## Pre-requirements -- GCC -- pkg-config -- protobuf-compiler (protoc) -- openssl -- libssl-dev - -Installation for ubuntu: -`sudo apt install -y gcc pkg-config protobuf-compiler openssl libssl-dev python3` - -### node 16 (or newer) - -This is required for the NodeJS wrapper, and for running benchmarks. - +### Install node 16 (or newer) ``` curl -s https://deb.nodesource.com/setup_16.x | sudo bash apt-get install nodejs npm npm i -g npm@8 ``` -## Build -To build GLIDE's Node client, run (on unix based systems): +## Install GLIDE package and build the example ``` -cd valkey-glide/node -git submodule update --init --recursive -npm install -rm -rf build-ts -npm run build:release cd valkey-glide/examples/node npm install npx tsc ``` ## Run -To run the example: +To run the example (make sure redis/valkey server is available at the address used in the example): ``` cd valkey-glide/examples/node node index.js diff --git a/examples/node/index.ts b/examples/node/index.ts index a72180b17c..59abc86243 100644 --- a/examples/node/index.ts +++ b/examples/node/index.ts @@ -4,7 +4,7 @@ import { GlideClient, GlideClusterClient, Logger } from "@valkey/valkey-glide"; -async function sendPingToNode() { +async function sendPingToStandAloneNode() { // When in Redis is in standalone mode, add address of the primary node, and any replicas you'd like to be able to read from. const addresses = [ { @@ -64,6 +64,9 @@ function setConsoleLogger() { } setFileLogger(); -await sendPingToNode(); setConsoleLogger(); -await sendPingToRandomNodeInCluster(); +// Enable for standalone mode +await sendPingToStandAloneNode(); + +// Enable for cluster mode +// await sendPingToRandomNodeInCluster(); diff --git a/examples/node/package.json b/examples/node/package.json index 712ae76e02..dbcd4ce52d 100644 --- a/examples/node/package.json +++ b/examples/node/package.json @@ -1,7 +1,7 @@ { "type": "module", "dependencies": { - "@valkey/valkey-glide": "^1.1.0", + "@valkey/valkey-glide": "latest", "@types/node": "^20.4.8" }, "devDependencies": { From 0cff921c95dae36be29fc76c62a84f0e2814c0a5 Mon Sep 17 00:00:00 2001 From: Avi Fenesh <55848801+avifenesh@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:13:47 +0300 Subject: [PATCH 17/18] Py/rc testing (#2314) * Fix python CD Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Signed-off-by: Yury-Fridlyand * Install python 3.8 Signed-off-by: Yury-Fridlyand * fix import path Signed-off-by: Adar Ovadia * fix file name Signed-off-by: Adar Ovadia * added RC tests to python Signed-off-by: avifenesh * fix test matrix Signed-off-by: avifenesh * add github token to rust ci Signed-off-by: avifenesh * exclude rc tests from mypy Signed-off-by: avifenesh * added license Signed-off-by: avifenesh * Update index.js Signed-off-by: Avi Fenesh <55848801+avifenesh@users.noreply.github.com> --------- Signed-off-by: Yury-Fridlyand Signed-off-by: Adar Ovadia Signed-off-by: avifenesh Signed-off-by: Avi Fenesh <55848801+avifenesh@users.noreply.github.com> Co-authored-by: Yury-Fridlyand Co-authored-by: Adar Ovadia --- .github/workflows/pypi-cd.yml | 59 +++++ .github/workflows/rust.yml | 1 + python/pyproject.toml | 2 +- utils/.gitignore | 2 + utils/release-candidate-testing/node/index.js | 3 + .../python/__init__.py | 1 + .../python/rc_test.py | 208 ++++++++++++++++++ .../python/requirements.txt | 1 + 8 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 utils/.gitignore create mode 100644 utils/release-candidate-testing/python/__init__.py create mode 100644 utils/release-candidate-testing/python/rc_test.py create mode 100644 utils/release-candidate-testing/python/requirements.txt diff --git a/.github/workflows/pypi-cd.yml b/.github/workflows/pypi-cd.yml index 9e0e3d1240..e69343f234 100644 --- a/.github/workflows/pypi-cd.yml +++ b/.github/workflows/pypi-cd.yml @@ -215,3 +215,62 @@ jobs: with: command: upload args: --skip-existing python/wheels/* + + test-release: + if: github.event_name != 'pull_request' + name: Test the release + runs-on: ${{ matrix.build.RUNNER }} + needs: [publish-to-pypi, load-platform-matrix] + strategy: + fail-fast: false + matrix: + build: ${{ fromJson(needs.load-platform-matrix.outputs.PLATFORM_MATRIX) }} + steps: + - name: Setup self-hosted runner access + if: ${{ matrix.build.TARGET == 'aarch64-unknown-linux-gnu' }} + run: sudo chown -R $USER:$USER /home/ubuntu/actions-runner/_work/valkey-glide + + - name: checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.12 + + - name: Install ValKey + uses: ./.github/workflows/install-valkey + with: + version: "8.0.0" + + - name: Check if RC and set a distribution tag for the package + shell: bash + run: | + if [[ "${GITHUB_REF:11}" == *"rc"* ]] + then + echo "This is a release candidate" + export pip_pre="--pre" + else + echo "This is a stable release" + export pip_pre="" + fi + echo "PIP_PRE=${pip_pre}" >> $GITHUB_ENV + + - name: Run the tests + shell: bash + working-directory: ./utils/release-candidate-testing/python + run: | + python -m venv venv + source venv/bin/activate + pip install -U pip + pip install ${PIP_PRE} valkey-glide + python rc_test.py + + # Reset the repository to make sure we get the clean checkout of the action later in other actions. + # It is not required since in other actions we are cleaning before the action, but it is a good practice to do it here as well. + - name: Reset repository + if: ${{ contains(matrix.build.RUNNER, 'self-hosted') }} + shell: bash + run: | + git reset --hard + git clean -xdf diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 3ebfc8a5a3..c022e3e419 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -69,6 +69,7 @@ jobs: os: "ubuntu" target: "x86_64-unknown-linux-gnu" engine-version: ${{ matrix.engine.version }} + github-token: ${{ secrets.GITHUB_TOKEN }} - uses: Swatinem/rust-cache@v2 diff --git a/python/pyproject.toml b/python/pyproject.toml index c0399197b8..8a44924019 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -33,4 +33,4 @@ extend-ignore = ['E203'] target-version = ['py38', 'py39', 'py310', 'py311', 'py312'] [tool.mypy] -exclude = [ 'submodules' ] +exclude = [ 'submodules', 'utils/release-candidate-testing' ] diff --git a/utils/.gitignore b/utils/.gitignore new file mode 100644 index 0000000000..d10b2296e7 --- /dev/null +++ b/utils/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +servers/ diff --git a/utils/release-candidate-testing/node/index.js b/utils/release-candidate-testing/node/index.js index b537c25468..be55f97cc4 100644 --- a/utils/release-candidate-testing/node/index.js +++ b/utils/release-candidate-testing/node/index.js @@ -1,3 +1,6 @@ +/** + * Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 + */ import { GlideClient, GlideClusterClient } from "@valkey/valkey-glide"; import { ValkeyCluster } from "../../TestUtils.js"; diff --git a/utils/release-candidate-testing/python/__init__.py b/utils/release-candidate-testing/python/__init__.py new file mode 100644 index 0000000000..fa59791e66 --- /dev/null +++ b/utils/release-candidate-testing/python/__init__.py @@ -0,0 +1 @@ +# Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 diff --git a/utils/release-candidate-testing/python/rc_test.py b/utils/release-candidate-testing/python/rc_test.py new file mode 100644 index 0000000000..669b303be7 --- /dev/null +++ b/utils/release-candidate-testing/python/rc_test.py @@ -0,0 +1,208 @@ +# Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0 + +import asyncio +from typing import List, Tuple +import os +import subprocess +import sys + +SCRIPT_FILE = os.path.abspath(f"{__file__}/../../../cluster_manager.py") + +from glide import ( + GlideClusterClient, + GlideClusterClientConfiguration, + NodeAddress, + GlideClient, + GlideClientConfiguration, +) + + +def start_servers(cluster_mode: bool, shard_count: int, replica_count: int) -> str: + args_list: List[str] = [sys.executable, SCRIPT_FILE] + args_list.append("start") + if cluster_mode: + args_list.append("--cluster-mode") + args_list.append(f"-n {shard_count}") + args_list.append(f"-r {replica_count}") + p = subprocess.Popen( + args_list, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + output, err = p.communicate(timeout=40) + if p.returncode != 0: + raise Exception(f"Failed to create a cluster. Executed: {p}:\n{err}") + print("Servers started successfully") + return output + + +def parse_cluster_script_start_output(output: str) -> Tuple[List[NodeAddress], str]: + assert "CLUSTER_FOLDER" in output and "CLUSTER_NODES" in output + lines_output: List[str] = output.splitlines() + cluster_folder: str = "" + nodes_addr: List[NodeAddress] = [] + for line in lines_output: + if "CLUSTER_FOLDER" in line: + splitted_line = line.split("CLUSTER_FOLDER=") + assert len(splitted_line) == 2 + cluster_folder = splitted_line[1] + if "CLUSTER_NODES" in line: + nodes_list: List[NodeAddress] = [] + splitted_line = line.split("CLUSTER_NODES=") + assert len(splitted_line) == 2 + nodes_addresses = splitted_line[1].split(",") + assert len(nodes_addresses) > 0 + for addr in nodes_addresses: + host, port = addr.split(":") + nodes_list.append(NodeAddress(host, int(port))) + nodes_addr = nodes_list + print("Cluster script output parsed successfully") + return nodes_addr, cluster_folder + + +def stop_servers(folder: str) -> str: + args_list: List[str] = [sys.executable, SCRIPT_FILE] + args_list.extend(["stop", "--cluster-folder", folder]) + p = subprocess.Popen( + args_list, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + output, err = p.communicate(timeout=40) + if p.returncode != 0: + raise Exception(f"Failed to stop the cluster. Executed: {p}:\n{err}") + print("Servers stopped successfully") + return output + + +async def run_commands(client: GlideClient) -> None: + print("Executing commands") + # Set a bunch of keys + for i in range(100): + res = await client.set(f"foo{i}".encode(), b"bar") + if res != "OK": + print(res) + raise Exception(f"Unexpected set response, expected 'OK', got {res}") + print("Keys set successfully") + # Get the keys + for i in range(10): + val = await client.get(f"foo{i}") + if val != b"bar": + print(val) + raise Exception(f"Unexpected value, expected b'bar', got {val}") + print("Keys retrieved successfully") + # Run some various commands + pong = await client.ping() + if pong != b"PONG": + print(pong) + raise Exception(f"Unexpected ping response, expected b'PONG', got {pong}") + print(f"Ping successful: {pong}") + # Set a bunch of keys to delete + array_of_keys: List[bytes] = [f"foo{i}".encode() for i in range(1, 4)] + # delete the keys + deleted_keys_num = await client.delete(array_of_keys) + print(f"Deleted keys: {deleted_keys_num}") + # check that the correct number of keys were deleted + if deleted_keys_num != 3: + print(deleted_keys_num) + raise Exception( + f"Unexpected number of keys deleted, expected 3, got {deleted_keys_num}" + ) + # check that the keys were deleted + for i in range(1, 4): + val = await client.get(f"foo{i}") + if val is not None: + print(val) + raise Exception(f"Unexpected value, expected None, got {val}") + print("Keys deleted successfully") + + # Test INCR command + incr_key = b"counter" + await client.set(incr_key, b"0") + incr_result = await client.incr(incr_key) + if incr_result != 1: + raise Exception(f"Unexpected INCR result, expected 1, got {incr_result}") + print("INCR command successful") + + # Test LPUSH and LRANGE commands + list_key = b"mylist" + await client.lpush(list_key, [b"world", b"hello"]) + list_values = await client.lrange(list_key, 0, -1) + if list_values != [b"hello", b"world"]: + raise Exception( + f"Unexpected LRANGE result, expected [b'hello', b'world'], got {list_values}" + ) + print("LPUSH and LRANGE commands successful") + + # Test HSET and HGETALL commands + hash_key = b"myhash" + await client.hset(hash_key, {b"field1": b"value1", b"field2": b"value2"}) + hash_values = await client.hgetall(hash_key) + if hash_values != {b"field1": b"value1", b"field2": b"value2"}: + raise Exception( + f"Unexpected HGETALL result, expected {{b'field1': b'value1', b'field2': b'value2'}}, got {hash_values}" + ) + print("HSET and HGETALL commands successful") + + print("All commands executed successfully") + + +async def create_cluster_client( + nodes_list: List[NodeAddress] = [("localhost", 6379)] +) -> GlideClusterClient: + addresses: List[NodeAddress] = nodes_list + config = GlideClusterClientConfiguration( + addresses=addresses, + client_name="test_cluster_client", + ) + client = await GlideClusterClient.create(config) + print("Cluster client created successfully") + return client + + +async def create_standalone_client(server: List[NodeAddress]) -> GlideClient: + config = GlideClientConfiguration( + addresses=server, + client_name="test_standalone_client", + ) + client = await GlideClient.create(config) + print("Standalone client created successfully") + return client + + +async def test_standalone_client() -> None: + print("Testing standalone client") + output = start_servers(False, 1, 1) + servers, folder = parse_cluster_script_start_output(output) + standalone_client = await create_standalone_client(servers) + await run_commands(standalone_client) + stop_servers(folder) + print("Standalone client test completed") + + +async def test_cluster_client() -> None: + print("Testing cluster client") + output = start_servers(True, 3, 1) + servers, folder = parse_cluster_script_start_output(output) + cluster_client = await create_cluster_client(servers) + await run_commands(cluster_client) + stop_servers(folder) + print("Cluster client test completed") + + +async def test_clients() -> None: + await test_cluster_client() + print("Cluster client test passed") + await test_standalone_client() + print("Standalone client test passed") + + +def main() -> None: + asyncio.run(test_clients()) + print("All tests completed successfully") + + +if __name__ == "__main__": + main() diff --git a/utils/release-candidate-testing/python/requirements.txt b/utils/release-candidate-testing/python/requirements.txt new file mode 100644 index 0000000000..cac8dc5db0 --- /dev/null +++ b/utils/release-candidate-testing/python/requirements.txt @@ -0,0 +1 @@ +valkey-glide From 44ec72b618656d625f0fdea2b2cd06b2afe9c241 Mon Sep 17 00:00:00 2001 From: adarovadya Date: Mon, 23 Sep 2024 20:16:24 +0300 Subject: [PATCH 18/18] Node: fix docs (#2346) * Node: fix docs Signed-off-by: Adar Ovadia * fix readme Signed-off-by: Adar Ovadia * Node: add readme examples Signed-off-by: Adar Ovadia --------- Signed-off-by: Adar Ovadia Co-authored-by: Adar Ovadia --- README.md | 11 +++--- csharp/README.md | 38 ------------------- examples/node/index.ts | 4 +- java/client/build.gradle | 2 +- node/README.md | 73 ++++++++++++++++++++++++++++++++++--- node/npm/glide/package.json | 4 +- node/package.json | 2 +- 7 files changed, 79 insertions(+), 55 deletions(-) delete mode 100644 csharp/README.md diff --git a/README.md b/README.md index 4ccfd8594d..cf3714f92f 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,18 @@ Valkey General Language Independent Driver for the Enterprise (GLIDE), is an ope ## Supported Engine Versions Valkey GLIDE is API-compatible with the following engine versions: -| Engine Type | 6.2 | 7.0 | 7.2 | -|-----------------------|-------|-------|-------| -| Valkey | - | - | V | -| Redis | V | V | V | +| Engine Type | 6.2 | 7.0 | 7.2 | 8.0 | +|-----------------------|-------|-------|-------|-------| +| Valkey | - | - | V | V | +| Redis | V | V | V | - | ## Current Status -In this release, Valkey GLIDE is available for Python and Java. Support for Node.js is actively under development, with plans to include more programming languages in the future. We're tracking future features on the [roadmap](https://github.com/orgs/valkey-io/projects/11). +In this release, Valkey GLIDE is available for Python, Java and Node.js. Support for GO is actively under development, with plans to include more programming languages in the future. We're tracking future features on the [roadmap](https://github.com/orgs/valkey-io/projects/11). ## Getting Started - [Java](./java/README.md) - [Python](./python/README.md) +- [Node](./node/README.md) - [Documentation](https://github.com/valkey-io/valkey-glide/wiki) ## Getting Help diff --git a/csharp/README.md b/csharp/README.md deleted file mode 100644 index 390b146adc..0000000000 --- a/csharp/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# C# wrapper - -The C# wrapper is currently not in a usable state and is under development. - -# Valkey GLIDE - -Valkey General Language Independent Driver for the Enterprise (GLIDE), is an open-source Valkey client library. Valkey GLIDE is one of the official client libraries for Valkey, and it supports all Valkey commands. Valkey GLIDE supports Valkey 7.2 and above, and Redis open-source 6.2, 7.0 and 7.2. Application programmers use Valkey GLIDE to safely and reliably connect their applications to Valkey- and Redis OSS- compatible services. Valkey GLIDE is designed for reliability, optimized performance, and high-availability, for Valkey and Redis OSS based applications. It is sponsored and supported by AWS, and is pre-configured with best practices learned from over a decade of operating Redis OSS-compatible services used by hundreds of thousands of customers. To help ensure consistency in application development and operations, Valkey GLIDE is implemented using a core driver framework, written in Rust, with language specific extensions. This design ensures consistency in features across languages and reduces overall complexity. - -## Supported Engine Versions - -Refer to the [Supported Engine Versions table](https://github.com/valkey-io/valkey-glide/blob/main/README.md#supported-engine-versions) for details. - -## Current Status - -We've made Valkey GLIDE an open-source project, and are releasing it in Preview to the community to gather feedback, and actively collaborate on the project roadmap. We welcome questions and contributions from all Redis stakeholders. -This preview release is recommended for testing purposes only. - -# Getting Started - C# Wrapper - -## .net sdk supported version - -.net 6.0 or higher. - -## Basic Example - -```csharp - -using Glide; - -AsyncClient glideClient = new (host, PORT, useTLS); -await glideClient.SetAsync("foo", "bar"); -string? value = await glideClient.GetAsync("foo"); -glideClient.Dispose(); -``` - -### Building & Testing - -Development instructions for local building & testing the package are in the [DEVELOPER.md](DEVELOPER.md#build-from-source) file. diff --git a/examples/node/index.ts b/examples/node/index.ts index 59abc86243..b721d51331 100644 --- a/examples/node/index.ts +++ b/examples/node/index.ts @@ -5,7 +5,7 @@ import { GlideClient, GlideClusterClient, Logger } from "@valkey/valkey-glide"; async function sendPingToStandAloneNode() { - // When in Redis is in standalone mode, add address of the primary node, and any replicas you'd like to be able to read from. + // When Valkey is in standalone mode, add address of the primary node, and any replicas you'd like to be able to read from. const addresses = [ { host: "localhost", @@ -34,7 +34,7 @@ async function send_set_and_get(client: GlideClient | GlideClusterClient) { } async function sendPingToRandomNodeInCluster() { - // When in Redis is cluster mode, add address of any nodes, and the client will find all nodes in the cluster. + // When Valkey is in cluster mode, add address of any nodes, and the client will find all nodes in the cluster. const addresses = [ { host: "localhost", diff --git a/java/client/build.gradle b/java/client/build.gradle index 0178f311ea..46fa8f4cee 100644 --- a/java/client/build.gradle +++ b/java/client/build.gradle @@ -209,7 +209,7 @@ publishing { } developers { developer { - name = 'valkey-glide' + name = 'Valkey GLIDE Maintainers' url = 'https://github.com/valkey-io/valkey-glide.git' } } diff --git a/node/README.md b/node/README.md index 6d98b6a856..d215bc102f 100644 --- a/node/README.md +++ b/node/README.md @@ -6,16 +6,20 @@ Valkey General Language Independent Driver for the Enterprise (GLIDE), is an ope Refer to the [Supported Engine Versions table](https://github.com/valkey-io/valkey-glide/blob/main/README.md#supported-engine-versions) for details. -## Current Status - -We've made Valkey GLIDE an open-source project, and are releasing it in Preview to the community to gather feedback, and actively collaborate on the project roadmap. We welcome questions and contributions from all Redis stakeholders. -This preview release is recommended for testing purposes only. - # Getting Started - Node Wrapper ## System Requirements -In this release, Valkey GLIDE is available for Python and Java. Support for Node.js is actively under development, with plans to include more programming languages in the future. We're tracking future features on the [roadmap](https://github.com/orgs/aws/projects/187/). +The release of Valkey GLIDE was tested on the following platforms: + +Linux: + +- Ubuntu 22.04.1 (x86_64) +- Amazon Linux 2023 (AL2023) (x86_64) + +macOS: + +- macOS 12.7 (Apple silicon/aarch_64 and Intel/x86_64) ## NodeJS supported version @@ -29,6 +33,63 @@ Visit our [wiki](https://github.com/valkey-io/valkey-glide/wiki/NodeJS-wrapper) Development instructions for local building & testing the package are in the [DEVELOPER.md](https://github.com/valkey-io/valkey-glide/blob/main/node/DEVELOPER.md#build-from-source) file. +## Basic Examples + +#### Standalone Mode: + +```typescript +import { GlideClient, GlideClusterClient, Logger } from "@valkey/valkey-glide"; +// When Valkey is in standalone mode, add address of the primary node, and any replicas you'd like to be able to read from. +const addresses = [ + { + host: "localhost", + port: 6379, + }, +]; +// Check `GlideClientConfiguration/GlideClusterClientConfiguration` for additional options. +const client = await GlideClient.createClient({ + addresses: addresses, + // if the server uses TLS, you'll need to enable it. Otherwise, the connection attempt will time out silently. + // useTLS: true, + clientName: "test_standalone_client", +}); +// The empty array signifies that there are no additional arguments. +const pong = await client.customCommand(["PING"]); +console.log(pong); +const set_response = await client.set("foo", "bar"); +console.log(`Set response is = ${set_response}`); +const get_response = await client.get("foo"); +console.log(`Get response is = ${get_response}`); +``` + +#### Cluster Mode: + +```typescript +import { GlideClient, GlideClusterClient, Logger } from "@valkey/valkey-glide"; +// When Valkey is in cluster mode, add address of any nodes, and the client will find all nodes in the cluster. +const addresses = [ + { + host: "localhost", + port: 6379, + }, +]; +// Check `GlideClientConfiguration/GlideClusterClientConfiguration` for additional options. +const client = await GlideClusterClient.createClient({ + addresses: addresses, + // if the cluster nodes use TLS, you'll need to enable it. Otherwise the connection attempt will time out silently. + // useTLS: true, + clientName: "test_cluster_client", +}); +// The empty array signifies that there are no additional arguments. +const pong = await client.customCommand(["PING"], { route: "randomNode" }); +console.log(pong); +const set_response = await client.set("foo", "bar"); +console.log(`Set response is = ${set_response}`); +const get_response = await client.get("foo"); +console.log(`Get response is = ${get_response}`); +client.close(); +``` + ### Supported platforms Currentlly the package is supported on: diff --git a/node/npm/glide/package.json b/node/npm/glide/package.json index 14a274572c..9514160893 100644 --- a/node/npm/glide/package.json +++ b/node/npm/glide/package.json @@ -2,7 +2,7 @@ "name": "${scope}${pkg_name}", "types": "build-ts/index.d.ts", "version": "${package_version}", - "description": "An AWS-sponsored, open-source Redis client.", + "description": "General Language Independent Driver for the Enterprise (GLIDE) for Valkey", "main": "build-ts/index.js", "module": "build-ts/index.js", "type": "commonjs", @@ -26,7 +26,7 @@ "client", "valkey-glide" ], - "author": "Amazon Web Services", + "author": "Valkey GLIDE Maintainers", "license": "Apache-2.0", "bugs": { "url": "https://github.com/valkey-io/valkey-glide/issues" diff --git a/node/package.json b/node/package.json index ce6fdb9747..20dbeea80b 100644 --- a/node/package.json +++ b/node/package.json @@ -58,7 +58,7 @@ "typescript": "^5.5.4", "uuid": "^10.0.0" }, - "author": "Valkey contributors", + "author": "Valkey GLIDE Maintainers", "license": "Apache-2.0", "publishConfig": { "${registry_scope}registry": "https://registry.npmjs.org/",