Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: upgrade qdrant addon to v1.0 API, refactor scripts and add ut #1124

Merged
merged 8 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions addons/qdrant/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@ version: 1.0.0-alpha.0
# This is the version number of qdrant.
appVersion: "1.10.0"

# Add a dependency to the kubeblocks definition library chart
dependencies:
- name: kblib
version: 0.1.0
repository: file://../kblib
alias: extra

home: https://qdrant.tech/
icon: https://qdrant.tech/images/logo_with_text.svg


maintainers:
- name: iziang
url: https://github.com/apecloud/kubeblocks/


sources:
- https://github.com/apecloud/kubeblocks/

annotations:
addon.kubeblocks.io/kubeblocks-version: ">=0.9.0"
addon.kubeblocks.io/kubeblocks-version: ">=1.0.0"
addon.kubeblocks.io/model: "vector"
addon.kubeblocks.io/provider: "community"
204 changes: 204 additions & 0 deletions addons/qdrant/scripts-ut-spec/qdrant_member_leave_spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
# shellcheck shell=bash
# shellcheck disable=SC2034

# validate_shell_type_and_version defined in shellspec/spec_helper.sh used to validate the expected shell type and version this script needs to run.
if ! validate_shell_type_and_version "bash" 4 &>/dev/null; then
echo "qdrant_member_leave_spec.sh skip cases because dependency bash version 4 or higher is not installed."
exit 0
fi

source ./utils.sh

# The unit test needs to rely on the common library functions defined in kblib.
# Therefore, we first dynamically generate the required common library files from the kblib library chart.
common_library_file="./common.sh"
generate_common_library $common_library_file

Describe "Qdrant Member Leave Script Tests"
# Load the script to be tested
Include $common_library_file
Include ../scripts/qdrant-member-leave.sh

init() {
# set ut_mode to true to hack control flow in the script
ut_mode="true"
}
BeforeAll "init"

cleanup() {
rm -f $common_library_file;
}
AfterAll 'cleanup'

un_setup() {
# Reset environment variables before each test
unset KB_LEAVE_MEMBER_POD_IP
leave_peer_uri="http://test-ip:6333"
}

# Mock jq to simulate its output
jq() {
case $2 in
*".result.peer_id"*)
echo "leave-peer-id"
;;
*".result.raft_info.leader"*)
echo "leader-peer-id"
;;
*".result.collections | length"*)
echo 2
;;
*".result.collections[].name"*)
echo "collection1" "collection2"
;;
*".result.local_shards[] | length"*)
echo 2
;;
*".result.local_shards[].shard_id"*)
echo "shard1" "shard2"
;;
*".result.local_shards"*)
echo '["shard1","shard2"]'
;;
*)
echo "unknown jq filter"
;;
esac
}

Describe "move_shards()"
It "moves shards from leave peer to leader"
un_setup
KB_LEAVE_MEMBER_POD_IP="test-ip"
cluster_info='{"result":{"peer_id":"leave-peer-id","raft_info":{"leader":"leader-peer-id"}}}'
leave_peer_id="leave-peer-id"
leader_peer_id="leader-peer-id"

curl() {
# Mock the response for collections
if [[ $1 == *"/collections"* ]]; then
echo '{"result":{"collections":[{"name":"collection1"},{"name":"collection2"}]}}'
elif [[ $1 == *"/collections/collection1/cluster"* ]]; then
echo '{"result":{"local_shards":[{"shard_id":"shard1"},{"shard_id":"shard2"}]}}'
elif [[ $1 == *"/collections/collection2/cluster"* ]]; then
echo '{"result":{"local_shards":[{"shard_id":"shard3"}]}}'
fi
return 0 # Simulate successful curl
}

check_leave_shard_ids() {
echo "mock check_leave_shard_ids called"
return 0
}

When run move_shards
The output should include "move shard shard1 in col_name collection1 from leave-peer-id to leader-peer-id"
The output should include "move shard shard2 in col_name collection1 from leave-peer-id to leader-peer-id"
The status should be success
End

It "handles no collections found"
un_setup
KB_LEAVE_MEMBER_POD_IP="test-ip"
curl() {
echo '{"result":{"collections":[]}}'
return 0
}

jq() {
case $2 in
*".result.collections | length"*)
echo 0
;;
*)
echo "unknown jq filter"
;;
esac
}

When run move_shards
The output should include "no collections found in the cluster"
The status should be success
End

It "handles no shards found in a collection"
un_setup
KB_LEAVE_MEMBER_POD_IP="test-ip"
curl() {
if [[ $1 == *"/collections"* ]]; then
echo '{"result":{"collections":[{"name":"collection1"}]}}'
elif [[ $1 == *"/collections/collection1/cluster"* ]]; then
echo '{"result":{"local_shards":[]}}'
fi
return 0
}

jq() {
case $2 in
*".result.peer_id"*)
echo "leave-peer-id"
;;
*".result.raft_info.leader"*)
echo "leader-peer-id"
;;
*".result.collections | length"*)
echo 2
;;
*".result.collections[].name"*)
echo "collection1" "collection2"
;;
*".result.local_shards[] | length"*)
echo 0
;;
*)
echo "unknown jq filter"
;;
esac
}

When run move_shards
The output should include "no shards found in collection collection1"
The output should include "no shards found in collection collection2"
The status should be success
End
End

Describe "remove_peer()"
It "removes the peer from the cluster"
un_setup
KB_LEAVE_MEMBER_POD_IP="test-ip"
leave_peer_id="leave-peer-id"

curl() {
return 0 # Simulate successful delete
}

When run remove_peer
The output should include "remove peer leave-peer-id from cluster"
The status should be success
End
End

Describe "leave_member()"
It "executes the leave member process"
un_setup
KB_LEAVE_MEMBER_POD_IP="test-ip"
cluster_info='{"result":{"peer_id":"leave-peer-id","raft_info":{"leader":"leader-peer-id"}}}'
leave_peer_id="leave-peer-id"
leader_peer_id="leader-peer-id"

move_shards() {
echo "mock move_shards called"
}
remove_peer() {
echo "mock remove_peer called"
}

When run leave_member
The output should include "scaling in, we need to move local shards to other peers and remove local peer from the cluster"
The output should include "mock move_shards called"
The output should include "mock remove_peer called"
The status should be success
End
End
End
110 changes: 110 additions & 0 deletions addons/qdrant/scripts-ut-spec/qdrant_setup_spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# shellcheck shell=bash
# shellcheck disable=SC2034

# validate_shell_type_and_version defined in shellspec/spec_helper.sh used to validate the expected shell type and version this script needs to run.
if ! validate_shell_type_and_version "bash" 4 &>/dev/null; then
echo "qdrant_setup_spec.sh skip cases because dependency bash version 4 or higher is not installed."
exit 0
fi

source ./utils.sh

# The unit test needs to rely on the common library functions defined in kblib.
# Therefore, we first dynamically generate the required common library files from the kblib library chart.
common_library_file="./common.sh"
generate_common_library $common_library_file

Describe "Qdrant Server Setup Script Tests"
# Load the script to be tested
Include $common_library_file
Include ../scripts/qdrant-setup.sh

init() {
# set ut_mode to true to hack control flow in the script
ut_mode="true"
}
BeforeAll "init"

cleanup() {
rm -f $common_library_file;
}
AfterAll 'cleanup'

un_setup() {
# Reset environment variables before each test
unset QDRANT_POD_NAME_LIST
unset QDRANT_POD_FQDN_LIST
unset CURRENT_POD_NAME
}

Describe "get_boostrap_node()"
It "returns the minimum lexicographical pod fqdn"
un_setup
QDRANT_POD_NAME_LIST="pod-a,pod-b,pod-c"
QDRANT_POD_FQDN_LIST="pod-a.example.com,pod-b.example.com,pod-c.example.com"
When run get_boostrap_node
The output should equal "pod-a.example.com"
The status should be success
End

It "returns an error if the fqdn cannot be found"
un_setup
QDRANT_POD_NAME_LIST="pod-x,pod-y,pod-z"
QDRANT_POD_FQDN_LIST="pod-a.example.com,pod-y.example.com,pod-z.example.com"
When run get_boostrap_node
The stderr should include "Error: Failed to get pod: pod-x fqdn from pod fqdn list:"
The status should be failure
End
End

Describe "start_server()"
It "starts server with bootstrap node when current pod is not bootstrap"
un_setup
CURRENT_POD_NAME="pod-b"
QDRANT_POD_NAME_LIST="pod-a,pod-b,pod-c"
QDRANT_POD_FQDN_LIST="pod-a.example.com,pod-b.example.com,pod-c.example.com"
./tools/curl() {
echo "mock func get params: $1"
return 0 # Simulate successful curl
}
./qdrant() {
echo "mock qdrant func get params: $1 $2 $3 $4"
return 0 # Simulate successful curl
}
When run start_server
The output should include "mock func get params: http://pod-a.example.com:6333/cluster"
The output should include "mock qdrant func get params: --bootstrap http://pod-a.example.com:6335 --uri http://pod-b.example.com:6335"
The status should be success
End

It "starts server with bootstrap node when current pod is bootstrap"
un_setup
CURRENT_POD_NAME="pod-a"
QDRANT_POD_NAME_LIST="pod-a,pod-b,pod-c"
QDRANT_POD_FQDN_LIST="pod-a.example.com,pod-b.example.com,pod-c.example.com"
./qdrant() {
echo "mock qdrant func get params: $1 $2"
return 0 # Simulate successful curl
}
When run start_server
The output should include "mock qdrant func get params: --uri http://pod-a.example.com:6335"
The status should be success
End

It "exits with error if QDRANT_POD_NAME_LIST is not set"
un_setup
QDRANT_POD_FQDN_LIST="pod-a.example.com,pod-b.example.com,pod-c.example.com"
When run start_server
The stderr should include "QDRANT_POD_NAME_LIST or QDRANT_POD_FQDN_LIST is not set, please check."
The status should be failure
End

It "exits with error if QDRANT_POD_FQDN_LIST is not set"
un_setup
QDRANT_POD_NAME_LIST="pod-a,pod-b,pod-c"
When run start_server
The stderr should include "QDRANT_POD_NAME_LIST or QDRANT_POD_FQDN_LIST is not set, please check."
The status should be failure
End
End
End
32 changes: 32 additions & 0 deletions addons/qdrant/scripts-ut-spec/utils.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

# utils functions for shellspec unit tests

convert_tpl_to_bash() {
local input_file="$1"
local output_file="$2"

sed -e '/^{{\/\*$/,/^\*\/}}$/d' \
-e '/^{{-.*}}/d' \
-e 's/{{- define ".*" }}//' \
-e 's/{{- end }}//' \
"$input_file" >> "$output_file"
}

generate_common_library() {
local library_file="$1"

libcommons_tpl_file="../../kblib/templates/_libcommons.tpl"
libpods_tpl_file="../../kblib/templates/_libpods.tpl"
libstrings_tpl_file="../../kblib/templates/_libstrings.tpl"
libenvs_tpl_file="../../kblib/templates/_libenvs.tpl"
libcompvars_tpl_file="../../kblib/templates/_libcompvars.tpl"
libututils_tpl_file="../../kblib/templates/_libututils.tpl"

convert_tpl_to_bash $libcommons_tpl_file "$library_file"
convert_tpl_to_bash $libpods_tpl_file "$library_file"
convert_tpl_to_bash $libstrings_tpl_file "$library_file"
convert_tpl_to_bash $libenvs_tpl_file "$library_file"
convert_tpl_to_bash $libcompvars_tpl_file "$library_file"
convert_tpl_to_bash $libututils_tpl_file "$library_file"
}
Loading
Loading