From 7470d4cfde546768c4204f243ec61909b2b544a3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Thu, 23 May 2024 11:30:52 -0600 Subject: [PATCH 001/215] Added basic CI/CD --- .github/workflows/integration_test.yml | 47 +++++++++++++++++ tests/aerospike-proximus.yml | 57 +++++++++++++++++++++ tests/aerospike.conf | 71 ++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 .github/workflows/integration_test.yml create mode 100644 tests/aerospike-proximus.yml create mode 100644 tests/aerospike.conf diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml new file mode 100644 index 00000000..fee6c95c --- /dev/null +++ b/.github/workflows/integration_test.yml @@ -0,0 +1,47 @@ +name: Run Unit Tests + +on: + pull_request: + branches: + - dev + +jobs: + test: + runs-on: ubuntu-latest + + + strategy: + matrix: + python-version: [3.8, 3.9, 3.10, 3.11] + + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Start Aerospike Server + run: | + docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + - name: Create features.conf from secret + run: echo "${{ secrets.FEATURES_CONF }}" > ./features.conf + + - name: Start Aerospike Proximus + run: | + docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.3.1 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + - name: Run unit tests + run: | + python -m pytest -s + working-directory: tests \ No newline at end of file diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml new file mode 100644 index 00000000..ab79d385 --- /dev/null +++ b/tests/aerospike-proximus.yml @@ -0,0 +1,57 @@ +# Change the configuration for your use case. +# TODO: Link to Proximus docs + +cluster: + # Custom node-id. It will be auto-generated if not specified. + # node-id: a1 + + # Unique identifier for this cluster. + cluster-name: aerospike-proximus + node-id: ffffffffffffffff + +# The Proximus service listening ports, TLS and network interface. +service: + ports: + 5000: + addresses: + localhost + # Required when running behind NAT + #advertised-listeners: + # default: + # # List of externally accessible addresses and ports for this Proximus instance. + # - address: 10.0.0.1 + # port: 5000 + + +# Management API listening ports, TLS and network interface. +manage: + ports: + 5040: { } + +# Intra cluster interconnect listening ports, TLS and network interface. +interconnect: + ports: + 5001: + addresses: + localhost + +#heartbeat: +# seeds: +# - address: localhost +# port: 6001 + +# Target Aerospike cluster +aerospike: + seeds: + - localhost: + port: 3000 + +# The logging properties. +logging: + #format: json + #file: /var/log/aerospike-proximus/aerospike-proximus.log + enable-console-logging: true + levels: + com.aerospike.vector.index.cache.IndexCacheCoordinator: debug + # metrics-ticker: info + # root: debug \ No newline at end of file diff --git a/tests/aerospike.conf b/tests/aerospike.conf new file mode 100644 index 00000000..4e7bc9ad --- /dev/null +++ b/tests/aerospike.conf @@ -0,0 +1,71 @@ + +# Aerospike database configuration file +# This template sets up a single-node, single namespace developer environment. +# +# Alternatively, you can pass in your own configuration file. +# You can see more examples at +# https://github.com/aerospike/aerospike-server/tree/master/as/etc + +# This stanza must come first. +service { + feature-key-file /etc/aerospike/features.conf + cluster-name proximus +} + +logging { + + + + + + # Send log messages to stdout + console { + context any info + } +} + +network { + service { + address any + port 3000 + + # Uncomment the following to set the 'access-address' parameter to the + # IP address of the Docker host. This will the allow the server to correctly + # publish the address which applications and other nodes in the cluster to + # use when addressing this node. + # access-address + } + + heartbeat { + # mesh is used for environments that do not support multicast + mode mesh + address local + port 3002 + interval 150 + timeout 10 + } + + fabric { + # Intra-cluster communication port (migrates, replication, etc) + # default to same address in 'service' + address local + port 3001 + } + +} + +namespace proximus-meta { + replication-factor 2 +storage-engine memory { + data-size 2G +} +nsup-period 100 +} + +namespace test { + replication-factor 2 + storage-engine memory { + data-size 1G + } + nsup-period 60 +} \ No newline at end of file From 305e8ce994fd00648c5df5f716628ca73a99feb7 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Thu, 23 May 2024 11:34:02 -0600 Subject: [PATCH 002/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index fee6c95c..dc1bd4c6 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -24,7 +24,7 @@ jobs: docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - name: Create features.conf from secret - run: echo "${{ secrets.FEATURES_CONF }}" > ./features.conf + printf "%s" "${{ secrets.FEATURES_CONF }}" > ./features.conf - name: Start Aerospike Proximus run: | From 892a9dbd8b0f20f0cda281e9a745325d59270015 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Thu, 23 May 2024 11:34:44 -0600 Subject: [PATCH 003/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index dc1bd4c6..4f71a2e3 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -24,7 +24,8 @@ jobs: docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - name: Create features.conf from secret - printf "%s" "${{ secrets.FEATURES_CONF }}" > ./features.conf + run: printf "%s" "${{ secrets.FEATURES_CONF }}" > ./features.conf + - name: Start Aerospike Proximus run: | From baaf967b3aee5d3ee08d31b6027b04cb2fae27cc Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Thu, 23 May 2024 11:37:11 -0600 Subject: [PATCH 004/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 4f71a2e3..8a8dfcbb 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -26,6 +26,11 @@ jobs: - name: Create features.conf from secret run: printf "%s" "${{ secrets.FEATURES_CONF }}" > ./features.conf + - name: Cap + run: printf "%s" "${{ secrets.EXAM }}" > ./no.txt + + - name: Print + run: cat ./no.txt - name: Start Aerospike Proximus run: | From de1b66dd0297698a71c9c37bf405fd2f1427b0af Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Fri, 24 May 2024 09:15:22 -0600 Subject: [PATCH 005/215] Testing git-crypt --- .gitattributes | 1 + tests/features.conf | Bin 0 -> 88 bytes 2 files changed, 1 insertion(+) create mode 100644 .gitattributes create mode 100644 tests/features.conf diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..e15c51de --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +tests/features.conf filter=git-crypt diff=git-crypt diff --git a/tests/features.conf b/tests/features.conf new file mode 100644 index 0000000000000000000000000000000000000000..61071cd31e2868b3095f9f7d5a3204fd4add97df GIT binary patch literal 88 zcmV-e0H^-|M@dveQdv+`04<;p6}_#yvZHgJ@bk5%CY{@B(BkTS72Gp(F?^}>Cc)(3 ufMiE7K^QMNV8HmiTgg~3e8i{|LyA+XFQR4M9+#NNfROelcH3d@Y3V#ZBP+xJ literal 0 HcmV?d00001 From 1c1fa7ddb317d834e57f6a3c804989043f5237e5 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Fri, 24 May 2024 09:19:38 -0600 Subject: [PATCH 006/215] Fixed integration test to work with new features.conf --- .github/workflows/integration_test.yml | 10 ++-------- tests/features.conf | Bin 88 -> 1298 bytes 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 8a8dfcbb..3dc6fb25 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - python-version: [3.8, 3.9, 3.10, 3.11] + python-version: [3.9, 3.10, 3.11, 3.12] steps: @@ -23,18 +23,12 @@ jobs: run: | docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - name: Create features.conf from secret - run: printf "%s" "${{ secrets.FEATURES_CONF }}" > ./features.conf - - - name: Cap - run: printf "%s" "${{ secrets.EXAM }}" > ./no.txt - - name: Print run: cat ./no.txt - name: Start Aerospike Proximus run: | - docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.3.1 + docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 - name: Set up Python uses: actions/setup-python@v2 with: diff --git a/tests/features.conf b/tests/features.conf index 61071cd31e2868b3095f9f7d5a3204fd4add97df..025109466de6d2d5f476abcc1978353327d87ec9 100644 GIT binary patch literal 1298 zcmV+t1?~C(M@dveQdv+`0BQ!~1W}be=#dK~uT8`R+YhI$?aI8e7k)rOkasG!B)+XNf8)*D%6E!!h(uATf#h3jog{DWTw%_@ zLEs)hma=F@qG4b=8|M_eHa;gdviUAi`Gd=M3m-^4M5Y(Uk0`t)CRDz8tR|0$8oMPE zl2JptEST-Sp^O6HT6EFNvM$3bPEsMCEEfmZ5NV^f2?Wl04Wq7b{F0 z@Vo^ikO{w@?%5C~Hq6-$fSFsao`vHjI3PPtl8@-Hpx?Bt+iAd*-ovPjv{Q33Z6r?+ z>^nxA8LqFVxrJfx8%S)UniulPdkf=Yr>qj~?IF+eRT1KzsdEoqsOupP$7C%TcIjfx zP-*k4+dgVCx7LBHgyj?;{s6TG9!iTZDkl=*J0)a$NYeWTU}=8k6b`>#9}0^9dS16g z*_O@p_kb1@|Hv|{^joO?8uLRJEP8pCW}?S$-PhV*Eddit=Z|unuuKnWc7o0KmViG# z%^9wcr}%L02EqEn*{0K7w^+eLApHon!Uy9=7T4`0N|*LMNZkA;4YT~K7HT!l#<;KT z{wtxoa`QNpxSIOsL=4U?O2ch&FFlUU!{AY~R$^%6vXBr$sjuW ze$Rl7o!=?4_neMw8aUziOBB#TdC2qI28{p=46YmDjR7zdTP`O&LhvMM@QT~`)sjaU zp!q{!Py#l;NtKw0NrX8Y9~6DF|5CkiSC#IW*?HY>Q@2X}zFeoEUcfg2bZ-t0f@*iy z`AYYout7i{`QS~QdPQL9_>1S#PUo_X*qu&7-+()4}^VvGjC#Lq6pd_mru!TRVDgJTY1sPfV%FDHm02;94S_|AgUrAs` zmCHVorGrcOkM(wKF3R7-S>Ij59U^lw6zYj5hB(Xso?lzF5cq+Q-6!cN!rZL81VTQa zRn7EYJ@~S2RVFDhF1=6Gj)Y^=c#&K=JRu&ZpduRn$i*aL?)*QH?%HcC(E2Cautz!(t&js=nrX5 z6T}RzApH}z+n~g`(ArZ#^gcdAm^TZDfPXtOmez>+Mm-KW@VHjXZZdvcaY32jG%KPd zrGh0d`7l;Id;)phAb?DV2qqv+Cde}1#aMh_PxbzVu*#^8D2v|s#YmvM9|K`C#pO4- IM)Bs*8a>vFR{#J2 literal 88 zcmV-e0H^-|M@dveQdv+`04<;p6}_#yvZHgJ@bk5%CY{@B(BkTS72Gp(F?^}>Cc)(3 ufMiE7K^QMNV8HmiTgg~3e8i{|LyA+XFQR4M9+#NNfROelcH3d@Y3V#ZBP+xJ From 6d5fcab68d7e3e0065f14853e69be08902358b9b Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Fri, 24 May 2024 09:20:45 -0600 Subject: [PATCH 007/215] typo --- .github/workflows/integration_test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 3dc6fb25..59f88eec 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -23,8 +23,6 @@ jobs: run: | docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - name: Print - run: cat ./no.txt - name: Start Aerospike Proximus run: | From 388164f8dd0254606841512c38a47839677a0624 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Fri, 24 May 2024 09:24:23 -0600 Subject: [PATCH 008/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 59f88eec..6ae7787c 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -19,18 +19,22 @@ jobs: - name: Checkout code uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Start Aerospike Server run: | docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + working-directory: tests - name: Start Aerospike Proximus run: | docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} + working-directory: tests + - name: Install dependencies run: | From 073c5d878901fa0d4ecd9050333de101f81ccf24 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Fri, 24 May 2024 09:27:15 -0600 Subject: [PATCH 009/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 6ae7787c..5ff27ba2 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - python-version: [3.9, 3.10, 3.11, 3.12] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: From 10c190ab1ca4e0c3e382a296b41eccc2f16b50b7 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Fri, 24 May 2024 09:35:51 -0600 Subject: [PATCH 010/215] testing encryption of file. --- .github/workflows/integration_test.yml | 3 +++ tests/features.conf | Bin 1298 -> 88 bytes 2 files changed, 3 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 5ff27ba2..b5b47dad 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -24,6 +24,9 @@ jobs: with: python-version: ${{ matrix.python-version }} + - name: Print + run: cat ./tests/features.conf + - name: Start Aerospike Server run: | docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest diff --git a/tests/features.conf b/tests/features.conf index 025109466de6d2d5f476abcc1978353327d87ec9..61071cd31e2868b3095f9f7d5a3204fd4add97df 100644 GIT binary patch literal 88 zcmV-e0H^-|M@dveQdv+`04<;p6}_#yvZHgJ@bk5%CY{@B(BkTS72Gp(F?^}>Cc)(3 ufMiE7K^QMNV8HmiTgg~3e8i{|LyA+XFQR4M9+#NNfROelcH3d@Y3V#ZBP+xJ literal 1298 zcmV+t1?~C(M@dveQdv+`0BQ!~1W}be=#dK~uT8`R+YhI$?aI8e7k)rOkasG!B)+XNf8)*D%6E!!h(uATf#h3jog{DWTw%_@ zLEs)hma=F@qG4b=8|M_eHa;gdviUAi`Gd=M3m-^4M5Y(Uk0`t)CRDz8tR|0$8oMPE zl2JptEST-Sp^O6HT6EFNvM$3bPEsMCEEfmZ5NV^f2?Wl04Wq7b{F0 z@Vo^ikO{w@?%5C~Hq6-$fSFsao`vHjI3PPtl8@-Hpx?Bt+iAd*-ovPjv{Q33Z6r?+ z>^nxA8LqFVxrJfx8%S)UniulPdkf=Yr>qj~?IF+eRT1KzsdEoqsOupP$7C%TcIjfx zP-*k4+dgVCx7LBHgyj?;{s6TG9!iTZDkl=*J0)a$NYeWTU}=8k6b`>#9}0^9dS16g z*_O@p_kb1@|Hv|{^joO?8uLRJEP8pCW}?S$-PhV*Eddit=Z|unuuKnWc7o0KmViG# z%^9wcr}%L02EqEn*{0K7w^+eLApHon!Uy9=7T4`0N|*LMNZkA;4YT~K7HT!l#<;KT z{wtxoa`QNpxSIOsL=4U?O2ch&FFlUU!{AY~R$^%6vXBr$sjuW ze$Rl7o!=?4_neMw8aUziOBB#TdC2qI28{p=46YmDjR7zdTP`O&LhvMM@QT~`)sjaU zp!q{!Py#l;NtKw0NrX8Y9~6DF|5CkiSC#IW*?HY>Q@2X}zFeoEUcfg2bZ-t0f@*iy z`AYYout7i{`QS~QdPQL9_>1S#PUo_X*qu&7-+()4}^VvGjC#Lq6pd_mru!TRVDgJTY1sPfV%FDHm02;94S_|AgUrAs` zmCHVorGrcOkM(wKF3R7-S>Ij59U^lw6zYj5hB(Xso?lzF5cq+Q-6!cN!rZL81VTQa zRn7EYJ@~S2RVFDhF1=6Gj)Y^=c#&K=JRu&ZpduRn$i*aL?)*QH?%HcC(E2Cautz!(t&js=nrX5 z6T}RzApH}z+n~g`(ArZ#^gcdAm^TZDfPXtOmez>+Mm-KW@VHjXZZdvcaY32jG%KPd zrGh0d`7l;Id;)phAb?DV2qqv+Cde}1#aMh_PxbzVu*#^8D2v|s#YmvM9|K`C#pO4- IM)Bs*8a>vFR{#J2 From ecca7ed854d7e259f19c0b74d016c1611202ee5f Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Fri, 24 May 2024 09:40:34 -0600 Subject: [PATCH 011/215] Fixing features.conf --- .github/workflows/integration_test.yml | 3 --- tests/features.conf | Bin 88 -> 1298 bytes 2 files changed, 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index b5b47dad..5ff27ba2 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -24,9 +24,6 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Print - run: cat ./tests/features.conf - - name: Start Aerospike Server run: | docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest diff --git a/tests/features.conf b/tests/features.conf index 61071cd31e2868b3095f9f7d5a3204fd4add97df..025109466de6d2d5f476abcc1978353327d87ec9 100644 GIT binary patch literal 1298 zcmV+t1?~C(M@dveQdv+`0BQ!~1W}be=#dK~uT8`R+YhI$?aI8e7k)rOkasG!B)+XNf8)*D%6E!!h(uATf#h3jog{DWTw%_@ zLEs)hma=F@qG4b=8|M_eHa;gdviUAi`Gd=M3m-^4M5Y(Uk0`t)CRDz8tR|0$8oMPE zl2JptEST-Sp^O6HT6EFNvM$3bPEsMCEEfmZ5NV^f2?Wl04Wq7b{F0 z@Vo^ikO{w@?%5C~Hq6-$fSFsao`vHjI3PPtl8@-Hpx?Bt+iAd*-ovPjv{Q33Z6r?+ z>^nxA8LqFVxrJfx8%S)UniulPdkf=Yr>qj~?IF+eRT1KzsdEoqsOupP$7C%TcIjfx zP-*k4+dgVCx7LBHgyj?;{s6TG9!iTZDkl=*J0)a$NYeWTU}=8k6b`>#9}0^9dS16g z*_O@p_kb1@|Hv|{^joO?8uLRJEP8pCW}?S$-PhV*Eddit=Z|unuuKnWc7o0KmViG# z%^9wcr}%L02EqEn*{0K7w^+eLApHon!Uy9=7T4`0N|*LMNZkA;4YT~K7HT!l#<;KT z{wtxoa`QNpxSIOsL=4U?O2ch&FFlUU!{AY~R$^%6vXBr$sjuW ze$Rl7o!=?4_neMw8aUziOBB#TdC2qI28{p=46YmDjR7zdTP`O&LhvMM@QT~`)sjaU zp!q{!Py#l;NtKw0NrX8Y9~6DF|5CkiSC#IW*?HY>Q@2X}zFeoEUcfg2bZ-t0f@*iy z`AYYout7i{`QS~QdPQL9_>1S#PUo_X*qu&7-+()4}^VvGjC#Lq6pd_mru!TRVDgJTY1sPfV%FDHm02;94S_|AgUrAs` zmCHVorGrcOkM(wKF3R7-S>Ij59U^lw6zYj5hB(Xso?lzF5cq+Q-6!cN!rZL81VTQa zRn7EYJ@~S2RVFDhF1=6Gj)Y^=c#&K=JRu&ZpduRn$i*aL?)*QH?%HcC(E2Cautz!(t&js=nrX5 z6T}RzApH}z+n~g`(ArZ#^gcdAm^TZDfPXtOmez>+Mm-KW@VHjXZZdvcaY32jG%KPd zrGh0d`7l;Id;)phAb?DV2qqv+Cde}1#aMh_PxbzVu*#^8D2v|s#YmvM9|K`C#pO4- IM)Bs*8a>vFR{#J2 literal 88 zcmV-e0H^-|M@dveQdv+`04<;p6}_#yvZHgJ@bk5%CY{@B(BkTS72Gp(F?^}>Cc)(3 ufMiE7K^QMNV8HmiTgg~3e8i{|LyA+XFQR4M9+#NNfROelcH3d@Y3V#ZBP+xJ From 6f6dcb4d196d7d8180a4f603e1b751cd8715fbf9 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 18 Jun 2024 14:44:51 -0600 Subject: [PATCH 012/215] Initial commit --- proto/auth.proto | 22 +- proto/index.proto | 2 +- proto/transact.proto | 11 +- proto/types.proto | 31 +- proto/user-admin.proto | 84 +++++ proto/vector-db.proto | 24 +- src/aerospike_vector_search/admin.py | 4 +- src/aerospike_vector_search/aio/admin.py | 116 ++++++- src/aerospike_vector_search/aio/client.py | 5 +- .../aio/internal/channel_provider.py | 58 +++- src/aerospike_vector_search/client.py | 4 +- .../internal/channel_provider.py | 31 +- .../shared/admin_helpers.py | 92 +++++- .../shared/base_channel_provider.py | 33 +- src/aerospike_vector_search/shared/helpers.py | 5 +- .../shared/proto_generated/auth_pb2.py | 18 +- .../shared/proto_generated/auth_pb2_grpc.py | 29 +- .../shared/proto_generated/index_pb2.py | 4 +- .../shared/proto_generated/transact_pb2.py | 14 +- .../shared/proto_generated/types_pb2.py | 24 +- .../shared/proto_generated/user_admin_pb2.py | 45 +++ .../proto_generated/user_admin_pb2_grpc.py | 310 ++++++++++++++++++ .../shared/proto_generated/vector_db_pb2.py | 22 +- .../proto_generated/vector_db_pb2_grpc.py | 44 +-- src/aerospike_vector_search/types.py | 18 + tests/rbac/aio/conftest.py | 37 +++ tests/rbac/aio/test_admin_client_add_user.py | 75 +++++ tests/rbac/aio/test_admin_client_drop_user.py | 37 +++ tests/rbac/aio/test_admin_client_get_user.py | 38 +++ .../rbac/aio/test_admin_client_grant_roles.py | 49 +++ .../rbac/aio/test_admin_client_list_users.py | 40 +++ .../test_admin_client_update_credentials.py | 47 +++ tests/rbac/aio/utils.py | 4 + tests/{ => standard}/aio/__init__.py | 0 tests/{ => standard}/aio/conftest.py | 12 +- tests/{ => standard}/aio/requirements.txt | 0 .../aio/test_admin_client_index_create.py | 0 .../aio/test_admin_client_index_drop.py | 0 .../aio/test_admin_client_index_get.py | 0 .../aio/test_admin_client_index_get_status.py | 0 .../aio/test_admin_client_index_list.py | 0 .../aio/test_vector_client_delete.py | 0 .../aio/test_vector_client_exists.py | 0 .../aio/test_vector_client_get.py | 0 .../aio/test_vector_client_insert.py | 0 .../aio/test_vector_client_update.py | 0 .../aio/test_vector_client_upsert.py | 0 .../{ => standard}/aio/test_vector_search.py | 0 tests/{ => standard}/sync/__init__.py | 0 tests/{ => standard}/sync/conftest.py | 0 tests/{ => standard}/sync/requirements.txt | 0 .../sync/test_admin_client_index_create.py | 0 .../sync/test_admin_client_index_drop.py | 0 .../sync/test_admin_client_index_get.py | 0 .../test_admin_client_index_get_status.py | 0 .../sync/test_admin_client_index_list.py | 0 .../sync/test_vector_client_delete.py | 0 .../sync/test_vector_client_exists.py | 0 .../sync/test_vector_client_get.py | 0 .../sync/test_vector_client_insert.py | 0 .../sync/test_vector_client_update.py | 0 .../sync/test_vector_client_upsert.py | 0 .../{ => standard}/sync/test_vector_search.py | 0 63 files changed, 1260 insertions(+), 129 deletions(-) create mode 100644 proto/user-admin.proto create mode 100644 src/aerospike_vector_search/shared/proto_generated/user_admin_pb2.py create mode 100644 src/aerospike_vector_search/shared/proto_generated/user_admin_pb2_grpc.py create mode 100644 tests/rbac/aio/conftest.py create mode 100644 tests/rbac/aio/test_admin_client_add_user.py create mode 100644 tests/rbac/aio/test_admin_client_drop_user.py create mode 100644 tests/rbac/aio/test_admin_client_get_user.py create mode 100644 tests/rbac/aio/test_admin_client_grant_roles.py create mode 100644 tests/rbac/aio/test_admin_client_list_users.py create mode 100644 tests/rbac/aio/test_admin_client_update_credentials.py create mode 100644 tests/rbac/aio/utils.py rename tests/{ => standard}/aio/__init__.py (100%) rename tests/{ => standard}/aio/conftest.py (73%) rename tests/{ => standard}/aio/requirements.txt (100%) rename tests/{ => standard}/aio/test_admin_client_index_create.py (100%) rename tests/{ => standard}/aio/test_admin_client_index_drop.py (100%) rename tests/{ => standard}/aio/test_admin_client_index_get.py (100%) rename tests/{ => standard}/aio/test_admin_client_index_get_status.py (100%) rename tests/{ => standard}/aio/test_admin_client_index_list.py (100%) rename tests/{ => standard}/aio/test_vector_client_delete.py (100%) rename tests/{ => standard}/aio/test_vector_client_exists.py (100%) rename tests/{ => standard}/aio/test_vector_client_get.py (100%) rename tests/{ => standard}/aio/test_vector_client_insert.py (100%) rename tests/{ => standard}/aio/test_vector_client_update.py (100%) rename tests/{ => standard}/aio/test_vector_client_upsert.py (100%) rename tests/{ => standard}/aio/test_vector_search.py (100%) rename tests/{ => standard}/sync/__init__.py (100%) rename tests/{ => standard}/sync/conftest.py (100%) rename tests/{ => standard}/sync/requirements.txt (100%) rename tests/{ => standard}/sync/test_admin_client_index_create.py (100%) rename tests/{ => standard}/sync/test_admin_client_index_drop.py (100%) rename tests/{ => standard}/sync/test_admin_client_index_get.py (100%) rename tests/{ => standard}/sync/test_admin_client_index_get_status.py (100%) rename tests/{ => standard}/sync/test_admin_client_index_list.py (100%) rename tests/{ => standard}/sync/test_vector_client_delete.py (100%) rename tests/{ => standard}/sync/test_vector_client_exists.py (100%) rename tests/{ => standard}/sync/test_vector_client_get.py (100%) rename tests/{ => standard}/sync/test_vector_client_insert.py (100%) rename tests/{ => standard}/sync/test_vector_client_update.py (100%) rename tests/{ => standard}/sync/test_vector_client_upsert.py (100%) rename tests/{ => standard}/sync/test_vector_search.py (100%) diff --git a/proto/auth.proto b/proto/auth.proto index 22bbebb6..ef9178a3 100644 --- a/proto/auth.proto +++ b/proto/auth.proto @@ -3,22 +3,26 @@ syntax = "proto3"; package aerospike.vector; option go_package = "aerospike.com/vector/protos/"; -option java_package = "com.aerospike.vector.client"; +option java_package = "com.aerospike.vector.client.proto"; option java_multiple_files = true; -// Auth service -service AuthService { - rpc Get(AerospikeAuthRequest) returns (AerospikeAuthResponse) {} -} +import "google/protobuf/empty.proto"; +import "types.proto"; // An auth request to get an access token to perform operations on Aerospike // database. -message AerospikeAuthRequest { - string username = 1; - string password = 2; +message AuthRequest { + Credentials credentials = 1; } // An auth token to perform operations on Aerospike database. -message AerospikeAuthResponse { +message AuthResponse { string token = 1; } + +// Auth service +service AuthService { + // Request authentication. + rpc Authenticate(AuthRequest) returns (AuthResponse) {} +} + diff --git a/proto/index.proto b/proto/index.proto index 9748afc4..ec5e720a 100644 --- a/proto/index.proto +++ b/proto/index.proto @@ -3,7 +3,7 @@ syntax = "proto3"; package aerospike.vector; option go_package = "aerospike.com/vector/protos/"; -option java_package = "com.aerospike.vector.client"; +option java_package = "com.aerospike.vector.client.proto"; option java_multiple_files = true; import "google/protobuf/empty.proto"; diff --git a/proto/transact.proto b/proto/transact.proto index 5394a7ea..7c4dc441 100644 --- a/proto/transact.proto +++ b/proto/transact.proto @@ -1,10 +1,9 @@ - syntax = "proto3"; package aerospike.vector; option go_package = "aerospike.com/vector/protos/"; -option java_package = "com.aerospike.vector.client"; +option java_package = "com.aerospike.vector.client.proto"; option java_multiple_files = true; import "google/protobuf/empty.proto"; @@ -23,6 +22,14 @@ enum WriteType { // Insert / create the record if it does not exists. // Fails if the record already exist. INSERT_ONLY = 2; + + // Replace all fields in the record if it exists, else create the + // record if it does not exists. + REPLACE = 3; + + // Replace all fields in the record if it exists. + // Fails if the record does not exist. + REPLACE_ONLY = 4; } // Put request to insert/update a record. diff --git a/proto/types.proto b/proto/types.proto index 44bbbf5f..6d796a41 100644 --- a/proto/types.proto +++ b/proto/types.proto @@ -1,10 +1,9 @@ - syntax = "proto3"; package aerospike.vector; option go_package = "aerospike.com/vector/protos/"; -option java_package = "com.aerospike.vector.client"; +option java_package = "com.aerospike.vector.client.proto"; option java_multiple_files = true; // A record key. @@ -262,6 +261,34 @@ message IndexDefinitionList { repeated IndexDefinition indices = 1; } +// A role. +message Role { + // Role's unique name/id + string id = 1; +} + +// A user. +message User { + // User's username + string username = 1; + + // Granted roles + repeated string roles = 2; +} + +// Authentication credentials. +message Credentials { + string username = 1; + oneof credentials { + PasswordCredentials passwordCredentials = 2; + } +} + +// Password credentials. +message PasswordCredentials { + string password = 1; +} + // A boolean type message Boolean { bool value = 1; diff --git a/proto/user-admin.proto b/proto/user-admin.proto new file mode 100644 index 00000000..936effdc --- /dev/null +++ b/proto/user-admin.proto @@ -0,0 +1,84 @@ +syntax = "proto3"; + +package aerospike.vector; + +option go_package = "aerospike.com/vector/protos/"; +option java_package = "com.aerospike.vector.client.proto"; +option java_multiple_files = true; + +import "google/protobuf/empty.proto"; +import "types.proto"; + +// Add a new user +message AddUserRequest { + Credentials credentials = 1; + + // Granted roles + repeated string roles = 2; +} + +// Update user credentials +message UpdateCredentialsRequest { + Credentials credentials = 1; +} + +// Update user credentials +message DropUserRequest { + string username = 1; +} + +// Update user credentials +message GetUserRequest { + string username = 1; +} + +// Grant roles request +message GrantRolesRequest { + string username = 1; + repeated string roles = 2; +} + +// Revoke roles request +message RevokeRolesRequest { + string username = 1; + repeated string roles = 2; +} + +// A list of roles. +message ListRolesResponse { + // List of roles. + repeated Role roles = 1; +} + +// A list of users. +message ListUsersResponse { + // List of users. + repeated User users = 1; +} + +// User admin service +service UserAdminService { + // Add a new user. + rpc AddUser(AddUserRequest) returns (google.protobuf.Empty) {} + + // Update user credentials. + rpc UpdateCredentials(UpdateCredentialsRequest) returns (google.protobuf.Empty) {} + + // Drop a user. + rpc DropUser(DropUserRequest) returns (google.protobuf.Empty) {} + + // Get details for a user. + rpc GetUser(GetUserRequest) returns (User) {} + + // List users. + rpc ListUsers(google.protobuf.Empty) returns (ListUsersResponse) {} + + // Grant roles to a user. + rpc GrantRoles(GrantRolesRequest) returns (google.protobuf.Empty) {} + + // Revoke roles from a user. + rpc RevokeRoles(RevokeRolesRequest) returns (google.protobuf.Empty) {} + + // List roles. + rpc ListRoles(google.protobuf.Empty) returns (ListRolesResponse) {} +} diff --git a/proto/vector-db.proto b/proto/vector-db.proto index 344a16cd..6e002a90 100644 --- a/proto/vector-db.proto +++ b/proto/vector-db.proto @@ -3,7 +3,7 @@ syntax = "proto3"; package aerospike.vector; option go_package = "aerospike.com/vector/protos/"; -option java_package = "com.aerospike.vector.client"; +option java_package = "com.aerospike.vector.client.proto"; option java_multiple_files = true; import "google/protobuf/empty.proto"; @@ -59,14 +59,16 @@ message ClusterNodeEndpointsRequest { optional string listenerName = 1; } -message OwnedPartitions { - repeated uint64 ownedPartitions = 1; -} +message ClusteringState { + // Indicates if this node is in a cluster. + bool isInCluster = 1; + + // Unique identifier for the current cluster epoch. + // Valid only if the node is in cluster. + ClusterId clusterId = 2; -// Cluster partition ownership. -message ClusterPartitions { - // A map from node-ids to owned partition list. - map partitions = 1; + // Current cluster members. + repeated NodeId members = 3; } // Information about the service. @@ -82,9 +84,9 @@ service ClusterInfo { // Get current cluster-Id for the current cluster. rpc GetClusterId(google.protobuf.Empty) returns (ClusterId) {} + // Get current cluster-Id for the current cluster. + rpc GetClusteringState(google.protobuf.Empty) returns (ClusteringState) {} + // Get the advertised/listening endpoints for all nodes in the cluster, given a listener name. rpc GetClusterEndpoints(ClusterNodeEndpointsRequest) returns(ClusterNodeEndpoints) {} - - // Get per-node owned partition list for all nodes in the cluster. - rpc GetOwnedPartitions(google.protobuf.Empty) returns(ClusterPartitions) {} } diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index 637e230a..487bbe4d 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -24,6 +24,8 @@ def __init__( seeds: Union[types.HostPort, tuple[types.HostPort, ...]], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, + username: str = None, + password: str = None ) -> None: """ Initialize the Aerospike Vector Search Admin Client. @@ -40,7 +42,7 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer + seeds, listener_name, is_loadbalancer, username, password ) def index_create( diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index 98b32570..08342075 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -24,6 +24,9 @@ def __init__( seeds: Union[types.HostPort, tuple[types.HostPort, ...]], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, + username: Optional[str] = None, + password: Optional[str] = None, + root_certificate: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Admin Client. @@ -40,7 +43,7 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer + seeds, listener_name, is_loadbalancer, username, password, root_certificate ) async def index_create( @@ -98,7 +101,7 @@ async def index_create( ) try: - await index_stub.Create(index_create_request) + await index_stub.Create(index_create_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -132,7 +135,7 @@ async def index_drop(self, *, namespace: str, name: str) -> None: namespace, name, logger ) try: - await index_stub.Drop(index_drop_request) + await index_stub.Drop(index_drop_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -159,7 +162,7 @@ async def index_list(self) -> list[dict]: (index_stub, index_list_request) = self._prepare_index_list(logger) try: - response = await index_stub.List(index_list_request) + response = await index_stub.List(index_list_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -189,7 +192,7 @@ async def index_get( namespace, name, logger ) try: - response = await index_stub.Get(index_get_request) + response = await index_stub.Get(index_get_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -229,6 +232,109 @@ async def index_get_status(self, *, namespace: str, name: str) -> int: return self._respond_index_get_status(response) + async def add_user(self, *, username: str, password: str, roles: list[str]) -> int: + await self._channel_provider._is_ready() + + (user_admin_stub, add_user_request) = self._prepare_add_user( + username, password, roles, logger + ) + + + try: + await user_admin_stub.AddUser(add_user_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + async def update_credentials(self, *, username: str, password: str) -> int: + await self._channel_provider._is_ready() + + (user_admin_stub, update_credentials_request) = self._prepare_update_credentials( + username, password, logger + ) + try: + await user_admin_stub.UpdateCredentials(update_credentials_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + async def drop_user(self, *, username: str) -> int: + await self._channel_provider._is_ready() + + (user_admin_stub, drop_user_request) = self._prepare_drop_user( + username, logger + ) + try: + await user_admin_stub.DropUser(drop_user_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + async def get_user(self, *, username: str) -> int: + await self._channel_provider._is_ready() + + (user_admin_stub, get_user_request) = self._prepare_get_user( + username, logger + ) + try: + response = await user_admin_stub.GetUser(get_user_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + return self._respond_get_user(response) + + async def list_users(self) -> int: + await self._channel_provider._is_ready() + + (user_admin_stub, list_users_request) = self._prepare_list_users( + logger + ) + + try: + response = await user_admin_stub.ListUsers(list_users_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + return self._respond_list_users(response) + + async def grant_roles(self, *, username: str, roles: list[str]) -> int: + await self._channel_provider._is_ready() + + (user_admin_stub, grant_roles_request) = self._prepare_grant_roles( + username, roles, logger + ) + try: + await user_admin_stub.GrantRoles(grant_roles_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + async def revoke_roles(self, *, username: str, roles: list[str]) -> int: + await self._channel_provider._is_ready() + + (user_admin_stub, revoke_roles_request) = self._prepare_revoke_roles( + username, roles, logger + ) + try: + await user_admin_stub.RevokeRoles(revoke_roles_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + async def list_roles(self) -> int: + await self._channel_provider._is_ready() + + (user_admin_stub, list_roles_request) = self._prepare_list_roles( + logger + ) + try: + response = await user_admin_stub.ListRoles(list_roles_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + return self._respond_list_roles(response) + async def _wait_for_index_creation( self, *, diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index 7c248c6b..9dee89ef 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -27,6 +27,9 @@ def __init__( seeds: Union[types.HostPort, tuple[types.HostPort, ...]], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, + username: Optional[str] = None, + password: Optional[str] = None, + root_certificate: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Vector Client. @@ -44,7 +47,7 @@ def __init__( """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer + seeds, listener_name, is_loadbalancer, username, password, root_certificate ) async def insert( diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index aeb6581b..23e92705 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -1,6 +1,8 @@ import re import asyncio import logging +import jwt +from jwt.exceptions import InvalidTokenError from typing import Optional, Union import google.protobuf.empty_pb2 @@ -25,13 +27,18 @@ def __init__( seeds: tuple[types.HostPort, ...], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, + username: Optional[str] = None, + password: Optional[str] = None, + root_certificate: Optional[str] = None, ) -> None: - super().__init__(seeds, listener_name, is_loadbalancer) - asyncio.create_task(self._tend()) + super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate) self._tend_initalized: asyncio.Event = asyncio.Event() self._tend_ended: asyncio.Event = asyncio.Event() self._task: Optional[asyncio.Task] = None + self._initty = False + asyncio.create_task(self._tend()) + async def close(self): self._closed = True @@ -52,11 +59,13 @@ async def _is_ready(self): async def _tend(self): (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() + self._token = await self._authenticate(credentials=self._credentials) if end_tend: self._tend_ended.set() return + stubs = [] tasks = [] @@ -65,26 +74,26 @@ async def _tend(self): stub = vector_db_pb2_grpc.ClusterInfoStub(channel) stubs.append(stub) try: - tasks.append(stub.GetClusterId(empty)) - + tasks.append(await stub.GetClusterId(empty, credentials=grpc.access_token_call_credentials(self._token))) except Exception as e: logger.debug( "While tending, failed to get cluster id with error:" + str(e) ) - - new_cluster_ids = await asyncio.gather(*tasks) + new_cluster_ids = tasks for index, value in enumerate(new_cluster_ids): if self.check_cluster_id(value.id): update_endpoints_stub = stubs[index] break + if update_endpoints_stub: try: response = await update_endpoints_stub.GetClusterEndpoints( vector_db_pb2.ClusterNodeEndpointsRequest( listenerName=self.listener_name - ) + ), + credentials=grpc.access_token_call_credentials(self._token) ) temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) except Exception as e: @@ -137,4 +146,37 @@ async def _tend(self): def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.aio.Channel: # TODO: Take care of TLS host = re.sub(r"%.*", "", host) - return grpc.aio.insecure_channel(f"{host}:{port}") + + # Load the CA certificate + with open(self._root_certificate, 'rb') as f: + root_certificate = f.read() + + # Load the SSL/TLS credentials + ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate) + + #call_credentials = grpc.access_token_call_credentials(self._token) + + #composite_credentials = grpc.composite_channel_credentials(ssl_credentials, call_credentials) + + return grpc.aio.secure_channel(f"{host}:{port}", ssl_credentials) + + + async def _authenticate( + self, + *, + credentials + ) -> None: + + (auth_stub, auth_request) = self._prepare_authenticate( + credentials, logger + ) + + try: + response = await auth_stub.Authenticate(auth_request) + except grpc.RpcError as e: + print("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + return grpc.access_token_call_credentials(response.token) + + diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index f9b7d783..95fec629 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -27,6 +27,8 @@ def __init__( seeds: Union[types.HostPort, tuple[types.HostPort, ...]], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, + username: str = None, + password: str = None ) -> None: """ Initialize the Aerospike Vector Search Vector Client. @@ -44,7 +46,7 @@ def __init__( """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer + seeds, listener_name, is_loadbalancer, username, password ) def insert( diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index 51cf8254..946d1a38 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -25,8 +25,11 @@ def __init__( seeds: tuple[types.HostPort, ...], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, + username: str = None, + password: str = None, + tls_path: str = None ) -> None: - super().__init__(seeds, listener_name, is_loadbalancer) + super().__init__(seeds, listener_name, is_loadbalancer, username, password) self._tend_ended = threading.Event() self._timer = None self._tend() @@ -47,6 +50,7 @@ def close(self): def _tend(self): (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() + self._token = self._authenticate(self._credentials) if end_tend: self._tend_ended.set() @@ -57,7 +61,7 @@ def _tend(self): stub = vector_db_pb2_grpc.ClusterInfoStub(channel) try: - new_cluster_id = stub.GetClusterId(empty).id + new_cluster_id = stub.GetClusterId(empty, credentials=self._credentials).id if self.check_cluster_id(new_cluster_id): update_endpoints_stub = stub break @@ -73,7 +77,7 @@ def _tend(self): try: response = stub.GetClusterEndpoints( vector_db_pb2.ClusterNodeEndpointsRequest( - listenerName=self.listener_name + listenerName=self.listener_name, credentials=self._credentials ) ) temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) @@ -110,10 +114,29 @@ def _tend(self): logger.debug( "While tending, failed to close GRPC channel:" + str(e) ) - # TODO: check tend interval. + + self._timer = threading.Timer(1, self._tend).start() def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: # TODO: Take care of TLS host = re.sub(r"%.*", "", host) return grpc.insecure_channel(f"{host}:{port}") + + + def _authenticate( + self, + *, + credentials + ) -> None: + + (auth_stub, auth_request) = self._prepare_authenticate( + credentials, logger + ) + + try: + response = auth_stub.Authenticate(auth_request) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + return response diff --git a/src/aerospike_vector_search/shared/admin_helpers.py b/src/aerospike_vector_search/shared/admin_helpers.py index 02c2961e..392b6b12 100644 --- a/src/aerospike_vector_search/shared/admin_helpers.py +++ b/src/aerospike_vector_search/shared/admin_helpers.py @@ -8,8 +8,8 @@ import grpc from . import helpers -from .proto_generated import index_pb2_grpc -from .proto_generated import types_pb2 +from .proto_generated import index_pb2_grpc, user_admin_pb2_grpc +from .proto_generated import types_pb2, user_admin_pb2 from .. import types logger = logging.getLogger(__name__) @@ -106,6 +106,72 @@ def _prepare_index_get_status(self, namespace, name, logger) -> None: return (index_stub, index_get_status_request) + def _prepare_add_user(self, username, password, roles, logger) -> None: + logger.debug("Getting index status: username=%s, password=%s, roles=%s", username, password, roles) + + user_admin_stub = self._get_user_admin_stub() + credentials = helpers._get_credentials(username, password) + add_user_request = user_admin_pb2.AddUserRequest(credentials=credentials, roles=roles) + + return (user_admin_stub, add_user_request) + + def _prepare_update_credentials(self, username, password, logger) -> None: + logger.debug("Getting index status: username=%s, password=%s", username, password) + + user_admin_stub = self._get_user_admin_stub() + credentials = helpers._get_credentials(username, password) + update_user_request = user_admin_pb2.UpdateCredentialsRequest(credentials=credentials) + + return (user_admin_stub, update_user_request) + + def _prepare_drop_user(self, username, logger) -> None: + logger.debug("Getting index status: username=%s", username) + + user_admin_stub = self._get_user_admin_stub() + drop_user_request = user_admin_pb2.DropUserRequest(username=username) + + return (user_admin_stub, drop_user_request) + + def _prepare_get_user(self, username, logger) -> None: + logger.debug("Getting index status: username=%s", username) + + user_admin_stub = self._get_user_admin_stub() + get_user_request = user_admin_pb2.GetUserRequest(username=username) + + return (user_admin_stub, get_user_request) + + def _prepare_list_users(self, logger) -> None: + logger.debug("Getting index status") + + user_admin_stub = self._get_user_admin_stub() + list_users_request = empty + + return (user_admin_stub, list_users_request) + + def _prepare_grant_roles(self, username, roles, logger) -> None: + logger.debug("Getting index status: username=%s, roles=%s", username, roles) + + user_admin_stub = self._get_user_admin_stub() + grant_roles_request = user_admin_pb2.GrantRolesRequest(username=username, roles=roles) + + return (user_admin_stub, grant_roles_request) + + def _prepare_revoke_roles(self, username, roles, logger) -> None: + logger.debug("Getting index status: username=%s, roles=%s", username, roles) + + user_admin_stub = self._get_user_admin_stub() + revoke_roles_request = user_admin_pb2.RevokeRolesRequest(username=username, roles=roles) + + return (user_admin_stub, revoke_roles_request) + + def _prepare_list_roles(self, logger) -> None: + logger.debug("Getting index status") + + user_admin_stub = self._get_user_admin_stub() + list_roles_request = empty + + return (user_admin_stub, list_roles_request) + def _respond_index_list(self, response) -> None: response_list = [] for index in response.indices: @@ -147,15 +213,35 @@ def _respond_index_get(self, response) -> None: response_dict["hnsw_params"] = hnsw_params_dict return response_dict + def _respond_get_user(self, response) -> None: + + + return types.User(username=response.username, roles=list(response.roles)) + + def _respond_list_users(self, response) -> None: + user_list = [] + for user in response.users: + user_list.append(types.User(username=user.username, roles=list(user.roles))) + return user_list + + def _respond_list_roles(self, response) -> None: + return list(response.roles) + def _respond_index_get_status(self, response) -> None: return response.unmergedRecordCount def _get_index_stub(self): return index_pb2_grpc.IndexServiceStub(self._channel_provider.get_channel()) + def _get_user_admin_stub(self): + return user_admin_pb2_grpc.UserAdminServiceStub(self._channel_provider.get_channel()) + def _get_index_id(self, namespace, name): return types_pb2.IndexId(namespace=namespace, name=name) + def _get_add_user_request(self, namespace, name): + return user_admin_pb2.AddUserRequest(namespace=namespace, name=name) + def _prepare_wait_for_index_waiting(self, namespace, name, wait_interval): return helpers._prepare_wait_for_index_waiting( self, namespace, name, wait_interval @@ -163,4 +249,4 @@ def _prepare_wait_for_index_waiting(self, namespace, name, wait_interval): def _check_timeout(self, start_time, timeout): if start_time + timeout < time.monotonic(): - raise "timed-out waiting for index creation" + raise "timed-out waiting for index creation" \ No newline at end of file diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index 39de3682..4eed18f2 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -3,10 +3,14 @@ from typing import Optional, Union +import re import grpc from .. import types -from .proto_generated import vector_db_pb2 +from . import helpers + +from .proto_generated import vector_db_pb2, auth_pb2 +from .proto_generated import auth_pb2_grpc logger = logging.getLogger(__name__) @@ -29,10 +33,21 @@ def __init__( seeds: tuple[types.HostPort, ...], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, + username: str = None, + password: str = None, + root_certificates: str = None, + private_key: str = None, + public_key: str = None ) -> None: self.seeds: tuple[types.HostPort, ...] = seeds self.listener_name: Optional[str] = listener_name self._is_loadbalancer: Optional[bool] = is_loadbalancer + self._credentials = helpers._get_credentials(username, password) + self._root_certificates = root_certificates + self._private_key = private_key + self._public_key = public_key + + self._token = "" # dict of Node Number and ChannelAndEndponts object self._node_channels: dict[int, ChannelAndEndpoints] = {} self._seedChannels: Union[list[grpc.Channel], list[grpc.Channel.aio]] = [ @@ -129,3 +144,19 @@ def check_for_new_endpoints(self, node, newEndpoints): add_new_channel = True return (channel_endpoints, add_new_channel) + + def _prepare_authenticate(self, credentials, logger): + logger.debug( + "Refreshing auth token" + ) + auth_stub = self._get_auth_stub() + + auth_request = self._get_authenticate_request(self._credentials) + + return (auth_stub, auth_request) + + def _get_auth_stub(self): + return auth_pb2_grpc.AuthServiceStub(self.get_channel()) + + def _get_authenticate_request(self, credentials): + return auth_pb2.AuthRequest(credentials=credentials) diff --git a/src/aerospike_vector_search/shared/helpers.py b/src/aerospike_vector_search/shared/helpers.py index b203e9e6..ef8fe451 100644 --- a/src/aerospike_vector_search/shared/helpers.py +++ b/src/aerospike_vector_search/shared/helpers.py @@ -15,7 +15,7 @@ def _prepare_seeds(seeds) -> None: return seeds -def _prepare_wait_for_index_waiting(self, namespace, name, wait_interval): +def _prepare_wait_for_index_waiting(namespace, name, wait_interval): unmerged_record_initialized = False start_time = time.monotonic() @@ -31,3 +31,6 @@ def _prepare_wait_for_index_waiting(self, namespace, name, wait_interval): consecutive_index_validations, index_wait_request, ) + +def _get_credentials(username, password): + return types_pb2.Credentials(username=username, passwordCredentials=types_pb2.PasswordCredentials(password=password)) \ No newline at end of file diff --git a/src/aerospike_vector_search/shared/proto_generated/auth_pb2.py b/src/aerospike_vector_search/shared/proto_generated/auth_pb2.py index a59b79b4..484692e4 100644 --- a/src/aerospike_vector_search/shared/proto_generated/auth_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/auth_pb2.py @@ -12,20 +12,22 @@ _sym_db = _symbol_database.Default() +from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 +from . import types_pb2 as types__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nauth.proto\x12\x10\x61\x65rospike.vector\":\n\x14\x41\x65rospikeAuthRequest\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x10\n\x08password\x18\x02 \x01(\t\"&\n\x15\x41\x65rospikeAuthResponse\x12\r\n\x05token\x18\x01 \x01(\t2g\n\x0b\x41uthService\x12X\n\x03Get\x12&.aerospike.vector.AerospikeAuthRequest\x1a\'.aerospike.vector.AerospikeAuthResponse\"\x00\x42=\n\x1b\x63om.aerospike.vector.clientP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nauth.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"A\n\x0b\x41uthRequest\x12\x32\n\x0b\x63redentials\x18\x01 \x01(\x0b\x32\x1d.aerospike.vector.Credentials\"\x1d\n\x0c\x41uthResponse\x12\r\n\x05token\x18\x01 \x01(\t2^\n\x0b\x41uthService\x12O\n\x0c\x41uthenticate\x12\x1d.aerospike.vector.AuthRequest\x1a\x1e.aerospike.vector.AuthResponse\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'auth_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: _globals['DESCRIPTOR']._options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\033com.aerospike.vector.clientP\001Z\034aerospike.com/vector/protos/' - _globals['_AEROSPIKEAUTHREQUEST']._serialized_start=32 - _globals['_AEROSPIKEAUTHREQUEST']._serialized_end=90 - _globals['_AEROSPIKEAUTHRESPONSE']._serialized_start=92 - _globals['_AEROSPIKEAUTHRESPONSE']._serialized_end=130 - _globals['_AUTHSERVICE']._serialized_start=132 - _globals['_AUTHSERVICE']._serialized_end=235 + _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' + _globals['_AUTHREQUEST']._serialized_start=74 + _globals['_AUTHREQUEST']._serialized_end=139 + _globals['_AUTHRESPONSE']._serialized_start=141 + _globals['_AUTHRESPONSE']._serialized_end=170 + _globals['_AUTHSERVICE']._serialized_start=172 + _globals['_AUTHSERVICE']._serialized_end=266 # @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/auth_pb2_grpc.py b/src/aerospike_vector_search/shared/proto_generated/auth_pb2_grpc.py index 598f4490..3b13742d 100644 --- a/src/aerospike_vector_search/shared/proto_generated/auth_pb2_grpc.py +++ b/src/aerospike_vector_search/shared/proto_generated/auth_pb2_grpc.py @@ -15,10 +15,10 @@ def __init__(self, channel): Args: channel: A grpc.Channel. """ - self.Get = channel.unary_unary( - '/aerospike.vector.AuthService/Get', - request_serializer=auth__pb2.AerospikeAuthRequest.SerializeToString, - response_deserializer=auth__pb2.AerospikeAuthResponse.FromString, + self.Authenticate = channel.unary_unary( + '/aerospike.vector.AuthService/Authenticate', + request_serializer=auth__pb2.AuthRequest.SerializeToString, + response_deserializer=auth__pb2.AuthResponse.FromString, ) @@ -26,8 +26,9 @@ class AuthServiceServicer(object): """Auth service """ - def Get(self, request, context): - """Missing associated documentation comment in .proto file.""" + def Authenticate(self, request, context): + """Request authentication. + """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') @@ -35,10 +36,10 @@ def Get(self, request, context): def add_AuthServiceServicer_to_server(servicer, server): rpc_method_handlers = { - 'Get': grpc.unary_unary_rpc_method_handler( - servicer.Get, - request_deserializer=auth__pb2.AerospikeAuthRequest.FromString, - response_serializer=auth__pb2.AerospikeAuthResponse.SerializeToString, + 'Authenticate': grpc.unary_unary_rpc_method_handler( + servicer.Authenticate, + request_deserializer=auth__pb2.AuthRequest.FromString, + response_serializer=auth__pb2.AuthResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( @@ -52,7 +53,7 @@ class AuthService(object): """ @staticmethod - def Get(request, + def Authenticate(request, target, options=(), channel_credentials=None, @@ -62,8 +63,8 @@ def Get(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.AuthService/Get', - auth__pb2.AerospikeAuthRequest.SerializeToString, - auth__pb2.AerospikeAuthResponse.FromString, + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.AuthService/Authenticate', + auth__pb2.AuthRequest.SerializeToString, + auth__pb2.AuthResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/aerospike_vector_search/shared/proto_generated/index_pb2.py b/src/aerospike_vector_search/shared/proto_generated/index_pb2.py index 3d1d5812..fc4b6c66 100644 --- a/src/aerospike_vector_search/shared/proto_generated/index_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/index_pb2.py @@ -16,14 +16,14 @@ from . import types_pb2 as types__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0bindex.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"2\n\x13IndexStatusResponse\x12\x1b\n\x13unmergedRecordCount\x18\x02 \x01(\x03\x32\xf3\x02\n\x0cIndexService\x12\x45\n\x06\x43reate\x12!.aerospike.vector.IndexDefinition\x1a\x16.google.protobuf.Empty\"\x00\x12;\n\x04\x44rop\x12\x19.aerospike.vector.IndexId\x1a\x16.google.protobuf.Empty\"\x00\x12G\n\x04List\x12\x16.google.protobuf.Empty\x1a%.aerospike.vector.IndexDefinitionList\"\x00\x12\x45\n\x03Get\x12\x19.aerospike.vector.IndexId\x1a!.aerospike.vector.IndexDefinition\"\x00\x12O\n\tGetStatus\x12\x19.aerospike.vector.IndexId\x1a%.aerospike.vector.IndexStatusResponse\"\x00\x42=\n\x1b\x63om.aerospike.vector.clientP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0bindex.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"2\n\x13IndexStatusResponse\x12\x1b\n\x13unmergedRecordCount\x18\x02 \x01(\x03\x32\xf3\x02\n\x0cIndexService\x12\x45\n\x06\x43reate\x12!.aerospike.vector.IndexDefinition\x1a\x16.google.protobuf.Empty\"\x00\x12;\n\x04\x44rop\x12\x19.aerospike.vector.IndexId\x1a\x16.google.protobuf.Empty\"\x00\x12G\n\x04List\x12\x16.google.protobuf.Empty\x1a%.aerospike.vector.IndexDefinitionList\"\x00\x12\x45\n\x03Get\x12\x19.aerospike.vector.IndexId\x1a!.aerospike.vector.IndexDefinition\"\x00\x12O\n\tGetStatus\x12\x19.aerospike.vector.IndexId\x1a%.aerospike.vector.IndexStatusResponse\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'index_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: _globals['DESCRIPTOR']._options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\033com.aerospike.vector.clientP\001Z\034aerospike.com/vector/protos/' + _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' _globals['_INDEXSTATUSRESPONSE']._serialized_start=75 _globals['_INDEXSTATUSRESPONSE']._serialized_end=125 _globals['_INDEXSERVICE']._serialized_start=128 diff --git a/src/aerospike_vector_search/shared/proto_generated/transact_pb2.py b/src/aerospike_vector_search/shared/proto_generated/transact_pb2.py index 97b250b9..0ac82fdf 100644 --- a/src/aerospike_vector_search/shared/proto_generated/transact_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/transact_pb2.py @@ -16,18 +16,18 @@ from . import types_pb2 as types__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0etransact.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"\x89\x01\n\nPutRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12.\n\twriteType\x18\x02 \x01(\x0e\x32\x1b.aerospike.vector.WriteType\x12\'\n\x06\x66ields\x18\x03 \x03(\x0b\x32\x17.aerospike.vector.Field\"j\n\nGetRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12\x38\n\x0eprojectionSpec\x18\x02 \x01(\x0b\x32 .aerospike.vector.ProjectionSpec\"3\n\rExistsRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\"3\n\rDeleteRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\"b\n\x10IsIndexedRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12*\n\x07indexId\x18\x02 \x01(\x0b\x32\x19.aerospike.vector.IndexId\"R\n\x10ProjectionFilter\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .aerospike.vector.ProjectionType\x12\x0e\n\x06\x66ields\x18\x02 \x03(\t\"z\n\x0eProjectionSpec\x12\x33\n\x07include\x18\x01 \x01(\x0b\x32\".aerospike.vector.ProjectionFilter\x12\x33\n\x07\x65xclude\x18\x02 \x01(\x0b\x32\".aerospike.vector.ProjectionFilter\"\x83\x02\n\x13VectorSearchRequest\x12(\n\x05index\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12-\n\x0bqueryVector\x18\x02 \x01(\x0b\x32\x18.aerospike.vector.Vector\x12\r\n\x05limit\x18\x03 \x01(\r\x12\x34\n\nprojection\x18\x04 \x01(\x0b\x32 .aerospike.vector.ProjectionSpec\x12>\n\x10hnswSearchParams\x18\x05 \x01(\x0b\x32\".aerospike.vector.HnswSearchParamsH\x00\x42\x0e\n\x0csearchParams*9\n\tWriteType\x12\n\n\x06UPSERT\x10\x00\x12\x0f\n\x0bUPDATE_ONLY\x10\x01\x12\x0f\n\x0bINSERT_ONLY\x10\x02*2\n\x0eProjectionType\x12\x07\n\x03\x41LL\x10\x00\x12\x08\n\x04NONE\x10\x01\x12\r\n\tSPECIFIED\x10\x02\x32\xbc\x03\n\x08Transact\x12=\n\x03Put\x12\x1c.aerospike.vector.PutRequest\x1a\x16.google.protobuf.Empty\"\x00\x12?\n\x03Get\x12\x1c.aerospike.vector.GetRequest\x1a\x18.aerospike.vector.Record\"\x00\x12\x43\n\x06\x44\x65lete\x12\x1f.aerospike.vector.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\x06\x45xists\x12\x1f.aerospike.vector.ExistsRequest\x1a\x19.aerospike.vector.Boolean\"\x00\x12L\n\tIsIndexed\x12\".aerospike.vector.IsIndexedRequest\x1a\x19.aerospike.vector.Boolean\"\x00\x12U\n\x0cVectorSearch\x12%.aerospike.vector.VectorSearchRequest\x1a\x1a.aerospike.vector.Neighbor\"\x00\x30\x01\x42=\n\x1b\x63om.aerospike.vector.clientP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0etransact.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"\x89\x01\n\nPutRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12.\n\twriteType\x18\x02 \x01(\x0e\x32\x1b.aerospike.vector.WriteType\x12\'\n\x06\x66ields\x18\x03 \x03(\x0b\x32\x17.aerospike.vector.Field\"j\n\nGetRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12\x38\n\x0eprojectionSpec\x18\x02 \x01(\x0b\x32 .aerospike.vector.ProjectionSpec\"3\n\rExistsRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\"3\n\rDeleteRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\"b\n\x10IsIndexedRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12*\n\x07indexId\x18\x02 \x01(\x0b\x32\x19.aerospike.vector.IndexId\"R\n\x10ProjectionFilter\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .aerospike.vector.ProjectionType\x12\x0e\n\x06\x66ields\x18\x02 \x03(\t\"z\n\x0eProjectionSpec\x12\x33\n\x07include\x18\x01 \x01(\x0b\x32\".aerospike.vector.ProjectionFilter\x12\x33\n\x07\x65xclude\x18\x02 \x01(\x0b\x32\".aerospike.vector.ProjectionFilter\"\x83\x02\n\x13VectorSearchRequest\x12(\n\x05index\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12-\n\x0bqueryVector\x18\x02 \x01(\x0b\x32\x18.aerospike.vector.Vector\x12\r\n\x05limit\x18\x03 \x01(\r\x12\x34\n\nprojection\x18\x04 \x01(\x0b\x32 .aerospike.vector.ProjectionSpec\x12>\n\x10hnswSearchParams\x18\x05 \x01(\x0b\x32\".aerospike.vector.HnswSearchParamsH\x00\x42\x0e\n\x0csearchParams*X\n\tWriteType\x12\n\n\x06UPSERT\x10\x00\x12\x0f\n\x0bUPDATE_ONLY\x10\x01\x12\x0f\n\x0bINSERT_ONLY\x10\x02\x12\x0b\n\x07REPLACE\x10\x03\x12\x10\n\x0cREPLACE_ONLY\x10\x04*2\n\x0eProjectionType\x12\x07\n\x03\x41LL\x10\x00\x12\x08\n\x04NONE\x10\x01\x12\r\n\tSPECIFIED\x10\x02\x32\xbc\x03\n\x08Transact\x12=\n\x03Put\x12\x1c.aerospike.vector.PutRequest\x1a\x16.google.protobuf.Empty\"\x00\x12?\n\x03Get\x12\x1c.aerospike.vector.GetRequest\x1a\x18.aerospike.vector.Record\"\x00\x12\x43\n\x06\x44\x65lete\x12\x1f.aerospike.vector.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\x06\x45xists\x12\x1f.aerospike.vector.ExistsRequest\x1a\x19.aerospike.vector.Boolean\"\x00\x12L\n\tIsIndexed\x12\".aerospike.vector.IsIndexedRequest\x1a\x19.aerospike.vector.Boolean\"\x00\x12U\n\x0cVectorSearch\x12%.aerospike.vector.VectorSearchRequest\x1a\x1a.aerospike.vector.Neighbor\"\x00\x30\x01\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'transact_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: _globals['DESCRIPTOR']._options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\033com.aerospike.vector.clientP\001Z\034aerospike.com/vector/protos/' + _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' _globals['_WRITETYPE']._serialized_start=1002 - _globals['_WRITETYPE']._serialized_end=1059 - _globals['_PROJECTIONTYPE']._serialized_start=1061 - _globals['_PROJECTIONTYPE']._serialized_end=1111 + _globals['_WRITETYPE']._serialized_end=1090 + _globals['_PROJECTIONTYPE']._serialized_start=1092 + _globals['_PROJECTIONTYPE']._serialized_end=1142 _globals['_PUTREQUEST']._serialized_start=79 _globals['_PUTREQUEST']._serialized_end=216 _globals['_GETREQUEST']._serialized_start=218 @@ -44,6 +44,6 @@ _globals['_PROJECTIONSPEC']._serialized_end=738 _globals['_VECTORSEARCHREQUEST']._serialized_start=741 _globals['_VECTORSEARCHREQUEST']._serialized_end=1000 - _globals['_TRANSACT']._serialized_start=1114 - _globals['_TRANSACT']._serialized_end=1558 + _globals['_TRANSACT']._serialized_start=1145 + _globals['_TRANSACT']._serialized_end=1589 # @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/types_pb2.py b/src/aerospike_vector_search/shared/proto_generated/types_pb2.py index dea10644..2e582055 100644 --- a/src/aerospike_vector_search/shared/proto_generated/types_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/types_pb2.py @@ -14,20 +14,20 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btypes.proto\x12\x10\x61\x65rospike.vector\"\x91\x01\n\x03Key\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x10\n\x03set\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x15\n\x0bstringValue\x18\x03 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x04 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x05 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x06 \x01(\x03H\x00\x42\x07\n\x05valueB\x06\n\x04_set\"\x19\n\x08\x42oolData\x12\r\n\x05value\x18\x01 \x03(\x08\"\x1a\n\tFloatData\x12\r\n\x05value\x18\x01 \x03(\x02\"\x94\x01\n\x06MapKey\x12\x15\n\x0bstringValue\x18\x01 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x03 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x04 \x01(\x03H\x00\x12\x14\n\nfloatValue\x18\x05 \x01(\x02H\x00\x12\x15\n\x0b\x64oubleValue\x18\x06 \x01(\x01H\x00\x42\x07\n\x05value\"Y\n\x08MapEntry\x12%\n\x03key\x18\x01 \x01(\x0b\x32\x18.aerospike.vector.MapKey\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.aerospike.vector.Value\"2\n\x03Map\x12+\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x1a.aerospike.vector.MapEntry\"0\n\x04List\x12(\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x17.aerospike.vector.Value\"r\n\x06Vector\x12.\n\x08\x62oolData\x18\x01 \x01(\x0b\x32\x1a.aerospike.vector.BoolDataH\x00\x12\x30\n\tfloatData\x18\x02 \x01(\x0b\x32\x1b.aerospike.vector.FloatDataH\x00\x42\x06\n\x04\x64\x61ta\"\xb4\x02\n\x05Value\x12\x15\n\x0bstringValue\x18\x01 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x03 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x04 \x01(\x03H\x00\x12\x14\n\nfloatValue\x18\x05 \x01(\x02H\x00\x12\x15\n\x0b\x64oubleValue\x18\x06 \x01(\x01H\x00\x12)\n\x08mapValue\x18\x07 \x01(\x0b\x32\x15.aerospike.vector.MapH\x00\x12+\n\tlistValue\x18\x08 \x01(\x0b\x32\x16.aerospike.vector.ListH\x00\x12/\n\x0bvectorValue\x18\t \x01(\x0b\x32\x18.aerospike.vector.VectorH\x00\x12\x16\n\x0c\x62ooleanValue\x18\n \x01(\x08H\x00\x42\x07\n\x05value\"=\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.aerospike.vector.Value\"A\n\x17\x41\x65rospikeRecordMetadata\x12\x12\n\ngeneration\x18\x01 \x01(\r\x12\x12\n\nexpiration\x18\x02 \x01(\r\"\x85\x01\n\x06Record\x12\'\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x17.aerospike.vector.Field\x12\x46\n\x11\x61\x65rospikeMetadata\x18\x02 \x01(\x0b\x32).aerospike.vector.AerospikeRecordMetadataH\x00\x42\n\n\x08metadata\"z\n\x08Neighbor\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12-\n\x06record\x18\x02 \x01(\x0b\x32\x18.aerospike.vector.RecordH\x00\x88\x01\x01\x12\x10\n\x08\x64istance\x18\x03 \x01(\x02\x42\t\n\x07_record\"*\n\x07IndexId\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xa8\x01\n\nHnswParams\x12\x0e\n\x01m\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1b\n\x0e\x65\x66\x43onstruction\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x0f\n\x02\x65\x66\x18\x03 \x01(\rH\x02\x88\x01\x01\x12<\n\x0e\x62\x61tchingParams\x18\x04 \x01(\x0b\x32$.aerospike.vector.HnswBatchingParamsB\x04\n\x02_mB\x11\n\x0f_efConstructionB\x05\n\x03_ef\"*\n\x10HnswSearchParams\x12\x0f\n\x02\x65\x66\x18\x01 \x01(\rH\x00\x88\x01\x01\x42\x05\n\x03_ef\"\x84\x01\n\x12HnswBatchingParams\x12\x17\n\nmaxRecords\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x15\n\x08interval\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08\x64isabled\x18\x03 \x01(\x08H\x02\x88\x01\x01\x42\r\n\x0b_maxRecordsB\x0b\n\t_intervalB\x0b\n\t_disabled\"N\n\x0cIndexStorage\x12\x16\n\tnamespace\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x03set\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x0c\n\n_namespaceB\x06\n\x04_set\"\xe0\x03\n\x0fIndexDefinition\x12%\n\x02id\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12)\n\x04type\x18\x02 \x01(\x0e\x32\x1b.aerospike.vector.IndexType\x12\x12\n\ndimensions\x18\x03 \x01(\r\x12\x44\n\x14vectorDistanceMetric\x18\x04 \x01(\x0e\x32&.aerospike.vector.VectorDistanceMetric\x12\r\n\x05\x66ield\x18\x05 \x01(\t\x12\x16\n\tsetFilter\x18\x06 \x01(\tH\x01\x88\x01\x01\x12\x32\n\nhnswParams\x18\x07 \x01(\x0b\x32\x1c.aerospike.vector.HnswParamsH\x00\x12=\n\x06labels\x18\x08 \x03(\x0b\x32-.aerospike.vector.IndexDefinition.LabelsEntry\x12\x34\n\x07storage\x18\t \x01(\x0b\x32\x1e.aerospike.vector.IndexStorageH\x02\x88\x01\x01\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x08\n\x06paramsB\x0c\n\n_setFilterB\n\n\x08_storage\"I\n\x13IndexDefinitionList\x12\x32\n\x07indices\x18\x01 \x03(\x0b\x32!.aerospike.vector.IndexDefinition\"\x18\n\x07\x42oolean\x12\r\n\x05value\x18\x01 \x01(\x08*f\n\x14VectorDistanceMetric\x12\x15\n\x11SQUARED_EUCLIDEAN\x10\x00\x12\n\n\x06\x43OSINE\x10\x01\x12\x0f\n\x0b\x44OT_PRODUCT\x10\x02\x12\r\n\tMANHATTAN\x10\x03\x12\x0b\n\x07HAMMING\x10\x04*\x15\n\tIndexType\x12\x08\n\x04HNSW\x10\x00\x42=\n\x1b\x63om.aerospike.vector.clientP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btypes.proto\x12\x10\x61\x65rospike.vector\"\x91\x01\n\x03Key\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x10\n\x03set\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x15\n\x0bstringValue\x18\x03 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x04 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x05 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x06 \x01(\x03H\x00\x42\x07\n\x05valueB\x06\n\x04_set\"\x19\n\x08\x42oolData\x12\r\n\x05value\x18\x01 \x03(\x08\"\x1a\n\tFloatData\x12\r\n\x05value\x18\x01 \x03(\x02\"\x94\x01\n\x06MapKey\x12\x15\n\x0bstringValue\x18\x01 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x03 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x04 \x01(\x03H\x00\x12\x14\n\nfloatValue\x18\x05 \x01(\x02H\x00\x12\x15\n\x0b\x64oubleValue\x18\x06 \x01(\x01H\x00\x42\x07\n\x05value\"Y\n\x08MapEntry\x12%\n\x03key\x18\x01 \x01(\x0b\x32\x18.aerospike.vector.MapKey\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.aerospike.vector.Value\"2\n\x03Map\x12+\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x1a.aerospike.vector.MapEntry\"0\n\x04List\x12(\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x17.aerospike.vector.Value\"r\n\x06Vector\x12.\n\x08\x62oolData\x18\x01 \x01(\x0b\x32\x1a.aerospike.vector.BoolDataH\x00\x12\x30\n\tfloatData\x18\x02 \x01(\x0b\x32\x1b.aerospike.vector.FloatDataH\x00\x42\x06\n\x04\x64\x61ta\"\xb4\x02\n\x05Value\x12\x15\n\x0bstringValue\x18\x01 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x03 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x04 \x01(\x03H\x00\x12\x14\n\nfloatValue\x18\x05 \x01(\x02H\x00\x12\x15\n\x0b\x64oubleValue\x18\x06 \x01(\x01H\x00\x12)\n\x08mapValue\x18\x07 \x01(\x0b\x32\x15.aerospike.vector.MapH\x00\x12+\n\tlistValue\x18\x08 \x01(\x0b\x32\x16.aerospike.vector.ListH\x00\x12/\n\x0bvectorValue\x18\t \x01(\x0b\x32\x18.aerospike.vector.VectorH\x00\x12\x16\n\x0c\x62ooleanValue\x18\n \x01(\x08H\x00\x42\x07\n\x05value\"=\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.aerospike.vector.Value\"A\n\x17\x41\x65rospikeRecordMetadata\x12\x12\n\ngeneration\x18\x01 \x01(\r\x12\x12\n\nexpiration\x18\x02 \x01(\r\"\x85\x01\n\x06Record\x12\'\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x17.aerospike.vector.Field\x12\x46\n\x11\x61\x65rospikeMetadata\x18\x02 \x01(\x0b\x32).aerospike.vector.AerospikeRecordMetadataH\x00\x42\n\n\x08metadata\"z\n\x08Neighbor\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12-\n\x06record\x18\x02 \x01(\x0b\x32\x18.aerospike.vector.RecordH\x00\x88\x01\x01\x12\x10\n\x08\x64istance\x18\x03 \x01(\x02\x42\t\n\x07_record\"*\n\x07IndexId\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xa8\x01\n\nHnswParams\x12\x0e\n\x01m\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1b\n\x0e\x65\x66\x43onstruction\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x0f\n\x02\x65\x66\x18\x03 \x01(\rH\x02\x88\x01\x01\x12<\n\x0e\x62\x61tchingParams\x18\x04 \x01(\x0b\x32$.aerospike.vector.HnswBatchingParamsB\x04\n\x02_mB\x11\n\x0f_efConstructionB\x05\n\x03_ef\"*\n\x10HnswSearchParams\x12\x0f\n\x02\x65\x66\x18\x01 \x01(\rH\x00\x88\x01\x01\x42\x05\n\x03_ef\"\x84\x01\n\x12HnswBatchingParams\x12\x17\n\nmaxRecords\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x15\n\x08interval\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08\x64isabled\x18\x03 \x01(\x08H\x02\x88\x01\x01\x42\r\n\x0b_maxRecordsB\x0b\n\t_intervalB\x0b\n\t_disabled\"N\n\x0cIndexStorage\x12\x16\n\tnamespace\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x03set\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x0c\n\n_namespaceB\x06\n\x04_set\"\xe0\x03\n\x0fIndexDefinition\x12%\n\x02id\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12)\n\x04type\x18\x02 \x01(\x0e\x32\x1b.aerospike.vector.IndexType\x12\x12\n\ndimensions\x18\x03 \x01(\r\x12\x44\n\x14vectorDistanceMetric\x18\x04 \x01(\x0e\x32&.aerospike.vector.VectorDistanceMetric\x12\r\n\x05\x66ield\x18\x05 \x01(\t\x12\x16\n\tsetFilter\x18\x06 \x01(\tH\x01\x88\x01\x01\x12\x32\n\nhnswParams\x18\x07 \x01(\x0b\x32\x1c.aerospike.vector.HnswParamsH\x00\x12=\n\x06labels\x18\x08 \x03(\x0b\x32-.aerospike.vector.IndexDefinition.LabelsEntry\x12\x34\n\x07storage\x18\t \x01(\x0b\x32\x1e.aerospike.vector.IndexStorageH\x02\x88\x01\x01\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x08\n\x06paramsB\x0c\n\n_setFilterB\n\n\x08_storage\"I\n\x13IndexDefinitionList\x12\x32\n\x07indices\x18\x01 \x03(\x0b\x32!.aerospike.vector.IndexDefinition\"\x12\n\x04Role\x12\n\n\x02id\x18\x01 \x01(\t\"\'\n\x04User\x12\x10\n\x08username\x18\x01 \x01(\t\x12\r\n\x05roles\x18\x02 \x03(\t\"t\n\x0b\x43redentials\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x44\n\x13passwordCredentials\x18\x02 \x01(\x0b\x32%.aerospike.vector.PasswordCredentialsH\x00\x42\r\n\x0b\x63redentials\"\'\n\x13PasswordCredentials\x12\x10\n\x08password\x18\x01 \x01(\t\"\x18\n\x07\x42oolean\x12\r\n\x05value\x18\x01 \x01(\x08*f\n\x14VectorDistanceMetric\x12\x15\n\x11SQUARED_EUCLIDEAN\x10\x00\x12\n\n\x06\x43OSINE\x10\x01\x12\x0f\n\x0b\x44OT_PRODUCT\x10\x02\x12\r\n\tMANHATTAN\x10\x03\x12\x0b\n\x07HAMMING\x10\x04*\x15\n\tIndexType\x12\x08\n\x04HNSW\x10\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'types_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: _globals['DESCRIPTOR']._options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\033com.aerospike.vector.clientP\001Z\034aerospike.com/vector/protos/' + _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' _globals['_INDEXDEFINITION_LABELSENTRY']._options = None _globals['_INDEXDEFINITION_LABELSENTRY']._serialized_options = b'8\001' - _globals['_VECTORDISTANCEMETRIC']._serialized_start=2455 - _globals['_VECTORDISTANCEMETRIC']._serialized_end=2557 - _globals['_INDEXTYPE']._serialized_start=2559 - _globals['_INDEXTYPE']._serialized_end=2580 + _globals['_VECTORDISTANCEMETRIC']._serialized_start=2675 + _globals['_VECTORDISTANCEMETRIC']._serialized_end=2777 + _globals['_INDEXTYPE']._serialized_start=2779 + _globals['_INDEXTYPE']._serialized_end=2800 _globals['_KEY']._serialized_start=34 _globals['_KEY']._serialized_end=179 _globals['_BOOLDATA']._serialized_start=181 @@ -70,6 +70,14 @@ _globals['_INDEXDEFINITION_LABELSENTRY']._serialized_end=2316 _globals['_INDEXDEFINITIONLIST']._serialized_start=2354 _globals['_INDEXDEFINITIONLIST']._serialized_end=2427 - _globals['_BOOLEAN']._serialized_start=2429 - _globals['_BOOLEAN']._serialized_end=2453 + _globals['_ROLE']._serialized_start=2429 + _globals['_ROLE']._serialized_end=2447 + _globals['_USER']._serialized_start=2449 + _globals['_USER']._serialized_end=2488 + _globals['_CREDENTIALS']._serialized_start=2490 + _globals['_CREDENTIALS']._serialized_end=2606 + _globals['_PASSWORDCREDENTIALS']._serialized_start=2608 + _globals['_PASSWORDCREDENTIALS']._serialized_end=2647 + _globals['_BOOLEAN']._serialized_start=2649 + _globals['_BOOLEAN']._serialized_end=2673 # @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2.py b/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2.py new file mode 100644 index 00000000..c59c7b46 --- /dev/null +++ b/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: user-admin.proto +# Protobuf Python Version: 4.25.1 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 +from . import types_pb2 as types__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10user-admin.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"S\n\x0e\x41\x64\x64UserRequest\x12\x32\n\x0b\x63redentials\x18\x01 \x01(\x0b\x32\x1d.aerospike.vector.Credentials\x12\r\n\x05roles\x18\x02 \x03(\t\"N\n\x18UpdateCredentialsRequest\x12\x32\n\x0b\x63redentials\x18\x01 \x01(\x0b\x32\x1d.aerospike.vector.Credentials\"#\n\x0f\x44ropUserRequest\x12\x10\n\x08username\x18\x01 \x01(\t\"\"\n\x0eGetUserRequest\x12\x10\n\x08username\x18\x01 \x01(\t\"4\n\x11GrantRolesRequest\x12\x10\n\x08username\x18\x01 \x01(\t\x12\r\n\x05roles\x18\x02 \x03(\t\"5\n\x12RevokeRolesRequest\x12\x10\n\x08username\x18\x01 \x01(\t\x12\r\n\x05roles\x18\x02 \x03(\t\":\n\x11ListRolesResponse\x12%\n\x05roles\x18\x01 \x03(\x0b\x32\x16.aerospike.vector.Role\":\n\x11ListUsersResponse\x12%\n\x05users\x18\x01 \x03(\x0b\x32\x16.aerospike.vector.User2\xf8\x04\n\x10UserAdminService\x12\x45\n\x07\x41\x64\x64User\x12 .aerospike.vector.AddUserRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Y\n\x11UpdateCredentials\x12*.aerospike.vector.UpdateCredentialsRequest\x1a\x16.google.protobuf.Empty\"\x00\x12G\n\x08\x44ropUser\x12!.aerospike.vector.DropUserRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x45\n\x07GetUser\x12 .aerospike.vector.GetUserRequest\x1a\x16.aerospike.vector.User\"\x00\x12J\n\tListUsers\x12\x16.google.protobuf.Empty\x1a#.aerospike.vector.ListUsersResponse\"\x00\x12K\n\nGrantRoles\x12#.aerospike.vector.GrantRolesRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x0bRevokeRoles\x12$.aerospike.vector.RevokeRolesRequest\x1a\x16.google.protobuf.Empty\"\x00\x12J\n\tListRoles\x12\x16.google.protobuf.Empty\x1a#.aerospike.vector.ListRolesResponse\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'user_admin_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' + _globals['_ADDUSERREQUEST']._serialized_start=80 + _globals['_ADDUSERREQUEST']._serialized_end=163 + _globals['_UPDATECREDENTIALSREQUEST']._serialized_start=165 + _globals['_UPDATECREDENTIALSREQUEST']._serialized_end=243 + _globals['_DROPUSERREQUEST']._serialized_start=245 + _globals['_DROPUSERREQUEST']._serialized_end=280 + _globals['_GETUSERREQUEST']._serialized_start=282 + _globals['_GETUSERREQUEST']._serialized_end=316 + _globals['_GRANTROLESREQUEST']._serialized_start=318 + _globals['_GRANTROLESREQUEST']._serialized_end=370 + _globals['_REVOKEROLESREQUEST']._serialized_start=372 + _globals['_REVOKEROLESREQUEST']._serialized_end=425 + _globals['_LISTROLESRESPONSE']._serialized_start=427 + _globals['_LISTROLESRESPONSE']._serialized_end=485 + _globals['_LISTUSERSRESPONSE']._serialized_start=487 + _globals['_LISTUSERSRESPONSE']._serialized_end=545 + _globals['_USERADMINSERVICE']._serialized_start=548 + _globals['_USERADMINSERVICE']._serialized_end=1180 +# @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2_grpc.py b/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2_grpc.py new file mode 100644 index 00000000..8f465e4e --- /dev/null +++ b/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2_grpc.py @@ -0,0 +1,310 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 +from . import types_pb2 as types__pb2 +from . import user_admin_pb2 as user__admin__pb2 + + +class UserAdminServiceStub(object): + """User admin service + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.AddUser = channel.unary_unary( + '/aerospike.vector.UserAdminService/AddUser', + request_serializer=user__admin__pb2.AddUserRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + ) + self.UpdateCredentials = channel.unary_unary( + '/aerospike.vector.UserAdminService/UpdateCredentials', + request_serializer=user__admin__pb2.UpdateCredentialsRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + ) + self.DropUser = channel.unary_unary( + '/aerospike.vector.UserAdminService/DropUser', + request_serializer=user__admin__pb2.DropUserRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + ) + self.GetUser = channel.unary_unary( + '/aerospike.vector.UserAdminService/GetUser', + request_serializer=user__admin__pb2.GetUserRequest.SerializeToString, + response_deserializer=types__pb2.User.FromString, + ) + self.ListUsers = channel.unary_unary( + '/aerospike.vector.UserAdminService/ListUsers', + request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + response_deserializer=user__admin__pb2.ListUsersResponse.FromString, + ) + self.GrantRoles = channel.unary_unary( + '/aerospike.vector.UserAdminService/GrantRoles', + request_serializer=user__admin__pb2.GrantRolesRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + ) + self.RevokeRoles = channel.unary_unary( + '/aerospike.vector.UserAdminService/RevokeRoles', + request_serializer=user__admin__pb2.RevokeRolesRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + ) + self.ListRoles = channel.unary_unary( + '/aerospike.vector.UserAdminService/ListRoles', + request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + response_deserializer=user__admin__pb2.ListRolesResponse.FromString, + ) + + +class UserAdminServiceServicer(object): + """User admin service + """ + + def AddUser(self, request, context): + """Add a new user. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def UpdateCredentials(self, request, context): + """Update user credentials. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DropUser(self, request, context): + """Drop a user. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetUser(self, request, context): + """Get details for a user. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListUsers(self, request, context): + """List users. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GrantRoles(self, request, context): + """Grant roles to a user. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RevokeRoles(self, request, context): + """Revoke roles from a user. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListRoles(self, request, context): + """List roles. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_UserAdminServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'AddUser': grpc.unary_unary_rpc_method_handler( + servicer.AddUser, + request_deserializer=user__admin__pb2.AddUserRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), + 'UpdateCredentials': grpc.unary_unary_rpc_method_handler( + servicer.UpdateCredentials, + request_deserializer=user__admin__pb2.UpdateCredentialsRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), + 'DropUser': grpc.unary_unary_rpc_method_handler( + servicer.DropUser, + request_deserializer=user__admin__pb2.DropUserRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), + 'GetUser': grpc.unary_unary_rpc_method_handler( + servicer.GetUser, + request_deserializer=user__admin__pb2.GetUserRequest.FromString, + response_serializer=types__pb2.User.SerializeToString, + ), + 'ListUsers': grpc.unary_unary_rpc_method_handler( + servicer.ListUsers, + request_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + response_serializer=user__admin__pb2.ListUsersResponse.SerializeToString, + ), + 'GrantRoles': grpc.unary_unary_rpc_method_handler( + servicer.GrantRoles, + request_deserializer=user__admin__pb2.GrantRolesRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), + 'RevokeRoles': grpc.unary_unary_rpc_method_handler( + servicer.RevokeRoles, + request_deserializer=user__admin__pb2.RevokeRolesRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), + 'ListRoles': grpc.unary_unary_rpc_method_handler( + servicer.ListRoles, + request_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + response_serializer=user__admin__pb2.ListRolesResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'aerospike.vector.UserAdminService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class UserAdminService(object): + """User admin service + """ + + @staticmethod + def AddUser(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/AddUser', + user__admin__pb2.AddUserRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def UpdateCredentials(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/UpdateCredentials', + user__admin__pb2.UpdateCredentialsRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def DropUser(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/DropUser', + user__admin__pb2.DropUserRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetUser(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/GetUser', + user__admin__pb2.GetUserRequest.SerializeToString, + types__pb2.User.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ListUsers(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/ListUsers', + google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + user__admin__pb2.ListUsersResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GrantRoles(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/GrantRoles', + user__admin__pb2.GrantRolesRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def RevokeRoles(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/RevokeRoles', + user__admin__pb2.RevokeRolesRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ListRoles(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/ListRoles', + google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + user__admin__pb2.ListRolesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2.py b/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2.py index 3f7d4452..21cd88f9 100644 --- a/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2.py @@ -15,18 +15,16 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fvector-db.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\"\x0e\n\x0c\x41\x62outRequest\" \n\rAboutResponse\x12\x0f\n\x07version\x18\x01 \x01(\t\"\x17\n\tClusterId\x12\n\n\x02id\x18\x01 \x01(\x04\"\x14\n\x06NodeId\x12\n\n\x02id\x18\x01 \x01(\x04\">\n\x0eServerEndpoint\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\r\n\x05isTls\x18\x03 \x01(\x08\"I\n\x12ServerEndpointList\x12\x33\n\tendpoints\x18\x01 \x03(\x0b\x32 .aerospike.vector.ServerEndpoint\"\xb8\x01\n\x14\x43lusterNodeEndpoints\x12H\n\tendpoints\x18\x01 \x03(\x0b\x32\x35.aerospike.vector.ClusterNodeEndpoints.EndpointsEntry\x1aV\n\x0e\x45ndpointsEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x33\n\x05value\x18\x02 \x01(\x0b\x32$.aerospike.vector.ServerEndpointList:\x02\x38\x01\"I\n\x1b\x43lusterNodeEndpointsRequest\x12\x19\n\x0clistenerName\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x0f\n\r_listenerName\"*\n\x0fOwnedPartitions\x12\x17\n\x0fownedPartitions\x18\x01 \x03(\x04\"\xb2\x01\n\x11\x43lusterPartitions\x12G\n\npartitions\x18\x01 \x03(\x0b\x32\x33.aerospike.vector.ClusterPartitions.PartitionsEntry\x1aT\n\x0fPartitionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x30\n\x05value\x18\x02 \x01(\x0b\x32!.aerospike.vector.OwnedPartitions:\x02\x38\x01\x32Q\n\x05\x41\x62out\x12H\n\x03Get\x12\x1e.aerospike.vector.AboutRequest\x1a\x1f.aerospike.vector.AboutResponse\"\x00\x32\xda\x02\n\x0b\x43lusterInfo\x12?\n\tGetNodeId\x12\x16.google.protobuf.Empty\x1a\x18.aerospike.vector.NodeId\"\x00\x12\x45\n\x0cGetClusterId\x12\x16.google.protobuf.Empty\x1a\x1b.aerospike.vector.ClusterId\"\x00\x12n\n\x13GetClusterEndpoints\x12-.aerospike.vector.ClusterNodeEndpointsRequest\x1a&.aerospike.vector.ClusterNodeEndpoints\"\x00\x12S\n\x12GetOwnedPartitions\x12\x16.google.protobuf.Empty\x1a#.aerospike.vector.ClusterPartitions\"\x00\x42=\n\x1b\x63om.aerospike.vector.clientP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fvector-db.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\"\x0e\n\x0c\x41\x62outRequest\" \n\rAboutResponse\x12\x0f\n\x07version\x18\x01 \x01(\t\"\x17\n\tClusterId\x12\n\n\x02id\x18\x01 \x01(\x04\"\x14\n\x06NodeId\x12\n\n\x02id\x18\x01 \x01(\x04\">\n\x0eServerEndpoint\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\r\n\x05isTls\x18\x03 \x01(\x08\"I\n\x12ServerEndpointList\x12\x33\n\tendpoints\x18\x01 \x03(\x0b\x32 .aerospike.vector.ServerEndpoint\"\xb8\x01\n\x14\x43lusterNodeEndpoints\x12H\n\tendpoints\x18\x01 \x03(\x0b\x32\x35.aerospike.vector.ClusterNodeEndpoints.EndpointsEntry\x1aV\n\x0e\x45ndpointsEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x33\n\x05value\x18\x02 \x01(\x0b\x32$.aerospike.vector.ServerEndpointList:\x02\x38\x01\"I\n\x1b\x43lusterNodeEndpointsRequest\x12\x19\n\x0clistenerName\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x0f\n\r_listenerName\"\x81\x01\n\x0f\x43lusteringState\x12\x13\n\x0bisInCluster\x18\x01 \x01(\x08\x12.\n\tclusterId\x18\x02 \x01(\x0b\x32\x1b.aerospike.vector.ClusterId\x12)\n\x07members\x18\x03 \x03(\x0b\x32\x18.aerospike.vector.NodeId2Q\n\x05\x41\x62out\x12H\n\x03Get\x12\x1e.aerospike.vector.AboutRequest\x1a\x1f.aerospike.vector.AboutResponse\"\x00\x32\xd8\x02\n\x0b\x43lusterInfo\x12?\n\tGetNodeId\x12\x16.google.protobuf.Empty\x1a\x18.aerospike.vector.NodeId\"\x00\x12\x45\n\x0cGetClusterId\x12\x16.google.protobuf.Empty\x1a\x1b.aerospike.vector.ClusterId\"\x00\x12Q\n\x12GetClusteringState\x12\x16.google.protobuf.Empty\x1a!.aerospike.vector.ClusteringState\"\x00\x12n\n\x13GetClusterEndpoints\x12-.aerospike.vector.ClusterNodeEndpointsRequest\x1a&.aerospike.vector.ClusterNodeEndpoints\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'vector_db_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: _globals['DESCRIPTOR']._options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\033com.aerospike.vector.clientP\001Z\034aerospike.com/vector/protos/' + _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' _globals['_CLUSTERNODEENDPOINTS_ENDPOINTSENTRY']._options = None _globals['_CLUSTERNODEENDPOINTS_ENDPOINTSENTRY']._serialized_options = b'8\001' - _globals['_CLUSTERPARTITIONS_PARTITIONSENTRY']._options = None - _globals['_CLUSTERPARTITIONS_PARTITIONSENTRY']._serialized_options = b'8\001' _globals['_ABOUTREQUEST']._serialized_start=66 _globals['_ABOUTREQUEST']._serialized_end=80 _globals['_ABOUTRESPONSE']._serialized_start=82 @@ -45,14 +43,10 @@ _globals['_CLUSTERNODEENDPOINTS_ENDPOINTSENTRY']._serialized_end=487 _globals['_CLUSTERNODEENDPOINTSREQUEST']._serialized_start=489 _globals['_CLUSTERNODEENDPOINTSREQUEST']._serialized_end=562 - _globals['_OWNEDPARTITIONS']._serialized_start=564 - _globals['_OWNEDPARTITIONS']._serialized_end=606 - _globals['_CLUSTERPARTITIONS']._serialized_start=609 - _globals['_CLUSTERPARTITIONS']._serialized_end=787 - _globals['_CLUSTERPARTITIONS_PARTITIONSENTRY']._serialized_start=703 - _globals['_CLUSTERPARTITIONS_PARTITIONSENTRY']._serialized_end=787 - _globals['_ABOUT']._serialized_start=789 - _globals['_ABOUT']._serialized_end=870 - _globals['_CLUSTERINFO']._serialized_start=873 - _globals['_CLUSTERINFO']._serialized_end=1219 + _globals['_CLUSTERINGSTATE']._serialized_start=565 + _globals['_CLUSTERINGSTATE']._serialized_end=694 + _globals['_ABOUT']._serialized_start=696 + _globals['_ABOUT']._serialized_end=777 + _globals['_CLUSTERINFO']._serialized_start=780 + _globals['_CLUSTERINFO']._serialized_end=1124 # @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2_grpc.py b/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2_grpc.py index f05c2446..7db60972 100644 --- a/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2_grpc.py +++ b/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2_grpc.py @@ -90,16 +90,16 @@ def __init__(self, channel): request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, response_deserializer=vector__db__pb2.ClusterId.FromString, ) + self.GetClusteringState = channel.unary_unary( + '/aerospike.vector.ClusterInfo/GetClusteringState', + request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + response_deserializer=vector__db__pb2.ClusteringState.FromString, + ) self.GetClusterEndpoints = channel.unary_unary( '/aerospike.vector.ClusterInfo/GetClusterEndpoints', request_serializer=vector__db__pb2.ClusterNodeEndpointsRequest.SerializeToString, response_deserializer=vector__db__pb2.ClusterNodeEndpoints.FromString, ) - self.GetOwnedPartitions = channel.unary_unary( - '/aerospike.vector.ClusterInfo/GetOwnedPartitions', - request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - response_deserializer=vector__db__pb2.ClusterPartitions.FromString, - ) class ClusterInfoServicer(object): @@ -120,15 +120,15 @@ def GetClusterId(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') - def GetClusterEndpoints(self, request, context): - """Get the advertised/listening endpoints for all nodes in the cluster, given a listener name. + def GetClusteringState(self, request, context): + """Get current cluster-Id for the current cluster. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') - def GetOwnedPartitions(self, request, context): - """Get per-node owned partition list for all nodes in the cluster. + def GetClusterEndpoints(self, request, context): + """Get the advertised/listening endpoints for all nodes in the cluster, given a listener name. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -147,16 +147,16 @@ def add_ClusterInfoServicer_to_server(servicer, server): request_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, response_serializer=vector__db__pb2.ClusterId.SerializeToString, ), + 'GetClusteringState': grpc.unary_unary_rpc_method_handler( + servicer.GetClusteringState, + request_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + response_serializer=vector__db__pb2.ClusteringState.SerializeToString, + ), 'GetClusterEndpoints': grpc.unary_unary_rpc_method_handler( servicer.GetClusterEndpoints, request_deserializer=vector__db__pb2.ClusterNodeEndpointsRequest.FromString, response_serializer=vector__db__pb2.ClusterNodeEndpoints.SerializeToString, ), - 'GetOwnedPartitions': grpc.unary_unary_rpc_method_handler( - servicer.GetOwnedPartitions, - request_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - response_serializer=vector__db__pb2.ClusterPartitions.SerializeToString, - ), } generic_handler = grpc.method_handlers_generic_handler( 'aerospike.vector.ClusterInfo', rpc_method_handlers) @@ -203,7 +203,7 @@ def GetClusterId(request, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod - def GetClusterEndpoints(request, + def GetClusteringState(request, target, options=(), channel_credentials=None, @@ -213,14 +213,14 @@ def GetClusterEndpoints(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.ClusterInfo/GetClusterEndpoints', - vector__db__pb2.ClusterNodeEndpointsRequest.SerializeToString, - vector__db__pb2.ClusterNodeEndpoints.FromString, + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.ClusterInfo/GetClusteringState', + google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + vector__db__pb2.ClusteringState.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) @staticmethod - def GetOwnedPartitions(request, + def GetClusterEndpoints(request, target, options=(), channel_credentials=None, @@ -230,8 +230,8 @@ def GetOwnedPartitions(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.ClusterInfo/GetOwnedPartitions', - google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - vector__db__pb2.ClusterPartitions.FromString, + return grpc.experimental.unary_unary(request, target, '/aerospike.vector.ClusterInfo/GetClusterEndpoints', + vector__db__pb2.ClusterNodeEndpointsRequest.SerializeToString, + vector__db__pb2.ClusterNodeEndpoints.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/aerospike_vector_search/types.py b/src/aerospike_vector_search/types.py index d1077fb1..55395e85 100644 --- a/src/aerospike_vector_search/types.py +++ b/src/aerospike_vector_search/types.py @@ -140,6 +140,24 @@ class VectorDistanceMetric(enum.Enum): MANHATTAN: types_pb2.VectorDistanceMetric = types_pb2.VectorDistanceMetric.MANHATTAN HAMMING: types_pb2.VectorDistanceMetric = types_pb2.VectorDistanceMetric.HAMMING +class User(object): + """ + + PLACEHOLDER FOR TEXT + Args: + max_records (Optional[int], optional): Maximum number of records to fit in a batch. Defaults to 10000. + interval (Optional[int], optional): The maximum amount of time in milliseconds to wait before finalizing a batch. Defaults to 10000. + disabled (Optional[bool], optional): Disables batching for index updates. Default is False. + """ + + def __init__( + self, + *, + username: str, + roles: Optional[list[int]] = 10000, + ) -> None: + self.username = username + self.roles = roles class HnswBatchingParams(object): """ diff --git a/tests/rbac/aio/conftest.py b/tests/rbac/aio/conftest.py new file mode 100644 index 00000000..5d6bee7b --- /dev/null +++ b/tests/rbac/aio/conftest.py @@ -0,0 +1,37 @@ +import pytest +import asyncio + +from aerospike_vector_search.aio import Client +from aerospike_vector_search.aio.admin import Client as AdminClient +from aerospike_vector_search import types + +host = 'connector.aerospike.com' +port = 5000 + + + +@pytest.fixture(scope="module", autouse=True) +async def drop_all_indexes(): + async with AdminClient( + seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificates="/home/dpelini/Documents/prox/example/tls/connector.aerospike.com.crt", + private_key="/home/dpelini/Documents/prox/rbac-server/private_key.pem", public_key="/home/dpelini/Documents/prox/rbac-server/public_key.pem" + + ) as client: + index_list = await client.index_list() + + tasks = [] + for item in index_list: + tasks.append(client.index_drop(namespace="test", name=item['id']['name'])) + + + await asyncio.gather(*tasks) + +@pytest.fixture(scope="module") +async def session_rbac_admin_client(): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificates="/home/dpelini/Documents/prox/example/tls/connector.aerospike.com.crt", + private_key="/home/dpelini/Documents/prox/rbac-server/private_key.pem", public_key="/home/dpelini/Documents/prox/rbac-server/public_key.pem" + ) + yield client + await client.close() + diff --git a/tests/rbac/aio/test_admin_client_add_user.py b/tests/rbac/aio/test_admin_client_add_user.py new file mode 100644 index 00000000..a23eae5a --- /dev/null +++ b/tests/rbac/aio/test_admin_client_add_user.py @@ -0,0 +1,75 @@ +import pytest +from utils import random_int + +class add_user_test_case: + def __init__( + self, + *, + username, + password, + roles, + ): + self.username = username + self.password = password + self.roles = roles + +@pytest.mark.parametrize( + "test_case", + [ + add_user_test_case( + username="aio-add-user-" + str(random_int()), + password="alphanumeric", + roles=None + ), + ], +) +async def test_add_user(session_rbac_admin_client, test_case): + await session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=test_case.roles + + ) + + result = await session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == [] + +@pytest.mark.parametrize( + "test_case", + [ + add_user_test_case( + username="aio-add-user-" + str(random_int()), + password="eu123#$%", + roles=["admin"] + ), + add_user_test_case( + username="aio-add-user-" + str(random_int()), + password="radical", + roles=["read-write"] + ), + add_user_test_case( + username="aio-add-user-" + str(random_int()), + password="marshall", + roles=["admin", "read-write"] + ), + ], +) +async def test_add_user_with_roles(session_rbac_admin_client, test_case): + await session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=test_case.roles + ) + + result = await session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == test_case.roles diff --git a/tests/rbac/aio/test_admin_client_drop_user.py b/tests/rbac/aio/test_admin_client_drop_user.py new file mode 100644 index 00000000..83fa6c9c --- /dev/null +++ b/tests/rbac/aio/test_admin_client_drop_user.py @@ -0,0 +1,37 @@ +import pytest +from utils import random_int +from aerospike_vector_search import AVSServerError + + +class drop_user_test_case: + def __init__( + self, + *, + username, + password, + ): + self.username = username + self.password = password + +@pytest.mark.parametrize( + "test_case", + [ + drop_user_test_case( + username="aio-drop-user-" + str(random_int()), + password="tallyho", + ), + ], +) +async def test_drop_user(session_rbac_admin_client, test_case): + await session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=None + + ) + with pytest.raises(AVSServerError) as e_info: + result = await session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert e_info.value == "barnacle" diff --git a/tests/rbac/aio/test_admin_client_get_user.py b/tests/rbac/aio/test_admin_client_get_user.py new file mode 100644 index 00000000..2fde0191 --- /dev/null +++ b/tests/rbac/aio/test_admin_client_get_user.py @@ -0,0 +1,38 @@ +import pytest +from utils import random_int + + +class get_user_test_case: + def __init__( + self, + *, + username, + password, + ): + self.username = username + self.password = password + +@pytest.mark.parametrize( + "test_case", + [ + get_user_test_case( + username="aio-drop-user-" + str(random_int()), + password="tallyho", + ), + ], +) +async def test_get_user(session_rbac_admin_client, test_case): + await session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=None + + ) + + result = await session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == [] diff --git a/tests/rbac/aio/test_admin_client_grant_roles.py b/tests/rbac/aio/test_admin_client_grant_roles.py new file mode 100644 index 00000000..084ca5e8 --- /dev/null +++ b/tests/rbac/aio/test_admin_client_grant_roles.py @@ -0,0 +1,49 @@ +import pytest +from utils import random_int + + +class grant_roles_test_case: + def __init__( + self, + *, + username, + password, + roles, + granted_roles + ): + self.username = username + self.password = password + self.roles = roles + self.granted_roles = granted_roles + +@pytest.mark.parametrize( + "test_case", + [ + grant_roles_test_case( + username="aio-update-credentials-" + str(random_int()), + password="yeoldpassword", + roles=[], + granted_roles=["admin", "read-write"] + ), + ], +) +async def test_grant_roles(session_rbac_admin_client, test_case): + await session_rbac_admin_client.add_user( + username=test_case.username, + roles=test_case.roles + + ) + + await session_rbac_admin_client.grant_roles( + username=test_case.username, + roles=test_case.granted_roles + ) + + result = await session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.granted_roles == test_case.granted_roles + diff --git a/tests/rbac/aio/test_admin_client_list_users.py b/tests/rbac/aio/test_admin_client_list_users.py new file mode 100644 index 00000000..56c00060 --- /dev/null +++ b/tests/rbac/aio/test_admin_client_list_users.py @@ -0,0 +1,40 @@ +import pytest +from utils import random_int + + +class list_users_test_case: + def __init__( + self, + *, + username, + password + ): + self.username = username + self.password = password + +@pytest.mark.parametrize( + "test_case", + [ + list_users_test_case( + username="aio-list-user-" + str(random_int()), + password="sample", + ), + ], +) +async def test_list_users(session_rbac_admin_client, test_case): + await session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=None + + ) + + result = await session_rbac_admin_client.list_users() + user_found = False + for user in result: + if user.username == test_case.username: + assert results.roles = [] + user_found = True + + assert user_found + diff --git a/tests/rbac/aio/test_admin_client_update_credentials.py b/tests/rbac/aio/test_admin_client_update_credentials.py new file mode 100644 index 00000000..393cd14e --- /dev/null +++ b/tests/rbac/aio/test_admin_client_update_credentials.py @@ -0,0 +1,47 @@ +import pytest +from utils import random_int + + +class update_credentials_test_case: + def __init__( + self, + *, + username, + old_password, + new_password + ): + self.username = username + self.old_password = old_password + self.new_password = new_password + +@pytest.mark.parametrize( + "test_case", + [ + update_credentials_test_case( + username="aio-update-credentials-" + str(random_int()), + old_password="yeoldpassword", + new_password="newpass", + ), + ], +) +async def test_update_credentials(session_rbac_admin_client, test_case): + await session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.old_password, + roles=None + + ) + + await session_rbac_admin_client.update_credentials( + username=test_case.username, + password=test_case.new_password, + ) + + result = await session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == [] + diff --git a/tests/rbac/aio/utils.py b/tests/rbac/aio/utils.py new file mode 100644 index 00000000..9f84c492 --- /dev/null +++ b/tests/rbac/aio/utils.py @@ -0,0 +1,4 @@ +import random + +def random_int(): + return str(random.randint(0, 50_000)) \ No newline at end of file diff --git a/tests/aio/__init__.py b/tests/standard/aio/__init__.py similarity index 100% rename from tests/aio/__init__.py rename to tests/standard/aio/__init__.py diff --git a/tests/aio/conftest.py b/tests/standard/aio/conftest.py similarity index 73% rename from tests/aio/conftest.py rename to tests/standard/aio/conftest.py index 54f9b182..b90ff675 100644 --- a/tests/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -4,18 +4,23 @@ from aerospike_vector_search.aio.admin import Client as AdminClient from aerospike_vector_search import types -host = 'localhost' +host = 'connector.aerospike.com' port = 5000 + @pytest.fixture(scope="session", autouse=True) async def drop_all_indexes(): async with AdminClient( - seeds=types.HostPort(host=host, port=port) + seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificates="/home/dpelini/Documents/prox/rbac-server/connector.aerospike.com.crt", + private_key="/home/dpelini/Documents/prox/rbac-server/private_key.pem", public_key="/home/dpelini/Documents/prox/rbac-server/public_key.pem" + ) as client: index_list = await client.index_list() tasks = [] for item in index_list: tasks.append(client.index_drop(namespace="test", name=item['id']['name'])) + + await asyncio.gather(*tasks) @pytest.fixture(scope="module") @@ -26,7 +31,6 @@ async def session_admin_client(): yield client await client.close() - @pytest.fixture(scope="module") async def session_vector_client(): client = Client( @@ -41,4 +45,4 @@ async def function_admin_client(): seeds=types.HostPort(host=host, port=port) ) yield client - await client.close() \ No newline at end of file + await client.close() diff --git a/tests/aio/requirements.txt b/tests/standard/aio/requirements.txt similarity index 100% rename from tests/aio/requirements.txt rename to tests/standard/aio/requirements.txt diff --git a/tests/aio/test_admin_client_index_create.py b/tests/standard/aio/test_admin_client_index_create.py similarity index 100% rename from tests/aio/test_admin_client_index_create.py rename to tests/standard/aio/test_admin_client_index_create.py diff --git a/tests/aio/test_admin_client_index_drop.py b/tests/standard/aio/test_admin_client_index_drop.py similarity index 100% rename from tests/aio/test_admin_client_index_drop.py rename to tests/standard/aio/test_admin_client_index_drop.py diff --git a/tests/aio/test_admin_client_index_get.py b/tests/standard/aio/test_admin_client_index_get.py similarity index 100% rename from tests/aio/test_admin_client_index_get.py rename to tests/standard/aio/test_admin_client_index_get.py diff --git a/tests/aio/test_admin_client_index_get_status.py b/tests/standard/aio/test_admin_client_index_get_status.py similarity index 100% rename from tests/aio/test_admin_client_index_get_status.py rename to tests/standard/aio/test_admin_client_index_get_status.py diff --git a/tests/aio/test_admin_client_index_list.py b/tests/standard/aio/test_admin_client_index_list.py similarity index 100% rename from tests/aio/test_admin_client_index_list.py rename to tests/standard/aio/test_admin_client_index_list.py diff --git a/tests/aio/test_vector_client_delete.py b/tests/standard/aio/test_vector_client_delete.py similarity index 100% rename from tests/aio/test_vector_client_delete.py rename to tests/standard/aio/test_vector_client_delete.py diff --git a/tests/aio/test_vector_client_exists.py b/tests/standard/aio/test_vector_client_exists.py similarity index 100% rename from tests/aio/test_vector_client_exists.py rename to tests/standard/aio/test_vector_client_exists.py diff --git a/tests/aio/test_vector_client_get.py b/tests/standard/aio/test_vector_client_get.py similarity index 100% rename from tests/aio/test_vector_client_get.py rename to tests/standard/aio/test_vector_client_get.py diff --git a/tests/aio/test_vector_client_insert.py b/tests/standard/aio/test_vector_client_insert.py similarity index 100% rename from tests/aio/test_vector_client_insert.py rename to tests/standard/aio/test_vector_client_insert.py diff --git a/tests/aio/test_vector_client_update.py b/tests/standard/aio/test_vector_client_update.py similarity index 100% rename from tests/aio/test_vector_client_update.py rename to tests/standard/aio/test_vector_client_update.py diff --git a/tests/aio/test_vector_client_upsert.py b/tests/standard/aio/test_vector_client_upsert.py similarity index 100% rename from tests/aio/test_vector_client_upsert.py rename to tests/standard/aio/test_vector_client_upsert.py diff --git a/tests/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py similarity index 100% rename from tests/aio/test_vector_search.py rename to tests/standard/aio/test_vector_search.py diff --git a/tests/sync/__init__.py b/tests/standard/sync/__init__.py similarity index 100% rename from tests/sync/__init__.py rename to tests/standard/sync/__init__.py diff --git a/tests/sync/conftest.py b/tests/standard/sync/conftest.py similarity index 100% rename from tests/sync/conftest.py rename to tests/standard/sync/conftest.py diff --git a/tests/sync/requirements.txt b/tests/standard/sync/requirements.txt similarity index 100% rename from tests/sync/requirements.txt rename to tests/standard/sync/requirements.txt diff --git a/tests/sync/test_admin_client_index_create.py b/tests/standard/sync/test_admin_client_index_create.py similarity index 100% rename from tests/sync/test_admin_client_index_create.py rename to tests/standard/sync/test_admin_client_index_create.py diff --git a/tests/sync/test_admin_client_index_drop.py b/tests/standard/sync/test_admin_client_index_drop.py similarity index 100% rename from tests/sync/test_admin_client_index_drop.py rename to tests/standard/sync/test_admin_client_index_drop.py diff --git a/tests/sync/test_admin_client_index_get.py b/tests/standard/sync/test_admin_client_index_get.py similarity index 100% rename from tests/sync/test_admin_client_index_get.py rename to tests/standard/sync/test_admin_client_index_get.py diff --git a/tests/sync/test_admin_client_index_get_status.py b/tests/standard/sync/test_admin_client_index_get_status.py similarity index 100% rename from tests/sync/test_admin_client_index_get_status.py rename to tests/standard/sync/test_admin_client_index_get_status.py diff --git a/tests/sync/test_admin_client_index_list.py b/tests/standard/sync/test_admin_client_index_list.py similarity index 100% rename from tests/sync/test_admin_client_index_list.py rename to tests/standard/sync/test_admin_client_index_list.py diff --git a/tests/sync/test_vector_client_delete.py b/tests/standard/sync/test_vector_client_delete.py similarity index 100% rename from tests/sync/test_vector_client_delete.py rename to tests/standard/sync/test_vector_client_delete.py diff --git a/tests/sync/test_vector_client_exists.py b/tests/standard/sync/test_vector_client_exists.py similarity index 100% rename from tests/sync/test_vector_client_exists.py rename to tests/standard/sync/test_vector_client_exists.py diff --git a/tests/sync/test_vector_client_get.py b/tests/standard/sync/test_vector_client_get.py similarity index 100% rename from tests/sync/test_vector_client_get.py rename to tests/standard/sync/test_vector_client_get.py diff --git a/tests/sync/test_vector_client_insert.py b/tests/standard/sync/test_vector_client_insert.py similarity index 100% rename from tests/sync/test_vector_client_insert.py rename to tests/standard/sync/test_vector_client_insert.py diff --git a/tests/sync/test_vector_client_update.py b/tests/standard/sync/test_vector_client_update.py similarity index 100% rename from tests/sync/test_vector_client_update.py rename to tests/standard/sync/test_vector_client_update.py diff --git a/tests/sync/test_vector_client_upsert.py b/tests/standard/sync/test_vector_client_upsert.py similarity index 100% rename from tests/sync/test_vector_client_upsert.py rename to tests/standard/sync/test_vector_client_upsert.py diff --git a/tests/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py similarity index 100% rename from tests/sync/test_vector_search.py rename to tests/standard/sync/test_vector_search.py From 9b90d5951930b179e85d3252215c5c7458e92793 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 21 Jun 2024 10:46:36 -0600 Subject: [PATCH 013/215] Enabled client to work with either Auth+TLS or plain text --- src/aerospike_vector_search/admin.py | 146 ++++++++++++++++-- src/aerospike_vector_search/aio/admin.py | 4 +- src/aerospike_vector_search/aio/client.py | 18 +-- .../aio/internal/channel_provider.py | 73 ++++----- src/aerospike_vector_search/client.py | 73 ++++++--- .../internal/channel_provider.py | 36 +++-- .../shared/base_channel_provider.py | 42 +++-- src/aerospike_vector_search/shared/helpers.py | 6 +- tests/rbac/__init__.py | 0 tests/rbac/aio/__init__.py | 0 tests/rbac/aio/conftest.py | 21 ++- tests/rbac/aio/test_admin_client_add_user.py | 2 +- tests/rbac/aio/test_admin_client_drop_user.py | 11 +- tests/rbac/aio/test_admin_client_get_user.py | 2 +- .../rbac/aio/test_admin_client_grant_roles.py | 5 +- .../rbac/aio/test_admin_client_list_roles.py | 38 +++++ .../rbac/aio/test_admin_client_list_users.py | 4 +- .../aio/test_admin_client_revoke_roles.py | 50 ++++++ .../test_admin_client_update_credentials.py | 2 +- tests/rbac/aio/utils.py | 4 - tests/standard/__init__.py | 0 tests/standard/aio/aio_utils.py | 2 + tests/standard/aio/conftest.py | 6 +- .../aio/test_admin_client_index_create.py | 115 ++++++++------ .../aio/test_admin_client_index_drop.py | 24 ++- .../aio/test_admin_client_index_get.py | 27 ++-- .../aio/test_admin_client_index_get_status.py | 18 ++- .../aio/test_admin_client_index_list.py | 19 ++- .../standard/aio/test_vector_client_delete.py | 27 ++-- .../standard/aio/test_vector_client_exists.py | 20 ++- tests/standard/aio/test_vector_client_get.py | 22 +-- .../standard/aio/test_vector_client_insert.py | 42 +++-- .../standard/aio/test_vector_client_update.py | 31 ++-- .../standard/aio/test_vector_client_upsert.py | 34 ++-- tests/standard/sync/conftest.py | 9 +- tests/standard/sync/sync_utils.py | 2 + .../sync/test_admin_client_index_create.py | 109 +++++++------ .../sync/test_admin_client_index_drop.py | 24 ++- .../sync/test_admin_client_index_get.py | 27 ++-- .../test_admin_client_index_get_status.py | 19 ++- .../sync/test_admin_client_index_list.py | 19 ++- .../sync/test_vector_client_delete.py | 27 ++-- .../sync/test_vector_client_exists.py | 19 ++- tests/standard/sync/test_vector_client_get.py | 21 +-- .../sync/test_vector_client_insert.py | 41 +++-- .../sync/test_vector_client_update.py | 26 ++-- .../sync/test_vector_client_upsert.py | 31 ++-- tests/utils.py | 67 ++++++++ 48 files changed, 956 insertions(+), 409 deletions(-) create mode 100644 tests/rbac/__init__.py create mode 100644 tests/rbac/aio/__init__.py create mode 100644 tests/rbac/aio/test_admin_client_list_roles.py create mode 100644 tests/rbac/aio/test_admin_client_revoke_roles.py delete mode 100644 tests/rbac/aio/utils.py create mode 100644 tests/standard/__init__.py create mode 100644 tests/standard/aio/aio_utils.py create mode 100644 tests/standard/sync/sync_utils.py create mode 100644 tests/utils.py diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index 487bbe4d..3a096bef 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -10,7 +10,6 @@ logger = logging.getLogger(__name__) - class Client(BaseClient): """ Aerospike Vector Search Admin Client @@ -24,8 +23,9 @@ def __init__( seeds: Union[types.HostPort, tuple[types.HostPort, ...]], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, - username: str = None, - password: str = None + username: Optional[str] = None, + password: Optional[str] = None, + root_certificate: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Admin Client. @@ -42,7 +42,7 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password + seeds, listener_name, is_loadbalancer, username, password, root_certificate ) def index_create( @@ -84,6 +84,9 @@ def index_create( This method creates an index with the specified parameters and waits for the index creation to complete. It waits for up to 100,000 seconds for the index creation to complete. """ + + + (index_stub, index_create_request) = self._prepare_index_create( namespace, name, @@ -95,8 +98,9 @@ def index_create( index_meta_data, logger, ) + try: - index_stub.Create(index_create_request) + index_stub.Create(index_create_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -124,11 +128,13 @@ def index_drop(self, *, namespace: str, name: str) -> None: This method drops an index with the specified parameters and waits for the index deletion to complete. It waits for up to 100,000 seconds for the index deletion to complete. """ + + (index_stub, index_drop_request) = self._prepare_index_drop( namespace, name, logger ) try: - index_stub.Drop(index_drop_request) + index_stub.Drop(index_drop_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -151,15 +157,19 @@ def index_list(self) -> list[dict]: grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + (index_stub, index_list_request) = self._prepare_index_list(logger) try: - response = index_stub.List(index_list_request) + response = index_stub.List(index_list_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_list(response) - def index_get(self, *, namespace: str, name: str) -> dict[str, Union[int, str]]: + def index_get( + self, *, namespace: str, name: str + ) -> dict[str, Union[int, str]]: """ Retrieve the information related with an index. @@ -175,11 +185,13 @@ def index_get(self, *, namespace: str, name: str) -> dict[str, Union[int, str]]: This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + (index_stub, index_get_request) = self._prepare_index_get( namespace, name, logger ) try: - response = index_stub.Get(index_get_request) + response = index_stub.Get(index_get_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -206,6 +218,8 @@ def index_get_status(self, *, namespace: str, name: str) -> int: Warning: This API is subject to change. """ + + (index_stub, index_get_status_request) = self._prepare_index_get_status( namespace, name, logger ) @@ -217,6 +231,109 @@ def index_get_status(self, *, namespace: str, name: str) -> int: return self._respond_index_get_status(response) + def add_user(self, *, username: str, password: str, roles: list[str]) -> int: + + + (user_admin_stub, add_user_request) = self._prepare_add_user( + username, password, roles, logger + ) + + + try: + user_admin_stub.AddUser(add_user_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + def update_credentials(self, *, username: str, password: str) -> int: + + + (user_admin_stub, update_credentials_request) = self._prepare_update_credentials( + username, password, logger + ) + try: + user_admin_stub.UpdateCredentials(update_credentials_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + def drop_user(self, *, username: str) -> int: + + + (user_admin_stub, drop_user_request) = self._prepare_drop_user( + username, logger + ) + try: + user_admin_stub.DropUser(drop_user_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + def get_user(self, *, username: str) -> int: + + + (user_admin_stub, get_user_request) = self._prepare_get_user( + username, logger + ) + try: + response = user_admin_stub.GetUser(get_user_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + return self._respond_get_user(response) + + def list_users(self) -> int: + + + (user_admin_stub, list_users_request) = self._prepare_list_users( + logger + ) + + try: + response = user_admin_stub.ListUsers(list_users_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + return self._respond_list_users(response) + + def grant_roles(self, *, username: str, roles: list[str]) -> int: + + + (user_admin_stub, grant_roles_request) = self._prepare_grant_roles( + username, roles, logger + ) + try: + user_admin_stub.GrantRoles(grant_roles_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + def revoke_roles(self, *, username: str, roles: list[str]) -> int: + + + (user_admin_stub, revoke_roles_request) = self._prepare_revoke_roles( + username, roles, logger + ) + try: + user_admin_stub.RevokeRoles(revoke_roles_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + def list_roles(self) -> int: + + + (user_admin_stub, list_roles_request) = self._prepare_list_roles( + logger + ) + try: + response = user_admin_stub.ListRoles(list_roles_request, credentials=self._channel_provider._token) + except grpc.RpcError as e: + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + return self._respond_list_roles(response) + def _wait_for_index_creation( self, *, @@ -228,13 +345,15 @@ def _wait_for_index_creation( """ Wait for the index to be created. """ + + (index_stub, wait_interval, start_time, _, _, index_creation_request) = ( self._prepare_wait_for_index_waiting(namespace, name, wait_interval) ) while True: self._check_timeout(start_time, timeout) try: - index_stub.GetStatus(index_creation_request) + index_stub.GetStatus(index_creation_request, credentials=self._channel_provider._token) logger.debug("Index created succesfully") # Index has been created return @@ -258,6 +377,7 @@ def _wait_for_index_deletion( """ Wait for the index to be deleted. """ + # Wait interval between polling (index_stub, wait_interval, start_time, _, _, index_deletion_request) = ( @@ -268,7 +388,7 @@ def _wait_for_index_deletion( self._check_timeout(start_time, timeout) try: - index_stub.GetStatus(index_deletion_request) + index_stub.GetStatus(index_deletion_request, credentials=self._channel_provider._token) # Wait for some more time. time.sleep(wait_interval) except grpc.RpcError as e: @@ -292,7 +412,7 @@ def close(self): def __enter__(self): """ - Enter an asynchronous context manager for the admin client. + Enter a context manager for the admin client. Returns: VectorDbAdminlient: Aerospike Vector Search Admin Client instance. @@ -301,6 +421,6 @@ def __enter__(self): def __exit__(self, exc_type, exc_val, exc_tb): """ - Exit an asynchronous context manager for the admin client. + Exit a context manager for the admin client. """ self.close() diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index 08342075..3b4a57e3 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -354,7 +354,7 @@ async def _wait_for_index_creation( while True: self._check_timeout(start_time, timeout) try: - await index_stub.GetStatus(index_creation_request) + await index_stub.GetStatus(index_creation_request, credentials=self._channel_provider._token) logger.debug("Index created succesfully") # Index has been created return @@ -389,7 +389,7 @@ async def _wait_for_index_deletion( self._check_timeout(start_time, timeout) try: - await index_stub.GetStatus(index_deletion_request) + await index_stub.GetStatus(index_deletion_request, credentials=self._channel_provider._token) # Wait for some more time. await asyncio.sleep(wait_interval) except grpc.RpcError as e: diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index 9dee89ef..a9882ef2 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -83,7 +83,7 @@ async def insert( ) try: - await transact_stub.Put(insert_request) + await transact_stub.Put(insert_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -121,7 +121,7 @@ async def update( ) try: - await transact_stub.Put(update_request) + await transact_stub.Put(update_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -159,7 +159,7 @@ async def upsert( ) try: - await transact_stub.Put(upsert_request) + await transact_stub.Put(upsert_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -196,7 +196,7 @@ async def get( namespace, key, field_names, set_name, logger ) try: - response = await transact_stub.Get(get_request) + response = await transact_stub.Get(get_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -229,7 +229,7 @@ async def exists( ) try: - response = await transact_stub.Exists(exists_request) + response = await transact_stub.Exists(exists_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -259,7 +259,7 @@ async def delete( ) try: - await transact_stub.Delete(delete_request) + await transact_stub.Delete(delete_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -298,7 +298,7 @@ async def is_indexed( namespace, key, index_name, index_namespace, set_name, logger ) try: - response = await transact_stub.IsIndexed(is_indexed_request) + response = await transact_stub.IsIndexed(is_indexed_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -341,7 +341,7 @@ async def vector_search( ) try: - return [self._respond_neighbor(result) async for result in transact_stub.VectorSearch(vector_search_request)] + return [self._respond_neighbor(result) async for result in transact_stub.VectorSearch(vector_search_request, credentials=self._channel_provider._token)] except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -388,7 +388,7 @@ async def wait_for_index_completion( ) = self._prepare_wait_for_index_waiting(namespace, name, wait_interval) while True: try: - index_status = await index_stub.GetStatus(index_completion_request) + index_status = await index_stub.GetStatus(index_completion_request, credentials=self._channel_provider._token) except grpc.RpcError as e: if e.code() == grpc.StatusCode.UNAVAILABLE: diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 23e92705..4004413a 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -31,14 +31,14 @@ def __init__( password: Optional[str] = None, root_certificate: Optional[str] = None, ) -> None: + super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate) - self._tend_initalized: asyncio.Event = asyncio.Event() + self._tend_initalized: asyncio.Event = asyncio.Event() self._tend_ended: asyncio.Event = asyncio.Event() self._task: Optional[asyncio.Task] = None - self._initty = False - asyncio.create_task(self._tend()) + asyncio.create_task(self._tend()) async def close(self): self._closed = True @@ -59,13 +59,15 @@ async def _is_ready(self): async def _tend(self): (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() - self._token = await self._authenticate(credentials=self._credentials) + + if self._token: + if self._check_if_token_refresh_needed(): + await self._update_token_and_ttl() if end_tend: self._tend_ended.set() return - stubs = [] tasks = [] @@ -74,12 +76,18 @@ async def _tend(self): stub = vector_db_pb2_grpc.ClusterInfoStub(channel) stubs.append(stub) try: - tasks.append(await stub.GetClusterId(empty, credentials=grpc.access_token_call_credentials(self._token))) + tasks.append(stub.GetClusterId(empty, credentials=self._token)) except Exception as e: logger.debug( "While tending, failed to get cluster id with error:" + str(e) ) - new_cluster_ids = tasks + + try: + new_cluster_ids = await asyncio.gather(*tasks) + except Exception as e: + logger.debug( + "While tending, failed to gather results from GetClusterId:" + str(e) + ) for index, value in enumerate(new_cluster_ids): if self.check_cluster_id(value.id): @@ -93,7 +101,7 @@ async def _tend(self): vector_db_pb2.ClusterNodeEndpointsRequest( listenerName=self.listener_name ), - credentials=grpc.access_token_call_credentials(self._token) + credentials=self._token ) temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) except Exception as e: @@ -143,40 +151,35 @@ async def _tend(self): await asyncio.sleep(1) self._task = asyncio.create_task(self._tend()) + def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.aio.Channel: - # TODO: Take care of TLS host = re.sub(r"%.*", "", host) + if self._root_certificate: + with open(self._root_certificate, 'rb') as f: + root_certificate = f.read() - # Load the CA certificate - with open(self._root_certificate, 'rb') as f: - root_certificate = f.read() - - # Load the SSL/TLS credentials - ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate) - - #call_credentials = grpc.access_token_call_credentials(self._token) + ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate) - #composite_credentials = grpc.composite_channel_credentials(ssl_credentials, call_credentials) + return grpc.aio.secure_channel(f"{host}:{port}", ssl_credentials) - return grpc.aio.secure_channel(f"{host}:{port}", ssl_credentials) + else: + return grpc.aio.insecure_channel(f"{host}:{port}") - async def _authenticate( + async def _update_token_and_ttl( self, - *, - credentials ) -> None: + try: + (auth_stub, auth_request) = self._prepare_authenticate( + self._credentials, logger + ) - (auth_stub, auth_request) = self._prepare_authenticate( - credentials, logger - ) - - try: - response = await auth_stub.Authenticate(auth_request) - except grpc.RpcError as e: - print("Failed with error: %s", e) - raise types.AVSServerError(rpc_error=e) - - return grpc.access_token_call_credentials(response.token) - - + try: + response = await auth_stub.Authenticate(auth_request) + except grpc.RpcError as e: + print("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) + + self._respond_authenticate(response.token) + except Exception as e: + print(e) \ No newline at end of file diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index 95fec629..e7215653 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -11,10 +11,9 @@ logger = logging.getLogger(__name__) - class Client(BaseClient): """ - Aerospike Vector Search Admin Client + Aerospike Vector Search Vector Client This client specializes in performing database operations with vector data. Moreover, the client supports Hierarchical Navigable Small World (HNSW) vector searches, @@ -27,8 +26,9 @@ def __init__( seeds: Union[types.HostPort, tuple[types.HostPort, ...]], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, - username: str = None, - password: str = None + username: Optional[str] = None, + password: Optional[str] = None, + root_certificate: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Vector Client. @@ -46,7 +46,7 @@ def __init__( """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password + seeds, listener_name, is_loadbalancer, username, password, root_certificate ) def insert( @@ -74,12 +74,15 @@ def insert( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + + (transact_stub, insert_request) = self._prepare_insert( namespace, key, record_data, set_name, logger ) try: - transact_stub.Put(insert_request) + transact_stub.Put(insert_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -109,12 +112,15 @@ def update( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + + (transact_stub, update_request) = self._prepare_update( namespace, key, record_data, set_name, logger ) try: - transact_stub.Put(update_request) + transact_stub.Put(update_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -128,7 +134,7 @@ def upsert( set_name: Optional[str] = None, ) -> None: """ - Upsert a record in Aerospike Vector Search. + Update a record in Aerospike Vector Search. If record does exist, update the record. If record doesn't exist, the record is inserted. @@ -144,12 +150,15 @@ def upsert( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + + (transact_stub, upsert_request) = self._prepare_upsert( namespace, key, record_data, set_name, logger ) try: - transact_stub.Put(upsert_request) + transact_stub.Put(upsert_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -179,11 +188,14 @@ def get( grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + + (transact_stub, key, get_request) = self._prepare_get( namespace, key, field_names, set_name, logger ) try: - response = transact_stub.Get(get_request) + response = transact_stub.Get(get_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -208,11 +220,15 @@ def exists( grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + + (transact_stub, exists_request) = self._prepare_exists( namespace, key, set_name, logger ) + try: - response = transact_stub.Exists(exists_request) + response = transact_stub.Exists(exists_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -234,11 +250,15 @@ def delete( grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + + (transact_stub, delete_request) = self._prepare_delete( namespace, key, set_name, logger ) + try: - transact_stub.Delete(delete_request) + transact_stub.Delete(delete_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -270,11 +290,14 @@ def is_indexed( grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + + (transact_stub, is_indexed_request) = self._prepare_is_indexed( namespace, key, index_name, index_namespace, set_name, logger ) try: - response = transact_stub.IsIndexed(is_indexed_request) + response = transact_stub.IsIndexed(is_indexed_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -310,12 +333,14 @@ def vector_search( grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ + + (transact_stub, vector_search_request) = self._prepare_vector_search( namespace, index_name, query, limit, search_params, field_names, logger ) try: - return [self._respond_neighbor(result) for result in transact_stub.VectorSearch(vector_search_request)] + return [self._respond_neighbor(result) for result in transact_stub.VectorSearch(vector_search_request, credentials=self._channel_provider._token)] except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -327,7 +352,7 @@ def wait_for_index_completion( name: str, timeout: Optional[int] = sys.maxsize, wait_interval: Optional[int] = 12, - validation_checks: Optional[int] = 2, + validation_threshold: Optional[int] = 2, ) -> None: """ Wait for the index to have no pending index update operations. @@ -349,18 +374,20 @@ def wait_for_index_completion( The function polls the index status with a wait interval of 10 seconds until either the timeout is reached or the index has no pending index update operations. """ + + # Wait interval between polling ( index_stub, wait_interval, start_time, unmerged_record_initialized, - consecutive_index_validations, + validation_count, index_completion_request, ) = self._prepare_wait_for_index_waiting(namespace, name, wait_interval) while True: try: - index_status = index_stub.GetStatus(index_completion_request) + index_status = index_stub.GetStatus(index_completion_request, credentials=self._channel_provider._token) except grpc.RpcError as e: if e.code() == grpc.StatusCode.UNAVAILABLE: @@ -371,13 +398,13 @@ def wait_for_index_completion( if self._check_completion_condition( start_time, timeout, index_status, unmerged_record_initialized ): - if consecutive_index_validations == validation_checks: + if validation_count == validation_threshold: return else: - consecutive_index_validations += 1 + validation_count += 1 else: - consecutive_index_validations = 0 - time.sleep(wait_interval) + validation_count = 0 + time.sleep(wait_interval) def close(self): """ @@ -392,7 +419,7 @@ def close(self): def __enter__(self): """ - Enter an asynchronous context manager for the vector client. + Enter a context manager for the vector client. Returns: VectorDbClient: Aerospike Vector Search Vector Client instance. @@ -401,6 +428,6 @@ def __enter__(self): def __exit__(self, exc_type, exc_val, exc_tb): """ - Exit an asynchronous context manager for the vector client. + Exit a context manager for the vector client. """ self.close() diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index 946d1a38..bce3a839 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -25,11 +25,11 @@ def __init__( seeds: tuple[types.HostPort, ...], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, - username: str = None, - password: str = None, - tls_path: str = None + username: Optional[str] = None, + password: Optional[str] = None, + root_certificate: Optional[str] = None ) -> None: - super().__init__(seeds, listener_name, is_loadbalancer, username, password) + super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate) self._tend_ended = threading.Event() self._timer = None self._tend() @@ -50,11 +50,12 @@ def close(self): def _tend(self): (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() - self._token = self._authenticate(self._credentials) + if self._token: + if self._check_if_token_refresh_needed(): + self._update_token_and_ttl() if end_tend: self._tend_ended.set() - return for channel in channels: @@ -119,24 +120,31 @@ def _tend(self): self._timer = threading.Timer(1, self._tend).start() def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: - # TODO: Take care of TLS host = re.sub(r"%.*", "", host) - return grpc.insecure_channel(f"{host}:{port}") + if self._root_certificate: + with open(self._root_certificate, 'rb') as f: + root_certificate = f.read() + + ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate) + + return grpc.secure_channel(f"{host}:{port}", ssl_credentials) - def _authenticate( + else: + return grpc.insecure_channel(f"{host}:{port}") + + def _update_token_and_ttl( self, - *, - credentials ) -> None: (auth_stub, auth_request) = self._prepare_authenticate( - credentials, logger + self._credentials, logger ) try: response = auth_stub.Authenticate(auth_request) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + print("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - return response + + self._respond_authenticate(response.token) diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index 4eed18f2..f1551857 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -1,5 +1,7 @@ import logging import random +import time +import jwt from typing import Optional, Union @@ -33,21 +35,24 @@ def __init__( seeds: tuple[types.HostPort, ...], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, - username: str = None, - password: str = None, - root_certificates: str = None, - private_key: str = None, - public_key: str = None + username: Optional[str] = None, + password: Optional[str] = None, + root_certificate: Optional[str] = None, + private_key: Optional[str] = None, + public_key: Optional[str] = None ) -> None: self.seeds: tuple[types.HostPort, ...] = seeds self.listener_name: Optional[str] = listener_name self._is_loadbalancer: Optional[bool] = is_loadbalancer self._credentials = helpers._get_credentials(username, password) - self._root_certificates = root_certificates - self._private_key = private_key - self._public_key = public_key - - self._token = "" + if self._credentials: + self._token = True + else: + self._token = None + self._root_certificate = root_certificate + self._ttl = 0 + self._ttl_start = 0 + self._ttl_threshold = 0.9 # dict of Node Number and ChannelAndEndponts object self._node_channels: dict[int, ChannelAndEndpoints] = {} self._seedChannels: Union[list[grpc.Channel], list[grpc.Channel.aio]] = [ @@ -145,6 +150,15 @@ def check_for_new_endpoints(self, node, newEndpoints): return (channel_endpoints, add_new_channel) + + def _get_ttl(self, payload): + return payload['exp'] - payload['iat'] + + def _check_if_token_refresh_needed(self): + if self._token and (time.time() - self._ttl_start) > (self._ttl * self._ttl_threshold): + return True + return False + def _prepare_authenticate(self, credentials, logger): logger.debug( "Refreshing auth token" @@ -160,3 +174,11 @@ def _get_auth_stub(self): def _get_authenticate_request(self, credentials): return auth_pb2.AuthRequest(credentials=credentials) + + def _respond_authenticate(self, token): + payload = jwt.decode(token, "", algorithms=['RS256'], options={"verify_signature": False}) + print(payload) + self._ttl = self._get_ttl(payload) + self._ttl_start = payload['exp'] + + self._token = grpc.access_token_call_credentials(token) \ No newline at end of file diff --git a/src/aerospike_vector_search/shared/helpers.py b/src/aerospike_vector_search/shared/helpers.py index ef8fe451..ee78e1cf 100644 --- a/src/aerospike_vector_search/shared/helpers.py +++ b/src/aerospike_vector_search/shared/helpers.py @@ -15,13 +15,13 @@ def _prepare_seeds(seeds) -> None: return seeds -def _prepare_wait_for_index_waiting(namespace, name, wait_interval): +def _prepare_wait_for_index_waiting(client, namespace, name, wait_interval): unmerged_record_initialized = False start_time = time.monotonic() consecutive_index_validations = 0 - index_stub = index_pb2_grpc.IndexServiceStub(self._channel_provider.get_channel()) + index_stub = index_pb2_grpc.IndexServiceStub(client._channel_provider.get_channel()) index_wait_request = types_pb2.IndexId(namespace=namespace, name=name) return ( index_stub, @@ -33,4 +33,6 @@ def _prepare_wait_for_index_waiting(namespace, name, wait_interval): ) def _get_credentials(username, password): + if not username: + return None return types_pb2.Credentials(username=username, passwordCredentials=types_pb2.PasswordCredentials(password=password)) \ No newline at end of file diff --git a/tests/rbac/__init__.py b/tests/rbac/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/rbac/aio/__init__.py b/tests/rbac/aio/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/rbac/aio/conftest.py b/tests/rbac/aio/conftest.py index 5d6bee7b..ef07c44a 100644 --- a/tests/rbac/aio/conftest.py +++ b/tests/rbac/aio/conftest.py @@ -9,13 +9,22 @@ port = 5000 +@pytest.fixture +def username(request): + return request.config.getoption("--username") + +@pytest.fixture +def password(request): + return request.config.getoption("--password") + +@pytest.fixture +def root_certificate(request): + return request.config.getoption("--root_certificate") @pytest.fixture(scope="module", autouse=True) async def drop_all_indexes(): async with AdminClient( - seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificates="/home/dpelini/Documents/prox/example/tls/connector.aerospike.com.crt", - private_key="/home/dpelini/Documents/prox/rbac-server/private_key.pem", public_key="/home/dpelini/Documents/prox/rbac-server/public_key.pem" - + seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificate="/home/dpelini/Documents/prox/example/tls/connector.aerospike.com.crt", ) as client: index_list = await client.index_list() @@ -29,9 +38,11 @@ async def drop_all_indexes(): @pytest.fixture(scope="module") async def session_rbac_admin_client(): client = AdminClient( - seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificates="/home/dpelini/Documents/prox/example/tls/connector.aerospike.com.crt", - private_key="/home/dpelini/Documents/prox/rbac-server/private_key.pem", public_key="/home/dpelini/Documents/prox/rbac-server/public_key.pem" + seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificate="/home/dpelini/Documents/prox/example/tls/connector.aerospike.com.crt", ) yield client await client.close() + + + diff --git a/tests/rbac/aio/test_admin_client_add_user.py b/tests/rbac/aio/test_admin_client_add_user.py index a23eae5a..31b5d824 100644 --- a/tests/rbac/aio/test_admin_client_add_user.py +++ b/tests/rbac/aio/test_admin_client_add_user.py @@ -1,5 +1,5 @@ import pytest -from utils import random_int +from ...utils import random_int class add_user_test_case: def __init__( diff --git a/tests/rbac/aio/test_admin_client_drop_user.py b/tests/rbac/aio/test_admin_client_drop_user.py index 83fa6c9c..69d04f83 100644 --- a/tests/rbac/aio/test_admin_client_drop_user.py +++ b/tests/rbac/aio/test_admin_client_drop_user.py @@ -1,7 +1,7 @@ import pytest -from utils import random_int +from ...utils import random_int from aerospike_vector_search import AVSServerError - +import grpc class drop_user_test_case: def __init__( @@ -28,10 +28,13 @@ async def test_drop_user(session_rbac_admin_client, test_case): password=test_case.password, roles=None + ) + await session_rbac_admin_client.drop_user( + username=test_case.username, + ) with pytest.raises(AVSServerError) as e_info: result = await session_rbac_admin_client.get_user( username=test_case.username ) - - assert e_info.value == "barnacle" + assert e_info.value.rpc_error.code() == grpc.StatusCode.NOT_FOUND diff --git a/tests/rbac/aio/test_admin_client_get_user.py b/tests/rbac/aio/test_admin_client_get_user.py index 2fde0191..13efe163 100644 --- a/tests/rbac/aio/test_admin_client_get_user.py +++ b/tests/rbac/aio/test_admin_client_get_user.py @@ -1,5 +1,5 @@ import pytest -from utils import random_int +from ...utils import random_int class get_user_test_case: diff --git a/tests/rbac/aio/test_admin_client_grant_roles.py b/tests/rbac/aio/test_admin_client_grant_roles.py index 084ca5e8..b2d76679 100644 --- a/tests/rbac/aio/test_admin_client_grant_roles.py +++ b/tests/rbac/aio/test_admin_client_grant_roles.py @@ -1,5 +1,5 @@ import pytest -from utils import random_int +from ...utils import random_int class grant_roles_test_case: @@ -30,6 +30,7 @@ def __init__( async def test_grant_roles(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( username=test_case.username, + password=test_case.password, roles=test_case.roles ) @@ -45,5 +46,5 @@ async def test_grant_roles(session_rbac_admin_client, test_case): assert result.username == test_case.username - assert result.granted_roles == test_case.granted_roles + assert result.roles == test_case.granted_roles diff --git a/tests/rbac/aio/test_admin_client_list_roles.py b/tests/rbac/aio/test_admin_client_list_roles.py new file mode 100644 index 00000000..c6c979e5 --- /dev/null +++ b/tests/rbac/aio/test_admin_client_list_roles.py @@ -0,0 +1,38 @@ +import pytest +from ...utils import random_int + + +class list_roles_test_case: + def __init__( + self, + *, + username, + password, + roles, + ): + self.username = username + self.password = password + self.roles = roles + +@pytest.mark.parametrize( + "test_case", + [ + list_roles_test_case( + username="aio-list-roles-" + str(random_int()), + password="yeoldpassword", + roles=["admin", "read-write"] + ), + ], +) +async def test_list_roles(session_rbac_admin_client, test_case): + await session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=test_case.roles + + ) + + result = await session_rbac_admin_client.list_roles() + for role in result: + assert role.id in test_case.roles + diff --git a/tests/rbac/aio/test_admin_client_list_users.py b/tests/rbac/aio/test_admin_client_list_users.py index 56c00060..9871a99d 100644 --- a/tests/rbac/aio/test_admin_client_list_users.py +++ b/tests/rbac/aio/test_admin_client_list_users.py @@ -1,5 +1,5 @@ import pytest -from utils import random_int +from ...utils import random_int class list_users_test_case: @@ -33,7 +33,7 @@ async def test_list_users(session_rbac_admin_client, test_case): user_found = False for user in result: if user.username == test_case.username: - assert results.roles = [] + assert user.roles == [] user_found = True assert user_found diff --git a/tests/rbac/aio/test_admin_client_revoke_roles.py b/tests/rbac/aio/test_admin_client_revoke_roles.py new file mode 100644 index 00000000..2f6dfbb8 --- /dev/null +++ b/tests/rbac/aio/test_admin_client_revoke_roles.py @@ -0,0 +1,50 @@ +import pytest +from ...utils import random_int + + +class revoke_roles_test_case: + def __init__( + self, + *, + username, + password, + roles, + revoked_roles + ): + self.username = username + self.password = password + self.roles = roles + self.revoked_roles = revoked_roles + +@pytest.mark.parametrize( + "test_case", + [ + revoke_roles_test_case( + username="aio-revoke-roles-" + str(random_int()), + password="yeoldpassword", + roles=["admin", "read-write"], + revoked_roles=[] + ), + ], +) +async def test_revoke_roles(session_rbac_admin_client, test_case): + await session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=test_case.roles + + ) + + await session_rbac_admin_client.revoke_roles( + username=test_case.username, + roles=test_case.roles + ) + + result = await session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == test_case.revoked_roles + diff --git a/tests/rbac/aio/test_admin_client_update_credentials.py b/tests/rbac/aio/test_admin_client_update_credentials.py index 393cd14e..945aa3d4 100644 --- a/tests/rbac/aio/test_admin_client_update_credentials.py +++ b/tests/rbac/aio/test_admin_client_update_credentials.py @@ -1,5 +1,5 @@ import pytest -from utils import random_int +from ...utils import random_int class update_credentials_test_case: diff --git a/tests/rbac/aio/utils.py b/tests/rbac/aio/utils.py deleted file mode 100644 index 9f84c492..00000000 --- a/tests/rbac/aio/utils.py +++ /dev/null @@ -1,4 +0,0 @@ -import random - -def random_int(): - return str(random.randint(0, 50_000)) \ No newline at end of file diff --git a/tests/standard/__init__.py b/tests/standard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/standard/aio/aio_utils.py b/tests/standard/aio/aio_utils.py new file mode 100644 index 00000000..53cd64ab --- /dev/null +++ b/tests/standard/aio/aio_utils.py @@ -0,0 +1,2 @@ +async def drop_specified_index(admin_client, namespace, name): + await admin_client.index_drop(namespace=namespace, name=name) diff --git a/tests/standard/aio/conftest.py b/tests/standard/aio/conftest.py index b90ff675..4b386384 100644 --- a/tests/standard/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -4,14 +4,13 @@ from aerospike_vector_search.aio.admin import Client as AdminClient from aerospike_vector_search import types -host = 'connector.aerospike.com' +host = 'localhost' port = 5000 @pytest.fixture(scope="session", autouse=True) async def drop_all_indexes(): async with AdminClient( - seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificates="/home/dpelini/Documents/prox/rbac-server/connector.aerospike.com.crt", - private_key="/home/dpelini/Documents/prox/rbac-server/private_key.pem", public_key="/home/dpelini/Documents/prox/rbac-server/public_key.pem" + seeds=types.HostPort(host=host, port=port) ) as client: index_list = await client.index_list() @@ -23,6 +22,7 @@ async def drop_all_indexes(): await asyncio.gather(*tasks) + @pytest.fixture(scope="module") async def session_admin_client(): client = AdminClient( diff --git a/tests/standard/aio/test_admin_client_index_create.py b/tests/standard/aio/test_admin_client_index_create.py index f9691158..66b8d0ca 100644 --- a/tests/standard/aio/test_admin_client_index_create.py +++ b/tests/standard/aio/test_admin_client_index_create.py @@ -1,13 +1,14 @@ import pytest from aerospike_vector_search import types - +from ...utils import index_strategy +from .aio_utils import drop_specified_index +from hypothesis import given, settings, Verbosity class index_create_test_case: def __init__( self, *, namespace, - name, vector_field, dimensions, vector_distance_metric, @@ -16,7 +17,6 @@ def __init__( index_meta_data, ): self.namespace = namespace - self.name = name self.vector_field = vector_field self.dimensions = dimensions if vector_distance_metric == None: @@ -27,13 +27,14 @@ def __init__( self.index_params = index_params self.index_meta_data = index_meta_data - +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, index_create_test_case( namespace="test", - name="index_1", vector_field="example_1", dimensions=1024, vector_distance_metric=None, @@ -43,10 +44,12 @@ def __init__( ) ], ) -async def test_index_create(session_admin_client, test_case): +async def test_index_create(session_admin_client, test_case, random_name): + if test_case == None: + return await session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -57,7 +60,7 @@ async def test_index_create(session_admin_client, test_case): results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -69,15 +72,19 @@ async def test_index_create(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + await drop_specified_index(session_admin_client, test_case.namespace, random_name) + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, index_create_test_case( namespace="test", - name="index_2", vector_field="example_2", dimensions=495, vector_distance_metric=None, @@ -87,7 +94,6 @@ async def test_index_create(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_3", vector_field="example_3", dimensions=2048, vector_distance_metric=None, @@ -97,10 +103,10 @@ async def test_index_create(session_admin_client, test_case): ), ], ) -async def test_index_create_with_dimnesions(session_admin_client, test_case): +async def test_index_create_with_dimnesions(session_admin_client, test_case, random_name): await session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -108,10 +114,14 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case): index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, ) + + results = await session_admin_client.index_list() + found = False for result in results: - if result['id']['name'] == test_case.name: + + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -123,15 +133,21 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + await drop_specified_index(session_admin_client, test_case.namespace, random_name) + + + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, index_create_test_case( namespace="test", - name="index_4", vector_field="example_4", dimensions=1024, vector_distance_metric=types.VectorDistanceMetric.COSINE, @@ -141,7 +157,6 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_5", vector_field="example_5", dimensions=1024, vector_distance_metric=types.VectorDistanceMetric.DOT_PRODUCT, @@ -151,7 +166,6 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_6", vector_field="example_6", dimensions=1024, vector_distance_metric=types.VectorDistanceMetric.MANHATTAN, @@ -161,7 +175,6 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_7", vector_field="example_7", dimensions=1024, vector_distance_metric=types.VectorDistanceMetric.HAMMING, @@ -172,11 +185,13 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case): ], ) async def test_index_create_with_vector_distance_metric( - session_admin_client, test_case + session_admin_client, test_case, random_name ): + + await session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -187,7 +202,7 @@ async def test_index_create_with_vector_distance_metric( results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -199,15 +214,19 @@ async def test_index_create_with_vector_distance_metric( assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + await drop_specified_index(session_admin_client, test_case.namespace, random_name) + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, index_create_test_case( namespace="test", - name="index_8", vector_field="example_8", dimensions=1024, vector_distance_metric=None, @@ -217,7 +236,6 @@ async def test_index_create_with_vector_distance_metric( ), index_create_test_case( namespace="test", - name="index_9", vector_field="example_9", dimensions=1024, vector_distance_metric=None, @@ -227,10 +245,11 @@ async def test_index_create_with_vector_distance_metric( ), ], ) -async def test_index_create_with_sets(session_admin_client, test_case): +async def test_index_create_with_sets(session_admin_client, test_case, random_name): + await session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -241,7 +260,7 @@ async def test_index_create_with_sets(session_admin_client, test_case): results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -253,15 +272,19 @@ async def test_index_create_with_sets(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + await drop_specified_index(session_admin_client, test_case.namespace, random_name) + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, index_create_test_case( namespace="test", - name="index_10", vector_field="example_10", dimensions=1024, vector_distance_metric=None, @@ -275,7 +298,6 @@ async def test_index_create_with_sets(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_11", vector_field="example_11", dimensions=1024, vector_distance_metric=None, @@ -289,7 +311,6 @@ async def test_index_create_with_sets(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_12", vector_field="example_12", dimensions=1024, vector_distance_metric=None, @@ -303,10 +324,10 @@ async def test_index_create_with_sets(session_admin_client, test_case): ), ], ) -async def test_index_create_with_index_params(session_admin_client, test_case): +async def test_index_create_with_index_params(session_admin_client, test_case, random_name): await session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -317,7 +338,7 @@ async def test_index_create_with_index_params(session_admin_client, test_case): results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -329,28 +350,34 @@ async def test_index_create_with_index_params(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == test_case.index_params.batching_params.interval assert result['hnsw_params']['batching_params']['disabled'] == test_case.index_params.batching_params.disabled assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + await drop_specified_index(session_admin_client, test_case.namespace, random_name) + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, index_create_test_case( namespace="test", - name="index_13", vector_field="example_13", dimensions=1024, vector_distance_metric=None, sets=None, index_params=None, index_meta_data={"size": "large", "price": "$4.99", "currencyType": "CAN"}, - ), + ) ], ) -async def test_index_create_index_meta_data(session_admin_client, test_case): +async def test_index_create_index_meta_data(session_admin_client, test_case, random_name): + if test_case == None: + return await session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -361,7 +388,7 @@ async def test_index_create_index_meta_data(session_admin_client, test_case): results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -373,5 +400,7 @@ async def test_index_create_index_meta_data(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name - assert found == True \ No newline at end of file + assert result['storage']['set'] == random_name + assert found == True + await drop_specified_index(session_admin_client, test_case.namespace, random_name) + diff --git a/tests/standard/aio/test_admin_client_index_drop.py b/tests/standard/aio/test_admin_client_index_drop.py index 8a17460d..ac8d6bf4 100644 --- a/tests/standard/aio/test_admin_client_index_drop.py +++ b/tests/standard/aio/test_admin_client_index_drop.py @@ -1,18 +1,26 @@ import pytest -@pytest.fixture -async def add_index(function_admin_client): - await function_admin_client.index_create( +from ...utils import index_strategy + +from hypothesis import given, settings, Verbosity + + + + +@pytest.mark.parametrize("empty_test_case",[None, None]) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +async def test_index_drop(session_admin_client, empty_test_case, random_name): + await session_admin_client.index_create( namespace="test", - name="index_drop_1", + name=random_name, vector_field="art", dimensions=1024, ) - -async def test_index_drop(add_index, session_admin_client): - await session_admin_client.index_drop(namespace="test", name="index_drop_1") + await session_admin_client.index_drop(namespace="test", name=random_name) result = session_admin_client.index_list() result = await result for index in result: - assert index["id"]["name"] != "index_drop_1" + assert index["id"]["name"] != random_name + diff --git a/tests/standard/aio/test_admin_client_index_get.py b/tests/standard/aio/test_admin_client_index_get.py index 64eaf4ea..e6911405 100644 --- a/tests/standard/aio/test_admin_client_index_get.py +++ b/tests/standard/aio/test_admin_client_index_get.py @@ -1,21 +1,26 @@ import pytest +from ...utils import index_strategy +from .aio_utils import drop_specified_index +from hypothesis import given, settings, Verbosity -@pytest.fixture -async def add_index(function_admin_client): - await function_admin_client.index_create( + + + +@pytest.mark.parametrize("empty_test_case",[None, None]) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +async def test_index_get(session_admin_client, empty_test_case, random_name): + await session_admin_client.index_create( namespace="test", - name="index_get_1", + name=random_name, vector_field="science", dimensions=1024, ) - - -async def test_index_get(add_index, session_admin_client): result = await session_admin_client.index_get( - namespace="test", name="index_get_1" + namespace="test", name=random_name ) - assert result["id"]["name"] == "index_get_1" + assert result["id"]["name"] == random_name assert result["id"]["namespace"] == "test" assert result["dimensions"] == 1024 assert result['field'] == "science" @@ -26,4 +31,6 @@ async def test_index_get(add_index, session_admin_client): assert result["hnsw_params"]["batching_params"]["interval"] == 30000 assert not result["hnsw_params"]["batching_params"]["disabled"] assert result["storage"]["namespace"] == "test" - assert result["storage"]["set"] == "index_get_1" \ No newline at end of file + assert result["storage"]["set"] == random_name + + await drop_specified_index(session_admin_client, "test", random_name) diff --git a/tests/standard/aio/test_admin_client_index_get_status.py b/tests/standard/aio/test_admin_client_index_get_status.py index aef88b96..7cf06ab1 100644 --- a/tests/standard/aio/test_admin_client_index_get_status.py +++ b/tests/standard/aio/test_admin_client_index_get_status.py @@ -1,17 +1,21 @@ import pytest +from ...utils import index_strategy +from .aio_utils import drop_specified_index +from hypothesis import given, settings, Verbosity -@pytest.fixture -async def add_index(function_admin_client): - await function_admin_client.index_create( +@pytest.mark.parametrize("empty_test_case",[None, None]) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +async def test_index_get_status(session_admin_client, empty_test_case, random_name): + await session_admin_client.index_create( namespace="test", - name="index_get_status_1", + name=random_name, vector_field="science", dimensions=1024, ) - -async def test_index_get_status(add_index, session_admin_client): result = await session_admin_client.index_get_status( - namespace="test", name="index_get_status_1" + namespace="test", name=random_name ) assert result == 0 + await drop_specified_index(session_admin_client, "test", random_name) \ No newline at end of file diff --git a/tests/standard/aio/test_admin_client_index_list.py b/tests/standard/aio/test_admin_client_index_list.py index 6110926b..16dff127 100644 --- a/tests/standard/aio/test_admin_client_index_list.py +++ b/tests/standard/aio/test_admin_client_index_list.py @@ -1,4 +1,19 @@ -async def test_index_list(session_admin_client): +import pytest + +from ...utils import index_strategy +from .aio_utils import drop_specified_index +from hypothesis import given, settings, Verbosity + +@pytest.mark.parametrize("empty_test_case",[None, None]) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +async def test_index_list(session_admin_client, empty_test_case, random_name): + await session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="science", + dimensions=1024, + ) result = await session_admin_client.index_list() assert len(result) > 0 for index in result: @@ -14,4 +29,4 @@ async def test_index_list(session_admin_client): assert isinstance(index['hnsw_params']['batching_params']['disabled'], bool) assert isinstance(index['storage']['namespace'], str) assert isinstance(index['storage']['set'], str) - + await drop_specified_index(session_admin_client, "test", random_name) diff --git a/tests/standard/aio/test_vector_client_delete.py b/tests/standard/aio/test_vector_client_delete.py index c0ea0fa3..fd6342a1 100644 --- a/tests/standard/aio/test_vector_client_delete.py +++ b/tests/standard/aio/test_vector_client_delete.py @@ -1,67 +1,70 @@ import pytest from aerospike_vector_search import AVSServerError +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity class delete_test_case: def __init__( self, *, namespace, - key, record_data, set_name, ): self.namespace = namespace - self.key = key self.set_name = set_name self.record_data = record_data + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, delete_test_case( namespace="test", - key="aio/delete/1", set_name=None, record_data={"skills": [i for i in range(1024)]}, ), delete_test_case( namespace="test", - key="aio/delete/2", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, ) ], ) -async def test_vector_delete(session_vector_client, test_case): +async def test_vector_delete(session_vector_client, test_case, random_key): await session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) await session_vector_client.delete( namespace=test_case.namespace, - key=test_case.key, + key=random_key, ) with pytest.raises(AVSServerError) as e_info: result = await session_vector_client.get( - namespace=test_case.namespace, key=test_case.key + namespace=test_case.namespace, key=random_key ) - +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, delete_test_case( namespace="test", - key="aio/delete/3", set_name=None, record_data={"skills": [i for i in range(1024)]}, ), ], ) -async def test_vector_delete_without_record(session_vector_client, test_case): +async def test_vector_delete_without_record(session_vector_client, test_case, random_key): await session_vector_client.delete( namespace=test_case.namespace, - key=test_case.key, + key=random_key, ) \ No newline at end of file diff --git a/tests/standard/aio/test_vector_client_exists.py b/tests/standard/aio/test_vector_client_exists.py index c2f46346..86df1302 100644 --- a/tests/standard/aio/test_vector_client_exists.py +++ b/tests/standard/aio/test_vector_client_exists.py @@ -1,47 +1,53 @@ import pytest +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity class exists_test_case: def __init__( self, *, namespace, - key, record_data, set_name, ): self.namespace = namespace - self.key = key self.set_name = set_name self.record_data = record_data +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, exists_test_case( namespace="test", - key="aio/exists/1", set_name=None, record_data={"skills": [i for i in range(1024)]}, ), exists_test_case( namespace="test", - key="aio/exists/2", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, ) ], ) -async def test_vector_exists(session_vector_client, test_case): +async def test_vector_exists(session_vector_client, test_case, random_key): await session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) result = await session_vector_client.exists( namespace=test_case.namespace, - key=test_case.key, + key=random_key, ) assert result is True + + await session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) \ No newline at end of file diff --git a/tests/standard/aio/test_vector_client_get.py b/tests/standard/aio/test_vector_client_get.py index e5666716..e5ecc2a4 100644 --- a/tests/standard/aio/test_vector_client_get.py +++ b/tests/standard/aio/test_vector_client_get.py @@ -1,29 +1,30 @@ import pytest - +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity class get_test_case: def __init__( self, *, namespace, - key, field_names, set_name, record_data, expected_fields ): self.namespace = namespace - self.key = key self.field_names = field_names self.set_name = set_name self.record_data = record_data self.expected_fields = expected_fields +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, get_test_case( namespace="test", - key="aio/get/1", field_names=['skills'], set_name=None, record_data={"skills": [i for i in range(1024)]}, @@ -31,7 +32,6 @@ def __init__( ), get_test_case( namespace="test", - key="aio/get/2", field_names=['english'], set_name=None, record_data={"english": [float(i) for i in range(1024)]}, @@ -39,22 +39,26 @@ def __init__( ) ], ) -async def test_vector_get(session_vector_client, test_case): +async def test_vector_get(session_vector_client, test_case, random_key): await session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) result = await session_vector_client.get( - namespace=test_case.namespace, key=test_case.key, field_names=test_case.field_names + namespace=test_case.namespace, key=random_key, field_names=test_case.field_names ) assert result.key.namespace == test_case.namespace if(test_case.set_name == None): test_case.set_name = "" assert result.key.set == test_case.set_name - assert result.key.key == test_case.key + assert result.key.key == random_key assert result.fields == test_case.expected_fields + await session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) \ No newline at end of file diff --git a/tests/standard/aio/test_vector_client_insert.py b/tests/standard/aio/test_vector_client_insert.py index 39e00d85..24f0e2e1 100644 --- a/tests/standard/aio/test_vector_client_insert.py +++ b/tests/standard/aio/test_vector_client_insert.py @@ -1,74 +1,86 @@ import pytest from aerospike_vector_search import AVSServerError +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity +import asyncio +from hypothesis import given, settings class insert_test_case: def __init__( self, *, namespace, - key, record_data, set_name ): self.namespace = namespace - self.key = key self.record_data = record_data self.set_name = set_name - +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, insert_test_case( namespace="test", - key="aio/insert/1", record_data={"math": [i for i in range(1024)]}, set_name=None ), insert_test_case( namespace="test", - key="aio/insert/2", - record_data={"english": [float(i) for i in range(1024)]}, + record_data={"homeSkills": [float(i) for i in range(1024)]}, set_name=None ), insert_test_case( namespace="test", - key="aio/insert/3", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None ) ], ) -async def test_vector_insert_without_existing_record(session_vector_client, test_case): +async def test_vector_insert_without_existing_record(session_vector_client, test_case, random_key): await session_vector_client.insert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) + await session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, insert_test_case( namespace="test", - key="aio/insert/4", record_data={"math": [i for i in range(1024)]}, set_name=None ) ], ) -async def test_vector_insert_with_existing_record(session_vector_client, test_case): +async def test_vector_insert_with_existing_record(session_vector_client, test_case, random_key): await session_vector_client.insert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name - ) + ) with pytest.raises(AVSServerError) as e_info: await session_vector_client.insert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name - ) \ No newline at end of file + ) + await session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) \ No newline at end of file diff --git a/tests/standard/aio/test_vector_client_update.py b/tests/standard/aio/test_vector_client_update.py index 612e58e0..f913d956 100644 --- a/tests/standard/aio/test_vector_client_update.py +++ b/tests/standard/aio/test_vector_client_update.py @@ -1,74 +1,79 @@ import pytest from aerospike_vector_search import AVSServerError +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity class update_test_case: def __init__( self, *, namespace, - key, record_data, set_name ): self.namespace = namespace - self.key = key self.record_data = record_data self.set_name = set_name - +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, update_test_case( namespace="test", - key="aio/update/1", record_data={"math": [i for i in range(1024)]}, set_name=None ), update_test_case( namespace="test", - key="aio/update/2", record_data={"english": [float(i) for i in range(1024)]}, set_name=None ), update_test_case( namespace="test", - key="aio/update/3", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None ) ], ) -async def test_vector_update_with_existing_record(session_vector_client, test_case): +async def test_vector_update_with_existing_record(session_vector_client, test_case, random_key): await session_vector_client.insert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) await session_vector_client.update( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) - + await session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, update_test_case( namespace="test", - key="aio/update/4", record_data={"math": [i for i in range(1024)]}, set_name=None ) ], ) -async def test_vector_update_without_existing_record(session_vector_client, test_case): +async def test_vector_update_without_existing_record(session_vector_client, test_case, random_key): with pytest.raises(AVSServerError) as e_info: await session_vector_client.update( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) \ No newline at end of file diff --git a/tests/standard/aio/test_vector_client_upsert.py b/tests/standard/aio/test_vector_client_upsert.py index 482e107d..430834f3 100644 --- a/tests/standard/aio/test_vector_client_upsert.py +++ b/tests/standard/aio/test_vector_client_upsert.py @@ -1,65 +1,77 @@ import pytest +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity + class upsert_test_case: def __init__( self, *, namespace, - key, record_data, set_name ): self.namespace = namespace - self.key = key self.record_data = record_data self.set_name = set_name - +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, upsert_test_case( namespace="test", - key="aio/upsert/1", record_data={"math": [i for i in range(1024)]}, set_name=None ), upsert_test_case( namespace="test", - key="aio/upsert/2", record_data={"english": [float(i) for i in range(1024)]}, set_name=None ), upsert_test_case( namespace="test", - key="aio/upsert/3", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None ) ], ) -async def test_vector_upsert_without_existing_record(session_vector_client, test_case): +async def test_vector_upsert_without_existing_record(session_vector_client, test_case, random_key): await session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) + await session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, upsert_test_case( namespace="test", - key="upsert/4", record_data={"math": [i for i in range(1024)]}, set_name=None ) ], ) -async def test_vector_upsert_with_existing_record(session_vector_client, test_case): +async def test_vector_upsert_with_existing_record(session_vector_client, test_case, random_key): await session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name + ) + + await session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, ) \ No newline at end of file diff --git a/tests/standard/sync/conftest.py b/tests/standard/sync/conftest.py index 6b25c78d..4792d6c6 100644 --- a/tests/standard/sync/conftest.py +++ b/tests/standard/sync/conftest.py @@ -1,21 +1,25 @@ import pytest -import asyncio from aerospike_vector_search import Client from aerospike_vector_search.admin import Client as AdminClient from aerospike_vector_search import types host = 'localhost' port = 5000 + @pytest.fixture(scope="session", autouse=True) def drop_all_indexes(): with AdminClient( seeds=types.HostPort(host=host, port=port) + ) as client: index_list = client.index_list() + tasks = [] for item in index_list: client.index_drop(namespace="test", name=item['id']['name']) + + @pytest.fixture(scope="module") def session_admin_client(): client = AdminClient( @@ -24,7 +28,6 @@ def session_admin_client(): yield client client.close() - @pytest.fixture(scope="module") def session_vector_client(): client = Client( @@ -39,4 +42,4 @@ def function_admin_client(): seeds=types.HostPort(host=host, port=port) ) yield client - client.close() \ No newline at end of file + client.close() diff --git a/tests/standard/sync/sync_utils.py b/tests/standard/sync/sync_utils.py new file mode 100644 index 00000000..ece24752 --- /dev/null +++ b/tests/standard/sync/sync_utils.py @@ -0,0 +1,2 @@ +def drop_specified_index(admin_client, namespace, name): + admin_client.index_drop(namespace=namespace, name=name) diff --git a/tests/standard/sync/test_admin_client_index_create.py b/tests/standard/sync/test_admin_client_index_create.py index 62d18648..d29aaf5f 100644 --- a/tests/standard/sync/test_admin_client_index_create.py +++ b/tests/standard/sync/test_admin_client_index_create.py @@ -1,13 +1,14 @@ import pytest from aerospike_vector_search import types - +from ...utils import index_strategy +from .sync_utils import drop_specified_index +from hypothesis import given, settings, Verbosity class index_create_test_case: def __init__( self, *, namespace, - name, vector_field, dimensions, vector_distance_metric, @@ -16,7 +17,6 @@ def __init__( index_meta_data, ): self.namespace = namespace - self.name = name self.vector_field = vector_field self.dimensions = dimensions if vector_distance_metric == None: @@ -27,13 +27,13 @@ def __init__( self.index_params = index_params self.index_meta_data = index_meta_data - +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ index_create_test_case( namespace="test", - name="index_1", vector_field="example_1", dimensions=1024, vector_distance_metric=None, @@ -43,10 +43,12 @@ def __init__( ) ], ) -def test_index_create(session_admin_client, test_case): +def test_index_create(session_admin_client, test_case, random_name): + if test_case == None: + return session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -57,7 +59,7 @@ def test_index_create(session_admin_client, test_case): results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -69,15 +71,18 @@ def test_index_create(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + drop_specified_index(session_admin_client, test_case.namespace, random_name) + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ index_create_test_case( namespace="test", - name="index_2", vector_field="example_2", dimensions=495, vector_distance_metric=None, @@ -87,7 +92,6 @@ def test_index_create(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_3", vector_field="example_3", dimensions=2048, vector_distance_metric=None, @@ -97,10 +101,10 @@ def test_index_create(session_admin_client, test_case): ), ], ) -def test_index_create_with_dimnesions(session_admin_client, test_case): +def test_index_create_with_dimnesions(session_admin_client, test_case, random_name): session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -108,10 +112,14 @@ def test_index_create_with_dimnesions(session_admin_client, test_case): index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, ) + + results = session_admin_client.index_list() + found = False for result in results: - if result['id']['name'] == test_case.name: + + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -123,15 +131,20 @@ def test_index_create_with_dimnesions(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + drop_specified_index(session_admin_client, test_case.namespace, random_name) + + + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ index_create_test_case( namespace="test", - name="index_4", vector_field="example_4", dimensions=1024, vector_distance_metric=types.VectorDistanceMetric.COSINE, @@ -141,7 +154,6 @@ def test_index_create_with_dimnesions(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_5", vector_field="example_5", dimensions=1024, vector_distance_metric=types.VectorDistanceMetric.DOT_PRODUCT, @@ -151,7 +163,6 @@ def test_index_create_with_dimnesions(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_6", vector_field="example_6", dimensions=1024, vector_distance_metric=types.VectorDistanceMetric.MANHATTAN, @@ -161,7 +172,6 @@ def test_index_create_with_dimnesions(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_7", vector_field="example_7", dimensions=1024, vector_distance_metric=types.VectorDistanceMetric.HAMMING, @@ -172,11 +182,13 @@ def test_index_create_with_dimnesions(session_admin_client, test_case): ], ) def test_index_create_with_vector_distance_metric( - session_admin_client, test_case + session_admin_client, test_case, random_name ): + + session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -187,7 +199,7 @@ def test_index_create_with_vector_distance_metric( results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -199,15 +211,18 @@ def test_index_create_with_vector_distance_metric( assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + drop_specified_index(session_admin_client, test_case.namespace, random_name) + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ index_create_test_case( namespace="test", - name="index_8", vector_field="example_8", dimensions=1024, vector_distance_metric=None, @@ -217,7 +232,6 @@ def test_index_create_with_vector_distance_metric( ), index_create_test_case( namespace="test", - name="index_9", vector_field="example_9", dimensions=1024, vector_distance_metric=None, @@ -227,10 +241,11 @@ def test_index_create_with_vector_distance_metric( ), ], ) -def test_index_create_with_sets(session_admin_client, test_case): +def test_index_create_with_sets(session_admin_client, test_case, random_name): + session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -241,7 +256,7 @@ def test_index_create_with_sets(session_admin_client, test_case): results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -253,15 +268,18 @@ def test_index_create_with_sets(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + drop_specified_index(session_admin_client, test_case.namespace, random_name) + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ index_create_test_case( namespace="test", - name="index_10", vector_field="example_10", dimensions=1024, vector_distance_metric=None, @@ -275,7 +293,6 @@ def test_index_create_with_sets(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_11", vector_field="example_11", dimensions=1024, vector_distance_metric=None, @@ -289,7 +306,6 @@ def test_index_create_with_sets(session_admin_client, test_case): ), index_create_test_case( namespace="test", - name="index_12", vector_field="example_12", dimensions=1024, vector_distance_metric=None, @@ -303,10 +319,10 @@ def test_index_create_with_sets(session_admin_client, test_case): ), ], ) -def test_index_create_with_index_params(session_admin_client, test_case): +def test_index_create_with_index_params(session_admin_client, test_case, random_name): session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -317,7 +333,7 @@ def test_index_create_with_index_params(session_admin_client, test_case): results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -329,28 +345,33 @@ def test_index_create_with_index_params(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == test_case.index_params.batching_params.interval assert result['hnsw_params']['batching_params']['disabled'] == test_case.index_params.batching_params.disabled assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name + assert result['storage']['set'] == random_name assert found == True + drop_specified_index(session_admin_client, test_case.namespace, random_name) + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ index_create_test_case( namespace="test", - name="index_13", vector_field="example_13", dimensions=1024, vector_distance_metric=None, sets=None, index_params=None, index_meta_data={"size": "large", "price": "$4.99", "currencyType": "CAN"}, - ), + ) ], ) -def test_index_create_index_meta_data(session_admin_client, test_case): +def test_index_create_index_meta_data(session_admin_client, test_case, random_name): + if test_case == None: + return session_admin_client.index_create( namespace=test_case.namespace, - name=test_case.name, + name=random_name, vector_field=test_case.vector_field, dimensions=test_case.dimensions, vector_distance_metric=test_case.vector_distance_metric, @@ -361,7 +382,7 @@ def test_index_create_index_meta_data(session_admin_client, test_case): results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result['id']['name'] == random_name: found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions @@ -373,5 +394,7 @@ def test_index_create_index_meta_data(session_admin_client, test_case): assert result['hnsw_params']['batching_params']['interval'] == 30000 assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == test_case.name - assert found == True \ No newline at end of file + assert result['storage']['set'] == random_name + assert found == True + drop_specified_index(session_admin_client, test_case.namespace, random_name) + diff --git a/tests/standard/sync/test_admin_client_index_drop.py b/tests/standard/sync/test_admin_client_index_drop.py index 92777662..69375310 100644 --- a/tests/standard/sync/test_admin_client_index_drop.py +++ b/tests/standard/sync/test_admin_client_index_drop.py @@ -1,18 +1,26 @@ import pytest -@pytest.fixture -def add_index(function_admin_client): - function_admin_client.index_create( +from ...utils import index_strategy + +from hypothesis import given, settings, Verbosity + + + + +@pytest.mark.parametrize("empty_test_case",[None]) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +def test_index_drop(session_admin_client, empty_test_case, random_name): + session_admin_client.index_create( namespace="test", - name="index_drop_1", + name=random_name, vector_field="art", dimensions=1024, ) - -def test_index_drop(add_index, session_admin_client): - session_admin_client.index_drop(namespace="test", name="index_drop_1") + session_admin_client.index_drop(namespace="test", name=random_name) result = session_admin_client.index_list() result = result for index in result: - assert index["id"]["name"] != "index_drop_1" + assert index["id"]["name"] != random_name + diff --git a/tests/standard/sync/test_admin_client_index_get.py b/tests/standard/sync/test_admin_client_index_get.py index 41f791ee..d97e748d 100644 --- a/tests/standard/sync/test_admin_client_index_get.py +++ b/tests/standard/sync/test_admin_client_index_get.py @@ -1,21 +1,26 @@ import pytest +from ...utils import index_strategy +from .sync_utils import drop_specified_index +from hypothesis import given, settings, Verbosity -@pytest.fixture -def add_index(function_admin_client): - function_admin_client.index_create( + + + +@pytest.mark.parametrize("empty_test_case",[None]) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +def test_index_get(session_admin_client, empty_test_case, random_name): + session_admin_client.index_create( namespace="test", - name="index_get_1", + name=random_name, vector_field="science", dimensions=1024, ) - - -def test_index_get(add_index, session_admin_client): result = session_admin_client.index_get( - namespace="test", name="index_get_1" + namespace="test", name=random_name ) - assert result["id"]["name"] == "index_get_1" + assert result["id"]["name"] == random_name assert result["id"]["namespace"] == "test" assert result["dimensions"] == 1024 assert result['field'] == "science" @@ -26,4 +31,6 @@ def test_index_get(add_index, session_admin_client): assert result["hnsw_params"]["batching_params"]["interval"] == 30000 assert not result["hnsw_params"]["batching_params"]["disabled"] assert result["storage"]["namespace"] == "test" - assert result["storage"]["set"] == "index_get_1" \ No newline at end of file + assert result["storage"]["set"] == random_name + + drop_specified_index(session_admin_client, "test", random_name) diff --git a/tests/standard/sync/test_admin_client_index_get_status.py b/tests/standard/sync/test_admin_client_index_get_status.py index fee6bbe6..9d56f6de 100644 --- a/tests/standard/sync/test_admin_client_index_get_status.py +++ b/tests/standard/sync/test_admin_client_index_get_status.py @@ -1,17 +1,22 @@ import pytest +from ...utils import index_strategy +from .sync_utils import drop_specified_index +from hypothesis import given, settings, Verbosity -@pytest.fixture -def add_index(function_admin_client): - function_admin_client.index_create( +@pytest.mark.parametrize("empty_test_case",[None]) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +def test_index_get_status(session_admin_client, empty_test_case, random_name): + session_admin_client.index_create( namespace="test", - name="index_get_status_1", + name=random_name, vector_field="science", dimensions=1024, ) - -def test_index_get_status(add_index, session_admin_client): result = session_admin_client.index_get_status( - namespace="test", name="index_get_status_1" + namespace="test", name=random_name ) + assert result == 0 + drop_specified_index(session_admin_client, "test", random_name) \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_list.py b/tests/standard/sync/test_admin_client_index_list.py index 66312a06..483bb4ec 100644 --- a/tests/standard/sync/test_admin_client_index_list.py +++ b/tests/standard/sync/test_admin_client_index_list.py @@ -1,4 +1,19 @@ -def test_index_list(session_admin_client): +import pytest + +from ...utils import index_strategy +from .sync_utils import drop_specified_index +from hypothesis import given, settings, Verbosity + +@pytest.mark.parametrize("empty_test_case",[None]) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +def test_index_list(session_admin_client, empty_test_case, random_name): + session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="science", + dimensions=1024, + ) result = session_admin_client.index_list() assert len(result) > 0 for index in result: @@ -14,4 +29,4 @@ def test_index_list(session_admin_client): assert isinstance(index['hnsw_params']['batching_params']['disabled'], bool) assert isinstance(index['storage']['namespace'], str) assert isinstance(index['storage']['set'], str) - + drop_specified_index(session_admin_client, "test", random_name) diff --git a/tests/standard/sync/test_vector_client_delete.py b/tests/standard/sync/test_vector_client_delete.py index 95bd4272..55ab3981 100644 --- a/tests/standard/sync/test_vector_client_delete.py +++ b/tests/standard/sync/test_vector_client_delete.py @@ -1,67 +1,68 @@ import pytest from aerospike_vector_search import AVSServerError +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity class delete_test_case: def __init__( self, *, namespace, - key, record_data, set_name, ): self.namespace = namespace - self.key = key self.set_name = set_name self.record_data = record_data + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ delete_test_case( namespace="test", - key="delete/1", set_name=None, record_data={"skills": [i for i in range(1024)]}, ), delete_test_case( namespace="test", - key="delete/2", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, ) ], ) -def test_vector_delete(session_vector_client, test_case): +def test_vector_delete(session_vector_client, test_case, random_key): session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) session_vector_client.delete( namespace=test_case.namespace, - key=test_case.key, + key=random_key, ) with pytest.raises(AVSServerError) as e_info: result = session_vector_client.get( - namespace=test_case.namespace, key=test_case.key - ) - + namespace=test_case.namespace, key=random_key + ) +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ delete_test_case( namespace="test", - key="aio/delete/3", set_name=None, record_data={"skills": [i for i in range(1024)]}, ), ], ) -async def test_vector_delete_without_record(session_vector_client, test_case): +def test_vector_delete_without_record(session_vector_client, test_case, random_key): session_vector_client.delete( namespace=test_case.namespace, - key=test_case.key, + key=random_key, ) \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_exists.py b/tests/standard/sync/test_vector_client_exists.py index 984739ab..301cdd0f 100644 --- a/tests/standard/sync/test_vector_client_exists.py +++ b/tests/standard/sync/test_vector_client_exists.py @@ -1,47 +1,52 @@ import pytest +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity class exists_test_case: def __init__( self, *, namespace, - key, record_data, set_name, ): self.namespace = namespace - self.key = key self.set_name = set_name self.record_data = record_data +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ exists_test_case( namespace="test", - key="exists/1", set_name=None, record_data={"skills": [i for i in range(1024)]}, ), exists_test_case( namespace="test", - key="exists/2", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, ) ], ) -def test_vector_exists(session_vector_client, test_case): +def test_vector_exists(session_vector_client, test_case, random_key): session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) result = session_vector_client.exists( namespace=test_case.namespace, - key=test_case.key, + key=random_key, ) assert result is True + + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) diff --git a/tests/standard/sync/test_vector_client_get.py b/tests/standard/sync/test_vector_client_get.py index c4c18b56..328fcfe6 100644 --- a/tests/standard/sync/test_vector_client_get.py +++ b/tests/standard/sync/test_vector_client_get.py @@ -1,29 +1,29 @@ import pytest - +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity class get_test_case: def __init__( self, *, namespace, - key, field_names, set_name, record_data, expected_fields ): self.namespace = namespace - self.key = key self.field_names = field_names self.set_name = set_name self.record_data = record_data self.expected_fields = expected_fields +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ get_test_case( namespace="test", - key="get/1", field_names=['skills'], set_name=None, record_data={"skills": [i for i in range(1024)]}, @@ -31,7 +31,6 @@ def __init__( ), get_test_case( namespace="test", - key="get/2", field_names=['english'], set_name=None, record_data={"english": [float(i) for i in range(1024)]}, @@ -39,22 +38,26 @@ def __init__( ) ], ) -def test_vector_get(session_vector_client, test_case): +def test_vector_get(session_vector_client, test_case, random_key): session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) result = session_vector_client.get( - namespace=test_case.namespace, key=test_case.key, field_names=test_case.field_names + namespace=test_case.namespace, key=random_key, field_names=test_case.field_names ) assert result.key.namespace == test_case.namespace if(test_case.set_name == None): test_case.set_name = "" assert result.key.set == test_case.set_name - assert result.key.key == test_case.key + assert result.key.key == random_key assert result.fields == test_case.expected_fields + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_insert.py b/tests/standard/sync/test_vector_client_insert.py index ea3cab01..c9707bd8 100644 --- a/tests/standard/sync/test_vector_client_insert.py +++ b/tests/standard/sync/test_vector_client_insert.py @@ -1,73 +1,84 @@ import pytest from aerospike_vector_search import AVSServerError +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity + +from hypothesis import given, settings + class insert_test_case: def __init__( self, *, namespace, - key, record_data, set_name ): self.namespace = namespace - self.key = key self.record_data = record_data self.set_name = set_name - +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ insert_test_case( namespace="test", - key="insert/1", record_data={"math": [i for i in range(1024)]}, set_name=None ), insert_test_case( namespace="test", - key="insert/2", - record_data={"english": [float(i) for i in range(1024)]}, + record_data={"homeSkills": [float(i) for i in range(1024)]}, set_name=None ), insert_test_case( namespace="test", - key="insert/3", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None ) ], ) -def test_vector_insert_without_existing_record(session_vector_client, test_case): +def test_vector_insert_without_existing_record(session_vector_client, test_case, random_key): session_vector_client.insert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ insert_test_case( namespace="test", - key="insert/4", record_data={"math": [i for i in range(1024)]}, set_name=None ) ], ) -def test_vector_insert_with_existing_record(session_vector_client, test_case): +def test_vector_insert_with_existing_record(session_vector_client, test_case, random_key): session_vector_client.insert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name - ) + ) with pytest.raises(AVSServerError) as e_info: session_vector_client.insert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name - ) \ No newline at end of file + ) + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_update.py b/tests/standard/sync/test_vector_client_update.py index 5b954c23..2f259e81 100644 --- a/tests/standard/sync/test_vector_client_update.py +++ b/tests/standard/sync/test_vector_client_update.py @@ -1,74 +1,74 @@ import pytest from aerospike_vector_search import AVSServerError +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity class update_test_case: def __init__( self, *, namespace, - key, record_data, set_name ): self.namespace = namespace - self.key = key self.record_data = record_data self.set_name = set_name - +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ update_test_case( namespace="test", - key="update/1", record_data={"math": [i for i in range(1024)]}, set_name=None ), update_test_case( namespace="test", - key="update/2", record_data={"english": [float(i) for i in range(1024)]}, set_name=None ), update_test_case( namespace="test", - key="update/3", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None ) ], ) -def test_vector_update_with_existing_record(session_vector_client, test_case): +def test_vector_update_with_existing_record(session_vector_client, test_case, random_key): session_vector_client.insert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) session_vector_client.update( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ update_test_case( namespace="test", - key="update/4", record_data={"math": [i for i in range(1024)]}, set_name=None ) ], ) -def test_vector_update_without_existing_record(session_vector_client, test_case): +def test_vector_update_without_existing_record(session_vector_client, test_case, random_key): with pytest.raises(AVSServerError) as e_info: session_vector_client.update( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name - ) \ No newline at end of file + ) + \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_upsert.py b/tests/standard/sync/test_vector_client_upsert.py index a00119a4..c5488609 100644 --- a/tests/standard/sync/test_vector_client_upsert.py +++ b/tests/standard/sync/test_vector_client_upsert.py @@ -1,65 +1,74 @@ import pytest +from ...utils import key_strategy +from hypothesis import given, settings, Verbosity + class upsert_test_case: def __init__( self, *, namespace, - key, record_data, set_name ): self.namespace = namespace - self.key = key self.record_data = record_data self.set_name = set_name - +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ upsert_test_case( namespace="test", - key="upsert/1", record_data={"math": [i for i in range(1024)]}, set_name=None ), upsert_test_case( namespace="test", - key="upsert/2", record_data={"english": [float(i) for i in range(1024)]}, set_name=None ), upsert_test_case( namespace="test", - key="upsert/3", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None ) ], ) -def test_vector_upsert_without_existing_record(session_vector_client, test_case): +def test_vector_upsert_without_existing_record(session_vector_client, test_case, random_key): session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name ) + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ upsert_test_case( namespace="test", - key="upsert/4", record_data={"math": [i for i in range(1024)]}, set_name=None ) ], ) -def test_vector_upsert_with_existing_record(session_vector_client, test_case): +def test_vector_upsert_with_existing_record(session_vector_client, test_case, random_key): session_vector_client.upsert( namespace=test_case.namespace, - key=test_case.key, + key=random_key, record_data=test_case.record_data, set_name=test_case.set_name + ) + + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, ) \ No newline at end of file diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 00000000..fc8e0b7e --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,67 @@ +import random +import hypothesis.strategies as st +from hypothesis import given +import string + +def random_int(): + return str(random.randint(0, 50_000)) + +allowed_chars = ( + list(string.ascii_lowercase) + # a-z + list(string.ascii_uppercase) + # A-Z + list(string.digits) + # 0-9 + ['_', '-', '$'] # _, -, $ +) + +def key_strategy(): + return st.text( + alphabet=allowed_chars, min_size=1, max_size=100_000 + ).filter(lambda ns: ns not in ['0', '1', 'null']) + +def bin_strategy(): + return st.text( + alphabet=allowed_chars, min_size=1, max_size=15 + ).filter(lambda ns: ns not in ['0', '1', 'null']) + +def index_strategy(): + return st.text( + alphabet=allowed_chars, min_size=1, max_size=63 + ).filter(lambda ns: ns not in ['null']) + +""" +TODO: Implement Hypothesis +# Define the allowed characters + + + +# Define the Hypothesis strategy for generating valid bin name strings (up to 15 bytes) +bin_name_strategy = st.text( + alphabet=allowed_chars, min_size=1, max_size=15 +).filter(lambda bn: bn != 'null') + + + +def set_strategy(): + return st.text( + alphabet=allowed_chars, min_size=1, max_size=63 + ).filter(lambda ns: ns != 'null') + +def index_strategy +(): + return st.text( + alphabet=allowed_chars, min_size=1, max_size=15 + ).filter(lambda ns: ns != 'null') + + + + +# Define strategies for generating test data using valid strings +namespace_strategy = valid_string_strategy +key_strategy = valid_string_strategy +record_data_strategy = st.dictionaries( + keys=valid_string_strategy, + values=st.lists(st.integers() | st.floats() | st.booleans(), min_size=1, max_size=1024) +) +set_name_strategy = st.none() | valid_string_strategy + +""" \ No newline at end of file From 4324c862d154f451bfb8f05f72a6e81164ae4d36 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 24 Jun 2024 09:09:26 -0600 Subject: [PATCH 014/215] Finializing RBAC Functionality and tests --- .../aio/internal/channel_provider.py | 23 +++--- .../shared/base_channel_provider.py | 1 - tests/rbac/aio/conftest.py | 21 ++---- tests/rbac/conftest.py | 35 +++++++++ tests/rbac/sync/__init__.py | 0 tests/rbac/sync/conftest.py | 30 ++++++++ tests/rbac/sync/test_admin_client_add_user.py | 75 +++++++++++++++++++ .../rbac/sync/test_admin_client_drop_user.py | 40 ++++++++++ tests/rbac/sync/test_admin_client_get_user.py | 38 ++++++++++ .../sync/test_admin_client_grant_roles.py | 50 +++++++++++++ .../rbac/sync/test_admin_client_list_roles.py | 38 ++++++++++ .../rbac/sync/test_admin_client_list_users.py | 40 ++++++++++ .../sync/test_admin_client_revoke_roles.py | 50 +++++++++++++ .../test_admin_client_update_credentials.py | 47 ++++++++++++ tests/standard/conftest.py | 31 ++++++++ tests/standard/sync/conftest.py | 12 ++- 16 files changed, 497 insertions(+), 34 deletions(-) create mode 100644 tests/rbac/conftest.py create mode 100644 tests/rbac/sync/__init__.py create mode 100644 tests/rbac/sync/conftest.py create mode 100644 tests/rbac/sync/test_admin_client_add_user.py create mode 100644 tests/rbac/sync/test_admin_client_drop_user.py create mode 100644 tests/rbac/sync/test_admin_client_get_user.py create mode 100644 tests/rbac/sync/test_admin_client_grant_roles.py create mode 100644 tests/rbac/sync/test_admin_client_list_roles.py create mode 100644 tests/rbac/sync/test_admin_client_list_users.py create mode 100644 tests/rbac/sync/test_admin_client_revoke_roles.py create mode 100644 tests/rbac/sync/test_admin_client_update_credentials.py create mode 100644 tests/standard/conftest.py diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 4004413a..011fc996 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -65,6 +65,8 @@ async def _tend(self): await self._update_token_and_ttl() if end_tend: + self._tend_initalized.set() + self._tend_ended.set() return @@ -169,17 +171,14 @@ def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.aio.Channe async def _update_token_and_ttl( self, ) -> None: - try: - (auth_stub, auth_request) = self._prepare_authenticate( - self._credentials, logger - ) + (auth_stub, auth_request) = self._prepare_authenticate( + self._credentials, logger + ) - try: - response = await auth_stub.Authenticate(auth_request) - except grpc.RpcError as e: - print("Failed with error: %s", e) - raise types.AVSServerError(rpc_error=e) + try: + response = await auth_stub.Authenticate(auth_request) + except grpc.RpcError as e: + print("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) - self._respond_authenticate(response.token) - except Exception as e: - print(e) \ No newline at end of file + self._respond_authenticate(response.token) \ No newline at end of file diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index f1551857..8d397bee 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -177,7 +177,6 @@ def _get_authenticate_request(self, credentials): def _respond_authenticate(self, token): payload = jwt.decode(token, "", algorithms=['RS256'], options={"verify_signature": False}) - print(payload) self._ttl = self._get_ttl(payload) self._ttl_start = payload['exp'] diff --git a/tests/rbac/aio/conftest.py b/tests/rbac/aio/conftest.py index ef07c44a..962d9937 100644 --- a/tests/rbac/aio/conftest.py +++ b/tests/rbac/aio/conftest.py @@ -1,30 +1,25 @@ import pytest import asyncio - from aerospike_vector_search.aio import Client from aerospike_vector_search.aio.admin import Client as AdminClient from aerospike_vector_search import types -host = 'connector.aerospike.com' -port = 5000 - - -@pytest.fixture +@pytest.fixture(scope="module", autouse=True) def username(request): return request.config.getoption("--username") -@pytest.fixture +@pytest.fixture(scope="module", autouse=True) def password(request): return request.config.getoption("--password") -@pytest.fixture +@pytest.fixture(scope="module", autouse=True) def root_certificate(request): return request.config.getoption("--root_certificate") @pytest.fixture(scope="module", autouse=True) -async def drop_all_indexes(): +async def drop_all_indexes(username, password, root_certificate, host, port): async with AdminClient( - seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificate="/home/dpelini/Documents/prox/example/tls/connector.aerospike.com.crt", + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, ) as client: index_list = await client.index_list() @@ -32,17 +27,15 @@ async def drop_all_indexes(): for item in index_list: tasks.append(client.index_drop(namespace="test", name=item['id']['name'])) - await asyncio.gather(*tasks) @pytest.fixture(scope="module") -async def session_rbac_admin_client(): +async def session_rbac_admin_client(username, password, root_certificate, host, port): client = AdminClient( - seeds=types.HostPort(host=host, port=port), username="admin", password="admin", root_certificate="/home/dpelini/Documents/prox/example/tls/connector.aerospike.com.crt", + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, ) yield client await client.close() - diff --git a/tests/rbac/conftest.py b/tests/rbac/conftest.py new file mode 100644 index 00000000..70932fcb --- /dev/null +++ b/tests/rbac/conftest.py @@ -0,0 +1,35 @@ +import pytest +import asyncio +from aerospike_vector_search.aio import Client +from aerospike_vector_search.aio.admin import Client as AdminClient +from aerospike_vector_search import types + + +def pytest_addoption(parser): + parser.addoption("--username", action="store", default="admin", help="AVS Username") + parser.addoption("--password", action="store", default="admin", help="AVS Password") + parser.addoption("--host", action="store", default="localhost", help="AVS Host") + parser.addoption("--port", action="store", default=5000, help="AVS Port") + parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") + +@pytest.fixture(scope="module", autouse=True) +def username(request): + return request.config.getoption("--username") + +@pytest.fixture(scope="module", autouse=True) +def password(request): + return request.config.getoption("--password") + +@pytest.fixture(scope="module", autouse=True) +def root_certificate(request): + return request.config.getoption("--root_certificate") + + +@pytest.fixture(scope="module", autouse=True) +def host(request): + return request.config.getoption("--host") + +@pytest.fixture(scope="module", autouse=True) +def port(request): + return request.config.getoption("--port") + diff --git a/tests/rbac/sync/__init__.py b/tests/rbac/sync/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/rbac/sync/conftest.py b/tests/rbac/sync/conftest.py new file mode 100644 index 00000000..f5b3ddff --- /dev/null +++ b/tests/rbac/sync/conftest.py @@ -0,0 +1,30 @@ +import pytest + +from aerospike_vector_search import Client +from aerospike_vector_search.admin import Client as AdminClient +from aerospike_vector_search import types + + +@pytest.fixture(scope="module", autouse=True) +def drop_all_indexes(username, password, root_certificate, host, port): + with AdminClient( + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate + ) as client: + index_list = client.index_list() + + tasks = [] + for item in index_list: + client.index_drop(namespace="test", name=item['id']['name']) + + +@pytest.fixture(scope="module") +def session_rbac_admin_client(username, password, root_certificate, host, port): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, + ) + yield client + client.close() + + + + diff --git a/tests/rbac/sync/test_admin_client_add_user.py b/tests/rbac/sync/test_admin_client_add_user.py new file mode 100644 index 00000000..21c7a126 --- /dev/null +++ b/tests/rbac/sync/test_admin_client_add_user.py @@ -0,0 +1,75 @@ +import pytest +from ...utils import random_int + +class add_user_test_case: + def __init__( + self, + *, + username, + password, + roles, + ): + self.username = username + self.password = password + self.roles = roles + +@pytest.mark.parametrize( + "test_case", + [ + add_user_test_case( + username="aio-add-user-" + str(random_int()), + password="alphanumeric", + roles=None + ), + ], +) +def test_add_user(session_rbac_admin_client, test_case): + session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=test_case.roles + + ) + + result = session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == [] + +@pytest.mark.parametrize( + "test_case", + [ + add_user_test_case( + username="aio-add-user-" + str(random_int()), + password="eu123#$%", + roles=["admin"] + ), + add_user_test_case( + username="aio-add-user-" + str(random_int()), + password="radical", + roles=["read-write"] + ), + add_user_test_case( + username="aio-add-user-" + str(random_int()), + password="marshall", + roles=["admin", "read-write"] + ), + ], +) +def test_add_user_with_roles(session_rbac_admin_client, test_case): + session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=test_case.roles + ) + + result = session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == test_case.roles diff --git a/tests/rbac/sync/test_admin_client_drop_user.py b/tests/rbac/sync/test_admin_client_drop_user.py new file mode 100644 index 00000000..ef45208a --- /dev/null +++ b/tests/rbac/sync/test_admin_client_drop_user.py @@ -0,0 +1,40 @@ +import pytest +from ...utils import random_int +from aerospike_vector_search import AVSServerError +import grpc + +class drop_user_test_case: + def __init__( + self, + *, + username, + password, + ): + self.username = username + self.password = password + +@pytest.mark.parametrize( + "test_case", + [ + drop_user_test_case( + username="aio-drop-user-" + str(random_int()), + password="tallyho", + ), + ], +) +def test_drop_user(session_rbac_admin_client, test_case): + session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=None + + ) + session_rbac_admin_client.drop_user( + username=test_case.username, + + ) + with pytest.raises(AVSServerError) as e_info: + result = session_rbac_admin_client.get_user( + username=test_case.username + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.NOT_FOUND diff --git a/tests/rbac/sync/test_admin_client_get_user.py b/tests/rbac/sync/test_admin_client_get_user.py new file mode 100644 index 00000000..2ea401c1 --- /dev/null +++ b/tests/rbac/sync/test_admin_client_get_user.py @@ -0,0 +1,38 @@ +import pytest +from ...utils import random_int + + +class get_user_test_case: + def __init__( + self, + *, + username, + password, + ): + self.username = username + self.password = password + +@pytest.mark.parametrize( + "test_case", + [ + get_user_test_case( + username="aio-drop-user-" + str(random_int()), + password="tallyho", + ), + ], +) +def test_get_user(session_rbac_admin_client, test_case): + session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=None + + ) + + result = session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == [] diff --git a/tests/rbac/sync/test_admin_client_grant_roles.py b/tests/rbac/sync/test_admin_client_grant_roles.py new file mode 100644 index 00000000..85dc031d --- /dev/null +++ b/tests/rbac/sync/test_admin_client_grant_roles.py @@ -0,0 +1,50 @@ +import pytest +from ...utils import random_int + + +class grant_roles_test_case: + def __init__( + self, + *, + username, + password, + roles, + granted_roles + ): + self.username = username + self.password = password + self.roles = roles + self.granted_roles = granted_roles + +@pytest.mark.parametrize( + "test_case", + [ + grant_roles_test_case( + username="aio-update-credentials-" + str(random_int()), + password="yeoldpassword", + roles=[], + granted_roles=["admin", "read-write"] + ), + ], +) +def test_grant_roles(session_rbac_admin_client, test_case): + session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=test_case.roles + + ) + + session_rbac_admin_client.grant_roles( + username=test_case.username, + roles=test_case.granted_roles + ) + + result = session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == test_case.granted_roles + diff --git a/tests/rbac/sync/test_admin_client_list_roles.py b/tests/rbac/sync/test_admin_client_list_roles.py new file mode 100644 index 00000000..e88c72ca --- /dev/null +++ b/tests/rbac/sync/test_admin_client_list_roles.py @@ -0,0 +1,38 @@ +import pytest +from ...utils import random_int + + +class list_roles_test_case: + def __init__( + self, + *, + username, + password, + roles, + ): + self.username = username + self.password = password + self.roles = roles + +@pytest.mark.parametrize( + "test_case", + [ + list_roles_test_case( + username="aio-list-roles-" + str(random_int()), + password="yeoldpassword", + roles=["admin", "read-write"] + ), + ], +) +def test_list_roles(session_rbac_admin_client, test_case): + session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=test_case.roles + + ) + + result = session_rbac_admin_client.list_roles() + for role in result: + assert role.id in test_case.roles + diff --git a/tests/rbac/sync/test_admin_client_list_users.py b/tests/rbac/sync/test_admin_client_list_users.py new file mode 100644 index 00000000..1ac7f1b0 --- /dev/null +++ b/tests/rbac/sync/test_admin_client_list_users.py @@ -0,0 +1,40 @@ +import pytest +from ...utils import random_int + + +class list_users_test_case: + def __init__( + self, + *, + username, + password + ): + self.username = username + self.password = password + +@pytest.mark.parametrize( + "test_case", + [ + list_users_test_case( + username="aio-list-user-" + str(random_int()), + password="sample", + ), + ], +) +def test_list_users(session_rbac_admin_client, test_case): + session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=None + + ) + + result = session_rbac_admin_client.list_users() + user_found = False + for user in result: + if user.username == test_case.username: + assert user.roles == [] + user_found = True + + assert user_found + diff --git a/tests/rbac/sync/test_admin_client_revoke_roles.py b/tests/rbac/sync/test_admin_client_revoke_roles.py new file mode 100644 index 00000000..16a5367d --- /dev/null +++ b/tests/rbac/sync/test_admin_client_revoke_roles.py @@ -0,0 +1,50 @@ +import pytest +from ...utils import random_int + + +class revoke_roles_test_case: + def __init__( + self, + *, + username, + password, + roles, + revoked_roles + ): + self.username = username + self.password = password + self.roles = roles + self.revoked_roles = revoked_roles + +@pytest.mark.parametrize( + "test_case", + [ + revoke_roles_test_case( + username="aio-revoke-roles-" + str(random_int()), + password="yeoldpassword", + roles=["admin", "read-write"], + revoked_roles=[] + ), + ], +) +def test_revoke_roles(session_rbac_admin_client, test_case): + session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.password, + roles=test_case.roles + + ) + + session_rbac_admin_client.revoke_roles( + username=test_case.username, + roles=test_case.roles + ) + + result = session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == test_case.revoked_roles + diff --git a/tests/rbac/sync/test_admin_client_update_credentials.py b/tests/rbac/sync/test_admin_client_update_credentials.py new file mode 100644 index 00000000..a66d8a9d --- /dev/null +++ b/tests/rbac/sync/test_admin_client_update_credentials.py @@ -0,0 +1,47 @@ +import pytest +from ...utils import random_int + + +class update_credentials_test_case: + def __init__( + self, + *, + username, + old_password, + new_password + ): + self.username = username + self.old_password = old_password + self.new_password = new_password + +@pytest.mark.parametrize( + "test_case", + [ + update_credentials_test_case( + username="aio-update-credentials-" + str(random_int()), + old_password="yeoldpassword", + new_password="newpass", + ), + ], +) +def test_update_credentials(session_rbac_admin_client, test_case): + session_rbac_admin_client.add_user( + username=test_case.username, + password=test_case.old_password, + roles=None + + ) + + session_rbac_admin_client.update_credentials( + username=test_case.username, + password=test_case.new_password, + ) + + result = session_rbac_admin_client.get_user( + username=test_case.username + ) + + assert result.username == test_case.username + + assert result.roles == [] + diff --git a/tests/standard/conftest.py b/tests/standard/conftest.py new file mode 100644 index 00000000..53bc6bb5 --- /dev/null +++ b/tests/standard/conftest.py @@ -0,0 +1,31 @@ +import pytest + + +def pytest_addoption(parser): + parser.addoption("--username", action="store", default="admin", help="AVS Username") + parser.addoption("--password", action="store", default="admin", help="AVS Password") + parser.addoption("--host", action="store", default="localhost", help="AVS Host") + parser.addoption("--port", action="store", default=5000, help="AVS Port") + parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") + +@pytest.fixture(scope="module", autouse=True) +def username(request): + return request.config.getoption("--username") + +@pytest.fixture(scope="module", autouse=True) +def password(request): + return request.config.getoption("--password") + +@pytest.fixture(scope="module", autouse=True) +def root_certificate(request): + return request.config.getoption("--root_certificate") + + +@pytest.fixture(scope="module", autouse=True) +def host(request): + return request.config.getoption("--host") + +@pytest.fixture(scope="module", autouse=True) +def port(request): + return request.config.getoption("--port") + diff --git a/tests/standard/sync/conftest.py b/tests/standard/sync/conftest.py index 4792d6c6..a7c8a175 100644 --- a/tests/standard/sync/conftest.py +++ b/tests/standard/sync/conftest.py @@ -3,11 +3,9 @@ from aerospike_vector_search.admin import Client as AdminClient from aerospike_vector_search import types -host = 'localhost' -port = 5000 -@pytest.fixture(scope="session", autouse=True) -def drop_all_indexes(): +@pytest.fixture(scope="module", autouse=True) +def drop_all_indexes(host, port): with AdminClient( seeds=types.HostPort(host=host, port=port) @@ -21,7 +19,7 @@ def drop_all_indexes(): @pytest.fixture(scope="module") -def session_admin_client(): +def session_admin_client(host, port): client = AdminClient( seeds=types.HostPort(host=host, port=port) ) @@ -29,7 +27,7 @@ def session_admin_client(): client.close() @pytest.fixture(scope="module") -def session_vector_client(): +def session_vector_client(host, port): client = Client( seeds=types.HostPort(host=host, port=port) ) @@ -37,7 +35,7 @@ def session_vector_client(): client.close() @pytest.fixture -def function_admin_client(): +def function_admin_client(host, port): client = AdminClient( seeds=types.HostPort(host=host, port=port) ) From 8ba080f58aa926bbb5d39c3a8e352d2e595fadcf Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 2 Jul 2024 11:42:06 -0600 Subject: [PATCH 015/215] MTLS dirty commit Commit for Rahul to look through --- src/aerospike_vector_search/admin.py | 4 +- src/aerospike_vector_search/aio/admin.py | 4 +- src/aerospike_vector_search/aio/client.py | 4 +- .../aio/internal/channel_provider.py | 184 ++++++++++-------- src/aerospike_vector_search/client.py | 4 +- .../internal/channel_provider.py | 20 +- .../shared/base_channel_provider.py | 4 +- tests/rbac/aio/conftest.py | 17 +- tests/rbac/conftest.py | 16 +- tests/rbac/sync/conftest.py | 8 +- tests/standard/aio/conftest.py | 39 ++-- tests/standard/conftest.py | 12 +- 12 files changed, 200 insertions(+), 116 deletions(-) diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index 3a096bef..827d0c5d 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -26,6 +26,8 @@ def __init__( username: Optional[str] = None, password: Optional[str] = None, root_certificate: Optional[str] = None, + certificate_chain: Optional[str] = None, + private_key: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Admin Client. @@ -42,7 +44,7 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate + seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key ) def index_create( diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index 3b4a57e3..053a4528 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -27,6 +27,8 @@ def __init__( username: Optional[str] = None, password: Optional[str] = None, root_certificate: Optional[str] = None, + certificate_chain: Optional[str] = None, + private_key: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Admin Client. @@ -43,7 +45,7 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate + seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key ) async def index_create( diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index a9882ef2..39928d11 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -30,6 +30,8 @@ def __init__( username: Optional[str] = None, password: Optional[str] = None, root_certificate: Optional[str] = None, + certificate_chain: Optional[str] = None, + private_key: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Vector Client. @@ -47,7 +49,7 @@ def __init__( """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate + seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key ) async def insert( diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 011fc996..4ab9eb0c 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -30,9 +30,11 @@ def __init__( username: Optional[str] = None, password: Optional[str] = None, root_certificate: Optional[str] = None, + certificate_chain: Optional[str] = None, + private_key: Optional[str] = None, ) -> None: - super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate) + super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key) self._tend_initalized: asyncio.Event = asyncio.Event() self._tend_ended: asyncio.Event = asyncio.Event() @@ -58,109 +60,125 @@ async def _is_ready(self): await self._tend_initalized.wait() async def _tend(self): - (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() - - if self._token: - if self._check_if_token_refresh_needed(): - await self._update_token_and_ttl() - - if end_tend: - self._tend_initalized.set() + try: + (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() - self._tend_ended.set() - return + if self._token: + if self._check_if_token_refresh_needed(): + await self._update_token_and_ttl() - stubs = [] - tasks = [] + if end_tend: + self._tend_initalized.set() - for channel in channels: + self._tend_ended.set() + return - stub = vector_db_pb2_grpc.ClusterInfoStub(channel) - stubs.append(stub) - try: - tasks.append(stub.GetClusterId(empty, credentials=self._token)) - except Exception as e: - logger.debug( - "While tending, failed to get cluster id with error:" + str(e) - ) - - try: - new_cluster_ids = await asyncio.gather(*tasks) - except Exception as e: - logger.debug( - "While tending, failed to gather results from GetClusterId:" + str(e) - ) + stubs = [] + tasks = [] - for index, value in enumerate(new_cluster_ids): - if self.check_cluster_id(value.id): - update_endpoints_stub = stubs[index] - break + for channel in channels: + stub = vector_db_pb2_grpc.ClusterInfoStub(channel) + stubs.append(stub) + try: + tasks.append(await stub.GetClusterId(empty, credentials=self._token)) + except Exception as e: + logger.debug( + "While tending, failed to get cluster id with error:" + str(e) + ) - if update_endpoints_stub: try: - response = await update_endpoints_stub.GetClusterEndpoints( - vector_db_pb2.ClusterNodeEndpointsRequest( - listenerName=self.listener_name - ), - credentials=self._token - ) - temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) + new_cluster_ids = tasks except Exception as e: logger.debug( - "While tending, failed to get cluster endpoints with error:" - + str(e) + "While tending, failed to gather results from GetClusterId:" + str(e) ) - tasks = [] - add_new_channel_info = [] - - for node, newEndpoints in temp_endpoints.items(): - (channel_endpoints, add_new_channel) = self.check_for_new_endpoints( - node, newEndpoints - ) - - if add_new_channel: - try: - # TODO: Wait for all calls to drain - tasks.append(channel_endpoints.channel.close()) - except Exception as e: - logger.debug( - "While tending, failed to close GRPC channel:" + str(e) - ) - add_new_channel_info.append((node, newEndpoints)) - - for node, newEndpoints in add_new_channel_info: - self.add_new_channel_to_node_channels(node, newEndpoints) - - for node, channel_endpoints in list(self._node_channels.items()): - if not self._node_channels.get(node): - try: - # TODO: Wait for all calls to drain - tasks.append(channel_endpoints.channel.close()) - del self._node_channels[node] + for index, value in enumerate(new_cluster_ids): + if self.check_cluster_id(value.id): + update_endpoints_stub = stubs[index] + break + + + if update_endpoints_stub: + try: + response = await update_endpoints_stub.GetClusterEndpoints( + vector_db_pb2.ClusterNodeEndpointsRequest( + listenerName=self.listener_name + ), + credentials=self._token + ) + temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) + except Exception as e: + logger.debug( + "While tending, failed to get cluster endpoints with error:" + + str(e) + ) + + tasks = [] + add_new_channel_info = [] + + for node, newEndpoints in temp_endpoints.items(): + (channel_endpoints, add_new_channel) = self.check_for_new_endpoints( + node, newEndpoints + ) + + if add_new_channel: + try: + # TODO: Wait for all calls to drain + tasks.append(channel_endpoints.channel.close()) + except Exception as e: + logger.debug( + "While tending, failed to close GRPC channel:" + str(e) + ) + add_new_channel_info.append((node, newEndpoints)) + + for node, newEndpoints in add_new_channel_info: + self.add_new_channel_to_node_channels(node, newEndpoints) + + for node, channel_endpoints in list(self._node_channels.items()): + if not self._node_channels.get(node): + try: + # TODO: Wait for all calls to drain + tasks.append(channel_endpoints.channel.close()) + del self._node_channels[node] + + except Exception as e: + logger.debug( + "While tending, failed to close GRPC channel:" + str(e) + ) + + await asyncio.gather(*tasks) - except Exception as e: - logger.debug( - "While tending, failed to close GRPC channel:" + str(e) - ) - - await asyncio.gather(*tasks) - - self._tend_initalized.set() + self._tend_initalized.set() - # TODO: check tend interval. - await asyncio.sleep(1) - self._task = asyncio.create_task(self._tend()) + # TODO: check tend interval. + await asyncio.sleep(1) + self._task = asyncio.create_task(self._tend()) + except Exception as e: + print(e) - def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.aio.Channel: + def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: host = re.sub(r"%.*", "", host) if self._root_certificate: with open(self._root_certificate, 'rb') as f: root_certificate = f.read() - ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate) + if self._private_key: + with open(self._private_key, 'rb') as f: + private_key = f.read() + else: + private_key = None + + if self._certificate_chain: + with open(self._certificate_chain, 'rb') as f: + certificate_chain = f.read() + else: + certificate_chain = None + + + ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate, certificate_chain=certificate_chain, private_key=private_key) return grpc.aio.secure_channel(f"{host}:{port}", ssl_credentials) diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index e7215653..f8c786d9 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -29,6 +29,8 @@ def __init__( username: Optional[str] = None, password: Optional[str] = None, root_certificate: Optional[str] = None, + certificate_chain: Optional[str] = None, + private_key: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Vector Client. @@ -46,7 +48,7 @@ def __init__( """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate + seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key ) def insert( diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index bce3a839..3e6dd2cd 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -27,9 +27,11 @@ def __init__( is_loadbalancer: Optional[bool] = False, username: Optional[str] = None, password: Optional[str] = None, - root_certificate: Optional[str] = None + root_certificate: Optional[str] = None, + certificate_chain: Optional[str] = None, + private_key: Optional[str] = None, ) -> None: - super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate) + super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key) self._tend_ended = threading.Event() self._timer = None self._tend() @@ -126,7 +128,19 @@ def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: with open(self._root_certificate, 'rb') as f: root_certificate = f.read() - ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate) + if self._private_key: + with open(self._private_key, 'rb') as f: + private_key = f.read() + else: + private_key = None + + if self._certificate_chain: + with open(self._certificate_chain, 'rb') as f: + certificate_chain = f.read() + else: + certificate_chain = None + + ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate, certificate_chain=certificate_chain, private_key=private_key) return grpc.secure_channel(f"{host}:{port}", ssl_credentials) diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index 8d397bee..e2f8ed55 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -38,8 +38,8 @@ def __init__( username: Optional[str] = None, password: Optional[str] = None, root_certificate: Optional[str] = None, + certificate_chain: Optional[str] = None, private_key: Optional[str] = None, - public_key: Optional[str] = None ) -> None: self.seeds: tuple[types.HostPort, ...] = seeds self.listener_name: Optional[str] = listener_name @@ -50,6 +50,8 @@ def __init__( else: self._token = None self._root_certificate = root_certificate + self._certificate_chain = certificate_chain + self._private_key = private_key self._ttl = 0 self._ttl_start = 0 self._ttl_threshold = 0.9 diff --git a/tests/rbac/aio/conftest.py b/tests/rbac/aio/conftest.py index 962d9937..dad08115 100644 --- a/tests/rbac/aio/conftest.py +++ b/tests/rbac/aio/conftest.py @@ -17,9 +17,18 @@ def root_certificate(request): return request.config.getoption("--root_certificate") @pytest.fixture(scope="module", autouse=True) -async def drop_all_indexes(username, password, root_certificate, host, port): +def private_key(request): + return request.config.getoption("--private_key") + +@pytest.fixture(scope="module", autouse=True) +def certificate_chain(request): + return request.config.getoption("--certificate_chain") + + +@pytest.fixture(scope="module", autouse=True) +async def drop_all_indexes(username, password, host, port, root_certificate, certificate_chain, private_key): async with AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: index_list = await client.index_list() @@ -30,9 +39,9 @@ async def drop_all_indexes(username, password, root_certificate, host, port): await asyncio.gather(*tasks) @pytest.fixture(scope="module") -async def session_rbac_admin_client(username, password, root_certificate, host, port): +async def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): client = AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) yield client await client.close() diff --git a/tests/rbac/conftest.py b/tests/rbac/conftest.py index 70932fcb..329d0a6d 100644 --- a/tests/rbac/conftest.py +++ b/tests/rbac/conftest.py @@ -1,8 +1,4 @@ import pytest -import asyncio -from aerospike_vector_search.aio import Client -from aerospike_vector_search.aio.admin import Client as AdminClient -from aerospike_vector_search import types def pytest_addoption(parser): @@ -11,6 +7,9 @@ def pytest_addoption(parser): parser.addoption("--host", action="store", default="localhost", help="AVS Host") parser.addoption("--port", action="store", default=5000, help="AVS Port") parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") + parser.addoption("--certificate_chain", action="store", default=None, help="Path to certificate chain") + parser.addoption("--private_key", action="store", default=None, help="Path to private key") + @pytest.fixture(scope="module", autouse=True) def username(request): @@ -20,11 +19,18 @@ def username(request): def password(request): return request.config.getoption("--password") +@pytest.fixture(scope="module", autouse=True) +def private_key(request): + return request.config.getoption("--private_key") + +@pytest.fixture(scope="module", autouse=True) +def certificate_chain(request): + return request.config.getoption("--certificate_chain") + @pytest.fixture(scope="module", autouse=True) def root_certificate(request): return request.config.getoption("--root_certificate") - @pytest.fixture(scope="module", autouse=True) def host(request): return request.config.getoption("--host") diff --git a/tests/rbac/sync/conftest.py b/tests/rbac/sync/conftest.py index f5b3ddff..6d084552 100644 --- a/tests/rbac/sync/conftest.py +++ b/tests/rbac/sync/conftest.py @@ -6,9 +6,9 @@ @pytest.fixture(scope="module", autouse=True) -def drop_all_indexes(username, password, root_certificate, host, port): +def drop_all_indexes(username, password, root_certificate, host, port, certificate_chain, private_key): with AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: index_list = client.index_list() @@ -18,9 +18,9 @@ def drop_all_indexes(username, password, root_certificate, host, port): @pytest.fixture(scope="module") -def session_rbac_admin_client(username, password, root_certificate, host, port): +def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): client = AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) yield client client.close() diff --git a/tests/standard/aio/conftest.py b/tests/standard/aio/conftest.py index 4b386384..638263ff 100644 --- a/tests/standard/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -4,13 +4,30 @@ from aerospike_vector_search.aio.admin import Client as AdminClient from aerospike_vector_search import types -host = 'localhost' -port = 5000 +@pytest.fixture(scope="module", autouse=True) +def private_key(request): + return request.config.getoption("--private_key") -@pytest.fixture(scope="session", autouse=True) -async def drop_all_indexes(): +@pytest.fixture(scope="module", autouse=True) +def certificate_chain(request): + return request.config.getoption("--certificate_chain") + +@pytest.fixture(scope="module", autouse=True) +def root_certificate(request): + return request.config.getoption("--root_certificate") + +@pytest.fixture(scope="module", autouse=True) +def username(request): + return request.config.getoption("--username") + +@pytest.fixture(scope="module", autouse=True) +def password(request): + return request.config.getoption("--password") + +@pytest.fixture(scope="module", autouse=True) +async def drop_all_indexes(host, port, username, password, root_certificate, certificate_chain, private_key): async with AdminClient( - seeds=types.HostPort(host=host, port=port) + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: index_list = await client.index_list() @@ -24,25 +41,25 @@ async def drop_all_indexes(): @pytest.fixture(scope="module") -async def session_admin_client(): +async def session_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key): client = AdminClient( - seeds=types.HostPort(host=host, port=port) + seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password ) yield client await client.close() @pytest.fixture(scope="module") -async def session_vector_client(): +async def session_vector_client(host, port, username, password, root_certificate, certificate_chain, private_key): client = Client( - seeds=types.HostPort(host=host, port=port) + seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password ) yield client await client.close() @pytest.fixture -async def function_admin_client(): +async def function_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key): client = AdminClient( - seeds=types.HostPort(host=host, port=port) + seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password ) yield client await client.close() diff --git a/tests/standard/conftest.py b/tests/standard/conftest.py index 53bc6bb5..329d0a6d 100644 --- a/tests/standard/conftest.py +++ b/tests/standard/conftest.py @@ -7,6 +7,9 @@ def pytest_addoption(parser): parser.addoption("--host", action="store", default="localhost", help="AVS Host") parser.addoption("--port", action="store", default=5000, help="AVS Port") parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") + parser.addoption("--certificate_chain", action="store", default=None, help="Path to certificate chain") + parser.addoption("--private_key", action="store", default=None, help="Path to private key") + @pytest.fixture(scope="module", autouse=True) def username(request): @@ -16,11 +19,18 @@ def username(request): def password(request): return request.config.getoption("--password") +@pytest.fixture(scope="module", autouse=True) +def private_key(request): + return request.config.getoption("--private_key") + +@pytest.fixture(scope="module", autouse=True) +def certificate_chain(request): + return request.config.getoption("--certificate_chain") + @pytest.fixture(scope="module", autouse=True) def root_certificate(request): return request.config.getoption("--root_certificate") - @pytest.fixture(scope="module", autouse=True) def host(request): return request.config.getoption("--host") From e962e27878ea6303b41c0641d75549d35b367312 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 08:20:59 -0600 Subject: [PATCH 016/215] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab346708..f761ee69 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Python client for Aerospike Vector Search Database ## Prerequisites - - Python 3.9 or higher + - Python 3.9 or higher - pip version 9.0.1 or higher - Aerospike Vector Search DB and Aerospike clusters running. From 8d6a8842557e48d91df4a2893dbe7e55d44f21aa Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 08:34:41 -0600 Subject: [PATCH 017/215] Added jwt to requirements.txt --- README.md | 2 +- requirements.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f761ee69..ab346708 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Python client for Aerospike Vector Search Database ## Prerequisites - - Python 3.9 or higher + - Python 3.9 or higher - pip version 9.0.1 or higher - Aerospike Vector Search DB and Aerospike clusters running. diff --git a/requirements.txt b/requirements.txt index 4a325020..2f233963 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ grpcio protobuf -sphinx_rtd_theme \ No newline at end of file +sphinx_rtd_theme +jwt \ No newline at end of file From 57e8082e3f2cbe41320a0c6bda308e30fd398023 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 08:40:01 -0600 Subject: [PATCH 018/215] Update requirements.txt --- tests/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/requirements.txt b/tests/requirements.txt index 483b5812..e977eea7 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,4 +1,5 @@ numpy==1.26.4 pytest==7.4.0 pytest-aio==1.5.0 +jwt .. \ No newline at end of file From 2a96ccd3e6d4fa7c59df53a69a1c047d7241bf31 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 08:43:25 -0600 Subject: [PATCH 019/215] Fixed jwt install --- requirements.txt | 2 +- tests/requirements.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 2f233963..a10a9a08 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ grpcio protobuf sphinx_rtd_theme -jwt \ No newline at end of file +pyjwt \ No newline at end of file diff --git a/tests/requirements.txt b/tests/requirements.txt index e977eea7..483b5812 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,5 +1,4 @@ numpy==1.26.4 pytest==7.4.0 pytest-aio==1.5.0 -jwt .. \ No newline at end of file From f30771cf457e9ca8275c9bcb735c508da3b550c9 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 08:44:49 -0600 Subject: [PATCH 020/215] Update requirements.txt --- tests/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/requirements.txt b/tests/requirements.txt index 483b5812..bd1b5946 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,4 +1,5 @@ numpy==1.26.4 pytest==7.4.0 pytest-aio==1.5.0 +pyjwt .. \ No newline at end of file From 290e0bba0d16cf783ddba16341ec32b98068bcb6 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 08:47:17 -0600 Subject: [PATCH 021/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 5ff27ba2..cdb3dc29 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -45,5 +45,5 @@ jobs: - name: Run unit tests run: | - python -m pytest -s + python -m pytest standard -s working-directory: tests \ No newline at end of file From 0f8be024fa87fbd42ec94a0a687ef01605b75540 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 08:49:00 -0600 Subject: [PATCH 022/215] Update requirements.txt --- tests/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/requirements.txt b/tests/requirements.txt index bd1b5946..c8defcde 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -2,4 +2,5 @@ numpy==1.26.4 pytest==7.4.0 pytest-aio==1.5.0 pyjwt +hypothesis .. \ No newline at end of file From a236810bf033dd7d5f9573203d586b6efb8bc448 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 08:51:23 -0600 Subject: [PATCH 023/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index cdb3dc29..7bcfa10e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -45,5 +45,5 @@ jobs: - name: Run unit tests run: | - python -m pytest standard -s + python -m pytest standard/sync -s working-directory: tests \ No newline at end of file From f17748532e6e03e12bc6f82a528125c0d31e5def Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 08:56:53 -0600 Subject: [PATCH 024/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 7bcfa10e..da5f0820 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -33,6 +33,7 @@ jobs: - name: Start Aerospike Proximus run: | docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 + docker ps working-directory: tests From d72c10a382826b10fae150d36c81cff0f6298fc6 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:08:34 -0600 Subject: [PATCH 025/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index da5f0820..6595bea6 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -24,18 +24,6 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Start Aerospike Server - run: | - docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - working-directory: tests - - - - name: Start Aerospike Proximus - run: | - docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 - docker ps - working-directory: tests - - name: Install dependencies run: | @@ -46,5 +34,8 @@ jobs: - name: Run unit tests run: | + docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 + docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + sleep 10 python -m pytest standard/sync -s working-directory: tests \ No newline at end of file From 5417615d327ddd062aae6a2a496199b971c2a734 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:12:31 -0600 Subject: [PATCH 026/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 6595bea6..b0e49c61 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -36,6 +36,8 @@ jobs: run: | docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - sleep 10 + sleep 5 + docker ps + sleep 5 python -m pytest standard/sync -s working-directory: tests \ No newline at end of file From 2039ccf1d4cea2c63c02a32529f3bfbff0ee157d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:16:18 -0600 Subject: [PATCH 027/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index b0e49c61..c3c10001 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -34,8 +34,8 @@ jobs: - name: Run unit tests run: | - docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 - docker run -d --network=host --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + docker run -d -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 5 docker ps sleep 5 From 207122ea88807592612da32bc11fd08abf05c1ac Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:19:51 -0600 Subject: [PATCH 028/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c3c10001..5987b171 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -35,8 +35,11 @@ jobs: - name: Run unit tests run: | docker run -d -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 + sleep 5 + docker logs aerospike-proximus docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 5 + docker logs aerospike docker ps sleep 5 python -m pytest standard/sync -s From af213cf7d7d6a5e1447736b6fdb006dac1d72996 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:21:12 -0600 Subject: [PATCH 029/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 5987b171..4a20a53e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -35,6 +35,7 @@ jobs: - name: Run unit tests run: | docker run -d -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 + docker ps sleep 5 docker logs aerospike-proximus docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest From 76792842e55468db9e50e9078d1a64d70a125fdc Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:23:16 -0600 Subject: [PATCH 030/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 4a20a53e..40dcb5e3 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -35,7 +35,33 @@ jobs: - name: Run unit tests run: | docker run -d -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 + sleep 1 docker ps + docker logs aerospike-proximus + + sleep 1 + docker ps + docker logs aerospike-proximus + + sleep 1 + docker ps + docker logs aerospike-proximus + + sleep 1 + docker ps + docker logs aerospike-proximus + + sleep 1 + docker ps + docker logs aerospike-proximus + sleep 1 + docker ps + docker logs aerospike-proximus + + sleep 1 + docker ps + docker logs aerospike-proximus + sleep 5 docker logs aerospike-proximus docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest From a83b4ddde33cf4b86d390cf8721bc9b3187e2c0e Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:26:05 -0600 Subject: [PATCH 031/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 40dcb5e3..a0cc3b26 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -34,7 +34,7 @@ jobs: - name: Run unit tests run: | - docker run -d -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 + docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 sleep 1 docker ps docker logs aerospike-proximus @@ -61,7 +61,7 @@ jobs: sleep 1 docker ps docker logs aerospike-proximus - + sleep 5 docker logs aerospike-proximus docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest From 42c7ecebbc69d5221054f91b9796476b47ae7464 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:35:22 -0600 Subject: [PATCH 032/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index a0cc3b26..6993b94a 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -64,7 +64,7 @@ jobs: sleep 5 docker logs aerospike-proximus - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server:latest sleep 5 docker logs aerospike docker ps From 67786c85e6f67d3e2b357498b42c83957baa6c8d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:46:57 -0600 Subject: [PATCH 033/215] Added features.conf to secrets --- .gitattributes | 1 - .github/workflows/integration_test.yml | 43 +++++++------------------ tests/features.conf | Bin 1298 -> 0 bytes 3 files changed, 11 insertions(+), 33 deletions(-) delete mode 100644 .gitattributes delete mode 100644 tests/features.conf diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index e15c51de..00000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -tests/features.conf filter=git-crypt diff=git-crypt diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 6993b94a..75b92663 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -32,42 +32,21 @@ jobs: pip install -r requirements.txt working-directory: tests - - name: Run unit tests - run: | - docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 - sleep 1 - docker ps - docker logs aerospike-proximus - - sleep 1 - docker ps - docker logs aerospike-proximus - - sleep 1 - docker ps - docker logs aerospike-proximus - - sleep 1 - docker ps - docker logs aerospike-proximus - sleep 1 - docker ps - docker logs aerospike-proximus - sleep 1 - docker ps - docker logs aerospike-proximus + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests - sleep 1 - docker ps - docker logs aerospike-proximus - sleep 5 - docker logs aerospike-proximus + - name: Run unit tests + run: | + docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server:latest - sleep 5 - docker logs aerospike + sleep 10 docker ps - sleep 5 python -m pytest standard/sync -s working-directory: tests \ No newline at end of file diff --git a/tests/features.conf b/tests/features.conf deleted file mode 100644 index 025109466de6d2d5f476abcc1978353327d87ec9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1298 zcmV+t1?~C(M@dveQdv+`0BQ!~1W}be=#dK~uT8`R+YhI$?aI8e7k)rOkasG!B)+XNf8)*D%6E!!h(uATf#h3jog{DWTw%_@ zLEs)hma=F@qG4b=8|M_eHa;gdviUAi`Gd=M3m-^4M5Y(Uk0`t)CRDz8tR|0$8oMPE zl2JptEST-Sp^O6HT6EFNvM$3bPEsMCEEfmZ5NV^f2?Wl04Wq7b{F0 z@Vo^ikO{w@?%5C~Hq6-$fSFsao`vHjI3PPtl8@-Hpx?Bt+iAd*-ovPjv{Q33Z6r?+ z>^nxA8LqFVxrJfx8%S)UniulPdkf=Yr>qj~?IF+eRT1KzsdEoqsOupP$7C%TcIjfx zP-*k4+dgVCx7LBHgyj?;{s6TG9!iTZDkl=*J0)a$NYeWTU}=8k6b`>#9}0^9dS16g z*_O@p_kb1@|Hv|{^joO?8uLRJEP8pCW}?S$-PhV*Eddit=Z|unuuKnWc7o0KmViG# z%^9wcr}%L02EqEn*{0K7w^+eLApHon!Uy9=7T4`0N|*LMNZkA;4YT~K7HT!l#<;KT z{wtxoa`QNpxSIOsL=4U?O2ch&FFlUU!{AY~R$^%6vXBr$sjuW ze$Rl7o!=?4_neMw8aUziOBB#TdC2qI28{p=46YmDjR7zdTP`O&LhvMM@QT~`)sjaU zp!q{!Py#l;NtKw0NrX8Y9~6DF|5CkiSC#IW*?HY>Q@2X}zFeoEUcfg2bZ-t0f@*iy z`AYYout7i{`QS~QdPQL9_>1S#PUo_X*qu&7-+()4}^VvGjC#Lq6pd_mru!TRVDgJTY1sPfV%FDHm02;94S_|AgUrAs` zmCHVorGrcOkM(wKF3R7-S>Ij59U^lw6zYj5hB(Xso?lzF5cq+Q-6!cN!rZL81VTQa zRn7EYJ@~S2RVFDhF1=6Gj)Y^=c#&K=JRu&ZpduRn$i*aL?)*QH?%HcC(E2Cautz!(t&js=nrX5 z6T}RzApH}z+n~g`(ArZ#^gcdAm^TZDfPXtOmez>+Mm-KW@VHjXZZdvcaY32jG%KPd zrGh0d`7l;Id;)phAb?DV2qqv+Cde}1#aMh_PxbzVu*#^8D2v|s#YmvM9|K`C#pO4- IM)Bs*8a>vFR{#J2 From f6f0f4dd82c9d2dc3d30cbb02d48360cb3f0a3ea Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 09:58:30 -0600 Subject: [PATCH 034/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 75b92663..d68a6dce 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -37,7 +37,7 @@ jobs: env: FEATURE_FILE: ${{ secrets.FEATURE_FILE }} run: | - echo $FEATURE_FILE | base64 --decode > features.conf + echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests From 21a97a889760053ac3ac41457423d4c582477d93 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 10:03:28 -0600 Subject: [PATCH 035/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index d68a6dce..f4161041 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -37,6 +37,7 @@ jobs: env: FEATURE_FILE: ${{ secrets.FEATURE_FILE }} run: | + echo $FEATURE_FILE echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests From 82072d4701c6ef7cb4cb7c43ded24cf60b40101a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 10:09:42 -0600 Subject: [PATCH 036/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index f4161041..d68a6dce 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -37,7 +37,6 @@ jobs: env: FEATURE_FILE: ${{ secrets.FEATURE_FILE }} run: | - echo $FEATURE_FILE echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests From 2e918b46e33baf00fddb4d35c356c387b65bd3d0 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 10:11:41 -0600 Subject: [PATCH 037/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index d68a6dce..dff856ba 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -46,7 +46,19 @@ jobs: docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server:latest - sleep 10 + + docker logs aerospike + sleep 1 + + docker logs aerospike + sleep 1 + + docker logs aerospike + sleep 1 + + docker logs aerospike + sleep 1 + docker ps python -m pytest standard/sync -s working-directory: tests \ No newline at end of file From 1117beed2e5290924d5a00027de3083c436f3962 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 10:13:06 -0600 Subject: [PATCH 038/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index dff856ba..dd9d58a1 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -45,7 +45,7 @@ jobs: run: | docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server:latest + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest docker logs aerospike sleep 1 @@ -58,7 +58,7 @@ jobs: docker logs aerospike sleep 1 - + docker ps python -m pytest standard/sync -s working-directory: tests \ No newline at end of file From 552cca521c4fdd20c616e931a2c3befa7012e26c Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 8 Jul 2024 10:22:11 -0600 Subject: [PATCH 039/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index dd9d58a1..f30b6e8a 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -40,10 +40,16 @@ jobs: echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} - name: Run unit tests run: | - docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike/aerospike-proximus:0.4.0 + docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest @@ -57,7 +63,7 @@ jobs: sleep 1 docker logs aerospike - sleep 1 + sleep 10 docker ps python -m pytest standard/sync -s From 88b3595212c84d326f4648c67c0e47c3c2e4d2d3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 9 Jul 2024 08:30:55 -0600 Subject: [PATCH 040/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index f30b6e8a..2c8e42cb 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -51,20 +51,10 @@ jobs: run: | docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - docker logs aerospike - sleep 1 - - docker logs aerospike - sleep 1 - - docker logs aerospike - sleep 1 - - docker logs aerospike sleep 10 docker ps - python -m pytest standard/sync -s + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 working-directory: tests \ No newline at end of file From aef3eb759b0a32a44e4a00925d89efac81ae14bb Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 9 Jul 2024 08:43:55 -0600 Subject: [PATCH 041/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 2c8e42cb..9b27c12a 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -49,7 +49,7 @@ jobs: - name: Run unit tests run: | - docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --network=host -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest From 30eac7beed9d6f201ca4beaaad6c96ed6bcadf2b Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 10:56:58 -0600 Subject: [PATCH 042/215] auth_tls testing --- .github/workflows/integration_test.yml | 63 +++- .gitignore | 8 +- tests/__init__.py | 0 tests/aerospike-proximus.yml | 106 ++++-- tests/aerospike.conf | 11 +- tests/assets/aerospike-proximus.yml | 122 ++++++ tests/assets/aerospike.conf | 72 ++++ tests/assets/call_gen.sh | 15 + tests/assets/security_stanza.txt | 5 + tests/assets/service_stanza.txt | 9 + tests/assets/template.cnf | 364 ++++++++++++++++++ tests/assets/tls_stanza.txt | 13 + tests/gen.sh | 493 +++++++++++++++++++++++++ 13 files changed, 1253 insertions(+), 28 deletions(-) delete mode 100644 tests/__init__.py create mode 100755 tests/assets/aerospike-proximus.yml create mode 100755 tests/assets/aerospike.conf create mode 100755 tests/assets/call_gen.sh create mode 100755 tests/assets/security_stanza.txt create mode 100755 tests/assets/service_stanza.txt create mode 100755 tests/assets/template.cnf create mode 100755 tests/assets/tls_stanza.txt create mode 100755 tests/gen.sh diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 9b27c12a..643003c2 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -6,7 +6,7 @@ on: - dev jobs: - test: + test-normal: runs-on: ubuntu-latest @@ -57,4 +57,65 @@ jobs: docker ps python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 + working-directory: tests + + + test-tls-auth: + runs-on: ubuntu-latest + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: create config + run: | + assets/call_gen.sh + + - name: Run unit tests + run: | + docker run -d --network=host -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + sudo docker run --network=host -p 5000:5000 -v $(pwd)/aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v $(pwd)/features.conf:/etc/aerospike-proximus/features.conf -v $(pwd)/tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 10 + + docker ps + python -m pytest standard/sync -s --host brawn --port 5000 -root_certificate root.crt --private_key brawn.key.pem --certificate_chain brawn.crt -vs + working-directory: tests \ No newline at end of file diff --git a/.gitignore b/.gitignore index e9ab1de3..3c8ce17e 100644 --- a/.gitignore +++ b/.gitignore @@ -158,8 +158,14 @@ cython_debug/ # Vector search test files tests/siftsmall/* tests/siftsmall.tar.gz +tests/aerospike-proximus.yml +tests/aerospike.conf +tests/features.conf +tests/assets/features.conf +tests/tls/* # Notes notes.txt -public-key.asc \ No newline at end of file +public-key.asc + diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml index ab79d385..450eee96 100644 --- a/tests/aerospike-proximus.yml +++ b/tests/aerospike-proximus.yml @@ -1,13 +1,50 @@ # Change the configuration for your use case. -# TODO: Link to Proximus docs +# See: https://aerospike.com/docs/vector cluster: - # Custom node-id. It will be auto-generated if not specified. - # node-id: a1 - # Unique identifier for this cluster. cluster-name: aerospike-proximus - node-id: ffffffffffffffff + + # Custom node-id as 8 byte long in Hexadecimal format. + # It will be auto-generated if not specified. + # node-id: a1 + +# If TLS is desired, TLS configuration ids used +# and associated TLS configurations. +# +tls: + service-tls: + trust-store: + store-file: /etc/aerospike-proximus/tls/root.truststore.jks + store-password-file: /etc/aerospike-proximus/tls/storepass + key-store: + store-file: /etc/aerospike-proximus/tls/brawn.keystore.jks + store-password-file: /etc/aerospike-proximus/tls/storepass + key-password-file: /etc/aerospike-proximus/tls/keypass + mutual-auth: true + # Client certificate subject names that are allowed + allowed-peer-names: + - brawn +# interconnect-tls: +# trust-store: +# store-file: tls/ca.aerospike.com.truststore.jks +# store-password-file: tls/storepass +# key-store: +# store-file: tls/proximus.aerospike.com.keystore.jks +# store-password-file: tls/storepass +# key-password-file: tls/keypass +# override-tls-hostname: proximus.aerospike.com +# +# aerospike-tls: +# trust-store: +# store-file: tls/ca.aerospike.com.truststore.jks +# store-password-file: tls/storepass +# key-store: +# store-file: tls/proximus.aerospike.com.keystore.jks +# store-password-file: tls/storepass +# key-password-file: tls/keypass +# override-tls-hostname: asd.aerospike.com + # The Proximus service listening ports, TLS and network interface. service: @@ -15,43 +52,70 @@ service: 5000: addresses: localhost - # Required when running behind NAT - #advertised-listeners: - # default: - # # List of externally accessible addresses and ports for this Proximus instance. - # - address: 10.0.0.1 - # port: 5000 - + # If TLS needs to be enabled, tls configuration id. + tls-id: service-tls + # Required when running behind NAT + advertised-listeners: + default: + # List of externally accessible addresses and + # ports for this Proximus instance. + - address: brawn + port: 5000 # Management API listening ports, TLS and network interface. manage: ports: - 5040: { } + 5040: + addresses: + localhost + # If TLS needs to be enabled, tls configuration id. + #tls-id: service-tls + # Intra cluster interconnect listening ports, TLS and network interface. interconnect: + # Interconnect client side TLS configuration + # when TLS is enabled for interconnect + # client-tls-id: interconnect-tls ports: 5001: addresses: localhost + # If interconnect TLS needs to be enabled. + #tls-id: interconnect-tls #heartbeat: +# # Seed nodes to discover and form a cluster. # seeds: # - address: localhost # port: 6001 +# To enable client authentication + +security: + auth-token: + private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem + public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem + token-expiry: 300_000 + # Target Aerospike cluster aerospike: seeds: - localhost: port: 3000 + client-policy: + max-conns-per-node: 1000 + #tls-id: aerospike-tls + # + # Aerospike credentials if required. + #credentials: + # username: admin + # password-file: aerospike-password.txt + # The logging properties. -logging: - #format: json - #file: /var/log/aerospike-proximus/aerospike-proximus.log - enable-console-logging: true - levels: - com.aerospike.vector.index.cache.IndexCacheCoordinator: debug - # metrics-ticker: info - # root: debug \ No newline at end of file +#logging: +# #file: /var/log/aerospike-proximus/aerospike-proximus.log +# enable-console-logging: true +# levels: +# root: debug diff --git a/tests/aerospike.conf b/tests/aerospike.conf index 4e7bc9ad..a7c979df 100644 --- a/tests/aerospike.conf +++ b/tests/aerospike.conf @@ -13,10 +13,10 @@ service { } logging { - - - - + + + + # Send log messages to stdout console { @@ -68,4 +68,5 @@ namespace test { data-size 1G } nsup-period 60 -} \ No newline at end of file +} + diff --git a/tests/assets/aerospike-proximus.yml b/tests/assets/aerospike-proximus.yml new file mode 100755 index 00000000..0b6fe595 --- /dev/null +++ b/tests/assets/aerospike-proximus.yml @@ -0,0 +1,122 @@ +# Change the configuration for your use case. +# See: https://aerospike.com/docs/vector + +cluster: + # Unique identifier for this cluster. + cluster-name: aerospike-proximus + + # Custom node-id as 8 byte long in Hexadecimal format. + # It will be auto-generated if not specified. + # node-id: a1 + +# If TLS is desired, TLS configuration ids used +# and associated TLS configurations. +# +#tls: +# service-tls: +# trust-store: +# store-file: /etc/aerospike-proximus/tls/$root_certificate_name.truststore.jks +# store-password-file: /etc/aerospike-proximus/tls/storepass +# key-store: +# store-file: /etc/aerospike-proximus/tls/$server_name.keystore.jks +# store-password-file: /etc/aerospike-proximus/tls/storepass +# key-password-file: /etc/aerospike-proximus/tls/keypass +# mutual-auth: true +# # Client certificate subject names that are allowed +# allowed-peer-names: +# - $client_name +# interconnect-tls: +# trust-store: +# store-file: tls/ca.aerospike.com.truststore.jks +# store-password-file: tls/storepass +# key-store: +# store-file: tls/proximus.aerospike.com.keystore.jks +# store-password-file: tls/storepass +# key-password-file: tls/keypass +# override-tls-hostname: proximus.aerospike.com +# +# aerospike-tls: +# trust-store: +# store-file: tls/ca.aerospike.com.truststore.jks +# store-password-file: tls/storepass +# key-store: +# store-file: tls/proximus.aerospike.com.keystore.jks +# store-password-file: tls/storepass +# key-password-file: tls/keypass +# override-tls-hostname: asd.aerospike.com + + +# The Proximus service listening ports, TLS and network interface. +service: + ports: + 5000: + addresses: + localhost + # If TLS needs to be enabled, tls configuration id. + #tls-id: service-tls + + # Required when running behind NAT + #advertised-listeners: + # default: + # # List of externally accessible addresses and + # # ports for this Proximus instance. + # - address: $server_name + # port: 5000 + +# Management API listening ports, TLS and network interface. +manage: + ports: + 5040: + addresses: + localhost + # If TLS needs to be enabled, tls configuration id. + #tls-id: service-tls + + +# Intra cluster interconnect listening ports, TLS and network interface. +interconnect: + # Interconnect client side TLS configuration + # when TLS is enabled for interconnect + # client-tls-id: interconnect-tls + ports: + 5001: + addresses: + localhost + # If interconnect TLS needs to be enabled. + #tls-id: interconnect-tls + +#heartbeat: +# # Seed nodes to discover and form a cluster. +# seeds: +# - address: localhost +# port: 6001 + +# To enable client authentication + +#security: +# auth-token: +# private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem +# public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem +# token-expiry: 300_000 + +# Target Aerospike cluster +aerospike: + seeds: + - localhost: + port: 3000 + + client-policy: + max-conns-per-node: 1000 + #tls-id: aerospike-tls + # + # Aerospike credentials if required. + #credentials: + # username: admin + # password-file: aerospike-password.txt + +# The logging properties. +#logging: +# #file: /var/log/aerospike-proximus/aerospike-proximus.log +# enable-console-logging: true +# levels: +# root: debug diff --git a/tests/assets/aerospike.conf b/tests/assets/aerospike.conf new file mode 100755 index 00000000..a7c979df --- /dev/null +++ b/tests/assets/aerospike.conf @@ -0,0 +1,72 @@ + +# Aerospike database configuration file +# This template sets up a single-node, single namespace developer environment. +# +# Alternatively, you can pass in your own configuration file. +# You can see more examples at +# https://github.com/aerospike/aerospike-server/tree/master/as/etc + +# This stanza must come first. +service { + feature-key-file /etc/aerospike/features.conf + cluster-name proximus +} + +logging { + + + + + + # Send log messages to stdout + console { + context any info + } +} + +network { + service { + address any + port 3000 + + # Uncomment the following to set the 'access-address' parameter to the + # IP address of the Docker host. This will the allow the server to correctly + # publish the address which applications and other nodes in the cluster to + # use when addressing this node. + # access-address + } + + heartbeat { + # mesh is used for environments that do not support multicast + mode mesh + address local + port 3002 + interval 150 + timeout 10 + } + + fabric { + # Intra-cluster communication port (migrates, replication, etc) + # default to same address in 'service' + address local + port 3001 + } + +} + +namespace proximus-meta { + replication-factor 2 +storage-engine memory { + data-size 2G +} +nsup-period 100 +} + +namespace test { + replication-factor 2 + storage-engine memory { + data-size 1G + } + nsup-period 60 +} + diff --git a/tests/assets/call_gen.sh b/tests/assets/call_gen.sh new file mode 100755 index 00000000..42d18b41 --- /dev/null +++ b/tests/assets/call_gen.sh @@ -0,0 +1,15 @@ +./gen.sh \ + --tls_maybe y \ + --rbac_maybe y \ + --root_certificate_maybe y \ + --root_certificate_name root \ + --specify_details_maybe n \ + --openssl_cnf_maybe n \ + --password citrusstore \ + --key_pair_maybe y \ + --key_password citrusstore \ + --mutual_auth_maybe y \ + --client_name brawn \ + --server_name brawn \ + --port 5000 \ + --host brawn diff --git a/tests/assets/security_stanza.txt b/tests/assets/security_stanza.txt new file mode 100755 index 00000000..0d394039 --- /dev/null +++ b/tests/assets/security_stanza.txt @@ -0,0 +1,5 @@ +security: + auth-token: + private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem + public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem + token-expiry: 300_000 diff --git a/tests/assets/service_stanza.txt b/tests/assets/service_stanza.txt new file mode 100755 index 00000000..810fc65b --- /dev/null +++ b/tests/assets/service_stanza.txt @@ -0,0 +1,9 @@ + tls-id: service-tls + + # Required when running behind NAT + advertised-listeners: + default: + # List of externally accessible addresses and + # ports for this Proximus instance. + - address: brawn + port: 5000 diff --git a/tests/assets/template.cnf b/tests/assets/template.cnf new file mode 100755 index 00000000..edeae268 --- /dev/null +++ b/tests/assets/template.cnf @@ -0,0 +1,364 @@ +# +# OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +# Extra OBJECT IDENTIFIER info: +#oid_file = $ENV::HOME/.oid +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +# Policies used by the TSA examples. +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./ # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several ctificates with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/ca.aerospike.com.cert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/ca.aerospike.com.key.pem# The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extentions to add to the cert + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = AU +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = Some-State + +localityName = Locality Name (eg, city) + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Internet Widgits Pty Ltd + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (e.g. server FQDN or YOUR name) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ server_cert ] +# Extensions for server certificates (`man x509v3_config`). +basicConstraints = CA:FALSE +nsCertType = server +nsComment = "OpenSSL Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +keyUsage = critical, digitalSignature, keyEncipherment +extendedKeyUsage = serverAuth + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This is required for TSA certificates. +# extendedKeyUsage = critical,timeStamping + +[ v3_req ] + +# Extensions to add to a certificate request + +# basicConstraints = CA:TRUE +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment +# subjectAltName = @alt_names + +# [ alt_names ] + +[ v3_ca ] +basicConstraints = critical, CA:TRUE +keyUsage = critical, digitalSignature, cRLSign, keyCertSign + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +# basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ proxy_cert_ext ] +# These extensions should be added when creating a proxy certificate + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This really needs to be in place for it to be a proxy certificate. +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + +#################################################################### +[ tsa ] + +default_tsa = tsa_config1 # the default TSA section + +[ tsa_config1 ] + +# These are used by the TSA reply generation only. +dir = ./ # TSA root directory +serial = $dir/tsaserial # The current serial number (mandatory) +crypto_device = builtin # OpenSSL engine to use for signing +signer_cert = $dir/tsacert.pem # The TSA signing certificate + # (optional) +certs = $dir/cacert.pem # Certificate chain to include in reply + # (optional) +signer_key = $dir/private/tsakey.pem # The TSA private key (optional) + +default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) +other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) +digests = md5, sha1 # Acceptable message digests (mandatory) +accuracy = secs:1, millisecs:500, microsecs:100 # (optional) +clock_precision_digits = 0 # number of digits after dot. (optional) +ordering = yes # Is ordering defined for timestamps? + # (optional, default: no) +tsa_name = yes # Must the TSA name be included in the reply? + # (optional, default: no) +ess_cert_id_chain = no # Must the ESS cert id chain be included? + # (optional, default: no) diff --git a/tests/assets/tls_stanza.txt b/tests/assets/tls_stanza.txt new file mode 100755 index 00000000..adfb24cb --- /dev/null +++ b/tests/assets/tls_stanza.txt @@ -0,0 +1,13 @@ +tls: + service-tls: + trust-store: + store-file: /etc/aerospike-proximus/tls/root.truststore.jks + store-password-file: /etc/aerospike-proximus/tls/storepass + key-store: + store-file: /etc/aerospike-proximus/tls/brawn.keystore.jks + store-password-file: /etc/aerospike-proximus/tls/storepass + key-password-file: /etc/aerospike-proximus/tls/keypass + mutual-auth: true + # Client certificate subject names that are allowed + allowed-peer-names: + - brawn diff --git a/tests/gen.sh b/tests/gen.sh new file mode 100755 index 00000000..423425f9 --- /dev/null +++ b/tests/gen.sh @@ -0,0 +1,493 @@ +#!/bin/bash + +function generate_derivative_certs() { + + openssl genrsa -out $1.key 2048 + openssl rsa -in $1.key -out $1.key.pem + openssl rsa -aes256 -in $1.key.pem -out $1.key.encrypted.pem -passout file:tls/storepass + + openssl req -new -sha256 -key $1.key.pem -subj "/C=IN/ST=KA/O=Aerospike, Inc./CN=$1" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:$1,DNS:*.$1")) -out $1.csr + + openssl x509 -req -in $1.csr -CA $root_certificate_path -CAkey $root_certificate_key_path -CAcreateserial -out $1.crt -days 3650 -sha256 -extensions SAN -extfile <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:$1,DNS:*.$1")) + + # export certificate to pkcs12 + openssl pkcs12 -export -out $1.p12 -in $1.crt -inkey $1.key.pem -password file:tls/storepass + + chmod 777 $1.p12 + + # import pkcs12 into a keystore + keytool -importkeystore -srckeystore $1.p12 -destkeystore $1.keystore.jks -srcstoretype pkcs12 -srcstorepass citrusstore -deststorepass citrusstore -noprompt + + openssl x509 -noout -text -in $1.crt + + if [[ "$1" != "$2" ]]; then + openssl genrsa -out $2.key 2048 + openssl rsa -in $2.key -out $2.key.pem + openssl rsa -aes256 -in $2.key.pem -out $2.key.encrypted.pem -passout file:tls/storepass + + openssl req -new -sha256 -key $2.key.pem -subj "/C=IN/ST=KA/O=Aerospike, Inc./CN=$2" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:$2,DNS:*.$2")) -out $2.csr + + openssl x509 -req -in $2.csr -CA $root_certificate_path -CAkey $root_certificate_key_path -CAcreateserial -out $2.crt -days 3650 -sha256 -extensions SAN -extfile <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:$2,DNS:*.$2")) + + # export certificate to pkcs12 + openssl pkcs12 -export -out $2.p12 -in $2.crt -inkey $2.key.pem -password file:tls/storepass + + chmod 777 $2.p12 + + # import pkcs12 into a keystore + keytool -importkeystore -srckeystore $2.p12 -destkeystore $2.keystore.jks -srcstoretype pkcs12 -srcstorepass citrusstore -deststorepass citrusstore -noprompt + + openssl x509 -noout -text -in $2.crt + fi +} + +tls_maybe="" +rbac_maybe="" +root_certificate_maybe="" +root_certificate_name="" +specify_details_maybe="" +openssl_cnf_maybe="" +config="" +password="" +key_pair_maybe="" +key_password="" +mutual_auth_maybe="" +client_name="" +server_name="" +port="" +host="" + + +while [[ $# -gt 0 ]]; do + case $1 in + --tls_maybe) + tls_maybe="$2" + shift 2 + ;; + --rbac_maybe) + rbac_maybe="$2" + shift 2 + ;; + --root_certificate_maybe) + root_certificate_maybe="$2" + shift 2 + ;; + --root_certificate_name) + root_certificate_name="$2" + shift 2 + ;; + --specify_details_maybe) + specify_details_maybe="$2" + shift 2 + ;; + --openssl_cnf_maybe) + openssl_cnf_maybe="$2" + shift 2 + ;; + --config) + config="$2" + shift 2 + ;; + --password) + password="$2" + shift 2 + ;; + --key_pair_maybe) + key_pair_maybe="$2" + shift 2 + ;; + --key_password) + key_password="$2" + shift 2 + ;; + --mutual_auth_maybe) + mutual_auth_maybe="$2" + shift 2 + ;; + --client_name) + client_name="$2" + shift 2 + ;; + --server_name) + server_name="$2" + shift 2 + ;; + --port) + port="$2" + shift 2 + ;; + --host) + host="$2" + shift 2 + ;; + + *) + echo "Unknown parameter passed: $1" + exit 1 + ;; + esac +done + + +echo "Final values:" +echo "tls_maybe: $tls_maybe" +echo "rbac_maybe: $rbac_maybe" +echo "root_certificate_maybe: $root_certificate_maybe" +echo "root_certificate_name: $root_certificate_name" +echo "specify_details_maybe: $specify_details_maybe" +echo "openssl_cnf_maybe: $openssl_cnf_maybe" +echo "config: $config" +echo "password: $password" +echo "key_pair_maybe: $key_pair_maybe" +echo "key_password: $key_password" +echo "mutual_auth_maybe: $mutual_auth_maybe" +echo "client_name: $client_name" +echo "server_name: $server_name" +echo "port: $port" +echo "host: $host" + + +rm -rf tls +mkdir -p tls +mkdir -p tls/jwt +cp assets/aerospike-proximus.yml aerospike-proximus.yml +cp assets/aerospike.conf aerospike.conf +cp assets/features.conf features.conf + +echo "Welcome to the AVS Configuration generator" + +if [[ "$tls_maybe" == "" ]]; then + + read -p "Would you like to configure your server for TLS? (y/n): " tls_maybe +fi + +if [[ "$tls_maybe" != "y" && "$tls_maybe" != "n" ]]; then + echo "INVALID INPUT: must enter 'y' or 'n' " + exit 1 +fi + +if [[ "$rbac_maybe" == "" ]]; then + + read -p "Would you like to configure your server for Role-Based Access Control? (y/n): " rbac_maybe +fi + +if [[ "$rbac_maybe" != "y" && "$rbac_maybe" != "n" ]]; then + echo "INVALID INPUT: must enter 'y' or 'n' " + exit 1 +fi + +if [[ "$rbac_maybe" == "y" ]]; then + if [[ "$tls_maybe" == "n" ]]; then + echo "INVALID CONFIGURATION: TLS is required when using Role-Based Access Control" + exit 1 + fi +fi + + + +if [[ "$tls_maybe" == "y" ]]; then + if [[ "$root_certificate_maybe" == "" ]]; then + + read -p "Do you want to generate a root certificate? (y/n): " root_certificate_maybe + fi + if [[ "$root_certificate_maybe" == "y" ]]; then + if [[ "$root_certificate_name" == "" ]]; then + + read -p "What would you like the root certificate prefix to be " root_certificate_name + fi + if [[ "$specify_details_maybe" == "" ]]; then + + read -p "Do you want to specify details for certificate generation? (y/n): " specify_details_maybe + fi + + if [[ "$specify_details_maybe" == "y" ]]; then + read -p "Country Name (2 letter code) [AU]: " country + read -p "State or Province Name (full name) [Some-State]: " state + read -p "Locality Name (eg, city) []: " city + read -p "Organization Name (eg, company) [Internet Widgits Pty Ltd]: " organization + read -p "Organizational Unit Name (eg, section) []: " unit + read -p "Common Name (e.g. server FQDN or YOUR name) []: " common_name + read -p "Email Address []: " email + fi + + if [[ "$specify_details_maybe" != "n" ]]; then + echo "INVALID INPUT: 'y' or 'n' required" + exit 1 + fi + + + country=${country:-US} + state=${state:-SD} + city=${city:-Spearfish} + organization=${organization:-Aerospike} + unit=${unit:-$Client SDK Team} + common_name=${common_name:-aerospike-proximus} + email=${email:-dpelini@aerospike.com} + + subj="/C=$country/ST=$state/L=$city/O=$organization/OU=$unit/CN=$common_name/emailAddress=$email" + + echo $root_certificate_name + openssl genrsa -out $root_certificate_name.key 2048 + openssl rsa -in $root_certificate_name.key -out $root_certificate_name.key.pem + + # Generate a new self-signed certificate + openssl req -new -x509 -key $root_certificate_name.key.pem -out $root_certificate_name.crt -days 3650 -sha256 -subj "$subj" + + if [[ "$openssl_cnf_maybe" == "" ]]; then + + read -p "Would you like to specify an openssl configuration file" openssl_cnf_maybe + + fi + + if [[ "$openssl_cnf_maybe" == "y" ]]; then + if [[ "$config" == "" ]]; then + + read -p "What is the path of the config file" config + + fi + + + elif [[ "$openssl_cnf_maybe" == "n" ]]; then + config="assets/template.cnf" + else + echo "INVALID INPUT: 'y' or 'n' required" + exit 1 + fi + openssl req -config $config \ + -key $root_certificate_name.key.pem \ + -new -x509 -days 7300 -sha256 -extensions v3_ca \ + -out $root_certificate_name.cert.pem \ + -subj "$subj" + + if [[ "$password" == "" ]]; then + + read -sp "Set the password for the keystore/truststore file: " password + fi + + touch tls/storepass + touch tls/keypass + + chmod 777 tls/storepass + chmod 777 tls/keypass + + echo $password > tls/storepass + echo $password > tls/keypass + + keytool -import -file $root_certificate_name.crt --storepass citrusstore -keystore $root_certificate_name.truststore.jks -alias $root_certificate_name -noprompt + openssl x509 -noout -text -in $root_certificate_name.cert.pem + + root_certificate_path=$root_certificate_name.crt + root_certificate_key_path=$root_certificate_name.key.pem + + + + + + elif [[ "$root_certificate_maybe" == "n" ]]; then + if [[ "$root_certificate_path" == "" ]]; then + + read -p "What is the path of your pre-generated root_certificate: " root_certificate_path + + fi + if [[ "$root_certificate_key_path" == "" ]]; then + + read -p "What is the path of your pre-generated root_certificate key: " root_certificate_key_path + fi + else + echo "BRUHHHHHINVALID INPUT: 'y' or 'n' required" + exit 1 + fi + + if [[ "$rbac_maybe" == "y" ]]; then + if [[ "$key_pair_maybe" == "" ]]; then + read -p "Do you want to generate a key pair? (y/n): " key_pair_maybe + + if [[ "$key_password" == "" ]]; then + read -sp "Enter a password for your keypair? (y/n): " key_password + fi + + fi + + if [[ "$key_pair_maybe" == "y" ]]; then + echo $key_password + openssl genpkey -algorithm RSA -out tls/jwt/private_key.pem -pkeyopt rsa_keygen_bits:2048 + openssl rsa -in tls/jwt/private_key.pem -pubout -out tls/jwt/public_key.pem + + chmod 777 tls/jwt/private_key.pem + chmod 777 tls/jwt/public_key.pem + + security_stanza=$(cat < "assets/security_stanza.txt" + + + sed -i '95r assets/security_stanza.txt' aerospike-proximus.yml + + fi + fi + if [[ "$mutual_auth_maybe" == "" ]]; then + read -p "Would you like to enable mutual authentication TLS? (y/n): " mutual_auth_maybe + fi + + if [[ "$mutual_auth_maybe" == "y" ]]; then + if [[ "$client_name" == "" ]]; then + read -p "What would you like the client prefix to be " client_name + fi + if [[ "$server_name" == "" ]]; then + + read -p "What would you like the server prefix to be " server_name + fi + + generate_derivative_certs "$client_name" "$server_name" + + tls_stanza=$(cat < "assets/tls_stanza.txt" + + sed -i '14r assets/tls_stanza.txt' aerospike-proximus.yml + + if [[ "$port" == "" ]]; then + read -p "Specify a port address:" port + + fi + + service_stanza=$(cat < "assets/service_stanza.txt" + + sed -i '55r assets/service_stanza.txt' aerospike-proximus.yml + if [[ "$host" == "" ]]; then + read -p "Specify a host address:" host + + fi + line="$host $server_name" + + + # Check if the line exists in /etc/hosts + if ! grep -qF "$line" /etc/hosts; then + # Add the line to /etc/hosts + echo "$line" | sudo tee -a /etc/hosts > /dev/null + echo "Entry added to /etc/hosts." + fi + + elif [[ "$mutual_auth_maybe" == "n" ]]; then + generate_derivative_certs "child" "child" + + + tls_stanza=$(cat < "assets/tls_stanza.txt" + + sed -i '14r assets/tls_stanza.txt' aerospike-proximus.yml + if [[ "$port" == "" ]]; then + read -p "Specify a port address:" port + + fi + + service_stanza=$(cat < "assets/service_stanza.txt" + sed -i '55r assets/service_stanza.txt' aerospike-proximus.yml + + + + + if [[ "$host" == "" ]]; then + read -p "Specify a host address:" host + + fi + line="$host $server_name" + + + # Check if the line exists in /etc/hosts + if ! grep -qF "$line" /etc/hosts; then + # Add the line to /etc/hosts + echo "$line" | sudo tee -a /etc/hosts > /dev/null + echo "Entry added to /etc/hosts." + fi + fi +fi + + + +shopt -s extglob # Enable extended globbing + +mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py) tls/ + +mv tls/gen.sh gen.sh + +mv tls/aerospike-proximus.yml aerospike-proximus.yml + +mv tls/aerospike.conf aerospike.conf + +mv tls/features.conf features.conf + From 7d73368ddbe58febc146eefd26426e48cd68fd75 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 10:58:35 -0600 Subject: [PATCH 043/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 643003c2..7058cbbf 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -105,7 +105,8 @@ jobs: - name: create config run: | assets/call_gen.sh - + working-directory: tests + - name: Run unit tests run: | docker run -d --network=host -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT From 21b52180ad0df11403d11fee9289c15850e83bf4 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:04:13 -0600 Subject: [PATCH 044/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 7058cbbf..927cff67 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -106,13 +106,12 @@ jobs: run: | assets/call_gen.sh working-directory: tests - + - name: Run unit tests run: | docker run -d --network=host -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT - sudo docker run --network=host -p 5000:5000 -v $(pwd)/aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v $(pwd)/features.conf:/etc/aerospike-proximus/features.conf -v $(pwd)/tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run --network=host -p 5000:5000 -v $(pwd)/aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v $(pwd)/features.conf:/etc/aerospike-proximus/features.conf -v $(pwd)/tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 10 From 8df107cc1beb49399b7a380e8095ba146daee298 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:10:42 -0600 Subject: [PATCH 045/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 927cff67..c8b8174f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -109,9 +109,9 @@ jobs: - name: Run unit tests run: | - docker run -d --network=host -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run --network=host -p 5000:5000 -v $(pwd)/aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v $(pwd)/features.conf:/etc/aerospike-proximus/features.conf -v $(pwd)/tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 10 From 862157239eb0020ad0cd0708ca5952bc128e8e82 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:19:21 -0600 Subject: [PATCH 046/215] Update call_gen.sh --- tests/assets/call_gen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/assets/call_gen.sh b/tests/assets/call_gen.sh index 42d18b41..da5596ea 100755 --- a/tests/assets/call_gen.sh +++ b/tests/assets/call_gen.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host brawn + --host 0.0.0.0 From 9fe293da249d868c496396f583cf9e2f5b86b135 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:21:32 -0600 Subject: [PATCH 047/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c8b8174f..99c9da86 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -109,8 +109,8 @@ jobs: - name: Run unit tests run: | - docker run --network=host -p 5000:5000 -v $(pwd)/aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v $(pwd)/features.conf:/etc/aerospike-proximus/features.conf -v $(pwd)/tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --network=host -p 5000:5000 -v $(pwd)/aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v $(pwd)/features.conf:/etc/aerospike-proximus/features.conf -v $(pwd)/tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 10 From 02e9d83ffa1fd9a3aa20748475834b0ddf458567 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:23:54 -0600 Subject: [PATCH 048/215] Update gen.sh --- tests/gen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gen.sh b/tests/gen.sh index 423425f9..c10401bd 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -481,7 +481,7 @@ fi shopt -s extglob # Enable extended globbing -mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py) tls/ +mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py) tls/ mv tls/gen.sh gen.sh From cc627d161506f67429d6807b168fd1c9ee586b8a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:28:08 -0600 Subject: [PATCH 049/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 99c9da86..dd3efa37 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -110,7 +110,7 @@ jobs: - name: Run unit tests run: | - docker run -d --network=host -p 5000:5000 -v $(pwd)/aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v $(pwd)/features.conf:/etc/aerospike-proximus/features.conf -v $(pwd)/tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 10 From 8e6c13a9ffc1bd41a621c0eb7f8b18d4d5ad43f8 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:31:38 -0600 Subject: [PATCH 050/215] Added script for normal execurtion --- .github/workflows/integration_test.yml | 5 +++++ tests/assets/call_gen_normal.sh | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/assets/call_gen_normal.sh diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index dd3efa37..d2976bee 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -47,6 +47,11 @@ jobs: username: ${{ secrets.JFROG_USERNAME }} password: ${{ secrets.JFROG_PASSWORD }} + - name: create config + run: | + assets/call_gen_normal.sh + working-directory: tests + - name: Run unit tests run: | docker run -d --network=host -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT diff --git a/tests/assets/call_gen_normal.sh b/tests/assets/call_gen_normal.sh new file mode 100644 index 00000000..b5aeecb1 --- /dev/null +++ b/tests/assets/call_gen_normal.sh @@ -0,0 +1,15 @@ +./gen.sh \ + --tls_maybe n \ + --rbac_maybe n \ + --root_certificate_maybe y \ + --root_certificate_name root \ + --specify_details_maybe n \ + --openssl_cnf_maybe n \ + --password citrusstore \ + --key_pair_maybe y \ + --key_password citrusstore \ + --mutual_auth_maybe y \ + --client_name brawn \ + --server_name brawn \ + --port 5000 \ + --host 0.0.0.0 From e0439069ea3566d0863b9bf30ccc987bd37366bf Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:35:33 -0600 Subject: [PATCH 051/215] Update call_gen_normal.sh --- tests/assets/call_gen_normal.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tests/assets/call_gen_normal.sh diff --git a/tests/assets/call_gen_normal.sh b/tests/assets/call_gen_normal.sh old mode 100644 new mode 100755 From ac2209b3cc82a8e88ca9bff65fdba76ba777b7a7 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:52:30 -0600 Subject: [PATCH 052/215] Update utils.py --- tests/utils.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tests/utils.py diff --git a/tests/utils.py b/tests/utils.py old mode 100644 new mode 100755 From fc0fb246a999fab90860b1ef82725185c55adcc7 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 11:54:53 -0600 Subject: [PATCH 053/215] Create __init__.py --- tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b From c5b92d55069d41ca205b1c6814a93c8ed1c0edda Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 12:00:04 -0600 Subject: [PATCH 054/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index d2976bee..fa7cdebe 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -29,6 +29,8 @@ jobs: run: | python -m pip install --upgrade pip python setup.py + ls + ls siftsmall pip install -r requirements.txt working-directory: tests @@ -121,6 +123,6 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host brawn --port 5000 -root_certificate root.crt --private_key brawn.key.pem --certificate_chain brawn.crt -vs + python -m pytest standard/sync -s --host brawn --port 5000 -root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs working-directory: tests \ No newline at end of file From 1a3c60568e5b2cf3cd149dadc1c24344eb35941a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 12:06:12 -0600 Subject: [PATCH 055/215] Update gen.sh --- tests/gen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gen.sh b/tests/gen.sh index c10401bd..2920a402 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -481,7 +481,7 @@ fi shopt -s extglob # Enable extended globbing -mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py) tls/ +mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|siftsmall) tls/ mv tls/gen.sh gen.sh From 86ef6a24a02afff4135c28fdfd091ca1576b0c0a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 12:13:05 -0600 Subject: [PATCH 056/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index fa7cdebe..1dd9738e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -29,8 +29,6 @@ jobs: run: | python -m pip install --upgrade pip python setup.py - ls - ls siftsmall pip install -r requirements.txt working-directory: tests @@ -123,6 +121,6 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host brawn --port 5000 -root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs working-directory: tests \ No newline at end of file From 4a5a3855c4853d722b4dc24c3655fe14ea6b38c2 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 12:44:30 -0600 Subject: [PATCH 057/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 1dd9738e..1ce02a64 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -30,6 +30,8 @@ jobs: python -m pip install --upgrade pip python setup.py pip install -r requirements.txt + cat /etc/hosts + working-directory: tests @@ -58,6 +60,7 @@ jobs: docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + sleep 10 docker ps From ca8ca3a041ba04edcfc68e69dc7171bbc8a35b2b Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 12:47:14 -0600 Subject: [PATCH 058/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 1ce02a64..3115bce7 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -30,7 +30,6 @@ jobs: python -m pip install --upgrade pip python setup.py pip install -r requirements.txt - cat /etc/hosts working-directory: tests @@ -52,6 +51,8 @@ jobs: - name: create config run: | assets/call_gen_normal.sh + cat /etc/hosts + working-directory: tests - name: Run unit tests From a5cb481e9b8579d86a619c910154a65c8d8f7642 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 12:49:42 -0600 Subject: [PATCH 059/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 3115bce7..2758ceb2 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -114,6 +114,8 @@ jobs: - name: create config run: | assets/call_gen.sh + cat /etc/hosts + working-directory: tests - name: Run unit tests From 9f0b548191c662ddaff5d49a5e5148d927069135 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 13:02:09 -0600 Subject: [PATCH 060/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 2758ceb2..aa1519e1 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -121,9 +121,24 @@ jobs: - name: Run unit tests run: | - docker run -d --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + sleep 1 + docker logs aerospike-proximus + + sleep 1 + docker logs aerospike-proximus + + sleep 1 + docker logs aerospike-proximus + + sleep 1 + docker logs aerospike-proximus + + sleep 1 + docker logs aerospike-proximus + sleep 10 docker ps From 6953432c9a3f6edf4a1506f4fc149711d74c30a5 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 13:12:03 -0600 Subject: [PATCH 061/215] Update aerospike-proximus.yml --- tests/aerospike-proximus.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml index 450eee96..23186679 100644 --- a/tests/aerospike-proximus.yml +++ b/tests/aerospike-proximus.yml @@ -51,7 +51,7 @@ service: ports: 5000: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. tls-id: service-tls @@ -67,7 +67,7 @@ manage: ports: 5040: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -80,7 +80,7 @@ interconnect: ports: 5001: addresses: - localhost + 0.0.0.0 # If interconnect TLS needs to be enabled. #tls-id: interconnect-tls @@ -101,7 +101,7 @@ security: # Target Aerospike cluster aerospike: seeds: - - localhost: + - 0.0.0.0: port: 3000 client-policy: From 3e965d800a51f54761db86831e7ede36a5052b42 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 13:14:29 -0600 Subject: [PATCH 062/215] Update aerospike-proximus.yml --- tests/assets/aerospike-proximus.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/assets/aerospike-proximus.yml b/tests/assets/aerospike-proximus.yml index 0b6fe595..37d4333f 100755 --- a/tests/assets/aerospike-proximus.yml +++ b/tests/assets/aerospike-proximus.yml @@ -51,7 +51,7 @@ service: ports: 5000: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -68,7 +68,7 @@ manage: ports: 5040: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -81,14 +81,14 @@ interconnect: ports: 5001: addresses: - localhost + 0.0.0.0 # If interconnect TLS needs to be enabled. #tls-id: interconnect-tls #heartbeat: # # Seed nodes to discover and form a cluster. # seeds: -# - address: localhost +# - address: 0.0.0.0 # port: 6001 # To enable client authentication @@ -102,7 +102,7 @@ interconnect: # Target Aerospike cluster aerospike: seeds: - - localhost: + - 0.0.0.0: port: 3000 client-policy: From d692279179029d4be3c4225b6d788a9d168a91ab Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 13:34:35 -0600 Subject: [PATCH 063/215] update CI/CD --- .github/workflows/integration_test.yml | 9 +++++++-- tests/assets/aerospike-proximus.yml | 10 +++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index aa1519e1..8f53d32f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -111,11 +111,16 @@ jobs: password: ${{ secrets.JFROG_PASSWORD }} + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + - name: create config run: | assets/call_gen.sh cat /etc/hosts - working-directory: tests - name: Run unit tests @@ -138,7 +143,7 @@ jobs: sleep 1 docker logs aerospike-proximus - + sleep 10 docker ps diff --git a/tests/assets/aerospike-proximus.yml b/tests/assets/aerospike-proximus.yml index 37d4333f..0b6fe595 100755 --- a/tests/assets/aerospike-proximus.yml +++ b/tests/assets/aerospike-proximus.yml @@ -51,7 +51,7 @@ service: ports: 5000: addresses: - 0.0.0.0 + localhost # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -68,7 +68,7 @@ manage: ports: 5040: addresses: - 0.0.0.0 + localhost # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -81,14 +81,14 @@ interconnect: ports: 5001: addresses: - 0.0.0.0 + localhost # If interconnect TLS needs to be enabled. #tls-id: interconnect-tls #heartbeat: # # Seed nodes to discover and form a cluster. # seeds: -# - address: 0.0.0.0 +# - address: localhost # port: 6001 # To enable client authentication @@ -102,7 +102,7 @@ interconnect: # Target Aerospike cluster aerospike: seeds: - - 0.0.0.0: + - localhost: port: 3000 client-policy: From 781441dbce790d21b0b152d4c47d9eebbae72e67 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 13:52:24 -0600 Subject: [PATCH 064/215] Added tls config --- .github/workflows/integration_test.yml | 82 ++++++++++++++++++++++++++ tests/assets/call_gen_tls.sh | 15 +++++ 2 files changed, 97 insertions(+) create mode 100644 tests/assets/call_gen_tls.sh diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 8f53d32f..c8c55133 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -68,6 +68,88 @@ jobs: python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 working-directory: tests + test-tls: + runs-on: ubuntu-latest + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: create config + run: | + assets/call_gen_tls.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 1 + docker logs aerospike-proximus + + sleep 1 + docker logs aerospike-proximus + + sleep 1 + docker logs aerospike-proximus + + sleep 1 + docker logs aerospike-proximus + + sleep 1 + docker logs aerospike-proximus + + sleep 10 + + docker ps + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs + + working-directory: tests + test-tls-auth: runs-on: ubuntu-latest diff --git a/tests/assets/call_gen_tls.sh b/tests/assets/call_gen_tls.sh new file mode 100644 index 00000000..aec49e02 --- /dev/null +++ b/tests/assets/call_gen_tls.sh @@ -0,0 +1,15 @@ +./gen.sh \ + --tls_maybe y \ + --rbac_maybe n \ + --root_certificate_maybe y \ + --root_certificate_name root \ + --specify_details_maybe n \ + --openssl_cnf_maybe n \ + --password citrusstore \ + --key_pair_maybe y \ + --key_password citrusstore \ + --mutual_auth_maybe n \ + --client_name brawn \ + --server_name brawn \ + --port 5000 \ + --host 0.0.0.0 From 185a9361676195f4732822e7e0567c5275117730 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 14:03:07 -0600 Subject: [PATCH 065/215] Update call_gen_tls.sh --- tests/assets/call_gen_tls.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tests/assets/call_gen_tls.sh diff --git a/tests/assets/call_gen_tls.sh b/tests/assets/call_gen_tls.sh old mode 100644 new mode 100755 From fda6b77ff5b547604fad783c2ff35ec3484decc9 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 14:26:13 -0600 Subject: [PATCH 066/215] updated host address --- tests/assets/call_gen.sh | 2 +- tests/assets/call_gen_tls.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/assets/call_gen.sh b/tests/assets/call_gen.sh index da5596ea..f89dd648 100755 --- a/tests/assets/call_gen.sh +++ b/tests/assets/call_gen.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 0.0.0.0 + --host 127.0.0.1 diff --git a/tests/assets/call_gen_tls.sh b/tests/assets/call_gen_tls.sh index aec49e02..9bc0f270 100755 --- a/tests/assets/call_gen_tls.sh +++ b/tests/assets/call_gen_tls.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 0.0.0.0 + --host 127.0.0.1 From 90ba0795be36948a4d3e64235769030d154f0149 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 10 Jul 2024 14:32:46 -0600 Subject: [PATCH 067/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c8c55133..9e468ab8 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -146,7 +146,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host 127.0.0.1 --port 5000 --root_certificate tls/root.crt -vs working-directory: tests From 991f198862b4f7222ee3c8e924137d59798486e2 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 07:56:13 -0600 Subject: [PATCH 068/215] Remove static files --- tests/aerospike-proximus.yml | 121 ----------------------------------- tests/aerospike.conf | 72 --------------------- 2 files changed, 193 deletions(-) delete mode 100644 tests/aerospike-proximus.yml delete mode 100644 tests/aerospike.conf diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml deleted file mode 100644 index 23186679..00000000 --- a/tests/aerospike-proximus.yml +++ /dev/null @@ -1,121 +0,0 @@ -# Change the configuration for your use case. -# See: https://aerospike.com/docs/vector - -cluster: - # Unique identifier for this cluster. - cluster-name: aerospike-proximus - - # Custom node-id as 8 byte long in Hexadecimal format. - # It will be auto-generated if not specified. - # node-id: a1 - -# If TLS is desired, TLS configuration ids used -# and associated TLS configurations. -# -tls: - service-tls: - trust-store: - store-file: /etc/aerospike-proximus/tls/root.truststore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass - key-store: - store-file: /etc/aerospike-proximus/tls/brawn.keystore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass - key-password-file: /etc/aerospike-proximus/tls/keypass - mutual-auth: true - # Client certificate subject names that are allowed - allowed-peer-names: - - brawn -# interconnect-tls: -# trust-store: -# store-file: tls/ca.aerospike.com.truststore.jks -# store-password-file: tls/storepass -# key-store: -# store-file: tls/proximus.aerospike.com.keystore.jks -# store-password-file: tls/storepass -# key-password-file: tls/keypass -# override-tls-hostname: proximus.aerospike.com -# -# aerospike-tls: -# trust-store: -# store-file: tls/ca.aerospike.com.truststore.jks -# store-password-file: tls/storepass -# key-store: -# store-file: tls/proximus.aerospike.com.keystore.jks -# store-password-file: tls/storepass -# key-password-file: tls/keypass -# override-tls-hostname: asd.aerospike.com - - -# The Proximus service listening ports, TLS and network interface. -service: - ports: - 5000: - addresses: - 0.0.0.0 - # If TLS needs to be enabled, tls configuration id. - tls-id: service-tls - - # Required when running behind NAT - advertised-listeners: - default: - # List of externally accessible addresses and - # ports for this Proximus instance. - - address: brawn - port: 5000 -# Management API listening ports, TLS and network interface. -manage: - ports: - 5040: - addresses: - 0.0.0.0 - # If TLS needs to be enabled, tls configuration id. - #tls-id: service-tls - - -# Intra cluster interconnect listening ports, TLS and network interface. -interconnect: - # Interconnect client side TLS configuration - # when TLS is enabled for interconnect - # client-tls-id: interconnect-tls - ports: - 5001: - addresses: - 0.0.0.0 - # If interconnect TLS needs to be enabled. - #tls-id: interconnect-tls - -#heartbeat: -# # Seed nodes to discover and form a cluster. -# seeds: -# - address: localhost -# port: 6001 - -# To enable client authentication - -security: - auth-token: - private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem - public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem - token-expiry: 300_000 - -# Target Aerospike cluster -aerospike: - seeds: - - 0.0.0.0: - port: 3000 - - client-policy: - max-conns-per-node: 1000 - #tls-id: aerospike-tls - # - # Aerospike credentials if required. - #credentials: - # username: admin - # password-file: aerospike-password.txt - -# The logging properties. -#logging: -# #file: /var/log/aerospike-proximus/aerospike-proximus.log -# enable-console-logging: true -# levels: -# root: debug diff --git a/tests/aerospike.conf b/tests/aerospike.conf deleted file mode 100644 index a7c979df..00000000 --- a/tests/aerospike.conf +++ /dev/null @@ -1,72 +0,0 @@ - -# Aerospike database configuration file -# This template sets up a single-node, single namespace developer environment. -# -# Alternatively, you can pass in your own configuration file. -# You can see more examples at -# https://github.com/aerospike/aerospike-server/tree/master/as/etc - -# This stanza must come first. -service { - feature-key-file /etc/aerospike/features.conf - cluster-name proximus -} - -logging { - - - - - - # Send log messages to stdout - console { - context any info - } -} - -network { - service { - address any - port 3000 - - # Uncomment the following to set the 'access-address' parameter to the - # IP address of the Docker host. This will the allow the server to correctly - # publish the address which applications and other nodes in the cluster to - # use when addressing this node. - # access-address - } - - heartbeat { - # mesh is used for environments that do not support multicast - mode mesh - address local - port 3002 - interval 150 - timeout 10 - } - - fabric { - # Intra-cluster communication port (migrates, replication, etc) - # default to same address in 'service' - address local - port 3001 - } - -} - -namespace proximus-meta { - replication-factor 2 -storage-engine memory { - data-size 2G -} -nsup-period 100 -} - -namespace test { - replication-factor 2 - storage-engine memory { - data-size 1G - } - nsup-period 60 -} - From 0420a9c5b21a3e6d9d37bc361feecffabeec460c Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:02:41 -0600 Subject: [PATCH 069/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 9e468ab8..5049ff3f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -146,7 +146,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host 127.0.0.1 --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs working-directory: tests @@ -229,6 +229,15 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + echo " + + " + + cat aerospike-proximus.yml + cat aerospike.conf + cat tls/root.crt + cat tls/brawn.key.pem + cat tls/brawn.crt working-directory: tests \ No newline at end of file From ed5c7c57aa0983fb50b205c750590fa7ff3059b2 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:06:55 -0600 Subject: [PATCH 070/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 5049ff3f..2689b7ed 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -229,7 +229,6 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs echo " " @@ -239,5 +238,8 @@ jobs: cat tls/root.crt cat tls/brawn.key.pem cat tls/brawn.crt + + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + working-directory: tests \ No newline at end of file From 362737a09c78986511202dea17b6c069b22a391c Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:14:23 -0600 Subject: [PATCH 071/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 2689b7ed..ef4c59e1 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -146,7 +146,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host localhost --port 5000 --root_certificate tls/root.crt -vs working-directory: tests @@ -238,8 +238,8 @@ jobs: cat tls/root.crt cat tls/brawn.key.pem cat tls/brawn.crt - - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + + python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs working-directory: tests \ No newline at end of file From 8e9e803d7fb1615e5e0a5a25e3fe202bb2c6dd29 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:18:07 -0600 Subject: [PATCH 072/215] Update gen.sh --- tests/gen.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/gen.sh b/tests/gen.sh index 2920a402..b0b88eba 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -404,11 +404,11 @@ EOF # Check if the line exists in /etc/hosts - if ! grep -qF "$line" /etc/hosts; then - # Add the line to /etc/hosts - echo "$line" | sudo tee -a /etc/hosts > /dev/null - echo "Entry added to /etc/hosts." - fi + #if ! grep -qF "$line" /etc/hosts; then + # # Add the line to /etc/hosts + # echo "$line" | sudo tee -a /etc/hosts > /dev/null + # echo "Entry added to /etc/hosts." + #fi elif [[ "$mutual_auth_maybe" == "n" ]]; then generate_derivative_certs "child" "child" @@ -469,11 +469,11 @@ EOF # Check if the line exists in /etc/hosts - if ! grep -qF "$line" /etc/hosts; then - # Add the line to /etc/hosts - echo "$line" | sudo tee -a /etc/hosts > /dev/null - echo "Entry added to /etc/hosts." - fi + #if ! grep -qF "$line" /etc/hosts; then + # # Add the line to /etc/hosts + # echo "$line" | sudo tee -a /etc/hosts > /dev/null + # echo "Entry added to /etc/hosts." + #fi fi fi From 517e3795d966e22f3f524e974ff7cacc04b2f80e Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:27:55 -0600 Subject: [PATCH 073/215] Updated CI/CD --- .github/workflows/integration_test.yml | 4 ++-- tests/gen.sh | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index ef4c59e1..0459b9b7 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -146,7 +146,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host localhost --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host root --port 5000 --root_certificate tls/root.crt -vs working-directory: tests @@ -239,7 +239,7 @@ jobs: cat tls/brawn.key.pem cat tls/brawn.crt - python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs working-directory: tests \ No newline at end of file diff --git a/tests/gen.sh b/tests/gen.sh index b0b88eba..2920a402 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -404,11 +404,11 @@ EOF # Check if the line exists in /etc/hosts - #if ! grep -qF "$line" /etc/hosts; then - # # Add the line to /etc/hosts - # echo "$line" | sudo tee -a /etc/hosts > /dev/null - # echo "Entry added to /etc/hosts." - #fi + if ! grep -qF "$line" /etc/hosts; then + # Add the line to /etc/hosts + echo "$line" | sudo tee -a /etc/hosts > /dev/null + echo "Entry added to /etc/hosts." + fi elif [[ "$mutual_auth_maybe" == "n" ]]; then generate_derivative_certs "child" "child" @@ -469,11 +469,11 @@ EOF # Check if the line exists in /etc/hosts - #if ! grep -qF "$line" /etc/hosts; then - # # Add the line to /etc/hosts - # echo "$line" | sudo tee -a /etc/hosts > /dev/null - # echo "Entry added to /etc/hosts." - #fi + if ! grep -qF "$line" /etc/hosts; then + # Add the line to /etc/hosts + echo "$line" | sudo tee -a /etc/hosts > /dev/null + echo "Entry added to /etc/hosts." + fi fi fi From 5fc08b7d3c0c826ed7dfdf754d8536b783893e64 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:34:00 -0600 Subject: [PATCH 074/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 0459b9b7..1ff5c21f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -7,7 +7,7 @@ on: jobs: test-normal: - runs-on: ubuntu-latest + runs-on: macos-latest strategy: @@ -69,7 +69,7 @@ jobs: working-directory: tests test-tls: - runs-on: ubuntu-latest + runs-on: macos-latest strategy: @@ -152,7 +152,7 @@ jobs: test-tls-auth: - runs-on: ubuntu-latest + runs-on: macos-latest strategy: From 9028a475a976ce8b55616f33e2173c938f5771e3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:37:48 -0600 Subject: [PATCH 075/215] CI/CD update --- .github/workflows/integration_test.yml | 7 ++++++- tests/gen.sh | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 1ff5c21f..bd026f1c 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -122,6 +122,8 @@ jobs: cat /etc/hosts working-directory: tests + + - name: Run unit tests run: | @@ -192,6 +194,9 @@ jobs: username: ${{ secrets.JFROG_USERNAME }} password: ${{ secrets.JFROG_PASSWORD }} + - name: Add hosts to /etc/hosts + run: | + sudo echo "brawn" | sudo tee -a /etc/hosts - name: Set up RANDFILE environment variable run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV @@ -239,7 +244,7 @@ jobs: cat tls/brawn.key.pem cat tls/brawn.crt - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs working-directory: tests \ No newline at end of file diff --git a/tests/gen.sh b/tests/gen.sh index 2920a402..b0b88eba 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -404,11 +404,11 @@ EOF # Check if the line exists in /etc/hosts - if ! grep -qF "$line" /etc/hosts; then - # Add the line to /etc/hosts - echo "$line" | sudo tee -a /etc/hosts > /dev/null - echo "Entry added to /etc/hosts." - fi + #if ! grep -qF "$line" /etc/hosts; then + # # Add the line to /etc/hosts + # echo "$line" | sudo tee -a /etc/hosts > /dev/null + # echo "Entry added to /etc/hosts." + #fi elif [[ "$mutual_auth_maybe" == "n" ]]; then generate_derivative_certs "child" "child" @@ -469,11 +469,11 @@ EOF # Check if the line exists in /etc/hosts - if ! grep -qF "$line" /etc/hosts; then - # Add the line to /etc/hosts - echo "$line" | sudo tee -a /etc/hosts > /dev/null - echo "Entry added to /etc/hosts." - fi + #if ! grep -qF "$line" /etc/hosts; then + # # Add the line to /etc/hosts + # echo "$line" | sudo tee -a /etc/hosts > /dev/null + # echo "Entry added to /etc/hosts." + #fi fi fi From d68e745584ecf6a00d3333a4c4d2178b58de9d5f Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:40:21 -0600 Subject: [PATCH 076/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index bd026f1c..a823a9e1 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -122,8 +122,6 @@ jobs: cat /etc/hosts working-directory: tests - - - name: Run unit tests run: | @@ -194,9 +192,6 @@ jobs: username: ${{ secrets.JFROG_USERNAME }} password: ${{ secrets.JFROG_PASSWORD }} - - name: Add hosts to /etc/hosts - run: | - sudo echo "brawn" | sudo tee -a /etc/hosts - name: Set up RANDFILE environment variable run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV @@ -204,6 +199,11 @@ jobs: - name: Create .rnd file if it doesn't exist run: touch $HOME/.rnd + - name: Add hosts to /etc/hosts + run: | + sudo echo "127.0.0.1 postgres.dolphin.com" | sudo tee -a /etc/hosts + + - name: create config run: | assets/call_gen.sh @@ -244,7 +244,7 @@ jobs: cat tls/brawn.key.pem cat tls/brawn.crt - python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs working-directory: tests \ No newline at end of file From 2ea6ebab7e2e43fa53cfd412f9a088a935e1d04f Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:43:57 -0600 Subject: [PATCH 077/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index a823a9e1..9d79fe93 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -41,6 +41,9 @@ jobs: echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Docker Login uses: docker/login-action@v2 with: @@ -102,6 +105,9 @@ jobs: echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Docker Login uses: docker/login-action@v2 with: @@ -185,6 +191,9 @@ jobs: echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Docker Login uses: docker/login-action@v2 with: @@ -203,7 +212,7 @@ jobs: run: | sudo echo "127.0.0.1 postgres.dolphin.com" | sudo tee -a /etc/hosts - + - name: create config run: | assets/call_gen.sh From c187d1fbeff18c09434ab802b85306d467a24c26 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:49:38 -0600 Subject: [PATCH 078/215] uploading static files --- .github/workflows/integration_test.yml | 26 +++++---------------- .gitignore | 1 - tests/tls/brawn.crt | 23 +++++++++++++++++++ tests/tls/brawn.csr | 17 ++++++++++++++ tests/tls/brawn.key | 28 +++++++++++++++++++++++ tests/tls/brawn.key.encrypted.pem | 30 +++++++++++++++++++++++++ tests/tls/brawn.key.pem | 28 +++++++++++++++++++++++ tests/tls/brawn.keystore.jks | Bin 0 -> 2782 bytes tests/tls/brawn.p12 | Bin 0 -> 2723 bytes tests/tls/jwt/private_key.pem | 28 +++++++++++++++++++++++ tests/tls/jwt/public_key.pem | 9 ++++++++ tests/tls/keypass | 1 + tests/tls/root.cert.pem | 25 +++++++++++++++++++++ tests/tls/root.crt | 24 ++++++++++++++++++++ tests/tls/root.key | 28 +++++++++++++++++++++++ tests/tls/root.key.pem | 28 +++++++++++++++++++++++ tests/tls/root.srl | 1 + tests/tls/root.truststore.jks | Bin 0 -> 1414 bytes tests/tls/storepass | 1 + 19 files changed, 277 insertions(+), 21 deletions(-) create mode 100644 tests/tls/brawn.crt create mode 100644 tests/tls/brawn.csr create mode 100644 tests/tls/brawn.key create mode 100644 tests/tls/brawn.key.encrypted.pem create mode 100644 tests/tls/brawn.key.pem create mode 100644 tests/tls/brawn.keystore.jks create mode 100755 tests/tls/brawn.p12 create mode 100755 tests/tls/jwt/private_key.pem create mode 100755 tests/tls/jwt/public_key.pem create mode 100755 tests/tls/keypass create mode 100644 tests/tls/root.cert.pem create mode 100644 tests/tls/root.crt create mode 100644 tests/tls/root.key create mode 100644 tests/tls/root.key.pem create mode 100644 tests/tls/root.srl create mode 100644 tests/tls/root.truststore.jks create mode 100755 tests/tls/storepass diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 9d79fe93..57441695 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -7,7 +7,7 @@ on: jobs: test-normal: - runs-on: macos-latest + runs-on: ubuntu-latest strategy: @@ -41,9 +41,6 @@ jobs: echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Docker Login uses: docker/login-action@v2 with: @@ -53,7 +50,7 @@ jobs: - name: create config run: | - assets/call_gen_normal.sh + #assets/call_gen_normal.sh cat /etc/hosts working-directory: tests @@ -72,7 +69,7 @@ jobs: working-directory: tests test-tls: - runs-on: macos-latest + runs-on: ubuntu-latest strategy: @@ -105,9 +102,6 @@ jobs: echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Docker Login uses: docker/login-action@v2 with: @@ -124,7 +118,7 @@ jobs: - name: create config run: | - assets/call_gen_tls.sh + #assets/call_gen_tls.sh cat /etc/hosts working-directory: tests @@ -158,7 +152,7 @@ jobs: test-tls-auth: - runs-on: macos-latest + runs-on: ubuntu-latest strategy: @@ -191,9 +185,6 @@ jobs: echo $FEATURE_FILE | base64 --decode > features.conf working-directory: tests - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Docker Login uses: docker/login-action@v2 with: @@ -208,14 +199,9 @@ jobs: - name: Create .rnd file if it doesn't exist run: touch $HOME/.rnd - - name: Add hosts to /etc/hosts - run: | - sudo echo "127.0.0.1 postgres.dolphin.com" | sudo tee -a /etc/hosts - - - name: create config run: | - assets/call_gen.sh + #assets/call_gen.sh cat /etc/hosts working-directory: tests diff --git a/.gitignore b/.gitignore index 3c8ce17e..38b71458 100644 --- a/.gitignore +++ b/.gitignore @@ -162,7 +162,6 @@ tests/aerospike-proximus.yml tests/aerospike.conf tests/features.conf tests/assets/features.conf -tests/tls/* # Notes notes.txt diff --git a/tests/tls/brawn.crt b/tests/tls/brawn.crt new file mode 100644 index 00000000..b8e5249b --- /dev/null +++ b/tests/tls/brawn.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDyTCCArGgAwIBAgIUPq4Exc1hs+91ph8oWCkyzlJfVaAwDQYJKoZIhvcNAQEL +BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm +aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG +A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p +QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTQ0ODAzWhcNMzQwNzA5MTQ0ODAzWjBE +MQswCQYDVQQGEwJJTjELMAkGA1UECAwCS0ExGDAWBgNVBAoMD0Flcm9zcGlrZSwg +SW5jLjEOMAwGA1UEAwwFYnJhd24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCYSnUh1TtiTgeRqRl+AHW5GoKpxG0AKhg5gvJlFpKj7zbPfzUv9eHEUgr5 +EKS07zeStyMwLsxNUqSvAKko9yeGW8VPnT3WQ39mceGrpKwUe4nl4n5pcCSywJz/ +1uJCZVXcSy7JOUuqHi+m2fMDfgSJEeSKeV/yRA6MRP59Q/tYyHLLUj7Fsh5C+oTI +KzHK1w8CFABFp1pRSfsnujP9GV0CDXjtYWTa2xWrTYXYClFiWHgKwLQ18C4/xZPj +xyNDSoovPdb+YiKwzHD8//EC+DImf1jEg2RvjORMRW0IlpY2rjeQ8Pfjl2E4pxHu +0dsrSYyBHZ3HD2q5G17UJP12Cq1LAgMBAAGjXTBbMBkGA1UdEQQSMBCCBWJyYXdu +ggcqLmJyYXduMB0GA1UdDgQWBBS/+8nIUvKZA/OctrRXPTk9qV7xnDAfBgNVHSME +GDAWgBTgvyN83nU/9Q+Lkxy5PIjSYHvTmDANBgkqhkiG9w0BAQsFAAOCAQEAGRcy +xvZHWru4U6WO7D5ZPxA8/poWNCzmH5qYu/sHdd5Rys7gEBxfoZYFNmxycZbvCN5B +OD74M0aiu6d849cwyTzeaxu7/z7gJGM17sjLvyin5NvQ63SGzt5ohLkOXUd9tJTX +S7fedB0Y2eflrhW3JhFQuIcihG+FNEY10+0XB/WJ+b1sX0mskw5xSSw0QRFbKW6v +x3yb5FsvnVZayg5J8xJhwTm3SnxV/ZiKZ8sZjTuD6jXYAR6WuNptyKvCQCUtGcNu +qcjk+P0jzwIGkjITbM3bD7LCubxwnXwrQFg/7J2nAw4OgJdrOIY14nsizJ3AQs7i +DkEJbPlkVlXp4sQ6zA== +-----END CERTIFICATE----- diff --git a/tests/tls/brawn.csr b/tests/tls/brawn.csr new file mode 100644 index 00000000..17d0fcde --- /dev/null +++ b/tests/tls/brawn.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICtTCCAZ0CAQAwRDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMRgwFgYDVQQK +DA9BZXJvc3Bpa2UsIEluYy4xDjAMBgNVBAMMBWJyYXduMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAmEp1IdU7Yk4HkakZfgB1uRqCqcRtACoYOYLyZRaS +o+82z381L/XhxFIK+RCktO83krcjMC7MTVKkrwCpKPcnhlvFT5091kN/ZnHhq6Ss +FHuJ5eJ+aXAkssCc/9biQmVV3EsuyTlLqh4vptnzA34EiRHkinlf8kQOjET+fUP7 +WMhyy1I+xbIeQvqEyCsxytcPAhQARadaUUn7J7oz/RldAg147WFk2tsVq02F2ApR +Ylh4CsC0NfAuP8WT48cjQ0qKLz3W/mIisMxw/P/xAvgyJn9YxINkb4zkTEVtCJaW +Nq43kPD345dhOKcR7tHbK0mMgR2dxw9quRte1CT9dgqtSwIDAQABoCwwKgYJKoZI +hvcNAQkOMR0wGzAZBgNVHREEEjAQggVicmF3boIHKi5icmF3bjANBgkqhkiG9w0B +AQsFAAOCAQEARYwBIhgAkhuBTg6wKJ+9MIar6o/FoxpZmrcnNn+z2n1JsCMR3o8T +UOpgt9neBujECCiStnBaqVmGuKHGmhYe12cundz10e0lRG2UDproaxS39Msp9PD5 +PJVh7GD2fQ4skLtx7KBjhdf8HrQQGHbHcuf/pA1hs9CNPaNTm2MEuUDCPcN8kYRP +luZ0C35/BCb34JW7NjDi/fYGOmaSgh0zL1LQyt1VW/TKSG3n6Xec4fX2sLDZyvEF +X1Ua8OgZ7QOPrDMFLJTfKHKpZ6ACSgcd6WAGaXBCrwzn9cC3Uy4BJ+9Ewd2j+vxM +dng/ApYue+vrTbOWeIeGwzivcrXx2156Hw== +-----END CERTIFICATE REQUEST----- diff --git a/tests/tls/brawn.key b/tests/tls/brawn.key new file mode 100644 index 00000000..d58bfe18 --- /dev/null +++ b/tests/tls/brawn.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQCYSnUh1TtiTgeR +qRl+AHW5GoKpxG0AKhg5gvJlFpKj7zbPfzUv9eHEUgr5EKS07zeStyMwLsxNUqSv +AKko9yeGW8VPnT3WQ39mceGrpKwUe4nl4n5pcCSywJz/1uJCZVXcSy7JOUuqHi+m +2fMDfgSJEeSKeV/yRA6MRP59Q/tYyHLLUj7Fsh5C+oTIKzHK1w8CFABFp1pRSfsn +ujP9GV0CDXjtYWTa2xWrTYXYClFiWHgKwLQ18C4/xZPjxyNDSoovPdb+YiKwzHD8 +//EC+DImf1jEg2RvjORMRW0IlpY2rjeQ8Pfjl2E4pxHu0dsrSYyBHZ3HD2q5G17U +JP12Cq1LAgMBAAECgf9RXGJyxIx/M6b+787WH97saAJS/2Ltx0Czx99CIn5cyA3i +zU5iAl2H54gcnALFRQhERjDVPlKs1VLXjpaCh2Ez8L/IF8OPK0VbTo/fwS4Gr6rV +JlOeARCt0Zw2dTSTf2iucBnJ3ZdT6Rtkzal9R9YQx1cDQYZPwNE/9+sSFRhay8GB +4a8Zchu5aZ59aSbcuLm3dywgMJSIkhZKBMmSBbfCv/QMMSE56UC03YGT51rcchjp +BWYAFvpI0LYGWUlvSZS0z+qoF0E+5gB1pOXiTCOPVKSTlaDHJaC/xt/kmF9Y98Yi +T5uEOTCsen6lD9G4XkdCNPKPX68m13Ayu/xw0hECgYEA06wSC5UUrdTbkIDDdomo +c8CuukyYt/2AmrNe80OapRNxf4XAOS06G66YfF/Gc45O/UTqGtrVbD9IlzXhJncc +LwfhiOa7nUByYFx32okR1JJl19TqzDxHCOP4f/YRe3VyWpgEvSR+nJ9F/R94tlMy +Ga2Ky70aS2rOL+BXTfXPZB0CgYEAuC7nSvuH4pPgixERb9+C40pAxACWGHqF+8kb +nRD10/uOZjPP66//+NS/SykHFpC9GlvKNvnd5QJQywRR0pWLe7SXUtSKd2srYiu0 +fCWXtWL8nZ5Aq63vSL2ABirWY7eGpoAbXQyWb/x7sMy5CAYaVLZx5QyGFkJf8tZl +YrgGyocCgYBmN5H/Rd7WkxP0lDnP5GoUe9fk31hggWq5SiVwFBV54gnNKynIcq68 +73NznEyZQP+kDsN+dG7b9zN20e4IRTy2+XdQRRwUtCqHnh/CyK5zmL7Vm1xHhFRJ +Vs2J/aozlGPEm+St8hGyULfbpHcGlOZ8v/Fmscsg4FLxi8SdQTcFgQKBgDZ1l+ox +6YHzW6eDCnbbzeXK5M+PpNHkGI3UbxfIFgfyD67kjwwPZE59CXr9zJy9e0y561bK +FvRJ9P2yb0cm9LFFOqFBOxgIVjGW3qz+qJb3h95LFrAso94MOjiYnf+qGmRM6Mpg +mHLQYvpp7iQTOeHmeFLTmyolwh0Zi6ze4RMtAoGAbYTqaJMJ4X8+eHykM5WvMfXW +pSfEoLSxV5x3udoNKBRvPj22upLWX3v5NiF6bDe1wrgkvQ5/eQqgFB7V0+7vwl8s +qhf2sXwXA3KuzBeb5+Py6XaeBWo4Nc/gLhCywWIvCgbZzWofPGkffDcDS0RVAJSn +LlV2vQlMzHUS8fAWYPU= +-----END PRIVATE KEY----- diff --git a/tests/tls/brawn.key.encrypted.pem b/tests/tls/brawn.key.encrypted.pem new file mode 100644 index 00000000..1ddde4a8 --- /dev/null +++ b/tests/tls/brawn.key.encrypted.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFJTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQ2fzGFIPwqF+jPex3 +BbPXFQICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEHIZzbYlHdcXSydD +JKXxgDIEggTAI59S3UUYYWhWY1tQOBzWAeo+xUa+8sK39sMBjDMcPHt7hTptEAuG +c9NoQtUYN4yByTC15MvnUu/7pHDgSDBcbIw2po85Du03joKdH0aNM6uNsrTQAPOl +Vloy5hq8gMHm0GpoG3zPlFiz7jdPGRFOQgmD1fxvkCbkWGqBRi6jygZLqHgQRiCv +CQVHjDg/c3x167eeuEXHzb/K2cO8shVHU9H4dtMfzdEcMXxlrWkCNoBsXYmgDcTX +NJ+5/+vUVrfuOV4PkC0AVTiDOGBTrzaHEFET37rtNA9pSVy6/CLwEySoiLAwKOUN +Etp6LleXD84qcbEcgys5bSSZr/nIxULVSW8YBqBCHOADEKkOAtF+EOd29cQa9l6M +AxInR7qiWYNUuahxMxE1tKK29QaaoTDfQWM0LvWHbORAwZWVtd6D0K12R7j9TRmn +DmZ8v+RnYTNwqQ5jiIk+xCjor5mEbST+OI8CMHwK4m/zpaN+xD2LKNHtI88W1Ev5 +N5iU+0N4zQD50c5l8u4pPz7A4aIB1QYdKOG7t9SzbyEi6+JmVFpY06K17NrpfniT +jxjEUmat8fHsstGf0AQTtB/7PPDRb0yU6W3iX1/X5dbZU1aHz0RgwHqmsr8b9Ypg +eAbb/z5TjBrpbHlKK2o9D7pMeDrV6OWRW7lVEpi2mqlgcvS/YjsJF2U9iws7b61X +b5tPqPUyTa649BqsOChqkvpbAlh8wxi9Ngd5aJSTHS2F95XTmRDt2sneE7+dckPT +y7meTJu7FMV8sjVYA3NNngJk/Y8tLJEhUAArKh4HWz7a0DlN7q3nevXaT3nIxWO+ +UST32Bo9ReuQ0opv0rWMHQ+op3CidxmxwxWsp8eohiwM9ziCT2abdYJLcQOQdnsM +9r7iQRTQctSqMu2kBzSOJplTa1QVSWJoN/tBPC3LkjS8r4MFKPUtOtfUoyVA58sa +SKeX2fLDjaL9UZjCt5t/Ir2fiFPmMMfntsbaU7SplEStDg3/9Wivsa2EaYHHAJYu +k9Y/7yG/9+CjqcYKa7hVjYdjaB1HaGlTKIAUO3mSuLlFuRS5Ts/t5mJDjZbfKaJ+ +eAk5r1oQTLCISDGd9VjN3J+fAaScYZAt/DXOj7FPX6ZKzOljHePRVNDr2iQ/TIAg +6rd9kDozag2gzSwLxmGivNsz2EC03x5eD8p+Ab3nlmgrJFho4b+H2kknrdmaHt+R +q/f6qqdNOJATNlxUbLlBi2s54detOhsMsOBImzDGEYsBWnNq99d7hi5yLZP4ipPa +EBMzgt0MBHOrUYftof9B9gElClerZ7PhXW4j2pM8v2cQ3wZ4insyfD+B+kvW+Hbd +/wcJUPb+k7O8r4OAi/q1TM0xGO0rUKUE8TwycDq8zGApv5kIRKojgbM8cDFAHiZ/ +HD0yKSUV2kQQH5zZ5UqFZglJs841HLx5tmzk1H4RRY38b3M9/chyeWo1X9hzpgVt +74MGW7T/1HbGco85Pv2/PwlTPoCbDsedmRkeBWYTY+AcgzSRpwnQyTwivKtILchQ +TWI/qYPFaUv6nR5dYefxF+GORLMeQbymUi0Hzqsc7s5ucgfL2e6/Aivqr5iYQqZJ +mjjakxxzlSuoJ00pFDM2hFgwVPU6ozzPKQ== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/tls/brawn.key.pem b/tests/tls/brawn.key.pem new file mode 100644 index 00000000..d58bfe18 --- /dev/null +++ b/tests/tls/brawn.key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQCYSnUh1TtiTgeR +qRl+AHW5GoKpxG0AKhg5gvJlFpKj7zbPfzUv9eHEUgr5EKS07zeStyMwLsxNUqSv +AKko9yeGW8VPnT3WQ39mceGrpKwUe4nl4n5pcCSywJz/1uJCZVXcSy7JOUuqHi+m +2fMDfgSJEeSKeV/yRA6MRP59Q/tYyHLLUj7Fsh5C+oTIKzHK1w8CFABFp1pRSfsn +ujP9GV0CDXjtYWTa2xWrTYXYClFiWHgKwLQ18C4/xZPjxyNDSoovPdb+YiKwzHD8 +//EC+DImf1jEg2RvjORMRW0IlpY2rjeQ8Pfjl2E4pxHu0dsrSYyBHZ3HD2q5G17U +JP12Cq1LAgMBAAECgf9RXGJyxIx/M6b+787WH97saAJS/2Ltx0Czx99CIn5cyA3i +zU5iAl2H54gcnALFRQhERjDVPlKs1VLXjpaCh2Ez8L/IF8OPK0VbTo/fwS4Gr6rV +JlOeARCt0Zw2dTSTf2iucBnJ3ZdT6Rtkzal9R9YQx1cDQYZPwNE/9+sSFRhay8GB +4a8Zchu5aZ59aSbcuLm3dywgMJSIkhZKBMmSBbfCv/QMMSE56UC03YGT51rcchjp +BWYAFvpI0LYGWUlvSZS0z+qoF0E+5gB1pOXiTCOPVKSTlaDHJaC/xt/kmF9Y98Yi +T5uEOTCsen6lD9G4XkdCNPKPX68m13Ayu/xw0hECgYEA06wSC5UUrdTbkIDDdomo +c8CuukyYt/2AmrNe80OapRNxf4XAOS06G66YfF/Gc45O/UTqGtrVbD9IlzXhJncc +LwfhiOa7nUByYFx32okR1JJl19TqzDxHCOP4f/YRe3VyWpgEvSR+nJ9F/R94tlMy +Ga2Ky70aS2rOL+BXTfXPZB0CgYEAuC7nSvuH4pPgixERb9+C40pAxACWGHqF+8kb +nRD10/uOZjPP66//+NS/SykHFpC9GlvKNvnd5QJQywRR0pWLe7SXUtSKd2srYiu0 +fCWXtWL8nZ5Aq63vSL2ABirWY7eGpoAbXQyWb/x7sMy5CAYaVLZx5QyGFkJf8tZl +YrgGyocCgYBmN5H/Rd7WkxP0lDnP5GoUe9fk31hggWq5SiVwFBV54gnNKynIcq68 +73NznEyZQP+kDsN+dG7b9zN20e4IRTy2+XdQRRwUtCqHnh/CyK5zmL7Vm1xHhFRJ +Vs2J/aozlGPEm+St8hGyULfbpHcGlOZ8v/Fmscsg4FLxi8SdQTcFgQKBgDZ1l+ox +6YHzW6eDCnbbzeXK5M+PpNHkGI3UbxfIFgfyD67kjwwPZE59CXr9zJy9e0y561bK +FvRJ9P2yb0cm9LFFOqFBOxgIVjGW3qz+qJb3h95LFrAso94MOjiYnf+qGmRM6Mpg +mHLQYvpp7iQTOeHmeFLTmyolwh0Zi6ze4RMtAoGAbYTqaJMJ4X8+eHykM5WvMfXW +pSfEoLSxV5x3udoNKBRvPj22upLWX3v5NiF6bDe1wrgkvQ5/eQqgFB7V0+7vwl8s +qhf2sXwXA3KuzBeb5+Py6XaeBWo4Nc/gLhCywWIvCgbZzWofPGkffDcDS0RVAJSn +LlV2vQlMzHUS8fAWYPU= +-----END PRIVATE KEY----- diff --git a/tests/tls/brawn.keystore.jks b/tests/tls/brawn.keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..8e9634651e0a627a9f456c248c8e5f5ffa90c776 GIT binary patch literal 2782 zcma);X*3iL_s7k~Ft%(>NsT3i!Hj*$5*al1vL%$AkRfFYGnPnMGPcavheA|BV;wso zOUjltgHe_?lPypG^M6ji^SpYV7x&zAKi~VkFTdxa2pm&D00>3kh-GD$jyH;Dask)? z1q6;@Fo6U22m7H25aNGGkT@^_g8zf>{;5z_*uPzz8~|Ve0fPDiktmP94hR>@9;Nor z$cd5x3(N-8%w$!n&~G}F_opCY^^Bx`B7wj&yg&c~#mNf&|BFC&2n$MtmHk@05x^Y; z21tW>9U49dqcP@Iw2fO${badtFab=9($2&*+62k=8sM6OFu|)7;ZB147PomF|48;k zpx^U%rx|xz-o{3+v>(qbnci;gPV_HLOWn4^?n~ykPfGYGs2Dj4Rl>BgH?Z~-hkh<{ zP*e$TdS6Vkn)|u4&0qWG&qE7ENW)o7b>5U(dEgA1GP)3KF1{F?Fr;qF!x5MvY;ycq z)~&9BFyLo2HlCtmDA7U2xn3q=fU4HNPgAJ042CaZrC+1X+Um zg_ZpPDzn6YACh~SvA*kghm&22cAqJTd;UpK4T@YyQ4?4C7(4 ztC^;DuxDHQtT{tAbwf8%8$W?sV|V-0!DnhgZqx89KI^3Jr{_GgXIaA zS3Nc@m%Zio=*g+;^s6zjQk0Y8Hn!b$m;U7|sg*$!bi%I95eoLdO_UH;Sokpq2{o_z z;8beit|JQy))D<5q-M7@PS|J8q~jpFh>=N>$-Q;C0%-Hs?5XPaymQ{+*9y!H?MJ@flI~( z83VSDL0xyVtRCm2+Ra>n564+`c$ImOd^Hb}X1!mvB6fp5C#cZgyR)u;+qh|*>^*(8 z+@GBYI?IuAwnwbaN|l^!a(nju@Zc1*sSeS*b05=&)$8yo*`FE`U3Bl?dHC#+(>fii z0-kGWAT>n`DVr?;V}=cJ4cFshOSI*Em}+m+cOvRMunqB`*{zXEo&~kpUcl&sn?qMf zW0!uuWB|44Jvz~J_FY8;s)qBZmRNB%+~C3)y$*!b{oD<#M3TlmHF z!dh!=o3TNqt9~1CVwr01_bGo{axQWXw{?$kEZ(0tcjH*(UH(L<(Q;Zqxn^gc@nw;W zg?Qh^o!S;gu?UcPfOm_)n!g_p)7CY8#YN793Szp7ER{22i|t)^w_H_Px_ayumm!tw zqo7J#QMyq@m)VDhpUsMYNi59NE%iLfC(=!E$MA@28!Pp>%#6KYr-Gdf=9$EoieHSozxRIg4q$zLzJ}#~ zc~S)7jHd0R7B*t zkBrm8;Ew7Yr_3rekH7#%8&gaF$?gN6JepB6IUS%gMOkcLUhcc1AzYG`j0R%`@Ysz z%C%Rh)DaW2T^)+_TRy9X5>^F1u5C8?WgetD*8w~+ulK7xfB_sHpa(qrOzpWAY!#_xbPidO#`-j9zL~vl$GMeP03C zhK28)YkMFbnkrIrbAcATef&h!Db6|(3n;w5h;xt%c^Dc|mH>4k2??&3%H3!@4r83b z`TgM9R3G%)s+nBsat5_R=qXcvT1?0Vm@Zq(SNS)kh6j3m-#sCw1*xvnw8+IKmq5lc zuCx4IVrw)`ZjQ7jj!5>zQVk0ts`S`}S8l>Q!OeIBoIC>}JC#93AgCYELO zA&+~j-08sMAt880=rS_G;$A}Iyi^%Y2rgf#(E|5Lhm|K?0KBaY`*oD(7ffs`l;Sa( zOdN4Glb%RP4;(T`Cz#ZE_4kU~%Fl@>@^p!Hs=*~gAP)ecwxGJ-b_bQ9-iw_TlEiz|f zdZ}3>L*-I1hXiOmxs1)}2-dH9Nx}Fuxw(Qpl2_|kZAV%$oU9Z)3s*f!H62J!QEWTfKLGKmk+hgamGYr~1097ZBbBt2a9%B6 zmgP4WF~N4sXyO~u&-(jBwB2ekR=_euvo-sY)=aF3%zGuY2<)`!OiXN#wZFe6?3D!;5TCVrX(om9RVW(6cHUt)vnQ^Mr>l0Tr;gvF+!_Fjo7<(E7T}e z)M&*hrD8|z7FD&bd;b5^`|*Bw&wHNd`S5&tf9Hh}*s>V`OfUkQDTq}j>RQz9DZn29 zGJ)+1kidpMu`k02z{YM1S1rYrDyP# z=PCyg$a@Mt#;cH=4Hc z5$w}^;dQT$jEhDn9y>k1$iJ?jT^b{*9zdekV|BJ^=g%%x zd7jN5*;b)$Tm}gbB|>Ln9tojE`EKg!owX`&oi5O7aLgkiTBI`I=;VTP&AkBob9HH!pPheA$M4~Hh_G<;T5#^ix(%ysEHXUMZnF?7K4R~q2hyi zx4tca*<0d17UraK_r>;es!pU|^y=(+k35B+aT=dJt_te3EBzWU6hG?aZ^S;1;QwrP zX<8t5EZAGhf8m3aMcv}B?CkNn_8S@sPkQRgdN>|Sb2IrnA%^-eh(JIR=$fO^7h|uX zsUtL-Z};v^TsGtossQP%(0+5x2>YbKh?o-F>#m!m1E}lzp{ptXq!ub{N(T>m0v z8bB`Xx>Ipg5RYy_T7Luv+(#7uzTv1EHm-+;-I!P4O0M2&^@u@XmRRVwq~h(#LFt%i zXOm#Z{U%<7(D1}mT>XOBnYQ!q)u_ff+Fkd%0#|}`Jx$!o5W@w<+730{vUE8~13oCV zj2`|51i4YvA{p$Lfysq?1^+~BCqU2h^Rgf&$WYaw~Ooyb%f^+kZGH(hIbk?2sz zeDLhn>P}sgQt+yPp6x>Xu5_!ph&>&IJ+}EVhG$EO;Lx&o*-h~hm6q`D~tiTY`C!#4(D&7pnQ*gTkDOdj23=bomCJfac3f6$>It+hMcz5O!?lcu2-J;HRi8htUl9e$c^P#t1&MkO&-1x zd2o}Q{dHe54MnzE}OHzmD-Yy&p~7!_{qLB1)T^tiSs&Q_xc z!~ir;ZR+*~HU_K1dz8|F63WJ;BJig90!S}_a=jyW$a zJCxC-Z2Y4E%c`*Ka`kkd#go497h@(}rZDkVaoQSj4;+22OT&>JCm%U0v28KTZ~CVK z+hhhlH%(W+`Ni&xwI-)h+;wvuU0^g4g^B2I9h;xU#SdMjeosm$oe2#n)UC^Un?>F& zZdNo86yqJ8*-X6Mk>*UzDu9kpj!`IaJ%$yTd=n9Wm~(zOm*-4Dz{vJYbmK9vmgRfC zv=kwEk*)dQOH|;d)g8V1NaoGa{)L(qln%5QbkRC65-;NVN<-!Fq3F5R)z}wSLFPjq zc4>Y;FFTGvz$O}Sd`Ur?vS5^(_7^s;&A+4_RFP~UDZ^*6XGO}0s4_iuanR=U#xiexlakv+TT50YPD8~% zk>6Su1FU+bAI)*4G#?|N+mD3YDlVU!G6kBtO!sFNAvpJwR=ils9^Id}H*b-8=Q|xmPcBSsvz;fkv4^k);P37M_ynoA36u4C;g8%%46FsbZkK z#~D&`c#Z%Kas@4Z=@A4Mv5XvvrrOpHNXcf_uHCcgJ7bc|_S}}OHnKjuEEq0KJm&~7 zOcgad)zQ-1=Os2;8Pd;loPzOo;y?{}JR`pf5Iu6@`mRimNSt1qMzr>iE=g;bMnow#6T4}AAJvjY?FVnf<8;@I zXlr!!djT3kQPD0j7_}idQ!<@M4QT#6wmycuI4swjqe)C^Kw7A${v6^wFcv)w>I-@# zMxYknQBy4wZ=;3MDGW?_qt4canpjg(sG$My#6U#`V}2q^B&JiW^Nz`Z9shr*&m z+=|U_ktWhAXJw);nc$97@?u``rkSddgnGI!J6^YZn_EpYsM1*ta(TZO6UEAJZLDEb zT00So3BI=+Th&O;*_+^^tbbElgT7<%_`TD`nt*zwC-!A0_rBNLN$Ne*b;;x z4<-442O>E6e6D1*=c9NA<$c3LrFIGj1=X}V0yOX_^10ildxAPDqVR9S1s&~cZ)Ph* z)CcQ%URxG^0{EsU^hnIwI#6ySh2U;eiq?^MDd!=x#ley+0Riov4bS8`mXgVo5#!z{ zaodX0gou&*Pm#hk&F0odsrT+kif-q@p)m2^U}fcn^8tCxc|5@LO&BhV{kEOj)asa} zLq0v277PwM_4}=31TZrIMb(3f{MY;o-F!Zf@*ZS9Hlqx*R;izsiok>1?%{jxHv(B? O++-V54#wR7LF?b4DD|lT literal 0 HcmV?d00001 diff --git a/tests/tls/jwt/private_key.pem b/tests/tls/jwt/private_key.pem new file mode 100755 index 00000000..1e488c16 --- /dev/null +++ b/tests/tls/jwt/private_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCEApkTPcxFmkmw +foQYX8TIz6hcTgtHEZe2vhTjqpQCIJ02jkSRoDfvpJ1Q2b0/ge3h/hXTuQsZQyid +Np84/pr8TTYfCDMiQzAVBKS/2QOYRgreVU8ETryi+KMalgqWjCaSl5o6Bm2XpAk8 +LXRgkegMYtMjX/fFR5KETZB9pPaLvctMLIfuoAUZVfA5fLJVixXDYZKOdudmNfDK +Rnw6kG0Xuu7bvM2u96yC9i9LlAKLmgp/wgimy80LC+qRuGE70qgUb0rNBN/A03p/ +vO354p9Qd1cdDLBULyev/Jlo7zF1iEDll3cf+eLuPyB9MDv/TyfkzeEd2nir6+Cs +HMSNOyxLAgMBAAECggEABHRJ/KTjKvNlH81vtkV/pamhbAE+JCxrIBa91wi/FxXz ++A6eMFkQSh0V1HqPBiuOKUf3gz4FKoRiRHEUDPTvqdUOdHGZuBg9m8KdBH7VaOKZ +efMK8tbtSoUf4RpwSlrO77dUfuIPT0SRAzTNbndoiwfH9Ajy7/cq8cfkOOPDZeek +d6fGyREgLZIx1+RWa5r685QKpO3RtxUFDqOWiwaEr2axARjUhmpahHF0X5qMawvm +24OWZwoY7n5AcZDodRBr8J5DcWBTqW7N/0tPdhGA2FncLIWIkW0ZkvJlB9AT8SzC +3MV4R3G1Gi0QKloRhlna/lSfKzfnr9HwyTpJobw1wQKBgQC5/aMYRQYmaPkdes7t +pzEYp+Wrddp2M1uRY7mpW0k/iHxnPPaHfGDae3y1zDWYT4p96Te9c2MKlE7hnoVt +4BvAtOR/OLQ3yDfG2Rs2XpUmFbzVyWbjpMtsG0/jS5oIVoKPlJ1YEYzWM5tk8nn2 +K5RbWy11cazKWWLWrCArk84y2wKBgQC1s02mNP7Agj57mcREpimwGJcyshCZEpWq +/12H8DYntA2hCUyvZtBxFA7MCGheUaIy5cAsfQ526kqgKcMKIQjT9VJLMlNQeplz +0CgS+vgV/sGy/D0Y03hgvJRTYTLEfXvs3/Mhf1bWGbQ1jRPTtYwunAoirjcRrrqr +8Fl/bPrPUQKBgE0QhkqhFwpFRqtrXmBkfVhdATIJVCrT3uYgLya4N2KG2B0iyneb +FrqQnjzpz287zgOb5cevDuOsTf74YwsC6BzyFxeL1Eikwk+3V6owiJZOPX9Lw0Eh +4FP8AR8KDVnVFqYNiyCZrQR4P7QVMGnK5t7vqadXIaR6YxTWH0JPLQovAoGBAIij +og0PZVRXna1NYS9O1aK7m1hgV+ME+tBw4WFM3yzUVjt3xtdQtgeTUd1VpUbolNU5 +uV67XJlIb34qaaXAWecrYQtzePvYdnWFX92GJfJEdl2nGjsFLE1zAwgA3DCvPPZR +I4FZRXAUPFTZFsPqjtSuO2EBKiB+CZsrT+JnjeVBAoGBAIq1/IyK8hpDbe/gStXx +eNMXUPGey3+F/G1kVe9Xo84SenNA38kGx74kMYm6Cvfn+gFSmUWhugEC+jWo6gws +xsm+yLsiHacqcg0lltCoW7GVK54yuGM6BVKJFj5UA78MRE4/n5d3jWqQdpdPKwgb +/gijYGi4X4SyHyvAoUCmaQ7r +-----END PRIVATE KEY----- diff --git a/tests/tls/jwt/public_key.pem b/tests/tls/jwt/public_key.pem new file mode 100755 index 00000000..90e9419b --- /dev/null +++ b/tests/tls/jwt/public_key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhAKZEz3MRZpJsH6EGF/E +yM+oXE4LRxGXtr4U46qUAiCdNo5EkaA376SdUNm9P4Ht4f4V07kLGUMonTafOP6a +/E02HwgzIkMwFQSkv9kDmEYK3lVPBE68ovijGpYKlowmkpeaOgZtl6QJPC10YJHo +DGLTI1/3xUeShE2QfaT2i73LTCyH7qAFGVXwOXyyVYsVw2GSjnbnZjXwykZ8OpBt +F7ru27zNrvesgvYvS5QCi5oKf8IIpsvNCwvqkbhhO9KoFG9KzQTfwNN6f7zt+eKf +UHdXHQywVC8nr/yZaO8xdYhA5Zd3H/ni7j8gfTA7/08n5M3hHdp4q+vgrBzEjTss +SwIDAQAB +-----END PUBLIC KEY----- diff --git a/tests/tls/keypass b/tests/tls/keypass new file mode 100755 index 00000000..b1f833ed --- /dev/null +++ b/tests/tls/keypass @@ -0,0 +1 @@ +citrusstore diff --git a/tests/tls/root.cert.pem b/tests/tls/root.cert.pem new file mode 100644 index 00000000..c094800d --- /dev/null +++ b/tests/tls/root.cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEJTCCAw2gAwIBAgIUbMAdEFltKwIimZ+A2pBJxQy8VckwDQYJKoZIhvcNAQEL +BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm +aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG +A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p +QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTQ0ODAzWhcNNDQwNzA2MTQ0ODAzWjCB +mTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNEMRIwEAYDVQQHDAlTcGVhcmZpc2gx +EjAQBgNVBAoMCUFlcm9zcGlrZTESMBAGA1UECwwJIFNESyBUZWFtMRswGQYDVQQD +DBJhZXJvc3Bpa2UtcHJveGltdXMxJDAiBgkqhkiG9w0BCQEWFWRwZWxpbmlAYWVy +b3NwaWtlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/us9JN +gFGtQJqQECMZ3f7dve12VVj1Z7zL69VRgWvDmigl4sBPAzIvPtiN9Iw5oXnKVEZR +3VX1ii07KMYlSEgsCqtb9fTcWD6DTQverHJUSG7MpQCmtHtA8qQwk99TDUMKy3Nc +aJWTFbrT6ezplAVfD0IVTn77Vj3prnBWPOIhAhLOIw1TBrRIk/WU8Be8A31AMgEW +khnIZfPK9Ehi5kzNJMLAlVKIPDReqV9bu9nYD8sTBeXD43Zx4ii/+kZYEQxXpgnm +0thQujp/n87fG7Jt4Tcs01joYg1B1L5ixOk0493bt3C/r1EEyvqOf0RNSBJehUsx +s7KQis8rOWlwJNECAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAYYwHQYDVR0OBBYEFOC/I3zedT/1D4uTHLk8iNJge9OYMB8GA1UdIwQYMBaA +FOC/I3zedT/1D4uTHLk8iNJge9OYMA0GCSqGSIb3DQEBCwUAA4IBAQCX7g+JVOE8 +NqJJmwEUZ1j0+xor+p+gap/3oHiYfqzmd6VYXfo6N+gtkZA7oDoeiXZF5QjbkvKl +G/4Uag/cdOP5rFXHAmaIZt/+e7eLUKxCc7SGQzhoJLkW0T+nY6UoDMyvJ3a+MxY7 +266LRbYmWsozdiQmE+Hhobu+MXoE6tZ3gRJi9Lp5jolTmJr3aQbPB1oxe2zz4zcc +/gg6ugRFDdpM6egmhRYWXZhsgi6MmKde2iXgyLvfeZ/vdMqB0fnMy0gC3Eckc+SL +5NLiOUGTD8H+fTkULITwOKQEP9XSLqvxqaKxK0vz9iI68jBq/8EFH6MarixJBF2v +/XHa5pIGmSAy +-----END CERTIFICATE----- diff --git a/tests/tls/root.crt b/tests/tls/root.crt new file mode 100644 index 00000000..c0a883b8 --- /dev/null +++ b/tests/tls/root.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIUHrjN0H7pFMJnd6GqzO+/ra1pONwwDQYJKoZIhvcNAQEL +BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm +aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG +A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p +QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTQ0ODAzWhcNMzQwNzA5MTQ0ODAzWjCB +mTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNEMRIwEAYDVQQHDAlTcGVhcmZpc2gx +EjAQBgNVBAoMCUFlcm9zcGlrZTESMBAGA1UECwwJIFNESyBUZWFtMRswGQYDVQQD +DBJhZXJvc3Bpa2UtcHJveGltdXMxJDAiBgkqhkiG9w0BCQEWFWRwZWxpbmlAYWVy +b3NwaWtlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/us9JN +gFGtQJqQECMZ3f7dve12VVj1Z7zL69VRgWvDmigl4sBPAzIvPtiN9Iw5oXnKVEZR +3VX1ii07KMYlSEgsCqtb9fTcWD6DTQverHJUSG7MpQCmtHtA8qQwk99TDUMKy3Nc +aJWTFbrT6ezplAVfD0IVTn77Vj3prnBWPOIhAhLOIw1TBrRIk/WU8Be8A31AMgEW +khnIZfPK9Ehi5kzNJMLAlVKIPDReqV9bu9nYD8sTBeXD43Zx4ii/+kZYEQxXpgnm +0thQujp/n87fG7Jt4Tcs01joYg1B1L5ixOk0493bt3C/r1EEyvqOf0RNSBJehUsx +s7KQis8rOWlwJNECAwEAAaNTMFEwHQYDVR0OBBYEFOC/I3zedT/1D4uTHLk8iNJg +e9OYMB8GA1UdIwQYMBaAFOC/I3zedT/1D4uTHLk8iNJge9OYMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAKkztVxX2mJpfV93VKuyDXQ6lgmASjEz +ijUN+n0z+zIuiR7MOGxQP2jgyFuq9ZJxpI4d1GlUgdhLxCEM47B3B9EZEMXaVP97 +bLr7HObM0rZNzfZZCWEO8AyH18kvuwYiy+2OvKfdPlFb767KoIkET4YhVCMmziln +mn7kX2KVuBd/TFqwh2Ti/m3Ng1du6/XVqvvckAYVIUEaoKFdsQZCOLlJbQwwGBDv +ZFWUfoD8ZjXZ3wA4VG/QGV54SZlvLpA1fa2c5Oialw4XYHSA2rd95HcCvm6NSn6a +0zajEByl+MayoIAkfomiXuNtw24s8LJF1iLFZ4lP6PoJrZGVc6UsvrI= +-----END CERTIFICATE----- diff --git a/tests/tls/root.key b/tests/tls/root.key new file mode 100644 index 00000000..6cbd37fe --- /dev/null +++ b/tests/tls/root.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/7rPSTYBRrUCa +kBAjGd3+3b3tdlVY9We8y+vVUYFrw5ooJeLATwMyLz7YjfSMOaF5ylRGUd1V9Yot +OyjGJUhILAqrW/X03Fg+g00L3qxyVEhuzKUAprR7QPKkMJPfUw1DCstzXGiVkxW6 +0+ns6ZQFXw9CFU5++1Y96a5wVjziIQISziMNUwa0SJP1lPAXvAN9QDIBFpIZyGXz +yvRIYuZMzSTCwJVSiDw0XqlfW7vZ2A/LEwXlw+N2ceIov/pGWBEMV6YJ5tLYULo6 +f5/O3xuybeE3LNNY6GINQdS+YsTpNOPd27dwv69RBMr6jn9ETUgSXoVLMbOykIrP +KzlpcCTRAgMBAAECggEACt6+VhLb+Yw9Fl/iPRWvBSsqcX1oIycXbGm1ciX5BSkd +ZQiTw3naG8yRk+7SvsIZEUpubFLgvOiAjlQdWJ8GDWnaoxa8yuTTldtGeN2QMVOx +DD7oea1nV3tvvpEuf8l+rNlKuV5ugSmk03li5E88ihMWnHLT2LTb/xrJ7Yxxy2nz +RDBsZDQ2GWmY1HwRVt+5JmDOdavChX7/tNgOTMl6pY/5GK1IVOUza48Msw7ZSRM6 +LR41qXS183jpssOlSfT78fjQ508waoTn8YdE2tBnyKYviEl8/JTWw+wJ+dunnCka +c+vv/uY842TbC9m+eZIQDNKC22w4QpPinTWEOvVBIQKBgQD4dondGand40p4Nssl +aLDVWhB7pIKGyPFk2onVBVIqsc1MbH+jcqwFt36Ic2XLnTI2rIdTmmU5p2Mnh+Im +iKDSULNOYpaCvYPD5mkwZQCZRIqq1brFNs6qwGjVU+s3+sSxRfFj3mk0ZMAzx56P +Yd95MZRUiOwe9iWsno0/IdfcIQKBgQDFwSumNJcW74ZV/GUzWPNBECYkDa+ScXC6 +NzD/rxb2SeBlaE1m9U/2uR/BC04J3XDQOnckFNSzgzUDecrGQSFk9GnICbq6jmIK +wLhWEcmsY+W+Q8B/9Pq4PB9nJbGNpHkulBPnlRkJfHYmkC3sk/nMdGxKdsBjmoVd +lQI/t+KysQKBgQD1Me39fw0OhvZ/yfsSMM2JzvbDPeb94qGuWKh6y2R587tZNx2D +DHBMt/er6s3DcZ8TK5Hk5FIO4mxMn6GDS4QB6Vf5+/ryjNnS4rhd5N8BYg3CZ2eI +pfyvr3AFTmqrdNLU6uQ8HUoPRXoT32RPtVOXQ2FRR0pVh65IOrPDYL+oYQKBgGZn +NoQ1vXuqA0Vpkro5OJYbl7SZxa4uwjIbvGraryhQbzvz/AjxxTu8932OrhWbrvyV +Gfb8NnzS19P58JAjT/ioPFLS/vf2HTz2OT6QrX9wp5qUGQ3pvR9EOvq94Si43+vH +0FresX1hDwm/JZjZs8Q1EZKp1cx+SsuACw8V2PWxAoGASbTkb+bNTmxm1fr+RxtH +n/sWNVEvQJyr39NQd/ppz/n4sGKPXsowzp+Jw5j2Kp8dZiXA7c2R0iJMJye0mdVo +Cz6AvJI6Z9Cbq4X2vOHigl/a2RYqoqKzNE2kzuftH+KSpXOI1OYVAGYCGj0pqVNs +7wMWeCoynScUAqsPYm/sCGY= +-----END PRIVATE KEY----- diff --git a/tests/tls/root.key.pem b/tests/tls/root.key.pem new file mode 100644 index 00000000..6cbd37fe --- /dev/null +++ b/tests/tls/root.key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/7rPSTYBRrUCa +kBAjGd3+3b3tdlVY9We8y+vVUYFrw5ooJeLATwMyLz7YjfSMOaF5ylRGUd1V9Yot +OyjGJUhILAqrW/X03Fg+g00L3qxyVEhuzKUAprR7QPKkMJPfUw1DCstzXGiVkxW6 +0+ns6ZQFXw9CFU5++1Y96a5wVjziIQISziMNUwa0SJP1lPAXvAN9QDIBFpIZyGXz +yvRIYuZMzSTCwJVSiDw0XqlfW7vZ2A/LEwXlw+N2ceIov/pGWBEMV6YJ5tLYULo6 +f5/O3xuybeE3LNNY6GINQdS+YsTpNOPd27dwv69RBMr6jn9ETUgSXoVLMbOykIrP +KzlpcCTRAgMBAAECggEACt6+VhLb+Yw9Fl/iPRWvBSsqcX1oIycXbGm1ciX5BSkd +ZQiTw3naG8yRk+7SvsIZEUpubFLgvOiAjlQdWJ8GDWnaoxa8yuTTldtGeN2QMVOx +DD7oea1nV3tvvpEuf8l+rNlKuV5ugSmk03li5E88ihMWnHLT2LTb/xrJ7Yxxy2nz +RDBsZDQ2GWmY1HwRVt+5JmDOdavChX7/tNgOTMl6pY/5GK1IVOUza48Msw7ZSRM6 +LR41qXS183jpssOlSfT78fjQ508waoTn8YdE2tBnyKYviEl8/JTWw+wJ+dunnCka +c+vv/uY842TbC9m+eZIQDNKC22w4QpPinTWEOvVBIQKBgQD4dondGand40p4Nssl +aLDVWhB7pIKGyPFk2onVBVIqsc1MbH+jcqwFt36Ic2XLnTI2rIdTmmU5p2Mnh+Im +iKDSULNOYpaCvYPD5mkwZQCZRIqq1brFNs6qwGjVU+s3+sSxRfFj3mk0ZMAzx56P +Yd95MZRUiOwe9iWsno0/IdfcIQKBgQDFwSumNJcW74ZV/GUzWPNBECYkDa+ScXC6 +NzD/rxb2SeBlaE1m9U/2uR/BC04J3XDQOnckFNSzgzUDecrGQSFk9GnICbq6jmIK +wLhWEcmsY+W+Q8B/9Pq4PB9nJbGNpHkulBPnlRkJfHYmkC3sk/nMdGxKdsBjmoVd +lQI/t+KysQKBgQD1Me39fw0OhvZ/yfsSMM2JzvbDPeb94qGuWKh6y2R587tZNx2D +DHBMt/er6s3DcZ8TK5Hk5FIO4mxMn6GDS4QB6Vf5+/ryjNnS4rhd5N8BYg3CZ2eI +pfyvr3AFTmqrdNLU6uQ8HUoPRXoT32RPtVOXQ2FRR0pVh65IOrPDYL+oYQKBgGZn +NoQ1vXuqA0Vpkro5OJYbl7SZxa4uwjIbvGraryhQbzvz/AjxxTu8932OrhWbrvyV +Gfb8NnzS19P58JAjT/ioPFLS/vf2HTz2OT6QrX9wp5qUGQ3pvR9EOvq94Si43+vH +0FresX1hDwm/JZjZs8Q1EZKp1cx+SsuACw8V2PWxAoGASbTkb+bNTmxm1fr+RxtH +n/sWNVEvQJyr39NQd/ppz/n4sGKPXsowzp+Jw5j2Kp8dZiXA7c2R0iJMJye0mdVo +Cz6AvJI6Z9Cbq4X2vOHigl/a2RYqoqKzNE2kzuftH+KSpXOI1OYVAGYCGj0pqVNs +7wMWeCoynScUAqsPYm/sCGY= +-----END PRIVATE KEY----- diff --git a/tests/tls/root.srl b/tests/tls/root.srl new file mode 100644 index 00000000..4fc0a683 --- /dev/null +++ b/tests/tls/root.srl @@ -0,0 +1 @@ +3EAE04C5CD61B3EF75A61F28582932CE525F55A0 diff --git a/tests/tls/root.truststore.jks b/tests/tls/root.truststore.jks new file mode 100644 index 0000000000000000000000000000000000000000..f40343732cbb51707e672febe555494e8257081d GIT binary patch literal 1414 zcmV;11$p`~f(3#C0Ru3C1uO;$Duzgg_YDCD0ic2f9Rz{}88Ctc6)=JY5e5k=hDe6@ z4FLxRpn?SgFoFdB0s#Opf&}*l2`Yw2hW8Bt2LUi<1_>&LNQU*#)ClCSwATSID2r7n1hW8Bu2?YQ! z9R>+thDZTr0|Wso1Q0LJ{d~T+Q%*t#g7sIPf98OK1b~b8spFx>nODNnk+f{JlBm~d z_x1(~U4XPv@VtT2Pp+v9HmJ-w)@y&RV)yt4HJA2wf?Vz4OgY*>la*`f^jY1NXmsJLxnSW@!V>P|9mKoavpQk zu4(2mFvxjpSigHfOY>t~L;- z%Z`n$&X~5#y|``VmyfRV1N>9wLl-*LUj+MdeW|dG zO^u*jUY&f&7Is5#Ez)fqn#RE{lHiVzR@krn$wh%k+&>6N&5e-Ew&{4OEw}vIS2x+6 z8kPxxx6^0o+2`V()l|xe(4%2zN;n;Mez~K`aBlrx)Fe1IWeVceF{=k(lx*7k7#BiE zXj=m>`Dr?^qV4S(cF;a(o9E}LG`xQ5`A?+|3c7Vi7s#F#z;WOAzE-pbV-wxPG0q0F zx(sFQ%1>Lp0lG;ANKMXhIhbK)lav7NR)jmCQ3M&n3$epU)*Lfo2{FFbIxp1(SeIv} z_Y2npF=W8~hEVz-(_bU{?O07a@0Ry;Up!GRps?}BB6Z8=Aj4PSL3%<>tl5u$-%1!O z()QfFNmOMP=Ul--YOA3OBKse99?vQfM@fkOsd!1~TX!S_69govOUMVX8ObTe2_f{c3*1@#w32xMy@8S{gPbdGMF8H* zU?rHEa3-V@zQdyvY3)KX7L&-#Vt~hb5dENSDh6jRfM_uk8gRppwnMm_I+BYZ~ho=lmigOr+!va%nXI z)+nC9UddDJi3`z0sKUiu-Jx7#f8xr{li0FWFxKtN`}{et5REDVGo2H04Y0zp+rhLi zY%N5D6<6K^uhBy#D0_%sTYuOJ=>&ErA5G zbTVIK%0UD4r(#HXr^bKU&e*B&U=Xo-1;sNIyX>=2?PIBxglVN6%6vBYv24r^HN)vb z2?0WTZCx@#X|``y?c|f5ed#J`ql}Rk#*xzp`wcZWCvN}tTn`6@B}Xt#FflL<1_@w> zNC9O71OfpC00bbwmQkH`_ Date: Thu, 11 Jul 2024 08:50:08 -0600 Subject: [PATCH 079/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 57441695..79a6ebe6 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -146,7 +146,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host root --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs working-directory: tests @@ -239,7 +239,7 @@ jobs: cat tls/brawn.key.pem cat tls/brawn.crt - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest standard/sync -s --host brawn--port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs working-directory: tests \ No newline at end of file From 408007d8a9ea6e54ca974f0b754bc1fcbf49aae6 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:54:36 -0600 Subject: [PATCH 080/215] Added static files --- .gitignore | 2 - tests/aerospike-proximus.yml | 121 +++++++++++++++++++++++++++++++++++ tests/aerospike.conf | 72 +++++++++++++++++++++ 3 files changed, 193 insertions(+), 2 deletions(-) create mode 100755 tests/aerospike-proximus.yml create mode 100755 tests/aerospike.conf diff --git a/.gitignore b/.gitignore index 38b71458..b5a7d648 100644 --- a/.gitignore +++ b/.gitignore @@ -158,8 +158,6 @@ cython_debug/ # Vector search test files tests/siftsmall/* tests/siftsmall.tar.gz -tests/aerospike-proximus.yml -tests/aerospike.conf tests/features.conf tests/assets/features.conf diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml new file mode 100755 index 00000000..450eee96 --- /dev/null +++ b/tests/aerospike-proximus.yml @@ -0,0 +1,121 @@ +# Change the configuration for your use case. +# See: https://aerospike.com/docs/vector + +cluster: + # Unique identifier for this cluster. + cluster-name: aerospike-proximus + + # Custom node-id as 8 byte long in Hexadecimal format. + # It will be auto-generated if not specified. + # node-id: a1 + +# If TLS is desired, TLS configuration ids used +# and associated TLS configurations. +# +tls: + service-tls: + trust-store: + store-file: /etc/aerospike-proximus/tls/root.truststore.jks + store-password-file: /etc/aerospike-proximus/tls/storepass + key-store: + store-file: /etc/aerospike-proximus/tls/brawn.keystore.jks + store-password-file: /etc/aerospike-proximus/tls/storepass + key-password-file: /etc/aerospike-proximus/tls/keypass + mutual-auth: true + # Client certificate subject names that are allowed + allowed-peer-names: + - brawn +# interconnect-tls: +# trust-store: +# store-file: tls/ca.aerospike.com.truststore.jks +# store-password-file: tls/storepass +# key-store: +# store-file: tls/proximus.aerospike.com.keystore.jks +# store-password-file: tls/storepass +# key-password-file: tls/keypass +# override-tls-hostname: proximus.aerospike.com +# +# aerospike-tls: +# trust-store: +# store-file: tls/ca.aerospike.com.truststore.jks +# store-password-file: tls/storepass +# key-store: +# store-file: tls/proximus.aerospike.com.keystore.jks +# store-password-file: tls/storepass +# key-password-file: tls/keypass +# override-tls-hostname: asd.aerospike.com + + +# The Proximus service listening ports, TLS and network interface. +service: + ports: + 5000: + addresses: + localhost + # If TLS needs to be enabled, tls configuration id. + tls-id: service-tls + + # Required when running behind NAT + advertised-listeners: + default: + # List of externally accessible addresses and + # ports for this Proximus instance. + - address: brawn + port: 5000 +# Management API listening ports, TLS and network interface. +manage: + ports: + 5040: + addresses: + localhost + # If TLS needs to be enabled, tls configuration id. + #tls-id: service-tls + + +# Intra cluster interconnect listening ports, TLS and network interface. +interconnect: + # Interconnect client side TLS configuration + # when TLS is enabled for interconnect + # client-tls-id: interconnect-tls + ports: + 5001: + addresses: + localhost + # If interconnect TLS needs to be enabled. + #tls-id: interconnect-tls + +#heartbeat: +# # Seed nodes to discover and form a cluster. +# seeds: +# - address: localhost +# port: 6001 + +# To enable client authentication + +security: + auth-token: + private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem + public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem + token-expiry: 300_000 + +# Target Aerospike cluster +aerospike: + seeds: + - localhost: + port: 3000 + + client-policy: + max-conns-per-node: 1000 + #tls-id: aerospike-tls + # + # Aerospike credentials if required. + #credentials: + # username: admin + # password-file: aerospike-password.txt + +# The logging properties. +#logging: +# #file: /var/log/aerospike-proximus/aerospike-proximus.log +# enable-console-logging: true +# levels: +# root: debug diff --git a/tests/aerospike.conf b/tests/aerospike.conf new file mode 100755 index 00000000..a7c979df --- /dev/null +++ b/tests/aerospike.conf @@ -0,0 +1,72 @@ + +# Aerospike database configuration file +# This template sets up a single-node, single namespace developer environment. +# +# Alternatively, you can pass in your own configuration file. +# You can see more examples at +# https://github.com/aerospike/aerospike-server/tree/master/as/etc + +# This stanza must come first. +service { + feature-key-file /etc/aerospike/features.conf + cluster-name proximus +} + +logging { + + + + + + # Send log messages to stdout + console { + context any info + } +} + +network { + service { + address any + port 3000 + + # Uncomment the following to set the 'access-address' parameter to the + # IP address of the Docker host. This will the allow the server to correctly + # publish the address which applications and other nodes in the cluster to + # use when addressing this node. + # access-address + } + + heartbeat { + # mesh is used for environments that do not support multicast + mode mesh + address local + port 3002 + interval 150 + timeout 10 + } + + fabric { + # Intra-cluster communication port (migrates, replication, etc) + # default to same address in 'service' + address local + port 3001 + } + +} + +namespace proximus-meta { + replication-factor 2 +storage-engine memory { + data-size 2G +} +nsup-period 100 +} + +namespace test { + replication-factor 2 + storage-engine memory { + data-size 1G + } + nsup-period 60 +} + From 7bceebd0b2cf356a5efc79bf740ea87f6e49e10b Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 08:57:09 -0600 Subject: [PATCH 081/215] Update aerospike-proximus.yml --- tests/aerospike-proximus.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml index 450eee96..4904c327 100755 --- a/tests/aerospike-proximus.yml +++ b/tests/aerospike-proximus.yml @@ -51,7 +51,7 @@ service: ports: 5000: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. tls-id: service-tls @@ -67,7 +67,7 @@ manage: ports: 5040: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -80,7 +80,7 @@ interconnect: ports: 5001: addresses: - localhost + 0.0.0.0 # If interconnect TLS needs to be enabled. #tls-id: interconnect-tls From 10c624fa1ed90771d7a265bc1e828f6b670f74e9 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 09:05:55 -0600 Subject: [PATCH 082/215] test --- .github/workflows/integration_test.yml | 4 ++-- tests/aerospike-proximus.yml | 6 +++--- tests/gen.sh | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 79a6ebe6..52822d3f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -146,7 +146,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs + python -m pytest rbac/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs working-directory: tests @@ -239,7 +239,7 @@ jobs: cat tls/brawn.key.pem cat tls/brawn.crt - python -m pytest standard/sync -s --host brawn--port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest rbac/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs working-directory: tests \ No newline at end of file diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml index 4904c327..450eee96 100755 --- a/tests/aerospike-proximus.yml +++ b/tests/aerospike-proximus.yml @@ -51,7 +51,7 @@ service: ports: 5000: addresses: - 0.0.0.0 + localhost # If TLS needs to be enabled, tls configuration id. tls-id: service-tls @@ -67,7 +67,7 @@ manage: ports: 5040: addresses: - 0.0.0.0 + localhost # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -80,7 +80,7 @@ interconnect: ports: 5001: addresses: - 0.0.0.0 + localhost # If interconnect TLS needs to be enabled. #tls-id: interconnect-tls diff --git a/tests/gen.sh b/tests/gen.sh index b0b88eba..2920a402 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -404,11 +404,11 @@ EOF # Check if the line exists in /etc/hosts - #if ! grep -qF "$line" /etc/hosts; then - # # Add the line to /etc/hosts - # echo "$line" | sudo tee -a /etc/hosts > /dev/null - # echo "Entry added to /etc/hosts." - #fi + if ! grep -qF "$line" /etc/hosts; then + # Add the line to /etc/hosts + echo "$line" | sudo tee -a /etc/hosts > /dev/null + echo "Entry added to /etc/hosts." + fi elif [[ "$mutual_auth_maybe" == "n" ]]; then generate_derivative_certs "child" "child" @@ -469,11 +469,11 @@ EOF # Check if the line exists in /etc/hosts - #if ! grep -qF "$line" /etc/hosts; then - # # Add the line to /etc/hosts - # echo "$line" | sudo tee -a /etc/hosts > /dev/null - # echo "Entry added to /etc/hosts." - #fi + if ! grep -qF "$line" /etc/hosts; then + # Add the line to /etc/hosts + echo "$line" | sudo tee -a /etc/hosts > /dev/null + echo "Entry added to /etc/hosts." + fi fi fi From a9190c941d4db9128d2055f8af4f9da36d5ca8a8 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 09:10:30 -0600 Subject: [PATCH 083/215] CI/CD tests --- .github/workflows/integration_test.yml | 2 +- tests/aerospike-proximus.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 52822d3f..d6488d1e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -50,7 +50,7 @@ jobs: - name: create config run: | - #assets/call_gen_normal.sh + assets/call_gen_normal.sh cat /etc/hosts working-directory: tests diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml index 450eee96..4904c327 100755 --- a/tests/aerospike-proximus.yml +++ b/tests/aerospike-proximus.yml @@ -51,7 +51,7 @@ service: ports: 5000: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. tls-id: service-tls @@ -67,7 +67,7 @@ manage: ports: 5040: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -80,7 +80,7 @@ interconnect: ports: 5001: addresses: - localhost + 0.0.0.0 # If interconnect TLS needs to be enabled. #tls-id: interconnect-tls From 0ed057c412a4fcdca2bc67320f7fb7bf00cdfa21 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 09:17:50 -0600 Subject: [PATCH 084/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index d6488d1e..5a4e98dd 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -116,6 +116,10 @@ jobs: - name: Create .rnd file if it doesn't exist run: touch $HOME/.rnd + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + - name: create config run: | #assets/call_gen_tls.sh @@ -199,6 +203,10 @@ jobs: - name: Create .rnd file if it doesn't exist run: touch $HOME/.rnd + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + - name: create config run: | #assets/call_gen.sh From f8786e418bb3a015886c60b585cb83a2d1d78a2d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 09:36:15 -0600 Subject: [PATCH 085/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 5a4e98dd..f8124581 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -57,7 +57,7 @@ jobs: - name: Run unit tests run: | - docker run -d --network=host -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest @@ -119,7 +119,7 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - + - name: create config run: | #assets/call_gen_tls.sh @@ -129,7 +129,7 @@ jobs: - name: Run unit tests run: | - docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --name aerospike-proximus -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 1 @@ -216,7 +216,7 @@ jobs: - name: Run unit tests run: | - docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --name aerospike-proximus -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 1 From 8e762ebbdab4f93ce2b87f1926e82a53ee866f8c Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 09:57:46 -0600 Subject: [PATCH 086/215] CI/CD update --- tests/aerospike-proximus.yml | 6 ++-- tests/tls/brawn.crt | 32 ++++++++--------- tests/tls/brawn.csr | 24 ++++++------- tests/tls/brawn.key | 52 +++++++++++++-------------- tests/tls/brawn.key.encrypted.pem | 56 +++++++++++++++--------------- tests/tls/brawn.key.pem | 52 +++++++++++++-------------- tests/tls/brawn.keystore.jks | Bin 2782 -> 2798 bytes tests/tls/brawn.p12 | Bin 2723 -> 2739 bytes tests/tls/jwt/private_key.pem | 52 +++++++++++++-------------- tests/tls/jwt/public_key.pem | 14 ++++---- tests/tls/root.cert.pem | 34 +++++++++--------- tests/tls/root.crt | 32 ++++++++--------- tests/tls/root.key | 52 +++++++++++++-------------- tests/tls/root.key.pem | 52 +++++++++++++-------------- tests/tls/root.srl | 2 +- tests/tls/root.truststore.jks | Bin 1414 -> 1414 bytes 16 files changed, 230 insertions(+), 230 deletions(-) diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml index 4904c327..450eee96 100755 --- a/tests/aerospike-proximus.yml +++ b/tests/aerospike-proximus.yml @@ -51,7 +51,7 @@ service: ports: 5000: addresses: - 0.0.0.0 + localhost # If TLS needs to be enabled, tls configuration id. tls-id: service-tls @@ -67,7 +67,7 @@ manage: ports: 5040: addresses: - 0.0.0.0 + localhost # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -80,7 +80,7 @@ interconnect: ports: 5001: addresses: - 0.0.0.0 + localhost # If interconnect TLS needs to be enabled. #tls-id: interconnect-tls diff --git a/tests/tls/brawn.crt b/tests/tls/brawn.crt index b8e5249b..8a76ef43 100644 --- a/tests/tls/brawn.crt +++ b/tests/tls/brawn.crt @@ -1,23 +1,23 @@ -----BEGIN CERTIFICATE----- -MIIDyTCCArGgAwIBAgIUPq4Exc1hs+91ph8oWCkyzlJfVaAwDQYJKoZIhvcNAQEL +MIIDyTCCArGgAwIBAgIUMij/pbwGviyZpK6mp88qghxc25UwDQYJKoZIhvcNAQEL BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p -QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTQ0ODAzWhcNMzQwNzA5MTQ0ODAzWjBE +QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTU1NzIwWhcNMzQwNzA5MTU1NzIwWjBE MQswCQYDVQQGEwJJTjELMAkGA1UECAwCS0ExGDAWBgNVBAoMD0Flcm9zcGlrZSwg SW5jLjEOMAwGA1UEAwwFYnJhd24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCYSnUh1TtiTgeRqRl+AHW5GoKpxG0AKhg5gvJlFpKj7zbPfzUv9eHEUgr5 -EKS07zeStyMwLsxNUqSvAKko9yeGW8VPnT3WQ39mceGrpKwUe4nl4n5pcCSywJz/ -1uJCZVXcSy7JOUuqHi+m2fMDfgSJEeSKeV/yRA6MRP59Q/tYyHLLUj7Fsh5C+oTI -KzHK1w8CFABFp1pRSfsnujP9GV0CDXjtYWTa2xWrTYXYClFiWHgKwLQ18C4/xZPj -xyNDSoovPdb+YiKwzHD8//EC+DImf1jEg2RvjORMRW0IlpY2rjeQ8Pfjl2E4pxHu -0dsrSYyBHZ3HD2q5G17UJP12Cq1LAgMBAAGjXTBbMBkGA1UdEQQSMBCCBWJyYXdu -ggcqLmJyYXduMB0GA1UdDgQWBBS/+8nIUvKZA/OctrRXPTk9qV7xnDAfBgNVHSME -GDAWgBTgvyN83nU/9Q+Lkxy5PIjSYHvTmDANBgkqhkiG9w0BAQsFAAOCAQEAGRcy -xvZHWru4U6WO7D5ZPxA8/poWNCzmH5qYu/sHdd5Rys7gEBxfoZYFNmxycZbvCN5B -OD74M0aiu6d849cwyTzeaxu7/z7gJGM17sjLvyin5NvQ63SGzt5ohLkOXUd9tJTX -S7fedB0Y2eflrhW3JhFQuIcihG+FNEY10+0XB/WJ+b1sX0mskw5xSSw0QRFbKW6v -x3yb5FsvnVZayg5J8xJhwTm3SnxV/ZiKZ8sZjTuD6jXYAR6WuNptyKvCQCUtGcNu -qcjk+P0jzwIGkjITbM3bD7LCubxwnXwrQFg/7J2nAw4OgJdrOIY14nsizJ3AQs7i -DkEJbPlkVlXp4sQ6zA== +AoIBAQDoQyl1Gq9UPJ/VD3lCQ87u+P2hiPhJoC/GH7Z9GYcqEwrz1QiK2Q4Vuhsp +Mr2/9CaNnTrx0vbzGZ4A1uTCEWx6tAA/I1Uzh4o76c0F3japG0QsjnRILeno6OCY +1WBDi90QtrpW/lvEI0kCle5rF5gk0DJjjzlwiuyxzfc+MZNMJNtgDzgHkW1gbQ5h +c0OdLHmOgvbl3RePLF3hUr6KfvgkNmB/aINmQOxXqR1UI7G3mvQu7Twz+PtFT+GJ +YSTaQDnOHo/Msm6ikpoW0/5XtNnv6VRjrf3KO6WUHFjz0+j3hJ3ddy9zXcEJPfIA +NZuuAj9E7YndNWX36cTe3mwL4TaVAgMBAAGjXTBbMBkGA1UdEQQSMBCCBWJyYXdu +ggcqLmJyYXduMB0GA1UdDgQWBBQdXaD08vNzfqHIwcTSULbgJpW5pDAfBgNVHSME +GDAWgBTAFJZAkhKzJsAi+T3S1FrHf11PpTANBgkqhkiG9w0BAQsFAAOCAQEAXmON +bE6XZ4Nh8+fEqudboJCU54CFReF+voVawNNCAEXQR3x36HvvlAq4mI9aq7E8n++H +ulE1PD4RqfabBIto+90h7h1HI+BGXMOp+PuUaNjAajQleJHpU5yhmYt/F7rFpqN+ +c9u/rMi/CXPrLzAx0CtfVPnX3MAEuKkXZWqHEfEHtG7kNG30jGIM50qTCEKeqKCs +XrZtBqYK73BC1EPlaj9ethesI6lEShm6s1hvZDNYVZfzA1VTGCkMpgwrvlg/OzC7 +LAQFkg1BT7Wzu9fF6+htICENOTWpFYBCJyjJUa/n58RoIFNpIqKSMuuEqUOfAUkh +j1CnIgCTWKBR7iAmxQ== -----END CERTIFICATE----- diff --git a/tests/tls/brawn.csr b/tests/tls/brawn.csr index 17d0fcde..86064556 100644 --- a/tests/tls/brawn.csr +++ b/tests/tls/brawn.csr @@ -1,17 +1,17 @@ -----BEGIN CERTIFICATE REQUEST----- MIICtTCCAZ0CAQAwRDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMRgwFgYDVQQK DA9BZXJvc3Bpa2UsIEluYy4xDjAMBgNVBAMMBWJyYXduMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAmEp1IdU7Yk4HkakZfgB1uRqCqcRtACoYOYLyZRaS -o+82z381L/XhxFIK+RCktO83krcjMC7MTVKkrwCpKPcnhlvFT5091kN/ZnHhq6Ss -FHuJ5eJ+aXAkssCc/9biQmVV3EsuyTlLqh4vptnzA34EiRHkinlf8kQOjET+fUP7 -WMhyy1I+xbIeQvqEyCsxytcPAhQARadaUUn7J7oz/RldAg147WFk2tsVq02F2ApR -Ylh4CsC0NfAuP8WT48cjQ0qKLz3W/mIisMxw/P/xAvgyJn9YxINkb4zkTEVtCJaW -Nq43kPD345dhOKcR7tHbK0mMgR2dxw9quRte1CT9dgqtSwIDAQABoCwwKgYJKoZI +AQEFAAOCAQ8AMIIBCgKCAQEA6EMpdRqvVDyf1Q95QkPO7vj9oYj4SaAvxh+2fRmH +KhMK89UIitkOFbobKTK9v/QmjZ068dL28xmeANbkwhFserQAPyNVM4eKO+nNBd42 +qRtELI50SC3p6OjgmNVgQ4vdELa6Vv5bxCNJApXuaxeYJNAyY485cIrssc33PjGT +TCTbYA84B5FtYG0OYXNDnSx5joL25d0Xjyxd4VK+in74JDZgf2iDZkDsV6kdVCOx +t5r0Lu08M/j7RU/hiWEk2kA5zh6PzLJuopKaFtP+V7TZ7+lUY639yjullBxY89Po +94Sd3Xcvc13BCT3yADWbrgI/RO2J3TVl9+nE3t5sC+E2lQIDAQABoCwwKgYJKoZI hvcNAQkOMR0wGzAZBgNVHREEEjAQggVicmF3boIHKi5icmF3bjANBgkqhkiG9w0B -AQsFAAOCAQEARYwBIhgAkhuBTg6wKJ+9MIar6o/FoxpZmrcnNn+z2n1JsCMR3o8T -UOpgt9neBujECCiStnBaqVmGuKHGmhYe12cundz10e0lRG2UDproaxS39Msp9PD5 -PJVh7GD2fQ4skLtx7KBjhdf8HrQQGHbHcuf/pA1hs9CNPaNTm2MEuUDCPcN8kYRP -luZ0C35/BCb34JW7NjDi/fYGOmaSgh0zL1LQyt1VW/TKSG3n6Xec4fX2sLDZyvEF -X1Ua8OgZ7QOPrDMFLJTfKHKpZ6ACSgcd6WAGaXBCrwzn9cC3Uy4BJ+9Ewd2j+vxM -dng/ApYue+vrTbOWeIeGwzivcrXx2156Hw== +AQsFAAOCAQEAd+mEI51qQ4eMTPpQIAcXGr0LdnHxHfrswF3MgfLIYWaHZzp/4tp/ +RifVPwcuL6UXPYKSNtIfT7KV3ag9anqHeHLZhxtGyYhAC34z17alAN1cgkr8M3Lz +mRArej3GkJM41ZlVRs5yp9uwCWJLbAs2h6XwKhUyeY0LfVZ7aW3IGk13NA4mWTj+ +kqohNQTh3TABEFxIOG9lUfjqByz/+3Q5zizpePpQWUUz+HEjJpsoycMeNzq7BJLE +H4zwCZhCrzUCwvtkzbzNYDsQKCTE/jHjWSr3t9UwB6fP2bRow+/DrBB6B3ej8idV +QX5ancMClTtQLwhI89XnddNXUnkYMzT+TQ== -----END CERTIFICATE REQUEST----- diff --git a/tests/tls/brawn.key b/tests/tls/brawn.key index d58bfe18..68a04e88 100644 --- a/tests/tls/brawn.key +++ b/tests/tls/brawn.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQCYSnUh1TtiTgeR -qRl+AHW5GoKpxG0AKhg5gvJlFpKj7zbPfzUv9eHEUgr5EKS07zeStyMwLsxNUqSv -AKko9yeGW8VPnT3WQ39mceGrpKwUe4nl4n5pcCSywJz/1uJCZVXcSy7JOUuqHi+m -2fMDfgSJEeSKeV/yRA6MRP59Q/tYyHLLUj7Fsh5C+oTIKzHK1w8CFABFp1pRSfsn -ujP9GV0CDXjtYWTa2xWrTYXYClFiWHgKwLQ18C4/xZPjxyNDSoovPdb+YiKwzHD8 -//EC+DImf1jEg2RvjORMRW0IlpY2rjeQ8Pfjl2E4pxHu0dsrSYyBHZ3HD2q5G17U -JP12Cq1LAgMBAAECgf9RXGJyxIx/M6b+787WH97saAJS/2Ltx0Czx99CIn5cyA3i -zU5iAl2H54gcnALFRQhERjDVPlKs1VLXjpaCh2Ez8L/IF8OPK0VbTo/fwS4Gr6rV -JlOeARCt0Zw2dTSTf2iucBnJ3ZdT6Rtkzal9R9YQx1cDQYZPwNE/9+sSFRhay8GB -4a8Zchu5aZ59aSbcuLm3dywgMJSIkhZKBMmSBbfCv/QMMSE56UC03YGT51rcchjp -BWYAFvpI0LYGWUlvSZS0z+qoF0E+5gB1pOXiTCOPVKSTlaDHJaC/xt/kmF9Y98Yi -T5uEOTCsen6lD9G4XkdCNPKPX68m13Ayu/xw0hECgYEA06wSC5UUrdTbkIDDdomo -c8CuukyYt/2AmrNe80OapRNxf4XAOS06G66YfF/Gc45O/UTqGtrVbD9IlzXhJncc -LwfhiOa7nUByYFx32okR1JJl19TqzDxHCOP4f/YRe3VyWpgEvSR+nJ9F/R94tlMy -Ga2Ky70aS2rOL+BXTfXPZB0CgYEAuC7nSvuH4pPgixERb9+C40pAxACWGHqF+8kb -nRD10/uOZjPP66//+NS/SykHFpC9GlvKNvnd5QJQywRR0pWLe7SXUtSKd2srYiu0 -fCWXtWL8nZ5Aq63vSL2ABirWY7eGpoAbXQyWb/x7sMy5CAYaVLZx5QyGFkJf8tZl -YrgGyocCgYBmN5H/Rd7WkxP0lDnP5GoUe9fk31hggWq5SiVwFBV54gnNKynIcq68 -73NznEyZQP+kDsN+dG7b9zN20e4IRTy2+XdQRRwUtCqHnh/CyK5zmL7Vm1xHhFRJ -Vs2J/aozlGPEm+St8hGyULfbpHcGlOZ8v/Fmscsg4FLxi8SdQTcFgQKBgDZ1l+ox -6YHzW6eDCnbbzeXK5M+PpNHkGI3UbxfIFgfyD67kjwwPZE59CXr9zJy9e0y561bK -FvRJ9P2yb0cm9LFFOqFBOxgIVjGW3qz+qJb3h95LFrAso94MOjiYnf+qGmRM6Mpg -mHLQYvpp7iQTOeHmeFLTmyolwh0Zi6ze4RMtAoGAbYTqaJMJ4X8+eHykM5WvMfXW -pSfEoLSxV5x3udoNKBRvPj22upLWX3v5NiF6bDe1wrgkvQ5/eQqgFB7V0+7vwl8s -qhf2sXwXA3KuzBeb5+Py6XaeBWo4Nc/gLhCywWIvCgbZzWofPGkffDcDS0RVAJSn -LlV2vQlMzHUS8fAWYPU= +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDoQyl1Gq9UPJ/V +D3lCQ87u+P2hiPhJoC/GH7Z9GYcqEwrz1QiK2Q4VuhspMr2/9CaNnTrx0vbzGZ4A +1uTCEWx6tAA/I1Uzh4o76c0F3japG0QsjnRILeno6OCY1WBDi90QtrpW/lvEI0kC +le5rF5gk0DJjjzlwiuyxzfc+MZNMJNtgDzgHkW1gbQ5hc0OdLHmOgvbl3RePLF3h +Ur6KfvgkNmB/aINmQOxXqR1UI7G3mvQu7Twz+PtFT+GJYSTaQDnOHo/Msm6ikpoW +0/5XtNnv6VRjrf3KO6WUHFjz0+j3hJ3ddy9zXcEJPfIANZuuAj9E7YndNWX36cTe +3mwL4TaVAgMBAAECggEAHmZ8DKnbfQkaWobV9kht03WfrP8CkJB48FPCTQmEWYt4 +iYW+wn26jDl5yKCtmWxZh3um9XQJgrQ9rBp0grpJGp5o0drMEhyRiVoGzdfSC7xX +5gUXT0NDNIsWqqpzGSQ7YS6poS1V0YxUyBPbywShk1/02Hcsq4BjjrpIvEk84GBK +vGQU5yusSax7+86VjGPKbs+zLKj4r+KmYoaZ70QUaRC82GLq1ECHjOIrcS+M2Ih3 +h3EQbDqMde3TNiKA+CNCeimY+1QsqMu+y/CeIp/W51DrCUiYzc4xMcXICLkwlBpP +hViCZQKz0Rexe+gepRYTTrjnwESbb0WQr3cuitmsmQKBgQD9tDi35xFx22EKujuZ +gCPsSIxQpJ0YmZbA8gSPOoxd3dwRQdpnwAHJLSb0TKqpA7c6iE6abDFx89juOX/m +JOzHQJ7+i2h6NtToP2RbbrWG97OXHeujlR1UuixYRXBv2FKYCWxfi1URic0cATmT +4f2FqM+ev1gpeZo2FA3sy5fZVwKBgQDqXUO/9I188R46rStUExXWbqqbnqgcTM7J +INEQ4CcEmpjsqagJK8lwep4Vlxx1Jwwhv6u1I+h2nytaGGEAywuf/gHUyzE+lWQO +Xd62c1qZuXvNUosUPdzeT9ndRXshV7FoQ2sYj3wJc/7QwWYULQyISLobTyfLgike +yZ/pQVq/8wKBgFkyAHLfgSmXaGG+IfAQthB/XR2JElYwwWiqbeHxQqJJuvIyRdgO +EFKrVjOztJhhXwzsGT5/ZU7b3Vu7yXSfbMOMu5lgZ+X32xigGOdwX8/IzFIHye2k +IkDEh4ytNR+NXVRok7pvoQPef8clwxlz7Y8NT5lPSm6iew4iNNcYqRVXAoGAYLNE +vhJIwvG2GF3VT+ZkD0swR++py6uBcwmAWeczEjo7uQKzm70ea7OcQKpOCqSm49Hz +JlV/mFpKh+0hMTOWQ1iKJuQEGJ+JXkgrGbr0+hLHW0ugqSRxWqU17o+5o2NMhwmy +SbsCYeAjlr0FwnNoBV+EsrnxYI3/K33j5lmZ+TMCgYAsmo1HdgeGSccAYVPKdp9h +/ITmVCPZpQfhQ4iQTIC/g1lo4UKg/5JZRpW12E0eHMOYALg5P5lcLlOzOjFyOLqH +tok2CYLSf8QKR2YfqiOXILn37MKUB0O1y7hDmULUXku5uhahk19+gW+zl1/fehWA +g926VRGxI0cOr/mwZGz0Uw== -----END PRIVATE KEY----- diff --git a/tests/tls/brawn.key.encrypted.pem b/tests/tls/brawn.key.encrypted.pem index 1ddde4a8..8a427261 100644 --- a/tests/tls/brawn.key.encrypted.pem +++ b/tests/tls/brawn.key.encrypted.pem @@ -1,30 +1,30 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFJTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQ2fzGFIPwqF+jPex3 -BbPXFQICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEHIZzbYlHdcXSydD -JKXxgDIEggTAI59S3UUYYWhWY1tQOBzWAeo+xUa+8sK39sMBjDMcPHt7hTptEAuG -c9NoQtUYN4yByTC15MvnUu/7pHDgSDBcbIw2po85Du03joKdH0aNM6uNsrTQAPOl -Vloy5hq8gMHm0GpoG3zPlFiz7jdPGRFOQgmD1fxvkCbkWGqBRi6jygZLqHgQRiCv -CQVHjDg/c3x167eeuEXHzb/K2cO8shVHU9H4dtMfzdEcMXxlrWkCNoBsXYmgDcTX -NJ+5/+vUVrfuOV4PkC0AVTiDOGBTrzaHEFET37rtNA9pSVy6/CLwEySoiLAwKOUN -Etp6LleXD84qcbEcgys5bSSZr/nIxULVSW8YBqBCHOADEKkOAtF+EOd29cQa9l6M -AxInR7qiWYNUuahxMxE1tKK29QaaoTDfQWM0LvWHbORAwZWVtd6D0K12R7j9TRmn -DmZ8v+RnYTNwqQ5jiIk+xCjor5mEbST+OI8CMHwK4m/zpaN+xD2LKNHtI88W1Ev5 -N5iU+0N4zQD50c5l8u4pPz7A4aIB1QYdKOG7t9SzbyEi6+JmVFpY06K17NrpfniT -jxjEUmat8fHsstGf0AQTtB/7PPDRb0yU6W3iX1/X5dbZU1aHz0RgwHqmsr8b9Ypg -eAbb/z5TjBrpbHlKK2o9D7pMeDrV6OWRW7lVEpi2mqlgcvS/YjsJF2U9iws7b61X -b5tPqPUyTa649BqsOChqkvpbAlh8wxi9Ngd5aJSTHS2F95XTmRDt2sneE7+dckPT -y7meTJu7FMV8sjVYA3NNngJk/Y8tLJEhUAArKh4HWz7a0DlN7q3nevXaT3nIxWO+ -UST32Bo9ReuQ0opv0rWMHQ+op3CidxmxwxWsp8eohiwM9ziCT2abdYJLcQOQdnsM -9r7iQRTQctSqMu2kBzSOJplTa1QVSWJoN/tBPC3LkjS8r4MFKPUtOtfUoyVA58sa -SKeX2fLDjaL9UZjCt5t/Ir2fiFPmMMfntsbaU7SplEStDg3/9Wivsa2EaYHHAJYu -k9Y/7yG/9+CjqcYKa7hVjYdjaB1HaGlTKIAUO3mSuLlFuRS5Ts/t5mJDjZbfKaJ+ -eAk5r1oQTLCISDGd9VjN3J+fAaScYZAt/DXOj7FPX6ZKzOljHePRVNDr2iQ/TIAg -6rd9kDozag2gzSwLxmGivNsz2EC03x5eD8p+Ab3nlmgrJFho4b+H2kknrdmaHt+R -q/f6qqdNOJATNlxUbLlBi2s54detOhsMsOBImzDGEYsBWnNq99d7hi5yLZP4ipPa -EBMzgt0MBHOrUYftof9B9gElClerZ7PhXW4j2pM8v2cQ3wZ4insyfD+B+kvW+Hbd -/wcJUPb+k7O8r4OAi/q1TM0xGO0rUKUE8TwycDq8zGApv5kIRKojgbM8cDFAHiZ/ -HD0yKSUV2kQQH5zZ5UqFZglJs841HLx5tmzk1H4RRY38b3M9/chyeWo1X9hzpgVt -74MGW7T/1HbGco85Pv2/PwlTPoCbDsedmRkeBWYTY+AcgzSRpwnQyTwivKtILchQ -TWI/qYPFaUv6nR5dYefxF+GORLMeQbymUi0Hzqsc7s5ucgfL2e6/Aivqr5iYQqZJ -mjjakxxzlSuoJ00pFDM2hFgwVPU6ozzPKQ== +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQuKDg90rv69yJIwdA +8R+1bgICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEGI6HAZn6n92DfJM +/T2nyx4EggTQyy0CxuU+cX2PrpL2dPpx6xsUxFAyV3EO4pXBcU8bkQFTkZ9HErxX +N2soUPVRLVa47fPcwK3U+YdI5dsJkq4q8p4YIdA4K8u+0zPAP46tyOvxCFPOFyH6 +iZYxFDjZKjoVgAOLOrXej+h8K75hZ7c3Ht30fff/KowYZKgygCAGecQldW4mXQv6 +ntT15YvaYbOtQEnVOiVjOXpm5nwubH+gi187/mmK87ynH4ihnx1t6plkA/19Mn4e +bG9YdBfnOHWfvP97USU7gMfOlNqvg27M9BrSE1VV2RciyfKFIeQhgLBbiczKxTHp +2XKyP8vCSgys+xgbDnxy9xZs3Ey5LdOH0afu93ie4BgLiVOBD4dQcdacZPQXeria +W5cbckpDPDExt7DebWY70aC4vkSCrA08CAa6UoAOCYb4S5JZbfCqt3KgCr/cfRx+ +JBNDHbHkFmmL0YuqxiLr4wKz2zc1+FCq5iDcX7DqFmWFVSBlSPfkdgD+3NzM4wO4 +ySJBwvRXIpVtDTGB5WEgAuZd+/eWAPqQYdBDKDFuDoOlCt/ZCH1JDGT1EX0D00ln +YyqlW5JVhEBxQAgAtvpFUO9LBbP9+Mg9tTFapyGT5pph8MPDU+TVWGz1j/7+eoDV +E6U80M4uWP8j834zUPGIvGsFM/jXi9/qkb3beGZ8NNEDms3I5/kvRuu0NYL28czM +MEnzlQY5/v9yWPY7+r+lM5F3ZPX5xpXiwyILD8vP3d/PyAzmPUrrtQp6fS6PKom9 +nmvwrvp38L4G0hBq7HF6Pcftt9g1MwLFpIjrZq3ddIgeK/YThCJ8EKbMqM5oxP8C +yDPpfKIAI+kp2TdQgHAJLuvzUsj4dOLNeIs8De3lb2trVZpoOV11bQSROs1neEY7 +FCY4lmAGye1IupyUAACHk7tAhYip5idoGY+DOZHbT4ML2qpoM2hmABA2qV9s27X2 +A9L63wQcXXzZcAiBUm7SKgh+GBiVyKUI4d3Ia4jixH8IcbLBY/+ySCkyUb1C4g3k +09p6sQSuZkO59WbGuuGJH8kIO76I6Arho2oPO2d5Zo3gmlS6tOW1t1ofsJpjQioa +wPZI+EfwY+ig6/GTAs2/J75Qti4K2iaz9JEBgnSaLBRNNXAiPYSZ0Yb+XSOVKD2T +Q8NbbB7e7+ErEM9LN8hG9KtaSrPsRUq3/6zUYTfoufiOCkLOeSoiqfk0KdGigHo7 +CDVb3Af6YOkLArNUbsQiA8YV5I1vviTdwLabqQoFRVJ2B7E0HQq2StAqblLc8q1I +EaW5KanQeLVh31Gxs8KYad0Stb/GusESs4W77cJs0ClosocfVYd+S4hdVBicwhR0 +ff4Ohs3jblpQgCTDiDeKwqug7HY9NN++Cm4AwgUZcx52tkRWrh0x++vLDBqds8Zr +227f1haBz7nhL5sh8OIgRBEDklrJLvVEixWFoTeeFuxLdTZuq0Y50DmwC6DsC5Te +Rdn0pfqsoqukVxtoJYpsnycDLs5RBFwhFTwLT0n6JVHXvMzG8yI/Bt0w9l1hRmfO +NnINg5I+glmbbGHgreRR5vVlJ1AETKlzga/COq141IzrcpCFelr8d4RUaiooxTxP +LkxlScU/dFPy3GNyUST/CtIpK9bXAC71g3Bx7YOMQ8Of3tgTzs1Lngs= -----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/tls/brawn.key.pem b/tests/tls/brawn.key.pem index d58bfe18..68a04e88 100644 --- a/tests/tls/brawn.key.pem +++ b/tests/tls/brawn.key.pem @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQCYSnUh1TtiTgeR -qRl+AHW5GoKpxG0AKhg5gvJlFpKj7zbPfzUv9eHEUgr5EKS07zeStyMwLsxNUqSv -AKko9yeGW8VPnT3WQ39mceGrpKwUe4nl4n5pcCSywJz/1uJCZVXcSy7JOUuqHi+m -2fMDfgSJEeSKeV/yRA6MRP59Q/tYyHLLUj7Fsh5C+oTIKzHK1w8CFABFp1pRSfsn -ujP9GV0CDXjtYWTa2xWrTYXYClFiWHgKwLQ18C4/xZPjxyNDSoovPdb+YiKwzHD8 -//EC+DImf1jEg2RvjORMRW0IlpY2rjeQ8Pfjl2E4pxHu0dsrSYyBHZ3HD2q5G17U -JP12Cq1LAgMBAAECgf9RXGJyxIx/M6b+787WH97saAJS/2Ltx0Czx99CIn5cyA3i -zU5iAl2H54gcnALFRQhERjDVPlKs1VLXjpaCh2Ez8L/IF8OPK0VbTo/fwS4Gr6rV -JlOeARCt0Zw2dTSTf2iucBnJ3ZdT6Rtkzal9R9YQx1cDQYZPwNE/9+sSFRhay8GB -4a8Zchu5aZ59aSbcuLm3dywgMJSIkhZKBMmSBbfCv/QMMSE56UC03YGT51rcchjp -BWYAFvpI0LYGWUlvSZS0z+qoF0E+5gB1pOXiTCOPVKSTlaDHJaC/xt/kmF9Y98Yi -T5uEOTCsen6lD9G4XkdCNPKPX68m13Ayu/xw0hECgYEA06wSC5UUrdTbkIDDdomo -c8CuukyYt/2AmrNe80OapRNxf4XAOS06G66YfF/Gc45O/UTqGtrVbD9IlzXhJncc -LwfhiOa7nUByYFx32okR1JJl19TqzDxHCOP4f/YRe3VyWpgEvSR+nJ9F/R94tlMy -Ga2Ky70aS2rOL+BXTfXPZB0CgYEAuC7nSvuH4pPgixERb9+C40pAxACWGHqF+8kb -nRD10/uOZjPP66//+NS/SykHFpC9GlvKNvnd5QJQywRR0pWLe7SXUtSKd2srYiu0 -fCWXtWL8nZ5Aq63vSL2ABirWY7eGpoAbXQyWb/x7sMy5CAYaVLZx5QyGFkJf8tZl -YrgGyocCgYBmN5H/Rd7WkxP0lDnP5GoUe9fk31hggWq5SiVwFBV54gnNKynIcq68 -73NznEyZQP+kDsN+dG7b9zN20e4IRTy2+XdQRRwUtCqHnh/CyK5zmL7Vm1xHhFRJ -Vs2J/aozlGPEm+St8hGyULfbpHcGlOZ8v/Fmscsg4FLxi8SdQTcFgQKBgDZ1l+ox -6YHzW6eDCnbbzeXK5M+PpNHkGI3UbxfIFgfyD67kjwwPZE59CXr9zJy9e0y561bK -FvRJ9P2yb0cm9LFFOqFBOxgIVjGW3qz+qJb3h95LFrAso94MOjiYnf+qGmRM6Mpg -mHLQYvpp7iQTOeHmeFLTmyolwh0Zi6ze4RMtAoGAbYTqaJMJ4X8+eHykM5WvMfXW -pSfEoLSxV5x3udoNKBRvPj22upLWX3v5NiF6bDe1wrgkvQ5/eQqgFB7V0+7vwl8s -qhf2sXwXA3KuzBeb5+Py6XaeBWo4Nc/gLhCywWIvCgbZzWofPGkffDcDS0RVAJSn -LlV2vQlMzHUS8fAWYPU= +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDoQyl1Gq9UPJ/V +D3lCQ87u+P2hiPhJoC/GH7Z9GYcqEwrz1QiK2Q4VuhspMr2/9CaNnTrx0vbzGZ4A +1uTCEWx6tAA/I1Uzh4o76c0F3japG0QsjnRILeno6OCY1WBDi90QtrpW/lvEI0kC +le5rF5gk0DJjjzlwiuyxzfc+MZNMJNtgDzgHkW1gbQ5hc0OdLHmOgvbl3RePLF3h +Ur6KfvgkNmB/aINmQOxXqR1UI7G3mvQu7Twz+PtFT+GJYSTaQDnOHo/Msm6ikpoW +0/5XtNnv6VRjrf3KO6WUHFjz0+j3hJ3ddy9zXcEJPfIANZuuAj9E7YndNWX36cTe +3mwL4TaVAgMBAAECggEAHmZ8DKnbfQkaWobV9kht03WfrP8CkJB48FPCTQmEWYt4 +iYW+wn26jDl5yKCtmWxZh3um9XQJgrQ9rBp0grpJGp5o0drMEhyRiVoGzdfSC7xX +5gUXT0NDNIsWqqpzGSQ7YS6poS1V0YxUyBPbywShk1/02Hcsq4BjjrpIvEk84GBK +vGQU5yusSax7+86VjGPKbs+zLKj4r+KmYoaZ70QUaRC82GLq1ECHjOIrcS+M2Ih3 +h3EQbDqMde3TNiKA+CNCeimY+1QsqMu+y/CeIp/W51DrCUiYzc4xMcXICLkwlBpP +hViCZQKz0Rexe+gepRYTTrjnwESbb0WQr3cuitmsmQKBgQD9tDi35xFx22EKujuZ +gCPsSIxQpJ0YmZbA8gSPOoxd3dwRQdpnwAHJLSb0TKqpA7c6iE6abDFx89juOX/m +JOzHQJ7+i2h6NtToP2RbbrWG97OXHeujlR1UuixYRXBv2FKYCWxfi1URic0cATmT +4f2FqM+ev1gpeZo2FA3sy5fZVwKBgQDqXUO/9I188R46rStUExXWbqqbnqgcTM7J +INEQ4CcEmpjsqagJK8lwep4Vlxx1Jwwhv6u1I+h2nytaGGEAywuf/gHUyzE+lWQO +Xd62c1qZuXvNUosUPdzeT9ndRXshV7FoQ2sYj3wJc/7QwWYULQyISLobTyfLgike +yZ/pQVq/8wKBgFkyAHLfgSmXaGG+IfAQthB/XR2JElYwwWiqbeHxQqJJuvIyRdgO +EFKrVjOztJhhXwzsGT5/ZU7b3Vu7yXSfbMOMu5lgZ+X32xigGOdwX8/IzFIHye2k +IkDEh4ytNR+NXVRok7pvoQPef8clwxlz7Y8NT5lPSm6iew4iNNcYqRVXAoGAYLNE +vhJIwvG2GF3VT+ZkD0swR++py6uBcwmAWeczEjo7uQKzm70ea7OcQKpOCqSm49Hz +JlV/mFpKh+0hMTOWQ1iKJuQEGJ+JXkgrGbr0+hLHW0ugqSRxWqU17o+5o2NMhwmy +SbsCYeAjlr0FwnNoBV+EsrnxYI3/K33j5lmZ+TMCgYAsmo1HdgeGSccAYVPKdp9h +/ITmVCPZpQfhQ4iQTIC/g1lo4UKg/5JZRpW12E0eHMOYALg5P5lcLlOzOjFyOLqH +tok2CYLSf8QKR2YfqiOXILn37MKUB0O1y7hDmULUXku5uhahk19+gW+zl1/fehWA +g926VRGxI0cOr/mwZGz0Uw== -----END PRIVATE KEY----- diff --git a/tests/tls/brawn.keystore.jks b/tests/tls/brawn.keystore.jks index 8e9634651e0a627a9f456c248c8e5f5ffa90c776..a74516a9ddea36595f3ea1bf6cb427130f34490c 100644 GIT binary patch delta 2618 zcmV-A3dQx_748*QFoFu|0s#Xsf(n!d2`Yw2hW8Bt2LYgh3WWrM3V|?!3Vkqw1*8TE zDuzgg_YDCD0ic2fl>~wXkuZV-|fSbw6G7beu)U^-!R1>G!=0fhe?CRZu5Mj5%~<->dKu zl%Cs_de#i)axL{uK+JuQ+Z2)rKAautmgkidbS)oleyYi)u`Oe+iU0+Nx8Qw6u)=te z1c~O5BdMuEer!n@gql8gn14J8kC_tvIS{aq{wO{h_4pI`n)Ffp0`C40k6i&8M%DK0 zpf8O#u@JJ@uc2PL@gU!0J$!L)N;%^*jM?ni4Xrkd08vob;|F7Pe93rv1F9@FBky%M zgJxUS|i?pVi= zFoU+M$6P7=v(lIIifWxD3hic!2}ylsvsRP3il3?4>1$ex;$l*>?uyRQ@@W|&)wHel z%TjiS_b{h+&?GmH%+oo@E#) z2ruO-39M4>DZnwvYt?p4!i8VKk5QS{3x9_+&n0*}!qi@7^mR`=d&9T9EK{;JY|^;Q zcy$OArO>>G68|L0cpWBm4Ne$c`)Y|64lpQFdJNsooI639Y=0Z+HFe7C@uG&#Y=F}j z91pCeP2pr23nj1OycO?HCz@{z}W_<`dP&XYQ+NC5Q{45$>k2;%N)X}#vBCD#-D zUtNVWiwZVuJjheH(pai#o{J=&1{A!7C@-$}cjB_0_NUa_W=+8wk?(_FO)2uF+Z}Bp z+%48}PEXl%9e=OvSo{>X(Qm!PRx*(=X#CxReF2Jj6j09|yK8)DlF#uI64BX@?T?CN zu=QUPvZ5L~X%hS?T(=pQK*v92kAE5H!@p6*_%3~S2Jjyj(tOh$IQNRI(tVn*X$^{( zyx2ER&flqKbZ&NL>q z!(%2kOYdty73{2Bzw8?*G-A2EgfGxaR~&&u+ih%SIzagk(LDCgmed1D_B7re-Pl@& z73O)W7*3Fo^=#xHrX9r#`?BmSbP29QHmWEn?+vhm0VT|78cMLX5Pa7(stUD*C@2o= zz-45Plz$rU*}Hun1@$FBiAU)bJ4muO#jF^z=-9{K!9UZEK z-NFkVNSTnG{X0&ewF{j?ibE@xKYLvgcU>k4G(GQ(n3Ut4s06IdVHbEGsO%(>?_3Sz zJuGMoV8oh&i11&`6h2-ARLhwT8@{5ZZVP*j0DlT7(4i=Ve>SfIpX)4tE3>{!U!*na z8}UQHswJ#LX&;1@r`G|3(9*8oImY_5x!rOcOXlq08$XwSEbub<{)%}keQ5C#Fa}q* zFS$fC($fvieMccfA@Rf7ZO=e1N23%L(eJy;0WONc6p(2#HZTze2`Yw2hW8Bt2^28| z9+Q*>9tSZqG&C?dGn2UmN)#l>jXw99)KL1EMreUOd8|P;-#?LxB!8IUX`^F=&3Id+ zl!7l%43dC?1VB3bF=}xXGp0pA31Ids`T^Ho{L+Ng>Sg?E_-s0&JxZ^hZ9Pa-&3NjQO@{c!45yqAm? zGTiQ09hQ^ukd%eUrGFRhxj|0pBfcI7(!c*XSOLc!-+^W|WDE*zeQG_)p>ISaWtP6d zpSuUIig(X*X@;U;=#nUk^MKxBWcg~$>ON&(({aaLx2?cYE%kXei(H&83}5ZP?TX^4 z`JD`0Clo=ifSVE?S0yk=&YV{<Q%CHN+gQ5^Dm$*{fapzSK=ztMI{u9;rYrv8M1%ppPCONN2{WG+)P3JgE z;P|%7N<#r$wN=3jmFJ#h6^EPZQIYEDeS-=OxFyw-+xZW0gydP;4E5yV=y+%{iyVN!JXyA?87g4&#at+l04VJ_PWYv9z65@7|h z1eJ0UMN<7unOhS_kglmBE#Fr`fYrS%uF0)+)Q|V=83R0bGcM5O*d2LAB}NW?b5h1F zNh8TwxB*ZF6b}sH)>2F8?XRo^L)BMuhjNVP6Mwz>t?iKC+>53Q{4zg{Yc#isqh(a_ zXn;Z;?t1kVaRX@GG&=q;P=*#l=P|FRk_-)WbyBz5mWaGgaCm0GLOWFkc`48)aB;BI z4;+?PXDJpDM8U4@rY62x zO6-RLrkLp`%b|=-Q`rP;zQzVQ4HUT989?JN^h+2|cM?J+(_PFp-5Hi$6rA^MBfh{^ z!C~HfiQvveK3Lrc?JtAhDe6@4FL=a0Ro_c1u!sz1uT(PAQawk zv)z}hHsx_ccghEIu^(>K!B!64F>vb_kPg20{biB)*E_(!m1i*hjmPWf)b1le4 zalCUzb?BuV#DZn;4o|id(U{nBZLrfN>36=)gn;M58kVHn_P@r7Zl;lt_E<~&CZEFD zBx*7?NL?1J3q6?bOIg_eZDKA6Fr*NZ$%BqKWjrXo@yXyp2%#OE(3kf)5Py%gF9O{$ zrPASbPb1=Wh|f7!4+?UX8%!D*mvqITdIIY)ONOOCMwZUZ-8L28*Ow*yN3$c>RLJ-UyVQ7A;s3J^ zoOLuFViG0q$C?A~k67YAH5_k7sW|Q8f_gVjZkk|KRzw9@xi|TM`_h0g3OHZltqfh3 z_`#7-s7dtvkVveXPt~K;MrKUowwLEelg$te=s;-(%sx5S6lBgeH(GE6RVD>3(R`pIi^x>a|mdRk!;A=sJq6x z3dVA{LjYec;dujOzklakXUh|b@Z6PA#9q@!KBOV3_TknOJzxlKq=MhM7KO!!7h;nt zynq%pPUHfE&_{8)VTFXGJ}+wbIL?## ze70swx`qSZ@X@Rf;W*yN0n&_b&sv<+Q}wv_2#B!B*$q7_?Kxmck3-Z2w0^QJ2yLU5 zcmzmj6GSt+D}NYWVq!nd7O}w$6nkZk>6LJRSIfA-7am`OM-#7FWPL2)F4~f+9ZWm) za!32==;JQ&=7W#S0t=0q{Clvy|3;Y7Ey9!z{bGc{xxy26emX;L(Y=ez&GzBc{pW&gUj?dhB*U)wN*>ONkyz z2o*-fqER)Kgriww`tV~mzQxB_;^qac?a~9RS0Uv{tHn;%jq6UM_$1-ow&cgCpOocI zaT@$rzkj2`Kc$<2q+(xgg=Gbk%ioqPji3?R2LGt4mpk)xx026~HQX$F(z zCPs^`zSlz&fhW^5CV@tDB&CZB+eIubK-OC!us&3&SkuF-$3Ad30P5mE%J(tu=eL{p zmHTyGp!t>eCyBB%>`BJ+$nt4$2CzZ10E()Md|iSkJ6G8~OMLs>rGuD`uIbdT%LB@o zJiJyj;Udf2&3dDM|Kqwy*S{2_`K3N7a=RVJD_-Hv`8Ri7maZ`m6wF3G3!?2Efa>)g zG>lv0fPw@-k%{cC?IGlSz$ceiN&mHx!CQ-6==Pz7 zbx<Ko)hb?Fr75Zl?rP9IlztA--!v5qX)>BMsm zBj4g?(#0G_$k?7!z2$pOxw*hqW=J^!L(3ZzrNME30XOC6@i=g(=ITLF5`RAoF00f< zxhk!clvGMCZB_f=-zt=hpE7`h;#&dbv0?OjB3a45zolTbFp$wqPWnHkD$Wv8x}*j& z5)JkTFXj&{ISu_7iJr*uV!nn@G=?!=CQ$`hRWyHZG@<5bp|2-Uf)1J5T}EwPVesG3 znHM2{K2sNLxgi-Z+?|ROcgSW1tVKw&I&!dF9m$RY8F||08qQiwvi=1eB+j$t)UaHh05;fdzPhGYIA^ zd{BpoyWlCOz!n%UtUA6JYLg49i$np=wR-p$5BLir@Oh-Soc%k0UPmL{4|`{=P*EumTm)Ho@1<1Q`o_-W$! z?Y9ESnLE4A7t(g7!1Fok0yQi}ADOz+=NM3FZXi9&l+(X@B~U9p#X!u+LY|}|^ZSzq zDEhTZGA5>W|L^@&!vmFqg0udy!|jQ}7&YY5<=ObGuaJfhSNzrISKw>ZiNx4{0^9yN zmD?c7niwIYa?V%SD!b@kLN>+TO0qiNg5{v-7nBkA_n`-yX;OZ(w<+F8M>VDd3M2#9 zj;9A+5ld~aKp8w*>m9J5O}~adn0x3#tW;k7z>=8_GkVn z`4&25F(|NPJ**=!N0_fwG=Z<2AGT+oe9~&>Qb4=Uz+?CL<~-#Movtt8vuRir%eoS| zc(c+^7-pR6MT4u!1A7!Kt^$^S9S#Rj#l+iZI1VBvn3wM{qFC^#Ol2`#I*va}Y6ZuU zo#a-v9=*TSloXA(P`gGc$xg3FEB!I=nk*BkoUddHs!7->b`{#tp0yH}QSxFU6~ac+ ziOM1CL;RF6Sm>im6j69PznD`!-Gm)0{UL*%WIk&mlb;F|I-;}g?F%6>0Cz$SOX^Jn ubfUU)#8$+KiNb_gis~C^mjo0e-cqtoDRFEwrrn}r>G!8>?Bz8A0w)kS6#HlZ diff --git a/tests/tls/brawn.p12 b/tests/tls/brawn.p12 index f3874c571e34c48ea25758de7a900e315e60c3cd..f5826c50af5ffdc3a4ecc701a2765244269f0993 100755 GIT binary patch delta 2592 zcmV+*3g7jk6|)s0FoFuN0s#Xsf(m5@2`Yw2hW8Bt2LYgh3RVPy3Q{nF3QmzCNf6U4 zq%9$QTwP$qBWQ5`k!+EBA%APVGjfQOAnad9&j=C9-c-iG+h2)!bVv;d0FnsTt`_ZUM*p_VP)B+VmFcmVO^ zo;}8F{VlPpvUBss!ey-g^{hP{A9AL4FGdpAfvfEFvqH!o1q1pB5P#%nS7Ut3EHumO z&4PR;iR<=^kTTpFBfRDDKnU_p06KPV^T`^;7Y{(m?#ujyf}Lk*qe;$clcb$%rv^g? zl-~fX+KYvnTz3v+0&<^4J#3Of-rjZ3=x(S)+|Sn{VmhIe$r`HUh@*1VJe>KT?vCO zhocO8$0Na+I$JfxUY=KQ=Ca&@#QAJ;J24Iaw*z?de`M(%cKFyhh8%atdM&DSl;vwN z#Z!NT?NzZu=hO;RyIALJJyT{FZ(ui%dNGISd*zZ2Uun%E*neRMtMpkfyEgkb0w(@|+yM@v{jU0Fg=%E=ieYi6`V)iR}(ZC&8kbCOMy|vPDj7J|NF6 z*%}f8=Z8-MTiD&Uea{!%C?CziQwDFjU~xx$!j z3RjCW`DiIPr~^jUm)E@?`mkoLv>0m<U`SfG>raV^kXe>GaR&1HG%pL?;sxoc;e8+&DsiA(? zDuzgg_YDCD0ic2feFTC9c`$+n zbufYjaRv)2hDe6@4FL=a0Ro_c1vxN+1pzgYOCS)K#wv9qtajfCKSF@#e-K)8*$;;{`g@w{^MVaO zn2iqZJMV*H`t>hk)9e+>@KF!UhPNM*ynLWYD}b|!rI>&SIl5}Nj6pUN(RYpQ8Jy=X z6_*#73n&iw=ywo+$-NE@bxzCjxxRn;h?=#HY2Knt`r`=Ox;EVq)2W!&PV{+;!RkT} z%(6n3lE;fFp`LM{nV?4oXM5dZ)0#vPma7hj?Gb@y_#>sN#N20fP;sge9?}}V^j6~u ziE;%%PaHCQFL*%ED?2NC=l~wJUMF3iV3v9X)VR_Aqp+DB7B0--{}L0RY;%9Ew_>s? zpR*3$rNz!XzRVgJb6LFWiX_WQq5U3}j;g8d^TVQS;Gl!OT8s$45DOaD6IyK*_!(cf z==^`sFk=wJHN22SK?&u_$qVSc2{*}Zd@T!9EKl0!i2w4_RKXvKV(;am8u!SLC>qR8 ziYI7H7H7lwiwdxwdanbfmArqq6G6D$N(#h;lgQ~r|2vM6O{(rLT!BNb)mzVjV27Wt zaV=;zLvJCoMnlcRQ|;xEUF^nG{uUQRaUt-AeYe-ozazORY*0&dmhJ6hb4&k4^JYA_ zGLL*f=zWBZqN(WU?*gCzWO0Z66|3T*6EAec74GfqDskIFpe*zrp%{P7)7#+(;2@OK590iI6NPN zfv@+sTj%+8_?j0l0_PF)+y11RB$gVkkG0ag`Q9$&NG@FlrvI=^o)yxY?b@Ses!n^O z_o<=MUzqd#e3-uzjWP!3=BDMxK6Rw?^9navm-n$XJBia*gr;tM#;W@b%qiPIT;HdP*GPC z@mP#DhKxE!cS2p|9usg9ydncvHD*E zmpf2CxJvyBmr|SbufAv;xO(Y0a_cIs@ohzWh1U7n6~-NvDR!>tDDo1zr*j4IiYMUK z13*MC(`-DjpaXxEu3q_{V%!)(*p@9*n~Iak1PM-jeFXAb13JAx)#tW*WfLPQG3?6_ z(-U)vfj9EyEy{{yX*ClrqN}4EkU7yhHC6CVr#Z0XS<=g!&Hp2knZ!4#@nrTonfhu? zo>gBgdXEnml#zuR{?_U@7RO`6pv>sB@xT$55h7@&mf(LyU_!5{w(?e20mtAR-=dys zVgNzd`>fO(s8^0mlP@DF*P~6*pNam@KCws%U85oFVZV&ZdA@U&i$g0*^x-Oix zui(Pzdk$0!{FdL{V7GIYIz4`+&6nlxmLuoZw^QnkGIT=`Eldb~ip{NH7w>2B5zFQ> z^3$W_ome&Kx$BBYF(oh~1_>&LNQUCpEbwngKaHbcpX7fipF#7kXMDuhBG;hxLkJ6BFkGb9@Wa2+?Kl zGoX?)DlzETbgxHVy6e@8ACvFu$Z6lp=Zhu`ba3v#_Jyvs!@X@5U{dS~F|<{0iW zH?w3Bp1|%1YXKI{x+M-7BNhDNUW$D=*0Eu(7EAH;fv(j8P;4f13{3qX8z%ZS3N^^&H1JE)?+gpId%w5>JkVCVt_Fi5)^9 z7EVe`8(XZu;H5#hWq+fPG`=WAE1y=HfEqQzcnmCOapkA;gC*Jf=ufBPnrNSEIXgru zULT;tS!%cjatna1-^%7M+}P5OoI5iCPVl}@<*n1G{N!uQ^8r@Gi~DCVW;kB1^qbN} zg>;AP;v{XOGWd)?+HFS~MZz}v&QT-&%NV+6lYto8RyyDrihtOAa42=<&nQ{6=K7zX z*|fq-KQffbw5!PvlPMDeb!Ifv%tSPJ0g(nsWm4T!Z`0oXLJD)p_fB!24E-fC48^TO z!AMePl%-OOm5R%3N|8kYw8!>JKrWQCB_37h3(nPuX5&#$3_AC0(s8g1ZO9tm&4EM< z%!?!P?`1iE*?&wzFiYez5|Xj=zio&+MCb_TP$-RKpm~}^hiFuMW&67oG#%92-i)>7 zA{W3U$~@9jp+m=a$9U^`N^VqZt2ET5s6%A3$Sdb8Cr=h7(yQly!3GRVr@kkRbV_FM z&%4F=R54Hfz-&z0e|-s={g8 z<&F0#zgHh)=LTp0U-sB~3YCEmL0PuQxo;pTDaUuSC%o%w9jOe%O%9NFFJyxEg8t;$ zYNNC8kq#Z(0-2D)UlYsow%kWcWS8o81aBRa=vHcIiwmk4`yLM5;Ahv=R4~uTSbdUe ziz3N}_?eUs4*6qWdy5MRohS#OW$~~>knoY0b03+kb)(i6! zois3#BQix%5n!H90&g~6OV znSN?oOet>IE(Ikxx@SphL)399F+5GcPIon0(s}#}{sek6Ew)J(n_!S+-^sFkdP1qS zDm^e)KXo=0K$n9nmPV_k;exzE@1c7Ct)UK$n^HE~W8bVN+t+W}sUDDG^ACl^>%wrX z5P#JF6Zb^! z$91~rG$ofCescUb8>5E=f&{>0EirHfe>q-bts)=%&A4eEHOAnj;92J?*=7!_2E`-r zQiyEqhU-ywe263|E7P3EH&gbwX9+UuX-5#uS(MCxuGmz^RWKvJBj4?d`3r|3$3JBb zaV~}8CiGd<7*!lH3f!D}qM1rfy{>=v;aorwHjGJEMM?yRH9JIs&A-^>;&F}BN7C|< zj;i5)cBV?Sp2VJ@_o%%yS9l^7*5UAvSi_lU(w?Oy+1%K9WEd9u6q0>6!xL!5)#f7tRmjLIADm}t^;xfAvy6)s z)^WIa-i844@|ME0(yrG)+p2#=GBIq4(F1`lyr$2XR13htZYJtqqC0x>0kBmKFVSBR z@9Gt`yEbdvz`mZZaX&b9j~HA^L$h9bTrWS1lNA5CZfN30hC#3LBd;Y7GddJUkp0@Du*xaNI6h(N<10I zH9RT5+bvdO1jf9b!$gg5Zd@WBr2QzGs*YSyRp%*;>!Q2VemH-Y)QDcyM7n_uplV&~ z0WxB}4V6AD$JV5&GJtIn|C(x?hg?Fj${F7@Gc#e2d^_(N;i=${(ssSt*zVXhFVrl{ zp+Jj~xHVZlnE2BX{8J$PdCYl;;2t$)BOQ2t|wYiln|Ni{G!}Duy~#asQR0h_@A)RXmU#$;dus zNm|6BvENUyMeKQL%K3uQq&pPRE^~l>DD|e%8azS6 zc0YPMpdo))Rrwl4I3O|c)TP71?ZM)$A3f2v6uerd*8y{yj>#tCU}U*iH61Z)-ZNZ< zdMIeqR_4*Eo*5ZK$?tBG;|QtTmDN+rh9h9Ds*Zuxca}9Cvb|SaQkY_0Cm{5rF(oh~ z1_>&LNQU z`hbE2fN0dKsVY#9Y_Si7B77Gi_&n(gadMm7kB(Q6~T2f#~$FF)#$|^7VyZgUpe^H=FPTYv zOHLtAQa$iw zG@`peW)`!6))GXEm{)Sd1L$p|N{>D7TbmR-&f&dV`D5e<2CZ=|Fm9 zqXbCP4Ok{W>%1gG{Ci#45u8e8AxNscBsO@=f4^@GQI{RIR|jBn!FvFKcWMR7Td7E~ zupZd*c&Uc>Ffk}o2S+>l3(mk`E?HA9+hF^4o*SZGfjQD^B7P<;zW~NrRMHcR`nJ)I zA$BND;%Acd3;%WdBX!Cg^eXH%XodZ+*p=^DmvQj3u{#D!qcM6&$+EuMTjF}rfOu|x zf6J1G)98z~LZN=0+UX{Cj;Lnn4%$qYAr634T0iRZve1)Lp_I=oSzIeOU6Nk~;H%_} zaz^ubyy#`OpZ1f*yf#NdYFy1AyB7lI$6@az9G^|L6~%H`wyEwc7;I4ka0iEh%h02g zf#7U*;)MbHp;4bvJVm={1fiaSBK=b!e{u*yNIbQJ?|92kCr)Y`g=n3N)4hr%a}y?B zlE;?uejYL2M2F`kG56h&f6`udepz&s2L|%j1vr45_bI(r2sG&Y7~Y+fd1PtCE4H{Rz#{rd_RtLX305O8?Qn{ahe8pw%76bconTIB>e+PQX z7i3D+2U0oQ&D9%Ct8MIu|wPr19 zpne_W17D>Fmshb1K>Nx$fT--Sf2yBu&h69m+xAc@JvfBY#*3)=O?GV!01$6Icip+3 z|44>jNbq=@_*ZF+-IB&Qw|P-P&M7`?a15hU+FduycWbm zf*u0DQ8DC=L6`~EI>@C}`k;{F%wu@bc1y~8$ccbvNC9O71OfpC00bZ!*l8w0hp23E zH5aYK4qp>u1ZwKhrBXYi!KGDFyT%*@6oEN(tRPn6Ver!GT|f*F0Wt?4OacNY5I=Hi A;s5{u delta 1290 zcmV+l1@-!d3x*4jY!ekd`gPS^tF;d@4vAnYRY!BJ=aGLTe=pDde7?6+PC^EP^;e#M z=753(fQ$F3y=p|Svcgop-~(ZrENw_wpWw1dE?IDI{MxS$F4O%|Dy^-h#C zv}WAQj%K@Xe->?_L+Lqx0`i81t9?*<+ZzM^!*!4XSh|t}Npd$hX>la*` zf^jY1NXmsJLxnSW@!V>P|9mKoavpQku4(2mFvxjpe^|eJKuumqG+Rt?afQObpnX8% zAEmBHloQgJd1_#55U=?hin6KJ7_K%Dr^}9wt9d>@X zqsee?{a(~0I5uSp;?*&$2VazI+WZ(7LPuy@126e$Ihe`W2;Pg}hKx=95{P0n#Sm|!S_69govOUMVX z8ObTe2_f{c3*1@#w32xMy@8S{gPbdGe?eBcPJaznDKio@*NG7U%pTBTS^^4svNV0oEvA}M5w~WT-~8ue`9~* z%FdJ6vQ{wG?acf9Ij<0nDgrZ|6LAf&!m``Jv@dKeM1&Pr-UF}L6idU!MledmNWeMW zH~u3E^}(PHzS(f7Ni1XhwjSI`S>b38D&E7fIt&U{wX(uf5n{cr&Oo7=&GvOqw%Sb# zPLvnS-W>I(K_X6O_6D+PP%UuTf06aCvXUQi{xwwai1Lzh{bxNV zbo6Fc;Z=N11@;~l-)*S8{^bMAI`rmCX1&rafdsO2GGAlLK?C%sVn}(X#(&z**s1Vf z5V3j%#WNJU?6XkqW2u#dX{8;?d^Y*9Y|IWd!|6f^0YZCiT{1#xwr^MMY~+)ked#J` zql}Rk#*xzp`wcZWCvN}tTn`6@B}Xt#FflL<1_@w>NC9O71OfpC00bbwmQkH`_ Date: Thu, 11 Jul 2024 10:14:54 -0600 Subject: [PATCH 087/215] updated certs --- .github/workflows/integration_test.yml | 8 ++-- tests/tls/brawn.crt | 32 +++++++------- tests/tls/brawn.csr | 24 +++++------ tests/tls/brawn.key | 52 +++++++++++------------ tests/tls/brawn.key.encrypted.pem | 56 ++++++++++++------------- tests/tls/brawn.key.pem | 52 +++++++++++------------ tests/tls/brawn.keystore.jks | Bin 2798 -> 2798 bytes tests/tls/brawn.p12 | Bin 2739 -> 2739 bytes tests/tls/jwt/private_key.pem | 52 +++++++++++------------ tests/tls/jwt/public_key.pem | 14 +++---- tests/tls/root.cert.pem | 34 +++++++-------- tests/tls/root.crt | 32 +++++++------- tests/tls/root.key | 52 +++++++++++------------ tests/tls/root.key.pem | 52 +++++++++++------------ tests/tls/root.srl | 2 +- tests/tls/root.truststore.jks | Bin 1414 -> 1414 bytes 16 files changed, 231 insertions(+), 231 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index f8124581..5a4e98dd 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -57,7 +57,7 @@ jobs: - name: Run unit tests run: | - docker run -d -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --network=host -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest @@ -119,7 +119,7 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - + - name: create config run: | #assets/call_gen_tls.sh @@ -129,7 +129,7 @@ jobs: - name: Run unit tests run: | - docker run -d --name aerospike-proximus -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 1 @@ -216,7 +216,7 @@ jobs: - name: Run unit tests run: | - docker run -d --name aerospike-proximus -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 1 diff --git a/tests/tls/brawn.crt b/tests/tls/brawn.crt index 8a76ef43..d6706ec2 100644 --- a/tests/tls/brawn.crt +++ b/tests/tls/brawn.crt @@ -1,23 +1,23 @@ -----BEGIN CERTIFICATE----- -MIIDyTCCArGgAwIBAgIUMij/pbwGviyZpK6mp88qghxc25UwDQYJKoZIhvcNAQEL +MIIDyTCCArGgAwIBAgIUXulxdroIMHUXVDh4uL1BIdTb+HgwDQYJKoZIhvcNAQEL BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p -QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTU1NzIwWhcNMzQwNzA5MTU1NzIwWjBE +QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTYxNDA4WhcNMzQwNzA5MTYxNDA4WjBE MQswCQYDVQQGEwJJTjELMAkGA1UECAwCS0ExGDAWBgNVBAoMD0Flcm9zcGlrZSwg SW5jLjEOMAwGA1UEAwwFYnJhd24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQDoQyl1Gq9UPJ/VD3lCQ87u+P2hiPhJoC/GH7Z9GYcqEwrz1QiK2Q4Vuhsp -Mr2/9CaNnTrx0vbzGZ4A1uTCEWx6tAA/I1Uzh4o76c0F3japG0QsjnRILeno6OCY -1WBDi90QtrpW/lvEI0kCle5rF5gk0DJjjzlwiuyxzfc+MZNMJNtgDzgHkW1gbQ5h -c0OdLHmOgvbl3RePLF3hUr6KfvgkNmB/aINmQOxXqR1UI7G3mvQu7Twz+PtFT+GJ -YSTaQDnOHo/Msm6ikpoW0/5XtNnv6VRjrf3KO6WUHFjz0+j3hJ3ddy9zXcEJPfIA -NZuuAj9E7YndNWX36cTe3mwL4TaVAgMBAAGjXTBbMBkGA1UdEQQSMBCCBWJyYXdu -ggcqLmJyYXduMB0GA1UdDgQWBBQdXaD08vNzfqHIwcTSULbgJpW5pDAfBgNVHSME -GDAWgBTAFJZAkhKzJsAi+T3S1FrHf11PpTANBgkqhkiG9w0BAQsFAAOCAQEAXmON -bE6XZ4Nh8+fEqudboJCU54CFReF+voVawNNCAEXQR3x36HvvlAq4mI9aq7E8n++H -ulE1PD4RqfabBIto+90h7h1HI+BGXMOp+PuUaNjAajQleJHpU5yhmYt/F7rFpqN+ -c9u/rMi/CXPrLzAx0CtfVPnX3MAEuKkXZWqHEfEHtG7kNG30jGIM50qTCEKeqKCs -XrZtBqYK73BC1EPlaj9ethesI6lEShm6s1hvZDNYVZfzA1VTGCkMpgwrvlg/OzC7 -LAQFkg1BT7Wzu9fF6+htICENOTWpFYBCJyjJUa/n58RoIFNpIqKSMuuEqUOfAUkh -j1CnIgCTWKBR7iAmxQ== +AoIBAQCtsS8f85RtepwSCTqeEzKslqbT4VC3yXe8W7FI4c8mOzYDe3Bp9veaU8Zt +dYtg5N35i7NPwCcGs5mbbwGZ6pB0SNnRWIHqRGJp7JsR1gg1Arm60/wbNW3G+Bnc +yIfrWJXntgTSu0v4BsKtUcPqBa9+8XTBusQxUbkYeaBEthCP7yB8pYdlLfOjrPn0 +6NvgMTrXiiO2AHucEACgjmKUa6tzHbVgD8+xuQ99yIMge1/CVL7hOPHjENCi6XVG +jJXjawt1EszGimAO8zNMaFCBOnXgmzis9e6AZEiDFjUSSKv1VhV2sq5VM0I+RQEW +HWbw+Haytgkvu4b7WMkjHG05z+63AgMBAAGjXTBbMBkGA1UdEQQSMBCCBWJyYXdu +ggcqLmJyYXduMB0GA1UdDgQWBBS4x26gBV882WqVk4gHnFgniz8fWzAfBgNVHSME +GDAWgBSmVqeKStXKxECpnUGWsZdc6I0AIzANBgkqhkiG9w0BAQsFAAOCAQEAYmTd +qkXlvJh6AX+PijnQhJWzeGeE+TE/nx0Ljo/MtFnu9WcbvPh6G8bf7Bl7TcAE2kWQ +eJxC7FC91al7au97ug3arbSdG/mLa0ShlrpH42U5xywdLsPH5FZsCgPmA0cnpOFJ +PfwVT65hC8laioBzlLMU1dS5WUd+dN+1sN4Dgg+dAZ88P8J0aRFsVc8KJ4q/yNX3 +pjA1ZmRDq8JibUyqNRy/N8mySQJLvPxJLHrkad9BwXooc4t5zG+STUpNWTxsJC6m +Br9jZ67gJUDkV5kmwqwpkwMl1nKOGgcC5EqMT4i5ijUenkfnotw7yjUmovygIwoP +ghf3nRnAKvuqM6wcPg== -----END CERTIFICATE----- diff --git a/tests/tls/brawn.csr b/tests/tls/brawn.csr index 86064556..a43726cb 100644 --- a/tests/tls/brawn.csr +++ b/tests/tls/brawn.csr @@ -1,17 +1,17 @@ -----BEGIN CERTIFICATE REQUEST----- MIICtTCCAZ0CAQAwRDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMRgwFgYDVQQK DA9BZXJvc3Bpa2UsIEluYy4xDjAMBgNVBAMMBWJyYXduMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA6EMpdRqvVDyf1Q95QkPO7vj9oYj4SaAvxh+2fRmH -KhMK89UIitkOFbobKTK9v/QmjZ068dL28xmeANbkwhFserQAPyNVM4eKO+nNBd42 -qRtELI50SC3p6OjgmNVgQ4vdELa6Vv5bxCNJApXuaxeYJNAyY485cIrssc33PjGT -TCTbYA84B5FtYG0OYXNDnSx5joL25d0Xjyxd4VK+in74JDZgf2iDZkDsV6kdVCOx -t5r0Lu08M/j7RU/hiWEk2kA5zh6PzLJuopKaFtP+V7TZ7+lUY639yjullBxY89Po -94Sd3Xcvc13BCT3yADWbrgI/RO2J3TVl9+nE3t5sC+E2lQIDAQABoCwwKgYJKoZI +AQEFAAOCAQ8AMIIBCgKCAQEArbEvH/OUbXqcEgk6nhMyrJam0+FQt8l3vFuxSOHP +Jjs2A3twafb3mlPGbXWLYOTd+YuzT8AnBrOZm28BmeqQdEjZ0ViB6kRiaeybEdYI +NQK5utP8GzVtxvgZ3MiH61iV57YE0rtL+AbCrVHD6gWvfvF0wbrEMVG5GHmgRLYQ +j+8gfKWHZS3zo6z59Ojb4DE614ojtgB7nBAAoI5ilGurcx21YA/PsbkPfciDIHtf +wlS+4Tjx4xDQoul1RoyV42sLdRLMxopgDvMzTGhQgTp14Js4rPXugGRIgxY1Ekir +9VYVdrKuVTNCPkUBFh1m8Ph2srYJL7uG+1jJIxxtOc/utwIDAQABoCwwKgYJKoZI hvcNAQkOMR0wGzAZBgNVHREEEjAQggVicmF3boIHKi5icmF3bjANBgkqhkiG9w0B -AQsFAAOCAQEAd+mEI51qQ4eMTPpQIAcXGr0LdnHxHfrswF3MgfLIYWaHZzp/4tp/ -RifVPwcuL6UXPYKSNtIfT7KV3ag9anqHeHLZhxtGyYhAC34z17alAN1cgkr8M3Lz -mRArej3GkJM41ZlVRs5yp9uwCWJLbAs2h6XwKhUyeY0LfVZ7aW3IGk13NA4mWTj+ -kqohNQTh3TABEFxIOG9lUfjqByz/+3Q5zizpePpQWUUz+HEjJpsoycMeNzq7BJLE -H4zwCZhCrzUCwvtkzbzNYDsQKCTE/jHjWSr3t9UwB6fP2bRow+/DrBB6B3ej8idV -QX5ancMClTtQLwhI89XnddNXUnkYMzT+TQ== +AQsFAAOCAQEANkULb/S0a2Ctjwc6sXMvQmgikP/PDz7uO+pKgDMvUQjNNxVNIe06 +EdNFyp5tj5a38nzudERXGHTZ2M4uZvGH8L6JSO8KnwFIBH8BTI4CRqfII4mNBwIp +ZoWvvMH5cLjkt0zOYynwKbpeX0osbnf9houzq87oH2MjTIGahP/wovdnqkPggWuP +ZZfiOCGvh8MgewrAbXwGrxd0piZNnh2ru7BAxOdyQcgQyv+7eQBhG/TnAngG/bL1 +B84oAkaePR9/Qw+OY/v51IIuulS76bG0h+xnrWNPa1QzVaYKJ0Cglx1QzkNxR4jS +ZpP5YiOEFZIix7r8MdoJvhyqI+SlmV/hrg== -----END CERTIFICATE REQUEST----- diff --git a/tests/tls/brawn.key b/tests/tls/brawn.key index 68a04e88..5a7589ad 100644 --- a/tests/tls/brawn.key +++ b/tests/tls/brawn.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDoQyl1Gq9UPJ/V -D3lCQ87u+P2hiPhJoC/GH7Z9GYcqEwrz1QiK2Q4VuhspMr2/9CaNnTrx0vbzGZ4A -1uTCEWx6tAA/I1Uzh4o76c0F3japG0QsjnRILeno6OCY1WBDi90QtrpW/lvEI0kC -le5rF5gk0DJjjzlwiuyxzfc+MZNMJNtgDzgHkW1gbQ5hc0OdLHmOgvbl3RePLF3h -Ur6KfvgkNmB/aINmQOxXqR1UI7G3mvQu7Twz+PtFT+GJYSTaQDnOHo/Msm6ikpoW -0/5XtNnv6VRjrf3KO6WUHFjz0+j3hJ3ddy9zXcEJPfIANZuuAj9E7YndNWX36cTe -3mwL4TaVAgMBAAECggEAHmZ8DKnbfQkaWobV9kht03WfrP8CkJB48FPCTQmEWYt4 -iYW+wn26jDl5yKCtmWxZh3um9XQJgrQ9rBp0grpJGp5o0drMEhyRiVoGzdfSC7xX -5gUXT0NDNIsWqqpzGSQ7YS6poS1V0YxUyBPbywShk1/02Hcsq4BjjrpIvEk84GBK -vGQU5yusSax7+86VjGPKbs+zLKj4r+KmYoaZ70QUaRC82GLq1ECHjOIrcS+M2Ih3 -h3EQbDqMde3TNiKA+CNCeimY+1QsqMu+y/CeIp/W51DrCUiYzc4xMcXICLkwlBpP -hViCZQKz0Rexe+gepRYTTrjnwESbb0WQr3cuitmsmQKBgQD9tDi35xFx22EKujuZ -gCPsSIxQpJ0YmZbA8gSPOoxd3dwRQdpnwAHJLSb0TKqpA7c6iE6abDFx89juOX/m -JOzHQJ7+i2h6NtToP2RbbrWG97OXHeujlR1UuixYRXBv2FKYCWxfi1URic0cATmT -4f2FqM+ev1gpeZo2FA3sy5fZVwKBgQDqXUO/9I188R46rStUExXWbqqbnqgcTM7J -INEQ4CcEmpjsqagJK8lwep4Vlxx1Jwwhv6u1I+h2nytaGGEAywuf/gHUyzE+lWQO -Xd62c1qZuXvNUosUPdzeT9ndRXshV7FoQ2sYj3wJc/7QwWYULQyISLobTyfLgike -yZ/pQVq/8wKBgFkyAHLfgSmXaGG+IfAQthB/XR2JElYwwWiqbeHxQqJJuvIyRdgO -EFKrVjOztJhhXwzsGT5/ZU7b3Vu7yXSfbMOMu5lgZ+X32xigGOdwX8/IzFIHye2k -IkDEh4ytNR+NXVRok7pvoQPef8clwxlz7Y8NT5lPSm6iew4iNNcYqRVXAoGAYLNE -vhJIwvG2GF3VT+ZkD0swR++py6uBcwmAWeczEjo7uQKzm70ea7OcQKpOCqSm49Hz -JlV/mFpKh+0hMTOWQ1iKJuQEGJ+JXkgrGbr0+hLHW0ugqSRxWqU17o+5o2NMhwmy -SbsCYeAjlr0FwnNoBV+EsrnxYI3/K33j5lmZ+TMCgYAsmo1HdgeGSccAYVPKdp9h -/ITmVCPZpQfhQ4iQTIC/g1lo4UKg/5JZRpW12E0eHMOYALg5P5lcLlOzOjFyOLqH -tok2CYLSf8QKR2YfqiOXILn37MKUB0O1y7hDmULUXku5uhahk19+gW+zl1/fehWA -g926VRGxI0cOr/mwZGz0Uw== +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtsS8f85RtepwS +CTqeEzKslqbT4VC3yXe8W7FI4c8mOzYDe3Bp9veaU8ZtdYtg5N35i7NPwCcGs5mb +bwGZ6pB0SNnRWIHqRGJp7JsR1gg1Arm60/wbNW3G+BncyIfrWJXntgTSu0v4BsKt +UcPqBa9+8XTBusQxUbkYeaBEthCP7yB8pYdlLfOjrPn06NvgMTrXiiO2AHucEACg +jmKUa6tzHbVgD8+xuQ99yIMge1/CVL7hOPHjENCi6XVGjJXjawt1EszGimAO8zNM +aFCBOnXgmzis9e6AZEiDFjUSSKv1VhV2sq5VM0I+RQEWHWbw+Haytgkvu4b7WMkj +HG05z+63AgMBAAECggEAA4Kjta0aEFZchh7KoPw5V3SZ/Yk9tOEs+tENla/+nEKx +FkPt4y5bFbLgvUCVZwlpFQyGPLPg9gk2LwaAzUgI0FjSkiEMSxxDsulVvvgI5W1f +LI/xNemQBOfpueURnieFrA+pLEsdv27/izouT/H6eIHPvsSUB30j1QNMQmc9kXMW +r57UW8JaA7OvOF1+NJ34B1sGodKyA+GF8FNzu9W+x5qiSUzTqElWbh6S0FZSXmnc +jpp9iEGCylcYF7QLN2OCZu5xyq4/lAyu0s8Xz0lt0SQvbefuuCX6q2h2Zbb7t9Ww +7N9VUR687jL6haY0ucF+E7VysObUqMFXj35uO3LQYQKBgQDpAoK6IV0Wa93yVMqx +ejuFZ8SzB/mbFaKaRfGVkf7evCZw+zSrMbRrOvpU7hyCAvIZ4ahKbPTJKFSBuSLV +NiFOBsbTt316olN4kR4kdAKW0D+DD6xslHX1AvdOVfYG82PXMHoKmi79yL7P/pv8 +W31KRwDKvzCidQBrdwsYFTm+IQKBgQC+1GUZ4isrfHtB/I+0SFqra4IuUTBd8wsm +yzgv0SR9mHG7RjL/LM/VjkfdCUWzLi/qAZXYs0ZAhn2sj5wFZrJxGLQC5FPgcCYu +N+AJxH+nrOo9eRLhrSxOyXHz8OsPJ10TvYWgETWLTvt4Yzo3d/a2SZbSVAeL/Fe5 +m9V39O8h1wKBgGFjq0AgscetThb7WbzUWgxoUs6BhtJLOKtCkLbzTpPKEEcot9rV +65LmE7tryn6MvKQUrUJuR+HL+YY+21BCT6lNK81R5CBduIWsIe0aj/p5EBK3elnn +s2W016jmRO6izBglKt1DlGB+h0JoKMpRcwyYoLwdLTa5sHM6TmjCdmABAoGBAKDS +II4Ks/UHCF1Y+salf3wds21TUN6sWAaOl0B9EjKiiZ6ZD5tLabABI4EdMldKImkk +guNIWnlAnqMRuBw5K0Ly3aneQO3RteuXfUDeD/MAX7wE0CvOpJuVW2qI66AuvVtI +ileWiThpDLatcT+T4yBGrkt9M4r+0/OBaAqbKfirAoGBAMWxNt0yw1YWWNDOq/9e +Zc0ZknbIgJuFXIQGYphglcrHCehjk0k8Xz5YPBzWNcmBgLKilTDPr5psTgM2e4Ru +M3fQ0pKEvgKIQJU/jdVUNq0TePcCQ+G4x7SzFmo78l10FtECcEL0ejvP4E/AvFZX +opeWhHSxxBG4BhlmVcLM9Hh8 -----END PRIVATE KEY----- diff --git a/tests/tls/brawn.key.encrypted.pem b/tests/tls/brawn.key.encrypted.pem index 8a427261..521c1d27 100644 --- a/tests/tls/brawn.key.encrypted.pem +++ b/tests/tls/brawn.key.encrypted.pem @@ -1,30 +1,30 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQuKDg90rv69yJIwdA -8R+1bgICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEGI6HAZn6n92DfJM -/T2nyx4EggTQyy0CxuU+cX2PrpL2dPpx6xsUxFAyV3EO4pXBcU8bkQFTkZ9HErxX -N2soUPVRLVa47fPcwK3U+YdI5dsJkq4q8p4YIdA4K8u+0zPAP46tyOvxCFPOFyH6 -iZYxFDjZKjoVgAOLOrXej+h8K75hZ7c3Ht30fff/KowYZKgygCAGecQldW4mXQv6 -ntT15YvaYbOtQEnVOiVjOXpm5nwubH+gi187/mmK87ynH4ihnx1t6plkA/19Mn4e -bG9YdBfnOHWfvP97USU7gMfOlNqvg27M9BrSE1VV2RciyfKFIeQhgLBbiczKxTHp -2XKyP8vCSgys+xgbDnxy9xZs3Ey5LdOH0afu93ie4BgLiVOBD4dQcdacZPQXeria -W5cbckpDPDExt7DebWY70aC4vkSCrA08CAa6UoAOCYb4S5JZbfCqt3KgCr/cfRx+ -JBNDHbHkFmmL0YuqxiLr4wKz2zc1+FCq5iDcX7DqFmWFVSBlSPfkdgD+3NzM4wO4 -ySJBwvRXIpVtDTGB5WEgAuZd+/eWAPqQYdBDKDFuDoOlCt/ZCH1JDGT1EX0D00ln -YyqlW5JVhEBxQAgAtvpFUO9LBbP9+Mg9tTFapyGT5pph8MPDU+TVWGz1j/7+eoDV -E6U80M4uWP8j834zUPGIvGsFM/jXi9/qkb3beGZ8NNEDms3I5/kvRuu0NYL28czM -MEnzlQY5/v9yWPY7+r+lM5F3ZPX5xpXiwyILD8vP3d/PyAzmPUrrtQp6fS6PKom9 -nmvwrvp38L4G0hBq7HF6Pcftt9g1MwLFpIjrZq3ddIgeK/YThCJ8EKbMqM5oxP8C -yDPpfKIAI+kp2TdQgHAJLuvzUsj4dOLNeIs8De3lb2trVZpoOV11bQSROs1neEY7 -FCY4lmAGye1IupyUAACHk7tAhYip5idoGY+DOZHbT4ML2qpoM2hmABA2qV9s27X2 -A9L63wQcXXzZcAiBUm7SKgh+GBiVyKUI4d3Ia4jixH8IcbLBY/+ySCkyUb1C4g3k -09p6sQSuZkO59WbGuuGJH8kIO76I6Arho2oPO2d5Zo3gmlS6tOW1t1ofsJpjQioa -wPZI+EfwY+ig6/GTAs2/J75Qti4K2iaz9JEBgnSaLBRNNXAiPYSZ0Yb+XSOVKD2T -Q8NbbB7e7+ErEM9LN8hG9KtaSrPsRUq3/6zUYTfoufiOCkLOeSoiqfk0KdGigHo7 -CDVb3Af6YOkLArNUbsQiA8YV5I1vviTdwLabqQoFRVJ2B7E0HQq2StAqblLc8q1I -EaW5KanQeLVh31Gxs8KYad0Stb/GusESs4W77cJs0ClosocfVYd+S4hdVBicwhR0 -ff4Ohs3jblpQgCTDiDeKwqug7HY9NN++Cm4AwgUZcx52tkRWrh0x++vLDBqds8Zr -227f1haBz7nhL5sh8OIgRBEDklrJLvVEixWFoTeeFuxLdTZuq0Y50DmwC6DsC5Te -Rdn0pfqsoqukVxtoJYpsnycDLs5RBFwhFTwLT0n6JVHXvMzG8yI/Bt0w9l1hRmfO -NnINg5I+glmbbGHgreRR5vVlJ1AETKlzga/COq141IzrcpCFelr8d4RUaiooxTxP -LkxlScU/dFPy3GNyUST/CtIpK9bXAC71g3Bx7YOMQ8Of3tgTzs1Lngs= +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQAoQS2zfjU3kOlNf8 +ulZiYAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEMOtuC47ngZ9H7I/ +NahjaXMEggTQ3IwF6kKkzQ5voZYELaJWfP0i+rabmFojQh1Q0+NThparHlWQkSV7 +BVKctoAajFa6/5w+N81czZk9X0JQIpfDrrInTZpCQgiWgEQnHXNY7mC12WwggZ4Q +gMFuhaUQzJgVIwkOQX2j++4bpsTJxoAm2EF6XA9ecGzPiS5awtoy8w6ClWZFsrU0 +vYd0/2OH+/OqZIpuwg9f3pNEQCXRcln5vj+xw+3maBweX7iQ5eJEIruFqYAIdRvX +vfJ2P+5FxjeDGF96ocMynC2chA5QEFsKJoyM0HBW6qb+RXCjy4aTwr8uzI1AJlNJ +4ql8D7BDfJNgpSP7ldn0N40UWJ6iheKIx+0zDaIL429x8I+dCFopJxs1Kd1GauW0 +Uv9QWsGdCAfoDau3xRF20GL9WHpqYjllOJwMAksYUpMLgb0MlVYnVloFoSN84oFp +J8CsBejmCsie7YL3NUnXN3Mp5ToPSL0Romdc2Vlz4Ees0s9N/AsT8GxuWI5mhASM +Ffju38cgJz/RsZ4Y+fbyKQ9tqkxI3ZSnHkPdVKbnmfbLZ8yjkHMEvcTfUB6lp9es +WQYWi7ubatZ0yLk8/UtETYne8iDFatWkz0Jdt67kNHntkY2c0IgyrgXgp8qa1TSO +wE7asHmbaRRQvUwJKaN0BueIm6ACZzwuncFc14WsZinmrP2d4BxAeB1fpd3tkphS +8s1nyPfY9IEzCCD3ynjEge3ElsClf1oUCnOr9G7ynqQzcuQ9EazzWvNLECFbKETA +b5gjaCWeyll06cOKepJZrl1DxMBU8HcbTGJrq0LDEh6qKQ9Ct918UxYytyhMMwd1 +jclPgrdbUrY8+ZGEMtV44tDyDMA7SI7Kp+qj4Q1HHtJd93woiquXgq+0jqgp8d2w ++ZVgkBMK0lCUiUnfJYthVmDGg65BNqjS0IKtHH3VpCXwnK/eP3p6S20HIsor1yjB +R66xayWxekcJbpxoF+R/mhw7F92AavQOnXZTxaWO7OGm14oUt1nX8yT2rL7Bekt8 +YzU2nxuhxfNwVm64RQYXPy0DUsMkWRZZhuMSjjvSnnu8hwopKhUfwKQi6ObijO5e +Kp0YCofQa0izIeRWDfHRwjBTz4rm5AmxkJs1UG33FrrchVqefFf72PR8wlgbn1FO +bB9/FTSxiQg0hYnPMN6xDtDlJJvX/iGmWSUW4UCkPJNXphZMqpqrqCiax5a4lyzw +k6e6MOsEuST+4EXXVXv5ykkEJmj8cCMfAXGQBKrcqyKat56kVcYUVkPAsJHQzc1y +46ZxtwruC2wHL+AwHY7CmGQfo3Jufa5cj+hMCmrKA+gDbpeI1w/0v0gg8DnCGA/j +GXb8BSCG4gsT5N1RTNfUhR+eUyfFX3d3/InLfC/C+t40jo9O3dB8LQQX/xlKKVqT +lj6Gp9v3vXYIKejMzRWLvWP4e8u+RDt+kFB9bMBvmSO+OVFCqKwqciueVH5Xm7JP +Q8StpWo0GD9vxPZ2J+dICs3822lF21n3NFiILx6oSfuQG/QeoZCCb/PUY7cECtws +wm7tEwM8kCFNvNH4Evca6HC9i6isKpTVRDKrcqDoF+656BxmV1aXgT7n6z+n1q0N +3N9LeotHjBh8cosJb3lQ5u3EczsdgF6ybsLM66dECYlNF4Wyl8szquM= -----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/tls/brawn.key.pem b/tests/tls/brawn.key.pem index 68a04e88..5a7589ad 100644 --- a/tests/tls/brawn.key.pem +++ b/tests/tls/brawn.key.pem @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDoQyl1Gq9UPJ/V -D3lCQ87u+P2hiPhJoC/GH7Z9GYcqEwrz1QiK2Q4VuhspMr2/9CaNnTrx0vbzGZ4A -1uTCEWx6tAA/I1Uzh4o76c0F3japG0QsjnRILeno6OCY1WBDi90QtrpW/lvEI0kC -le5rF5gk0DJjjzlwiuyxzfc+MZNMJNtgDzgHkW1gbQ5hc0OdLHmOgvbl3RePLF3h -Ur6KfvgkNmB/aINmQOxXqR1UI7G3mvQu7Twz+PtFT+GJYSTaQDnOHo/Msm6ikpoW -0/5XtNnv6VRjrf3KO6WUHFjz0+j3hJ3ddy9zXcEJPfIANZuuAj9E7YndNWX36cTe -3mwL4TaVAgMBAAECggEAHmZ8DKnbfQkaWobV9kht03WfrP8CkJB48FPCTQmEWYt4 -iYW+wn26jDl5yKCtmWxZh3um9XQJgrQ9rBp0grpJGp5o0drMEhyRiVoGzdfSC7xX -5gUXT0NDNIsWqqpzGSQ7YS6poS1V0YxUyBPbywShk1/02Hcsq4BjjrpIvEk84GBK -vGQU5yusSax7+86VjGPKbs+zLKj4r+KmYoaZ70QUaRC82GLq1ECHjOIrcS+M2Ih3 -h3EQbDqMde3TNiKA+CNCeimY+1QsqMu+y/CeIp/W51DrCUiYzc4xMcXICLkwlBpP -hViCZQKz0Rexe+gepRYTTrjnwESbb0WQr3cuitmsmQKBgQD9tDi35xFx22EKujuZ -gCPsSIxQpJ0YmZbA8gSPOoxd3dwRQdpnwAHJLSb0TKqpA7c6iE6abDFx89juOX/m -JOzHQJ7+i2h6NtToP2RbbrWG97OXHeujlR1UuixYRXBv2FKYCWxfi1URic0cATmT -4f2FqM+ev1gpeZo2FA3sy5fZVwKBgQDqXUO/9I188R46rStUExXWbqqbnqgcTM7J -INEQ4CcEmpjsqagJK8lwep4Vlxx1Jwwhv6u1I+h2nytaGGEAywuf/gHUyzE+lWQO -Xd62c1qZuXvNUosUPdzeT9ndRXshV7FoQ2sYj3wJc/7QwWYULQyISLobTyfLgike -yZ/pQVq/8wKBgFkyAHLfgSmXaGG+IfAQthB/XR2JElYwwWiqbeHxQqJJuvIyRdgO -EFKrVjOztJhhXwzsGT5/ZU7b3Vu7yXSfbMOMu5lgZ+X32xigGOdwX8/IzFIHye2k -IkDEh4ytNR+NXVRok7pvoQPef8clwxlz7Y8NT5lPSm6iew4iNNcYqRVXAoGAYLNE -vhJIwvG2GF3VT+ZkD0swR++py6uBcwmAWeczEjo7uQKzm70ea7OcQKpOCqSm49Hz -JlV/mFpKh+0hMTOWQ1iKJuQEGJ+JXkgrGbr0+hLHW0ugqSRxWqU17o+5o2NMhwmy -SbsCYeAjlr0FwnNoBV+EsrnxYI3/K33j5lmZ+TMCgYAsmo1HdgeGSccAYVPKdp9h -/ITmVCPZpQfhQ4iQTIC/g1lo4UKg/5JZRpW12E0eHMOYALg5P5lcLlOzOjFyOLqH -tok2CYLSf8QKR2YfqiOXILn37MKUB0O1y7hDmULUXku5uhahk19+gW+zl1/fehWA -g926VRGxI0cOr/mwZGz0Uw== +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtsS8f85RtepwS +CTqeEzKslqbT4VC3yXe8W7FI4c8mOzYDe3Bp9veaU8ZtdYtg5N35i7NPwCcGs5mb +bwGZ6pB0SNnRWIHqRGJp7JsR1gg1Arm60/wbNW3G+BncyIfrWJXntgTSu0v4BsKt +UcPqBa9+8XTBusQxUbkYeaBEthCP7yB8pYdlLfOjrPn06NvgMTrXiiO2AHucEACg +jmKUa6tzHbVgD8+xuQ99yIMge1/CVL7hOPHjENCi6XVGjJXjawt1EszGimAO8zNM +aFCBOnXgmzis9e6AZEiDFjUSSKv1VhV2sq5VM0I+RQEWHWbw+Haytgkvu4b7WMkj +HG05z+63AgMBAAECggEAA4Kjta0aEFZchh7KoPw5V3SZ/Yk9tOEs+tENla/+nEKx +FkPt4y5bFbLgvUCVZwlpFQyGPLPg9gk2LwaAzUgI0FjSkiEMSxxDsulVvvgI5W1f +LI/xNemQBOfpueURnieFrA+pLEsdv27/izouT/H6eIHPvsSUB30j1QNMQmc9kXMW +r57UW8JaA7OvOF1+NJ34B1sGodKyA+GF8FNzu9W+x5qiSUzTqElWbh6S0FZSXmnc +jpp9iEGCylcYF7QLN2OCZu5xyq4/lAyu0s8Xz0lt0SQvbefuuCX6q2h2Zbb7t9Ww +7N9VUR687jL6haY0ucF+E7VysObUqMFXj35uO3LQYQKBgQDpAoK6IV0Wa93yVMqx +ejuFZ8SzB/mbFaKaRfGVkf7evCZw+zSrMbRrOvpU7hyCAvIZ4ahKbPTJKFSBuSLV +NiFOBsbTt316olN4kR4kdAKW0D+DD6xslHX1AvdOVfYG82PXMHoKmi79yL7P/pv8 +W31KRwDKvzCidQBrdwsYFTm+IQKBgQC+1GUZ4isrfHtB/I+0SFqra4IuUTBd8wsm +yzgv0SR9mHG7RjL/LM/VjkfdCUWzLi/qAZXYs0ZAhn2sj5wFZrJxGLQC5FPgcCYu +N+AJxH+nrOo9eRLhrSxOyXHz8OsPJ10TvYWgETWLTvt4Yzo3d/a2SZbSVAeL/Fe5 +m9V39O8h1wKBgGFjq0AgscetThb7WbzUWgxoUs6BhtJLOKtCkLbzTpPKEEcot9rV +65LmE7tryn6MvKQUrUJuR+HL+YY+21BCT6lNK81R5CBduIWsIe0aj/p5EBK3elnn +s2W016jmRO6izBglKt1DlGB+h0JoKMpRcwyYoLwdLTa5sHM6TmjCdmABAoGBAKDS +II4Ks/UHCF1Y+salf3wds21TUN6sWAaOl0B9EjKiiZ6ZD5tLabABI4EdMldKImkk +guNIWnlAnqMRuBw5K0Ly3aneQO3RteuXfUDeD/MAX7wE0CvOpJuVW2qI66AuvVtI +ileWiThpDLatcT+T4yBGrkt9M4r+0/OBaAqbKfirAoGBAMWxNt0yw1YWWNDOq/9e +Zc0ZknbIgJuFXIQGYphglcrHCehjk0k8Xz5YPBzWNcmBgLKilTDPr5psTgM2e4Ru +M3fQ0pKEvgKIQJU/jdVUNq0TePcCQ+G4x7SzFmo78l10FtECcEL0ejvP4E/AvFZX +opeWhHSxxBG4BhlmVcLM9Hh8 -----END PRIVATE KEY----- diff --git a/tests/tls/brawn.keystore.jks b/tests/tls/brawn.keystore.jks index a74516a9ddea36595f3ea1bf6cb427130f34490c..cb4a5cf2f82b240aac097ca9ba3c4b94d6942daa 100644 GIT binary patch delta 2530 zcmV<82_5$C748*~b`%1el`C$**LA@TNw0Y>zWVB)pyrW^B!5=XGOtfiTC{fXvfW@} zh|UCp1kfEQXRAr~$2A}XW!+QYbi-k!!;^$gI!v-l{N@5uP`6(u7zy$lb1PEma2I3} zhc8k>q>=u36xAMPAtJ;F@$!fzr29xlRDt<>^Ew=#zTh@9#!HAI1cVnFPCXBUych?} z@=0&ruyu!*1%IyZiN6Cn{wM^Zv9|MR$Ris#n!1D>!x$k*px({4t(N*`rJl3;2ByNL z(3t*<5xc=v90K@nh;9Qb59i0kLQpIf^ylUNt>}F#6}6IVe)XNwY&_D~Pg+C=+e;*( ztr-V7;gd+#wkT{1A`V_}WdMIO^D1Q|(LiBYsC64dqkon=smy&`Rc7tC>8{&zJR)0Z z7Su~f+5LORwS_=peevaG2+0UN$v;rA-Cpf25~L?m=4n9Pe=QFW2aiYq$p~CB$WRBXZhQX0`v6S1t zNlO-f6)=}P@FD7fB(M{Hln7wBb-kK10X6O*27g@KlYm>NM2y%E7t109%~d+6f|^gkRkQjb?}$4r4AYuv}#0!yvNaPi%F zn193m$+<(zYdwPzfxtS+j;}~`C(a$k&#N*__0V@X_&&1rvF`&7f8zSvDH5-43H3NU z{{S3A9;qnI3oM@v0%-1Y<~ur}LRvl=^s24Id>ap@bFKn$-wcRhZS4auXKdA4<)q8a z0>xeY@z*n;09egvbh%yXgn90W;VStNL4Ppy0SJ&Cg`D4C>W;~)L{paY5$6xpBqFnj zeGrdcjQ!x7-E2+Z!?bf*>s>`9hix1?7anHymUZ@o)UUd9k+`;adlrkyndJs5taIdk zLBhe>o2wWEBQGz4)Ylp%)MSCrqFXRw?Y#k&&eeJ*m}<42iOYu;BAZj)DBPl+(SIM| zGBq*K=hNaG4&a@As&Fd4H?l$BPwQN16vy3HTzB83kgy=IShNiUPm&gheuFH5uu{dk zGdpU5-{&3ZMYIA&M3CZxG9jfzqW<8L6UUND#wJX|MkNgM*n~|Ij<=o%w*~V_ii3%W3!MKAT2W&) zL3=L`B8K%ji)2LvdUGzg;>J_evGkkKYcM%jSLy>Yx1>Y(EP9 zL1D&b89rrb6?)vz8@&-?XF)~c21VS^h(q++SO!B1qJQj*<&}wJo=|=R-ojq@kKC6`JFD)P zg^Zb{Hj5j~ay8(vq(mKX=*_&w-9S?xJQ6aTUsW1k4uro--s}mEgywNdGK|`Z7MV6~ zs`JDsS(oH~`V2Wmx|}AoDs+Xk`C?fIrW7ryDg^Sb_$thwm=!Ur650*^2Q*i-z-Af^ z%YWCoM*G>D3hRs~A~_zqcz_(t?78sbKaE&B#Xa5Y+FwHqq(`sEQUq9s21 zvKt6`LJQ><)yjp`&7MyLmi&v@VPccuth1MuV1-o?iI7G0sY~U=4t9oGJOWwf-haCx zAzsRdZZd96*k+(UQ!|Sp?m^uFgp&*y?+)Ln4Ec;!qo(V4!S154@w~mtMb&*k#~AN= z`8&$kj3v`k>flQtiO*sj-9w-Fk+{&!H}TEjxBH|SqyIdr?O?*DmBej62%5;7(g_o&uN6*_x1`4`yv#T~h#A)5QmYm-D^SURC#nh_j9~c z2G(GW(=S2K*xOSuX|zXZ(rH8T>^4$mC#nboh&d=#U>Rz=3M**x0%2d%JcNO z)!}03Pdj`IzTmSFCyvcd10-0r$AP@^X|WLSTBne|8pN>MB$L2U^Jqny=Pr(GP&%k` z%#u#fl1a$Yrt(&(x;6V~lNFHvi++<5y{PT*5$cnl3KcrqaHPJ#2-UJNIHpbxqR$K)`h-`L)`3JVFCgt5Y~g^XaE2J delta 2530 zcmV<82_5$C748*~b`<69om)Ag7N|pTQYZNo-|fSbw6G7beu)U^-!R1>G!=0f zhe?CRZu5Mj5%~<->dKul%Cs_de#i)axL{uK+JuQ+Z2)rKAautmgkidbS)oleyYi) zu`Oe+iU0+Nx8Qw6u)=te1c~O5BdMuEer!n@gql8gn14J8kC_tvIS{aq{wO{h_4pI` zn)Ffp0`C40k6i&8M%DK0pf8O#u@JJ@uc2PL@gU!0J$!L)N;%^*jM?ni4Xrkd08vob z;|F7Pe93rv1F9@FBky%MgJxUS|i?pVi=FoU+M$6P7=v(lIIifWxD3hic!2}ylsvsRP3il3?4>1$ex z;$l*>?uyRQ@@W|&)wHel%TjiS_b{h+&?GmH%+oo@E#)2ruO-39M4>DZnwvYt?p4!i8VKk5QS{3x9_+&n0*}!qi@7 z^mR`=d&9T9EK{;JY|^;Qcy$OArO>>G68|L0cpWBm4Ne$c`)Y|64lpQFdJNsooI639 zY=0Z+HFe7C@uG&#Y=F}j91pCeP2pr23nj1OycO?HCz@{z}W_<`dP&XYQ+NC5Q{ z45$>k2;%N)X}#vBCD#-DUtNVWiwZVuJjheH(pai#o{J=&1{A!7C@-$}cjB_0_NUa_ zW=+8wk?(_FO)2uF+Z}Bp+%48}PEXl%9e=OvSo{>X(Qm!PRx*(=X#CxReF2Jj6j09| zyK8)DlF#uI64BX@?T?CNu=QUPvZ5L~X%hS?T(=pQK*v92kAE5H!@p6*_%3~S2Jjyj z(tOh$IQNRI(tVn*X$^{(yx2ER&flqKbZ&NL>q!(%2kOYdty73{2Bzw8?*G-A2EgfGxaR~&&u+ih%SIzagk z(LDCgmed1D_B7re-Pl@&73O)W7*3Fo^=#xHrX9r#`?BmSbP29QHmWEn?+vhm0VT|7 z8cMLX5Pa7(stUD*C@2o=z-45Plz$rU*}Hun1@$FBiAU)bJ4muO#jF^z=-9{K!9UZE zK-NFkVNSTnG{X0&ewF{j?ibE@xKYLvgcU>k4G(GQ(n3Ut4 zs06IdVHbEGsO%(>?_3SzJuGMoV8oh&i11&`6h2-ARLhwT8@{5ZZVP*j0DlT7(4i=V ze>SfIpX)4tE3>{!U!*na8}UQHswJ#LX&;1@r`G|3(9*8oImY_5x!rOcOXlq08$XwS zEbub<{)%}keQ5C#Fa}q*FS$fC($fvieMccfA@Rf7ZO=e1N23%L(eJy;0WONc6p(2# zHZTze2`Yw2hW8Bt2^28|9+RX69|touG%z_cF_X##Nfac=jXw99)KL1EMreUOd8|P; z-#?LxB!8IUX`^F=&3Id+l!7l%43dC?1VB3bF=}xXGp0pA31Ids`T^Ho{L+Ng>Sg?E_-s0&JxZ^hZ9 zPa-&3NjQO@{c!45yqAm?GTiQ09hQ^ukd%eUrGFRhxj|0pBfcI7(!c*XSOLc!-+^W| zWDE*zeQG_)p>ISaWtP6dpSuUIig(X*X@;U;=#nUk^MKxBWcg~$>ON&(({aaLx2?cY zE%kXei(H&83}5ZP?TX^4`JD`0Clo=ifSVE?S0yk=&YV{<Q%CHN+gQ5^Dm$*{fapzSK=ztMI{u9;rYrv8M z1%ppPCONN2{WG+)P3JgE;P|%7N<#r$wN=3jmFJ#h6^EPZQIYEDeS-=OxFyw-+xZW0gydP;4E5yV=y+%{iyVN!JXyA?87g4&#a zt+l04VJ_PWYv9z65@7|h1eJ0UMN<7unOhS_kglmBE#Fr`fYrS%uF0)+)Q|V=83R0b zGcM5O*d2LAB}NW?b5h1FNh8TwxB*ZF6b}sH)>2F8?XRo^L)BMuhjNVP6Mwz>t?iKC z+>53Q{4zg{Yc#isqh(a_Xn;Z;?t1kVaRX@GG&=q;P=*#l=P|FRk_-)WbyBz5mWaGg zaCm0GLOWFkc`48)aB;BI z4;+?PXDJpDM8U4@rY62xO6-RLrkLp`%b|=-Q`rP;zQzVQ4HUT989?JN^h+2|cM?J+ z(_PFp-5Hi$6rA^MBfh{^!C3Kcqkt+mMN*k&9`c042YhHxS_ shx7~tzoIwzB3vAJqaP6j6e@Duao|B`@~52lI0e`P%s?1t3<3ft5aFQ3vj6}9 diff --git a/tests/tls/brawn.p12 b/tests/tls/brawn.p12 index f5826c50af5ffdc3a4ecc701a2765244269f0993..fdff0204ab4631a610b48621749679616091aec3 100755 GIT binary patch delta 2504 zcmV;(2{-n$6|)tPYY;W(8^-w_?;`(#qvER~{kxHSA%AaZETa_TKd-*$G|BUO#%+Lt z1TcdD4QAyO45Cb^3XB&jPI`leU&TZC{^qQD_Tl;O{m-TZ$ZTDmKJ&bOOu&xfACc?7 ziet&6Gb~*Yxp#VH^-F%-utRr1NY3LVbfSE->Q<2>@|LfVWGe}J-pTC1e9K>IIj*oymB+bmYn0rlh7_>ZiK{GSU^8qfS_PL!n;83l#}U(tJ>e%at?V*cr3lFHpj6L| z_%oofMZCbl$Tb4d>c6nSD3-UyUV(`RPsNYd_)O|b=}Zov)oHNcfin?rL~UDzL~1r= zFjLf+vuRT&{&fv)A1GSgXAA$|4N_DuWaAQ+u`=UeHLOkf-$IIa3N+hJT9@{j{(r{s zG?*iJvlb|_rh|yxdKwq(-3B5ThrEhle7_SL>cwqR@*HZXl~(9bf4#|Bj&8p z$5f9(xJ74aL?)Rz^*=`VCJ$JWPh273mJM@?>$X$@4H6RBjgL(708rfnox7|2NX7Ad zZZ57IpStfhxnH4)cFR0Af*b!pEq_~ui`sRR1y)Oh0O6U~W?7A|B0S6-o`E}DZWn5^ zxYn%W!8<@EK_kT1Q&}Ot(XM`q#62-4zDoHO8qEQNUEq1twOvOR;&Y)?`W@F0EjP44w6epYnf&|c9zg1c;a&tHXIquCIl5b1I zaCzg2k*1uoO<%(SREFNImPN~K_3U?A?U?@Zbbcdgl-5oZ4Q69?Qx=dCA_2|jZ&kbA zu~ymMZVrVMUeaeCy^8r>WHBx)Qji4EQ2Gcp`PhuwTycMryOOoz$2+f+U7uoB zdPf8}otgimr~{TlpGtccj(9z5){N^U)UuW(7tl_M6CJ>;5H*V`(|DW~BO?V0MRIU; z43@^{2H|*bdFyJz0hI!oKx}_T5+?#8aoq?ga#BRqKn>6|Jg;(LNtf59;HEdn#;*e?Y+>$m7v1=m8~xg5GJ8)*&_FG zLyKz;IQ0(nJ|E`p2tfG#ruDWZz_FX^Jp)AvwF>N(NsB|_?9;;n zROun39sWi(3${-(m)%NoPG4?e8MLKG3anWT3EIDRmn?r!p{TTRBbFHO3*kgzM=anN zI;#(Smx6ZmJ*K9B>@fIl$C5xfbQ5z0htkS6S|N-!OLvaDB*!<;xA_TGk&&3;KQO8% zLb?lG|Drh3nkk`OMFYqB(Tv8K1i$qBW7*+q5y`bL;`UjK=BDhxWhdZ(IMJC*mho9c z4MMkNf4qP5CRi^Di^+=h5hE1%Ybmy)Z++5XQ;pnU=_*^VsKBDsbN#BRQBdn`md#;7 z;QXQCFMUTC)CnOaN5iKzrv=zG7t(xudf)rKv25<(tA{Yaj(uwj?d7-x{)%GN2PX5! zYIZCDQ{ovqe1=JzMSW38+#pg604B`VN=L@=Vw!)mTkuTaE+)Gr;eCA;m0bjWdF!GY zPq7|>g|gEm(_$Dm=Rz8FV-gL!p@Wvj@Ua%Hy+Etd?ww%FNOU~;YK+D4Ro0V_5+oMf zivR<`B%dv;`rF}airbZ7jaton>I4$P)xxG26)OSDL0ZJ@eS%Bl0Txi#ClImRHX7rF z2x))89R%4LaJi@Tb>TTpUNOM*)S_XGX>-IrB#qIGl5#)hCKMc0{P*+3J33AU_sc%CTj5vg9Ol9o$X7vsX22Lf1HEwssW6eX~<;@ z6Mdj9_XbaZ*CAC3!~levzlqGD8li>u@FBtL8Y7Rz;=ULde^WW3KH@tu+YU&0G9`bO z#R$1VSRGU=zybz7=s%aL!^2q{y;TY;&pSJfiGDqL97r<8FEUD6{Fn+JuAKNqYom#h z5AGO_3!`{KfkDZUwO{u0yOt4KH$7z1>7XA_7g!7!it7bW{eT=0em>R_((TRL!5NHc zIl=)3nE2nxiNMke4Kuph{nQRDWBGrl<`DDSf=*56KE$UN?uSBi?6QA-X(~rco5k8R z$!(oEP%V4%(+=X#dTS7LGo3?VDQJ%*Ky!NrBEfi4Fq%mi5XS#pWTwhhGnyU20^nkU zd;Qv>OuUG{{$ioY$9%9ED(%y?RhVW#=R$NLF(oh~1_>&LNQUxyHaX`=l0tf)@cD)Dy delta 2504 zcmV;(2{-n$6|)tPYY@{cq%9$QTwP$qBWQ5`k!+EBA%APVGjfQOAnad9&j=C9-c-iG+h2)!bVv;d0FnsTt` z_ZUM*p_VP)B+VmFcmVO^o;}8F{VlPpvUBss!ey-g^{hP{A9AL4FGdpAfvfEFvqH!o z1q1pB5P#%nS7Ut3EHumO&4PR;iR<=^kTTpFBfRDDKnU_p06KPV^T`^;7Y{(m?#ujy zf}Lk*qe;$clcb$%rv^g?l-~fX+KYvnTz3v+0&<^4J#3Of-rjZ3=x(S)+|Sn{VmhIe$r`HUh@*1VJe>KT?vCOhocO8$0Na+I$JfxUY=KQ=Ca&@#QAJ;J24Iaw*z?de`M(% zcKFyhh8%atdM&DSl;vwN#Z!NT?NzZu=hO;RyIALJJyT{FZ(ui%dNGISd*zZ2Uun%E z*neRMtMpkfyEgkb0w(@|+yM@v{jU0Fg=%E=ieYi6`V)iR}(Z zC&8kbCOMy|vPDj7J|NF6*%}f8=Z8-MTiD&Uea z{!%C?CziQwDFjU~xx$!j3RjCW`DiIPr~^jUm)E@?`mkoLv>0m<U`SfG>raV^kXe>GaR&1HG z%pL?;sxoc;e8+&DsiA(?SF@# ze-K)8*$;;{`g@w{^MVaOn2iqZJMV*H`t>hk)9e+>@KF!UhPNM*ynLWYD}b|!rI>&S zIl5}Nj6pUN(RYpQ8Jy=X6_*#73n&iw=ywo+$-NE@bxzCjxxRn;h?=#HY2Knt`r`=O zx;EVq)2W!&PV{+;!RkT}%(6n3lE;fFp`LM{nV?4oXM5dZ)0#vPma7hj?Gb@y_#>sN z#N20fP;sge9?}}V^j6~uiE;%%PaHCQFL*%ED?2NC=l~wJUMF3iV3v9X)VR_Aqp+DB z7B0--{}L0RY;%9Ew_>s?pR*3$rNz!XzRVgJb6LFWiX_WQq5U3}j;g8d^TVQS;Gl!O zT8s$45DOaD6IyK*_!(cf==^`sFk=wJHN22SK?&u_$qVSc2{*}Zd@T!9EKl0!i2w4_ zRKXvKV(;am8u!SLC>qR8iYI7H7H7lwiwdxwdanbfmArqq6G6D$N(#h;lgQ~r|2vM6 zO{(rLT!BNb)mzVjV27WtaV=;zLvJCoMnlcRQ|;xEUF^nG{uUQRaUt-AeYe-ozazOR zY*0&dmhJ6hb4&k4^JYA_GLL*f=zWBZqN(WU?*gCzWO0Z66|3T*6EAec74GfqDskIF zpe*zrp%{P7)7#+(;2@OK590iI6NPNfv@+sTj%+8_?j0l0_PF)+y11RB$gVkkG0ag`Q9$&NG@Fl zrvI=^o)yxY?b@Ses!n^O_o<=MUzqd#e3-uzjWP!3=BDMxK6Rw?^9navm-n$XJBia*gr;t zM#;W@b%qiPIT;HdP*GPC@mP#DhKxE!cS2p|9usg9ydncvHD*Empf2CxJvyBmr|SbufAv;xO(Y0a_cIs@ohzWh1U7n6~-Nv zDR!>tDDo1zr*j4IiYMUK13*MC(`-DjpaXxEu3q_{V%!)(*p@9*n~Iak1PM-jeFXAb z13JAx)#tW*WfLPQG3?6_(-U)vfj9EyEy{{yX*ClrqN}4EkU7yhHC6CVr#Z0XS<=g! z&Hp2knZ!4#@nrTonfhu?o>gBgdXEnml#zuR{?_U@7RO`6pv>sB@xT$55h7@&mf(Ly zU_!5{w(?e20mtAR-=dysVgNzd`>fO(s8^0mlP@DF*P~6*pNam@KCws%U85oFV zZV&ZdA@U&i$g0*^x-Oixui(Pzdk$0!{FdL{V7GIYIz4`+&6nlxmLuoZw^QnkGIT=` zEldb~ip{NH7w>2B5zFQ>^3$W_ome&Kx$BBYF(oh~1_>&LNQUZE51<_Kf{?#-UYHo0%=gLVEmDPB!A$NwNuF;whH9z1QFK0 zN4J221b|Up{P;ulQqAxX!-b!c7>gt*PU9qCROD>0(B*6}@bu7pr7<*KDH$No(QGD) zgRK=-QN@jvUzT-~?^(fhzU-`ViWe~52RGePu*NXZ(rd4l?x39Wi01=?KQM~e@L;Ra zTL(FR1V#Ft6dfxLM#bs4 zx3FfuGt-JqkF+wd;jojXdODDqImZ+uhaif5?=}TiHGkg)xVIdNmC2%*zlsBLH#yuz zSKWlE9Z~3?VL?L|=m-dodVjINKY0Z8#^!xdx^z5e>Upvc3x?q(kMn*n)0ae8Fy>5e z!Dw~barXfJ1*6K+QquTx|SjvORHA~T_st^;?*5^=OW+cwP?o|EeiSSSmbYF(+H zCH0_m%R0E+A-JMJHII?E0ptO;AgoRi!BDwZ_8Y2^C_($%(r3vuwY7vR52YpJ<|V-+ zR-usT;4mk&BZqt-%cd^MnWT?c0Dxhfwi#;RcYh{TH$&Cf7ymGp9!p~sr4;)3bw`nu z?RfU06h#vLQ*-v{pD9$hr4XwT1{Fu%ohdB*jQ?n_6^2nBGi<-FXD)vSYB9DY>!&Zd zES%bpY){u=hb)8*`RkT#7rEUY20o0PmZqN~ETy^+kCmbOt=Hf~2m-kCb%F~a8)|p$ z5`Ug@(iWjIQAi`%=bV^p+jVh8=&!=SzA~cAB~vcbygsDb>bd5*lN-1_-KZ^K9z7E|iFusOK9oa7rq1Pd-Y(Kg2cCh0G=C`P zns=~w#(3bK(r*|SwQU<)T0AuJ*%96BV!@6EZoB1{GEyqC&#iL@4bfLfg$XC~(uHIs zt~N16R%AFv(kv)x^K?hUZJTgaoqI&Z2l`)8Jie`g*#?Q@n42<3&j29@>%DJGe~b4( zsk^rP9^fI!N-jmFgi_-b9)e43>wiLc(FG8ni5o}T^ADW{lSR{*?`Q`{2zMVVQeR^d`3Vuc~O)xPq4F(BdhDZTr0|WvA1povf7&x7oC~(sOsuN{NMmoVhE0)wB!34Dy~#>T(jl^p*-%DO zxB7sB1b}GNtEnnbk8H6Igd%(wA^1G$3vqI!F^SVrJ%tb+Di^T^){M5VNmT^rP$=37 z{XM?OpeX6u4<7q$bk?Z33RJn?a^Q&ulC?Z@@Nw%EBej4#;9@d6JYB5YJlw+Z$lf%p zTPNz{trbS{;(uNblqNTkwizhHe{7TzvrGj!dm>MSF9hYKexjq@?+n+C(uNdMSgvTeRD!@YfJ&B`ZJ z6?H<^3H@Z1UuIOYz$CD1zFJaXN5`*vP0A`S`n&tTW`9wjf{JwxYm)WLdqVIJofSS{ zRR`I%o1MV8tDBUd%BlQ)XG5*|yE`os7;sz&f1y#!A*lhQsqKtngB@MB8x{I)%rBWq zd`nItPf|Vbb9aFPg?4tA-~oGkYE94wRG@5Da8+`^fN#P1eI+%wiYKK-)PC-lN}zY5 zpHke+W>%u6_j-ei(0?Hb&gnpU zWTON~(+yZAKkK|CL;QPP*b$scWg$qayd*Yw%zwXc3{jUIwpRyWa>085fp=;J%3G;O zv9KQ4@_4C+_b@RiQwK*o`U}p$U@loxF56)HcAgueUV%B%Ya)IoEWZH8Sya*!i~6?F zjv;m^P2y*g^b7xW`y+MA9P}#eHE4zXuh^CES(kC}v#~n{OQSJ*NXfFk+FRm!(SUev zet*l7htuebwnCwPo!aRpc8;iK=nmRUmmv;-R9Zjk^Rm#BQ=yd4ELmJDH(ion1>mdX zjB-Zvc)aLkx1aWt#k@90LTX&iAiEa==f`31BpjbjwiU&4ShlI|EEsH218@h2fy>aN zl!4%EcH)Hr{Gm~wQ9MPvX#}C3f+GD>Ab)ZQLP$KdgYS6DPbW@l8--|{i_^V|C36!d zUXsU_@qQjL-b9DzB{BEikblx%c79oOlm`a#*9AC$ocAfcRtPlc{1|uSwx*xjHXMU| z1?&jcNZgcW8G=LX9|R2E9}OB;zQ+NTn^p(EI{-0)?NYg)e|*Jd?iK_4a+!xFu73x5 z$`@ox)dx~J+|AV+O{;C}n1Sjhg1w2AiuhbOh)k)bMrI=c=KCb0=2>8g&v$MJF@y!i z>;QR=`AM$1ZKg>j_)+8>>~fFku%Y1Hu$+z@|A<+y;yh=!jOkGwz~fYn>D{c4IJIUi zYM_1{;{#u%2bWi|3qbqIIe@6_uz#wbZqDt~^xO7ODm^%a(#DIZ`Av3h4FC{tJ$K!? zp8rUOUP$nGoA_60jNOvPIJbFGLCz^YYvgG3g2K39XIE{TSxB<{dFrfJJYVTH4!jn` zLxLUxzfm#djX{_R)jG(fRr;Wi;>=@s(RNG9d&r4^X5Rmt#5CJj=A4~!QClJ^6 BYcl`< From f1a9949f2df615ac1d9fecb590c71d23864751c5 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 10:24:33 -0600 Subject: [PATCH 088/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 5a4e98dd..e65e594f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -51,6 +51,8 @@ jobs: - name: create config run: | assets/call_gen_normal.sh + cat aerospike-proximus.yml + cat aerospike.conf cat /etc/hosts working-directory: tests @@ -119,10 +121,12 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - + - name: create config run: | - #assets/call_gen_tls.sh + assets/call_gen_tls.sh + cat aerospike-proximus.yml + cat aerospike.conf cat /etc/hosts working-directory: tests From d47658aa12ee59a1f60f6357b17eac4c4efc6254 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 10:33:13 -0600 Subject: [PATCH 089/215] updated conftest.py --- .github/workflows/integration_test.yml | 2 +- tests/standard/conftest.py | 4 ++-- tests/standard/sync/conftest.py | 24 +++++++++++++++--------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index e65e594f..9e0e9f1c 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -154,7 +154,7 @@ jobs: sleep 10 docker ps - python -m pytest rbac/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs working-directory: tests diff --git a/tests/standard/conftest.py b/tests/standard/conftest.py index 329d0a6d..00379be9 100644 --- a/tests/standard/conftest.py +++ b/tests/standard/conftest.py @@ -2,8 +2,8 @@ def pytest_addoption(parser): - parser.addoption("--username", action="store", default="admin", help="AVS Username") - parser.addoption("--password", action="store", default="admin", help="AVS Password") + parser.addoption("--username", action="store", default=None, help="AVS Username") + parser.addoption("--password", action="store", default=None, help="AVS Password") parser.addoption("--host", action="store", default="localhost", help="AVS Host") parser.addoption("--port", action="store", default=5000, help="AVS Port") parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") diff --git a/tests/standard/sync/conftest.py b/tests/standard/sync/conftest.py index a7c8a175..76d8d274 100644 --- a/tests/standard/sync/conftest.py +++ b/tests/standard/sync/conftest.py @@ -5,10 +5,9 @@ @pytest.fixture(scope="module", autouse=True) -def drop_all_indexes(host, port): +def drop_all_indexes(username, password, root_certificate, host, port, certificate_chain, private_key): with AdminClient( - seeds=types.HostPort(host=host, port=port) - + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: index_list = client.index_list() @@ -17,9 +16,16 @@ def drop_all_indexes(host, port): client.index_drop(namespace="test", name=item['id']['name']) +@pytest.fixture(scope="module") +def session_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + ) + yield client + client.close() @pytest.fixture(scope="module") -def session_admin_client(host, port): +def session_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): client = AdminClient( seeds=types.HostPort(host=host, port=port) ) @@ -27,17 +33,17 @@ def session_admin_client(host, port): client.close() @pytest.fixture(scope="module") -def session_vector_client(host, port): +def session_vector_client(username, password, root_certificate, host, port, certificate_chain, private_key): client = Client( - seeds=types.HostPort(host=host, port=port) + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) yield client client.close() @pytest.fixture -def function_admin_client(host, port): +def function_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): client = AdminClient( - seeds=types.HostPort(host=host, port=port) - ) + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + ) yield client client.close() From d348a48936ead227a028650ba4638e9f8bcca50f Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 10:46:14 -0600 Subject: [PATCH 090/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 9e0e9f1c..e6bccf8b 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -154,7 +154,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt -vs working-directory: tests From f4288505a82a9ee5775f3582492ec6adb811e2a2 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 10:47:08 -0600 Subject: [PATCH 091/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index e6bccf8b..a1f9452f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -154,7 +154,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt -vs working-directory: tests From 09d8eafd52bc494d7b3eedfd794477327152a669 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 11:47:36 -0600 Subject: [PATCH 092/215] CI/CD update --- .github/workflows/integration_test.yml | 6 ++- tests/gen.sh | 15 +++---- tests/tls/brawn.crt | 32 +++++++------- tests/tls/brawn.csr | 24 +++++------ tests/tls/brawn.key | 52 +++++++++++------------ tests/tls/brawn.key.encrypted.pem | 56 ++++++++++++------------- tests/tls/brawn.key.pem | 52 +++++++++++------------ tests/tls/brawn.keystore.jks | Bin 2798 -> 2798 bytes tests/tls/brawn.p12 | Bin 2739 -> 2739 bytes tests/tls/jwt/private_key.pem | 52 +++++++++++------------ tests/tls/jwt/public_key.pem | 14 +++---- tests/tls/root.cert.pem | 34 +++++++-------- tests/tls/root.crt | 32 +++++++------- tests/tls/root.key | 52 +++++++++++------------ tests/tls/root.key.pem | 52 +++++++++++------------ tests/tls/root.srl | 2 +- tests/tls/root.truststore.jks | Bin 1414 -> 1414 bytes 17 files changed, 240 insertions(+), 235 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index a1f9452f..ff9db93a 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -130,6 +130,10 @@ jobs: cat /etc/hosts working-directory: tests + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + - name: Run unit tests run: | @@ -154,7 +158,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs working-directory: tests diff --git a/tests/gen.sh b/tests/gen.sh index 2920a402..109bd83d 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -439,17 +439,21 @@ EOF read -p "Specify a port address:" port fi + if [[ "$host" == "" ]]; then + read -p "Specify a host address:" host + fi + service_stanza=$(cat <EIbx#?3;CoCppq0i@8VpkChW-=1h=zVa02- zw<03sl9&)Z5G~MbQZD04TBFDknhwhDfv_ZE+%tTy`Kd8EWgSKC*^u+EcgD!_Xkrgh z!CkcLILcBdeSaQRVXT%H`?QWSD!dfA?l?LWfH7?QWB@^IqOXx?#7TX?7YZxwvqmwQ~v?~=HLbhW)IxR}C?WA1c_zAD_YEA{+)#_4x!4Ty+lISI(=FjCc zii~Ckdd@^st@t)E1YI*6OrtcUt$_x!VbND89)eHeFMp#cZ8=Xr4byz8b;rfbatV8ySai8`YoF?mf6HY9bT{0prWj%g;@*GtN+ zt!2TwH;evIJ_?s}xr)u#Ci-r9Ms46qd1I#c#5$UKTP!Z(5EWG*xmV%h?i=%=&BYgK zYvBIZR)0r;cSNEy)rLmZPIv-YYn)zP?+sh5CtxatMZK0MX*>Ub5qTl@(F_!J(+A6^>MM@o{Cojv%% zK}r}DP2gr=AK2!>bfzk4XLovnC$$nd$0MeI*ng%se6Z=V7}fE9|KBh|1t_(FMQ_3a z>iP?_0xgn05GVK?g$F7C>nEXz~ba|AD|Aw~r-ziXS0O^wdMZG7- z&XP;@M|oa}5V^I6pX6Jpr)Rx%EX2bIgX^q=4-8yA6#Fq8x@i7!3iVxEA8MPoOIqxQ zQ-2(y+xbNUtm#?+C>e)L?Qy|<@Qu#B-v4i&q2lyws?&nEeSt584{RHwj{an%u$8MR z9=0WsJXbd58WT!*ovDit)ofm8qTHOOWRU2MfX3-n_FR`;{Ck^)Hr`(6K#6C$hnZ<= zpdrVav~AYz@1MgqsDCjy zl|*p8^QL{|uhCJQ0)c?^s3~%Q=uIxytpS@#{-Y1b>vh z35ZED+tDLzBn#C%T#E*b(%jCZsI}1pwhCSeoq~-ZOEC5x}J+x*zvV z?;O$WiSZ9c{(40$@>dHZ6T70x7JtObDIVSTM@>iUK`APTB;5&n;RfnZ8K6#RL4&Dt zzV4TdnJbP;ojWBWL45&7h7~Pz@l3$FyTMPKpyWcJ>{4!!I8vGuaSjMvvnAbb+PR?Y zy&vIq_pRtf2jMbR93I}Jo=V9uIv9U48JwQe9G^!UfgogVmg(nnV z6D}cikOHw}oQBlTj~@zhyLZSI&YaQk^PSfTN{I7Frz(^oQs%+_{mG3nJ$}cmMdq|6 z`u+%n497C%0yk+<4z>_}ocYL{k}op^bs!!nVTjG7QxPUt&m6EJ)#JAZ+7M14-#F$m zHZTze2`Yw2hW8Bt2^28|9+RX69tbipFflPUIWd#U1xXZwP218{zwHHJ+#Q84s$p<1 z4u8~sA{{BioqziwH(}-N9 z4Pt1fs1(rHtD0jS293Zo6>0s5J=38{1@Ib0N`HTsfSTfONi-7Ch?NpF6qtOM@0JSF zE~>ULXz7)&!td1)1Oc5SAR5we#ZYz>Im%=sKW7T^AwKP3em>T;fO<{hJ8`$SUZR4K zWS*}UtpLD9uopQJ0c6lT+{616++p5%Sj@+Zq8|t^IHj%lH&^!Ev0Fo{5_)mFZueN> zYyf|MxeEetQ749Z4G->w-@s)G|FyjU8ooOu{HX1Zlc=>uRfJPC1>!4#EXo3S5pP-MX_YB&-K-;acK4b!=M*(Z z{em`}ISIfj<9y6xEM0DqKE|LSbY8_sHjRHS#5vXqp()aCUj>~E3s&yl$4-yj&@K-t(bjGXjC(LL6tRN=u&SBj4y?!@LB0YvyMwf7BND@!q3OJj4Oq_~rn-OK zp5XcLw-0`ZL}`<#Y_GV;J(?QARdj%dbm?`18SP7~TUkd4KNjA`Y4x7HzWAK+$?7ZM znFK{;?!>|I(LcCFIKo3uV>cnW_O{9&OK;kDDyvdC@%7Ky3DEP~xzcZa@=$P|qx1vj zEbLWTq%~9qhMO})c~*6KTKB@=MjC%QZG|*8Y&(JGm5}o29miIPMn*zS+)1^ETNrzI z=cnKBt7iJS!>0BCJ z@5i86+}uY_!L2@9gNPF<890AyyM?27j;PwXJ8i>Yb|=XI4^%~nGSZG^ZMBAT*Cg~+ z(U)WyXtJ`<#eX!@)Spm(z4b9N`@M{;+nolf^zWVB)pyrW^B!5=XGOtfiTC{fXvfW@} zh|UCp1kfEQXRAr~$2A}XW!+QYbi-k!!;^$gI!v-l{N@5uP`6(u7zy$lb1PEma2I3} zhc8k>q>=u36xAMPAtJ;F@$!fzr29xlRDt<>^Ew=#zTh@9#!HAI1cVnFPCXBUych?} z@=0&ruyu!*1%IyZiN6Cn{wM^Zv9|MR$Ris#n!1D>!x$k*px({4t(N*`rJl3;2ByNL z(3t*<5xc=v90K@nh;9Qb59i0kLQpIf^ylUNt>}F#6}6IVe)XNwY&_D~Pg+C=+e;*( ztr-V7;gd+#wkT{1A`V_}WdMIO^D1Q|(LiBYsC64dqkon=smy&`Rc7tC>8{&zJR)0Z z7Su~f+5LORwS_=peevaG2+0UN$v;rA-Cpf25~L?m=4n9Pe=QFW2aiYq$p~CB$WRBXZhQX0`v6S1t zNlO-f6)=}P@FD7fB(M{Hln7wBb-kK10X6O*27g@KlYm>NM2y%E7t109%~d+6f|^gkRkQjb?}$4r4AYuv}#0!yvNaPi%F zn193m$+<(zYdwPzfxtS+j;}~`C(a$k&#N*__0V@X_&&1rvF`&7f8zSvDH5-43H3NU z{{S3A9;qnI3oM@v0%-1Y<~ur}LRvl=^s24Id>ap@bFKn$-wcRhZS4auXKdA4<)q8a z0>xeY@z*n;09egvbh%yXgn90W;VStNL4Ppy0SJ&Cg`D4C>W;~)L{paY5$6xpBqFnj zeGrdcjQ!x7-E2+Z!?bf*>s>`9hix1?7anHymUZ@o)UUd9k+`;adlrkyndJs5taIdk zLBhe>o2wWEBQGz4)Ylp%)MSCrqFXRw?Y#k&&eeJ*m}<42iOYu;BAZj)DBPl+(SIM| zGBq*K=hNaG4&a@As&Fd4H?l$BPwQN16vy3HTzB83kgy=IShNiUPm&gheuFH5uu{dk zGdpU5-{&3ZMYIA&M3CZxG9jfzqW<8L6UUND#wJX|MkNgM*n~|Ij<=o%w*~V_ii3%W3!MKAT2W&) zL3=L`B8K%ji)2LvdUGzg;>J_evGkkKYcM%jSLy>Yx1>Y(EP9 zL1D&b89rrb6?)vz8@&-?XF)~c21VS^h(q++S6jM9n#}8ff&@VS1Tl$%l!r<%8f}kW&3EfwV1dW!ump)% zVb8ulz}qa9;>axY(vk1S<4fmRw=okch#`$!em0&O8{%a__;k`;FCVC%qta(cUGa+M zB-t z4ax_E#b%$vQ``oISJ#`b{f1l+0(RQNB= z22ZWP99AYr+NHmgK#bnuV{U~z8@VD>2V z!*AAg@1id$X`YETxoI78VO0VGAP}d<&hUShPmtUwcD>Weqn>J#SLQcgO`ZlIs^dSS z5nUTZYC_|_=uDZf_h;sK8{>1C&YSMEs0{gxR->ltc){+Xu<^XT%0<s8K%{TGQ;J5pv8KeI^s_kIHrj^8PJ_wq~o8*@J z)+k(XRYBKCw(wq&D(I(GOFr?2+v0!cDM$tfkTPIWDi-q>4e;$abu z>L0``gI4i$#YAW?bquY^qO+=A`;+ZE!pPpW7-_&kez)gpukb1d5>ZVZVJ?4i8RBkr zqsUHiLpQqsBWwyyDutJ+aYxVFNCpbJakHy7US>#uW8*S6Fm8^|^O+q;&+{a9)Y)Zi zM5Qtr4#H7~Vg~)xFmVEyX<`j^4xj!HZN!wgbZk;1%{+iOQbf(tJpJijsq_+%3mz{@ z+uva7O*(V>+1qS17-jo{wsU_4Pk+505@?(;*{$uB~;BayZ>WF;y8(d zWzn#=7@-yHPZ(DS5VTl?;MR4jtyB*ST*KrnEqhw8Tk7=3M-YdRvE6Gy=u~-hKKFCH zQwG*xjngkd&)C~jFln?$Xwqpz^6WNJWhbf#1Bf{&RpW#_IO=>&h~`}U1-F^N70UDU zxz*uf=ubO*3%=m95hsq#P6H%Zwa0`ruIJ3bGdx%M%IPCibLG&TVVnMClEM#e diff --git a/tests/tls/brawn.p12 b/tests/tls/brawn.p12 index fdff0204ab4631a610b48621749679616091aec3..3457758ae5de70dd062e2813cce30b41a896749a 100755 GIT binary patch delta 2504 zcmV;(2{-n$6|)tPYY=)l6=nW07+~ErjdhVdnfsA@A%AFURth*z;5FiBMmYlm5qp4w z1Te_F&SEaz8c_0A%HWFzF%>q0^;<_5@Xnx7pRS&kL5FZRk9~ggD{_4qbT&gZ(aGFS z>8t+~)fAoXF$H?D1lm6=3*rbn=veEzA69x`Arg@rhixd>a8VfvZwfrp{ft(ew9Dh0 z(?7LQp?{1Ya?`g4!F7~_-2^o*yu8!$Ud)N^>&sE!;vIo%PzMV01x0rOP3G4LHHB#- z^+xtAz-0(=*GSa-pD;tQ1U{YJ2OMeq%ihhCbd7urnOf4-}lPG6XA^tD@ z)i221NAh@O1K$7V9d{w?LPprf-LgW_>(N{-Yy|n8NByyw&o~a93!|=0V4pte`JL0X z!{+mKs8FNh8m_rIZr#EVAlEZih2aeu`e^3Fvt@=H(g`lv591F}*#hRzT?dHb=LQv~ zR)6CP)))0t+(Jh%sr%Dv!7(hrVYw|_jLzO)rm?+xy&N9}Yi8idV`+)s5sdUiS}g`# zqor*Qe~z#fUx@vOgu3=c=uMI!7hyYDPVH?jWG^A#9;05jo*}FmMKypNW>hY}H>jXp zeygaZu#$DL0OJBQv)+LZD!sgQ#OFO(p?^AzszMSF7MrU}8;>*9+cRVHTGr#z>UM8z z!sl6>n0pV^%}`qyakmayrXn|S+)%_g?VWyl>t)1b`L(!hYUc_dA=uZuc@Q9DSE^bJ z7%G66pBXk~G${x4s*Fs+NZ;?7w-e3Rr`iKK zs80s8_Q&DJFCcf|?S|pq6pLfpS_j~;%hEl+66B0ZQJi_*asfbUwik^K;>aU$!%@g2 zxJYKxpkj5k3a3OJSRnudZ0OHfQh%)R1y%gb$&h^iMK7P~4?Kzoh;X}cYd^VDK5Rq~ z7n-nUrb8uYHWV&5{D2K-g5RJm9ZtgI{U#_x3Uoz6sR58Rb*a8fUyq4`?ZqrwPx_R+ zy>Jjth0mMvX0{0T$T~Ft-YU z41Bg>yX6ox20>(c!w>ahrEypb4wVBhxFU}>dB5qr_rP&w=g8IfFqy0vJ29)h+dsbD z&g8uP?$7EYbxeG#ojt1rEG5>G#+Voss4Nh!ximRN8K(?TOczPhas@W=ozb2)?L7c{ z*4i}>f>||4N>L~zL1Ubm<4oi$W2!E)B{iZo9&2Fp9wNMnxYBWj2#35K>xq0YUZCWv z*PSgvp_Na*#Wt4!w8H`&k+WoHg~bQ?ifhRwPggff0Wakg5sU%e$fJ|s1XK{O^*7Ne zu(<6^<@Lt)4$K6Rdm(@Q6BogK`vEP2&I&wR2(4WNf&|b)>de65mmnOMd1o!4h@$=M z#%W@Czn0BGZhjO)2cPID!1xng>8Omlx(+N0?_>{m>%nSWl3=fCF&wPE5YTFC=`B8O z2Y-s4oHHjZ7y|(Tc1vcYKn|`QEZ|BD8Fip70zR153drvsK|X&JL2k@efAX4n!GtA@ zhtqD!I|C12W*qW|l1~hpO!wwM4gOTPBX-fjgR6FLMdwN40tP5`CWYDwJ|$pj5T|U! zt;MGs)XSt=$M|b1S2JAA<=3`ItRt&%c!l{BJ&p5c?Dqu2LH(0pu1lM5{8?<^aHPv> zfk7~y%Cz4Ddgy=p<4tM+d=oFC^}!>wCnAvN53qsywF8C62>{M!)E>;1t2JO(iOFxO zo8Z&jV@&oC{o#9XOZYos)0L*%OFP=cpZPfC#GN5ZEG(}v4~dzBRkgLx84+H=GY7r5 zj*>C=cs{ffec>avYEiB!jDJ7zn7ESt)J8uKvKYWMFS&o`Fau;PG&1DvVh$zQL#ZZ0 zM6`}rZSm*nCB1sD-Zak$staLF=@x}KQILeUege(2tDnt77SK>EDtV|+n}Ar&UDCWZnn9v zCc-E^f|q^tJ-`(#t`J8dB$~;++4v4}z{l@$tbw#xhD2?Z0G&=N|h4n$-|LbO})f80A-k{j~tubQzES ztYb}W(~@Iv8Iw?%ZFz&ER(7hZNQKB5@Z`3~KtPk`PYG*p?r~JruVSS)j60e!<&!JP zj4i*RuDatS6HwL!x!*t^z#jKM0Q46)Lf5RgM`x>`HTac`G6Lk>e$evr0TCXxV0|o) zTxown=2(0K+%AA?h%sU>W%=Cr3QZ8*Tn(D1f^10o3vQ#EZ=*|75T>c1ok;TBWv>(v z22BfT#oSvAa|Pd+pDjEBEk+uCA;g%KHLv+gw9#Gp&U1KOr$&Wev}Eo)Sx)|ty@G9B zsOR>79zG9^6)4^KKP~yOon(|&>0Q(TcTj&(QmDFxqlYY1fK!Rlp@0au2 zwt7A%eR?bk+FBowK~WyPJEGhf;SS}z@sBJO9pTTeFn+@Izo6vFuAo6Jqf!3e@5Fyp zqy~i$-rs<0E?r7QhiiI@TAhC0Epxlfg6Zc9hez;JJ`z`h)!S!=g--OcoU#MkA$agR zuzAc2zyH7VmB`6nf9otMQ-k^@6Qb_iB(2K!rcHb%Qp^zH_F@j1`61~x5-6yQPd|3c zB>!WcZzXEP87RF60^>La-w{z|j>LbqI^`f4w3UGOlPocZht)mRdk@LsjUdV zT&LNQUQ<2>@|LfVWGe}J-pTC1e9K>IIj*oymB+bmYn0rlh7_>ZiK{GSU^8qfS_PL!n;83l#}U(tJ>e%at?V*cr3lFHpj6L| z_%oofMZCbl$Tb4d>c6nSD3-UyUV(`RPsNYd_)O|b=}Zov)oHNcfin?rL~UDzL~1r= zFjLf+vuRT&{&fv)A1GSgXAA$|4N_DuWaAQ+u`=UeHLOkf-$IIa3N+hJT9@{j{(r{s zG?*iJvlb|_rh|yxdKwq(-3B5ThrEhle7_SL>cwqR@*HZXl~(9bf4#|Bj&8p z$5f9(xJ74aL?)Rz^*=`VCJ$JWPh273mJM@?>$X$@4H6RBjgL(708rfnox7|2NX7Ad zZZ57IpStfhxnH4)cFR0Af*b!pEq_~ui`sRR1y)Oh0O6U~W?7A|B0S6-o`E}DZWn5^ zxYn%W!8<@EK_kT1Q&}Ot(XM`q#62-4zDoHO8qEQNUEq1twOvOR;&Y)?`W@F0EjP44w6epYnf&|c9zg1c;a&tHXIquCIl5b1I zaCzg2k*1uoO<%(SREFNImPN~K_3U?A?U?@Zbbcdgl-5oZ4Q69?Qx=dCA_2|jZ&kbA zu~ymMZVrVMUeaeCy^8r>WHBx)Qji4EQ2Gcp`PhuwTycMryOOoz$2+f+U7uoB zdPf8}otgimr~{TlpGtccj(9z5){N^U)UuW(7tl_M6CJ>;5H*V`(|DW~BO?V0MRIU; z43@^{2H|*bdFyJz0hI!oKx}_T5+?#8aoq?ga#BRqKn>6|Jg;(LNtf59;HEdn#;*e?Y+>$m7v1=m8~xg5GJ8)*&_FG zLyKz;IQ0(nJ|E`p2tfG#ruDWZz_FX^Jp)AvwF>N(NsB|_?9;;n zROun39sWi(3${-(m)%NoPG4?e8MLKG3anWT3EIDRmn?r!p{TTRBbFHO3*kgzM=anN zI;#(Smx6ZmJ*K9B>@fIl$C5xfbQ5z0htkS6S|N-!OLvaDB*!<;xA_TGk&&3;KQO8% zLb?lG|Drh3nkk`OMFYqB(Tv8K1i$qBW7*+q5y`bL;`UjK=BDhxWhdZ(IMJC*mho9c z4MMkNf4qP5CRi^Di^+=h5hE1%Ybmy)Z++5XQ;pnU=_*^VsKBDsbN#BRQBdn`md#;7 z;QXQCFMUTC)CnOaN5iKzrv=zG7t(xudf)rKv25<(tA{Yaj(uwj?d7-x{)%GN2PX5! zYIZCDQ{ovqe1=JzMSW38+#pg604B`VN=L@=Vw!)mTkuTaE+)Gr;eCA;m0bjWdF!GY zPq7|>g|gEm(_$Dm=Rz8FV-gL!p@Wvj@Ua%Hy+Etd?ww%FNOU~;YK+D4Ro0V_5+oMf zivR<`B%dv;`rF}airbZ7jaton>I4$P)xxG26)OSDL0ZJ@eS%Bl0Txi#ClImRHX7rF z2x))89R%4LaJi@Tb>TTpUNOM*)S_XGX>-IrB#qIGl5#)hCKMc0{P*+3J33AU_sc%CTj5vg9Ol9o$X7vsX22Lf1HEwssW6eX~<;@ z6Mdj9_XbaZ*CAC3!~levzlqGD8li>u@FBtL8Y7Rz;=ULde^WW3KH@tu+YU&0G9`bO z#R$1VSRGU=zybz7=s%aL!^2q{y;TY;&pSJfiGDqL97r<8FEUD6{Fn+JuAKNqYom#h z5AGO_3!`{KfkDZUwO{u0yOt4KH$7z1>7XA_7g!7!it7bW{eT=0em>R_((TRL!5NHc zIl=)3nE2nxiNMke4Kuph{nQRDWBGrl<`DDSf=*56KE$UN?uSBi?6QA-X(~rco5k8R z$!(oEP%V4%(+=X#dTS7LGo3?VDQJ%*Ky!NrBEfi4Fq%mi5XS#pWTwhhGnyU20^nkU zd;Qv>OuUG{{$ioY$9%9ED(%y?RhVW#=R$NLF(oh~1_>&LNQUxyHaX`=l0tf)@cD)Dy diff --git a/tests/tls/jwt/private_key.pem b/tests/tls/jwt/private_key.pem index be1412bb..dfb2ae4d 100755 --- a/tests/tls/jwt/private_key.pem +++ b/tests/tls/jwt/private_key.pem @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCUhwOA91sJzRrl -Q4lR55ly66sPdufZwh1Eas6a2yCmDV/IzL8WROUNfH9hb+traA7zpcR6EYXYd2gy -rPhfWUsYetddUyRhoo8kNPsY3g6R18BHt81QFxnYIEaX2PDRPzDD9GK34d3RoS9Q -9Ob7Ec6ZZ6JT8G/oB2KwfzEjVAtE6hMoQkLOpdTt5egX+txysrPpLCfkVT3Sr6Qo -AX9JQatoRvlga6biLr1dtXLQKyL2SpRbRTZ+4iyvndXfm6rc9UovUxtg4n/e5BXJ -YPrGBgIQzX06JMUexNQFpriD93xqxr3DA85dobngk1Y+B5MiOetW1+xfvDhk40kU -3pYDmVTxAgMBAAECggEAFVxCHOg1/7evewer9jYHGQJwmarsQXfLwBJWP+oXYhor -9ikQADK3Tam5I2O2U+jlYZVWUjHhRxY2djdEXxNsm+Aqx0FU9Z+sfgoKj0h8Mu2i -5GLi1Euw4VFppZ6YVOzaurZpA3Codzn69TsgrudK3ZVhwI2kd8D8KKLvh65SEpPD -6n79ATUJDNcQWV85dSdkmk7K3bHWcfmhQk+/1I1OszqRIdMzGxI69K5Sz/N+oNuF -M0cpAksvfTFzVNH0MFKQrLZEFQ/Uq1vpCSckM6YAOg1e12wpk/N2yS9VmzQlcKcN -bfKw7PLvu8Aqis9IOBitkGBm6n3ffVq+uK0xghooKwKBgQDJzBVYEXc36yHLjMZQ -r7IzSKM361gSkYZ0Kh7daPP8Uu3wEV9wR0MsBHpTItAQAgZzLA3p/4mSszOr7/ot -kDND+I9ze13yjxxqfXzD8+t9eGyebr1kgzV5wcWxFVxublMjvYMk/2OgMEJL2FlA -hVmU62xejenwtpG7BO/YHmJl5wKBgQC8bAIyWoNRZs6iylSo55Qoc5J62UuSIz2b -Po04Pfz4wxP0j3qbnFrqNZCo0iDde2hkmGNxFutKyXBmtOnzevT6n0FoyGhhIhQw -oTIihyIBGMWYrucFodsRQYkM1ONsDR/SAD+Ewoodi4r45+ycpO/dbrrvHm+Gxmio -eWb+V1ZjZwKBgQCdYXUkAjsgeVkaDuh79QrdxEDHU9yUXrqlzlPUCg5/M44uNN5i -CrHwmm1seTIbyfiNykXvwUPiDbC236oV7uiMkkYOoqBalBJtWwD7Mjju2gSca3F5 -+nqyQtWTjj1QQurEbQDi0es4+2o5DLpO/7El25XhCHzzJu/xE6CaxNeo8QKBgBbP -hJyP9KHgLlfq4sDn+DnFdBBHSizQ815d/j620m9TPpE25YL9NMxx26d0eOIXVJYJ -FNDWE3okVOU6NbByTEIjEYob6PcJZyRT/3vKnEVBuHo5gmJeK+U05+CTzUyBcj68 -JPRvkMTu5c4oVa7JEPjftOXJ63qHfpgWym80J5M1AoGALvdCK3MxMaWSY1MwT9hP -RImioRjRuPAzcqgNEBTjSpHWrlr98n5yPVss7dnNuSfPKkxUzF3aKdOndUqv8+Wz -sK2zxDis8MQ9dt+H1XPmlHTOorKw/fwZn12OuiSrivmwI7ocHgH22RaLSMRZUa2K -dP15qVMxHtJAao5VSMLzu8o= +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCZ1uZFUs/AGb3O +X5O2KWlcODBKQ+t+6quxVDET0BaVhFqHiwtbXy6M5POgmOQgBgT+jM4e40dCXY+D +d6WT32GLVQY1gUAKjVcWZ3KmXSdJu6VhSaY2KBifV4Bb9T/EvtUFsfMnYPbwdlES +uBRcz7neSVYsvZCw8Cgmx0Fypb2xeND0jrljzocMoGFkJLZAfmbDZK7DlMd4A6yo +feDEEX2sBwb8ntkg0fW3IjGUqgOo3d/xKXny0Bbl1jiSB/G8Pw1zwdCrm7xOqn2C +GueuGsZOlhj6bYtwy8HTIFQd6qiEdniKGbHIA0aYsXgL1OXbWoybhYTNF3HZvVs1 +2ur89aiHAgMBAAECggEASFs/zj5PcYqJ8C2bE5QxtorFB8EfW//zRkITnT6DyMpK +LDNVYaIIioNLJW+T6I38Pl+quPNsOkY4MH0Pd1gbEIYql/LVVME6w1JfpejtiCwG +cpZJ43IDdrqYqGfXGOoq1nVmqNBeBSaZJkVHaonXYbo7mmqEyfwC3o5cdZiH+pbd +8bzP4kaaE2xzEtCZXTTErNfANNQ+uumk8L0XUoyYOcLgYSP0GA3fdyGhpKkKJUcS +MJJWVFUGcv0mjGCeUburUMbjSAvoFPWcllYrQ4iV4PNAnU9Ds58szitQUmM85UyS +Kjf6MwCe9zEHRajlYUo/e3cR1rk0r6RAEHnZMfnMjQKBgQDWSv8knRgOlPYXbGiy +GHtodRCjhvaqh++AFNY5P/tS//y4XeQysjofMYuQLfEwam5aq6lr80Lr35KpD835 +oKAYtkf1EGqv4SWGtRivfVm/zPt8sLQwb5/XgCK6aejo4tObJxkOQg+12Wc7BFuJ +7lSk9ZEJDozMNHDFr+M9mtAqYwKBgQC3x9jtLc7bA+zkPZ/aKtv28l3ij95AsJu2 +23w8IU1vSjFuYfdjLFkQWI60hGLeguFSPV6LZCCPZ1qIOZOL0KSKcI+arXlCmlxv +VCjHdsEwJtyNZG4XMLxboKeUoZgORIt4PJpO8cguEEstWx8XP+X+ltsfDIFTSiSi +iiZaxSFwjQKBgQCqEnluaJNIN2ccbfilqBKBc69R6XJpI1usTl06sJHZbLr44+OR +bKv+R8cZFa0/HKkaovTibP1m0FjIfnedr6KAGmL/lxjlH4413BKMbLLHK3tImcFY +U68LTHHDevzTn/oLQDt9emaXj8SDLVEtJg7doNuL0ZVjGBeMfayfHvgpOwKBgQCa +6q+FXvPb0vdBfmDdOvuosq1JahTjWvwnq+SRm1D22wfIEHTE+IErMjs5F89v2cut +02V7ArAfsfOymTYyyXGp8TBcJpbs+cmpXrvxR72ZpWiNF3dlvQNKCaa5t23BuS4H +8K3ylgU0Ly/vz7vpkUeC0A9toNDzMLCpAuNJ6JpDkQKBgQCDHZn3zkRJQVQJ/YOj +tQ8o1iBrgMf/cBYLXenEuBgiy54R2nlf8z3DKSklHG08MFc2WQhAfZX/q/OItZvA +QSbYPRXaDxAwWp0sCjJwbJ6kaKZ442Cov/N+BkST/x4oGRTe5LVz44uDrSVtQi3L +O+Y+dpxm8KiZJ4UgEO70BYr8kA== -----END PRIVATE KEY----- diff --git a/tests/tls/jwt/public_key.pem b/tests/tls/jwt/public_key.pem index 826c4a78..f0ef2b62 100755 --- a/tests/tls/jwt/public_key.pem +++ b/tests/tls/jwt/public_key.pem @@ -1,9 +1,9 @@ -----BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlIcDgPdbCc0a5UOJUeeZ -cuurD3bn2cIdRGrOmtsgpg1fyMy/FkTlDXx/YW/ra2gO86XEehGF2HdoMqz4X1lL -GHrXXVMkYaKPJDT7GN4OkdfAR7fNUBcZ2CBGl9jw0T8ww/Rit+Hd0aEvUPTm+xHO -mWeiU/Bv6AdisH8xI1QLROoTKEJCzqXU7eXoF/rccrKz6Swn5FU90q+kKAF/SUGr -aEb5YGum4i69XbVy0Csi9kqUW0U2fuIsr53V35uq3PVKL1MbYOJ/3uQVyWD6xgYC -EM19OiTFHsTUBaa4g/d8asa9wwPOXaG54JNWPgeTIjnrVtfsX7w4ZONJFN6WA5lU -8QIDAQAB +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdbmRVLPwBm9zl+Ttilp +XDgwSkPrfuqrsVQxE9AWlYRah4sLW18ujOTzoJjkIAYE/ozOHuNHQl2Pg3elk99h +i1UGNYFACo1XFmdypl0nSbulYUmmNigYn1eAW/U/xL7VBbHzJ2D28HZRErgUXM+5 +3klWLL2QsPAoJsdBcqW9sXjQ9I65Y86HDKBhZCS2QH5mw2Suw5THeAOsqH3gxBF9 +rAcG/J7ZINH1tyIxlKoDqN3f8Sl58tAW5dY4kgfxvD8Nc8HQq5u8Tqp9ghrnrhrG +TpYY+m2LcMvB0yBUHeqohHZ4ihmxyANGmLF4C9Tl21qMm4WEzRdx2b1bNdrq/PWo +hwIDAQAB -----END PUBLIC KEY----- diff --git a/tests/tls/root.cert.pem b/tests/tls/root.cert.pem index 68f0ff67..e568c89a 100644 --- a/tests/tls/root.cert.pem +++ b/tests/tls/root.cert.pem @@ -1,25 +1,25 @@ -----BEGIN CERTIFICATE----- -MIIEJTCCAw2gAwIBAgIUdWe2opK1oe4aJBmSKA2iwL/+aJAwDQYJKoZIhvcNAQEL +MIIEJTCCAw2gAwIBAgIUE65bHzKRQD5RvagWhL62l19s8lcwDQYJKoZIhvcNAQEL BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p -QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTYxNDA4WhcNNDQwNzA2MTYxNDA4WjCB +QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTc0NjUxWhcNNDQwNzA2MTc0NjUxWjCB mTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNEMRIwEAYDVQQHDAlTcGVhcmZpc2gx EjAQBgNVBAoMCUFlcm9zcGlrZTESMBAGA1UECwwJIFNESyBUZWFtMRswGQYDVQQD DBJhZXJvc3Bpa2UtcHJveGltdXMxJDAiBgkqhkiG9w0BCQEWFWRwZWxpbmlAYWVy -b3NwaWtlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMQ7Z8lY -WwaeXPaq/6DZpeNtA8MuWEBjjodS0rSr7qLzdHRWMvv/RJ2vZh1mQCFWlMYuVae1 -o+IxhKPfZJy6j1KbiZ5JBBr60yvq09LUx4+xtFvFYlZq7OGU0a74+LzAty7qYUfw -qtnXBhS0pIxDypBDbP3LfF58It57vPXKHlE9keeKQtPKFi2W89WYTG9C7oYSJJPX -+TPc0DziGZt5tVpag6lrBWmKI522zM9Nj7qSjyW5Ios6MAlPWymVRtkituuFqaFa -L6FUzC1KoXAqVKUfJbWVL29fhvd77jAR9aIPhEktRO53uQQJg26JcKsKUXS7+zCQ -PVfPWHcyhQdRX80CAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E -BAMCAYYwHQYDVR0OBBYEFKZWp4pK1crEQKmdQZaxl1zojQAjMB8GA1UdIwQYMBaA -FKZWp4pK1crEQKmdQZaxl1zojQAjMA0GCSqGSIb3DQEBCwUAA4IBAQBwfj94C6Zb -xBIAxtVYJ8qg8gS/89ZGntamc8XWA3SVc4VCjKruwVnECyve9WBaPLp49kKAlMJQ -s3Kr5oAPa+zBrBUoozD1tOUKH5wUBVanSfCVMW5a7oVZwYU63uf/z7mSZwtoMufN -bQ/1V338kv1PxDu2+Bmw7EVPy7QmucS5NiHhgmdkBtzdQysOTJfpd1dcdHBOs+NG -FwpyyYZP3qTdTzHkrTNWGPSeqb3x143ufKtUwzmfxhErF8J7C+eJ/r8yS+d0k+xq -SXL/1nQAWY8aSvuxFROmywiMxcNUN1YVC+dv5/apDsgEbXh7fEOaRch6zfcnTz+s -N4NsQa40pgbL +b3NwaWtlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKUTA39N +YdkSF5pl58OUbHC8jpsMp+KKUaGcHvenXF6P2CusMN6GEQQDg/d4ANhnCCAjn7g0 +DKTd5RA9e/zRio7BzybWwn6D7g42cEgiMuRM2EhQHAmdvfccYAoNrmopaC5zlLwA +SfrOLmHEsUfpyLSqao7iMnhlysUVb5VlRRdsU8CYsGVh+JBplWUq4v9fgOXYlnee +YkuRChcmYlokCGHhP0j4BSCM+cRzg9FtbqTzhC/rM3xN9Uf1271A4hFAYoYcPjVI +DcrgsHU5IqWr5x0aribDmnmjpQ8ZdRlBeiyQgYdgpsUe6/P71ObOtUX2iTHA7bEX +Kj8fCen8ms7slB8CAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAYYwHQYDVR0OBBYEFErYXtFlvABhCMuC2Qr303WJ4nEXMB8GA1UdIwQYMBaA +FErYXtFlvABhCMuC2Qr303WJ4nEXMA0GCSqGSIb3DQEBCwUAA4IBAQCPNFBPrY6q +cUgDU6c24JR4vMpnSE1vF6IAEiB/uxzFF7Gclq27VJvfrgWOmNPbdBBUZcffQ20I +di1JRN+bU6ULfkwtGCidNCUSYc0l2Ok5g45kyFTix+1zHYfS4F77zPDfiNMMqV08 +Zq5x17RaAX3qM+GzOjbLXjqVOH8UVYENdafUmz43LEgHiBieRQMwwMnfr/WSjqv3 +JsQp9mqRrWWKVCpTKK9l0LkdsdIi24Y2CQI90xLGeNEfuylu7CkbaGF7sId03JQS +/1gxlWGS/CDWgISO9Bt0Ig75QZhOTOPOZn46rFVauxWsSNc2jC3nTpaOITPJG614 +vpcW9Uy5vh63 -----END CERTIFICATE----- diff --git a/tests/tls/root.crt b/tests/tls/root.crt index 038316ee..895ac240 100644 --- a/tests/tls/root.crt +++ b/tests/tls/root.crt @@ -1,24 +1,24 @@ -----BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIUAT9OnFkuqtVUx509aIj00w/95NAwDQYJKoZIhvcNAQEL +MIIEFTCCAv2gAwIBAgIUQwoybehzKNVyshCvYjpuXTv1h/QwDQYJKoZIhvcNAQEL BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p -QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTYxNDA4WhcNMzQwNzA5MTYxNDA4WjCB +QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTc0NjUxWhcNMzQwNzA5MTc0NjUxWjCB mTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNEMRIwEAYDVQQHDAlTcGVhcmZpc2gx EjAQBgNVBAoMCUFlcm9zcGlrZTESMBAGA1UECwwJIFNESyBUZWFtMRswGQYDVQQD DBJhZXJvc3Bpa2UtcHJveGltdXMxJDAiBgkqhkiG9w0BCQEWFWRwZWxpbmlAYWVy -b3NwaWtlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMQ7Z8lY -WwaeXPaq/6DZpeNtA8MuWEBjjodS0rSr7qLzdHRWMvv/RJ2vZh1mQCFWlMYuVae1 -o+IxhKPfZJy6j1KbiZ5JBBr60yvq09LUx4+xtFvFYlZq7OGU0a74+LzAty7qYUfw -qtnXBhS0pIxDypBDbP3LfF58It57vPXKHlE9keeKQtPKFi2W89WYTG9C7oYSJJPX -+TPc0DziGZt5tVpag6lrBWmKI522zM9Nj7qSjyW5Ios6MAlPWymVRtkituuFqaFa -L6FUzC1KoXAqVKUfJbWVL29fhvd77jAR9aIPhEktRO53uQQJg26JcKsKUXS7+zCQ -PVfPWHcyhQdRX80CAwEAAaNTMFEwHQYDVR0OBBYEFKZWp4pK1crEQKmdQZaxl1zo -jQAjMB8GA1UdIwQYMBaAFKZWp4pK1crEQKmdQZaxl1zojQAjMA8GA1UdEwEB/wQF -MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGnjMAmBLqFvfVTOAj5GBN8YLetTruXG -WUsqXWYXgEybyRFBuNRYFngm1dCv5vcjIwRKSK+kzwskOSQaRFCFpMlECz5zrfPO -pBvWIH7pRizrMDzG2z5HqevmbyTIsrNMSfUO7oK9xlbYKFg+EcnFe5tqDlxsdge9 -vB7WEBV320FdTIbDrBQS0kGRKi0Vi+3VwDgYAsld4jTEEApMDmEjRNS2F7G1j8gY -ahEr2HPHGxyLuuiYPP2msGlhczj5ceWLO2HQR0VQc4QM+T0e4xpAclX1OOtMODhy -CQtWehGaiEUndD63Cev5eYOlKt3mEPZwnCzVJgqVNhCH9e0A5DToE1o= +b3NwaWtlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKUTA39N +YdkSF5pl58OUbHC8jpsMp+KKUaGcHvenXF6P2CusMN6GEQQDg/d4ANhnCCAjn7g0 +DKTd5RA9e/zRio7BzybWwn6D7g42cEgiMuRM2EhQHAmdvfccYAoNrmopaC5zlLwA +SfrOLmHEsUfpyLSqao7iMnhlysUVb5VlRRdsU8CYsGVh+JBplWUq4v9fgOXYlnee +YkuRChcmYlokCGHhP0j4BSCM+cRzg9FtbqTzhC/rM3xN9Uf1271A4hFAYoYcPjVI +DcrgsHU5IqWr5x0aribDmnmjpQ8ZdRlBeiyQgYdgpsUe6/P71ObOtUX2iTHA7bEX +Kj8fCen8ms7slB8CAwEAAaNTMFEwHQYDVR0OBBYEFErYXtFlvABhCMuC2Qr303WJ +4nEXMB8GA1UdIwQYMBaAFErYXtFlvABhCMuC2Qr303WJ4nEXMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJQ+3wqepfOe8/SCOvgk/z3/NJjXZGUG +MB0ZtQnG7tqjRziZNVW9sYNA5qTCe1K0vDo65NT0vPuGrLlz3Pocjtk50hFiANg1 +c5L8wzFHvZVFciDrJ1w46aqaE6VhecH8T71QyQEKPP3c4pgtWeVzYbY+TSYApIMV +jtHZIh5FaFMGJHBFOzaRQC9e8kOctTyPsHCb8KwjCZGZx8+5WcG44AiCuIb15SmW +tE+ZLl5zlXfOSIs2O6VbX+P6t0loVdNaq1T477TU9aNg3ncBv93wrKb4rdjD1BaM +obItCr3X2PGqrE8heBcwUm0v5pXXxf2+K2KbKr7sQs41q6jeMDlViUo= -----END CERTIFICATE----- diff --git a/tests/tls/root.key b/tests/tls/root.key index 305722bf..8c99674d 100644 --- a/tests/tls/root.key +++ b/tests/tls/root.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEO2fJWFsGnlz2 -qv+g2aXjbQPDLlhAY46HUtK0q+6i83R0VjL7/0Sdr2YdZkAhVpTGLlWntaPiMYSj -32Scuo9Sm4meSQQa+tMr6tPS1MePsbRbxWJWauzhlNGu+Pi8wLcu6mFH8KrZ1wYU -tKSMQ8qQQ2z9y3xefCLee7z1yh5RPZHnikLTyhYtlvPVmExvQu6GEiST1/kz3NA8 -4hmbebVaWoOpawVpiiOdtszPTY+6ko8luSKLOjAJT1splUbZIrbrhamhWi+hVMwt -SqFwKlSlHyW1lS9vX4b3e+4wEfWiD4RJLUTud7kECYNuiXCrClF0u/swkD1Xz1h3 -MoUHUV/NAgMBAAECggEAD6Vil1UjlDHEx53R74KNvZuCfl8VMMnErRQEvQdCFKff -hsDHubwm/av6SEj6lIiUKKq8RXi6ti03aPSFz7xNSKt3oSarvItNZ+tGPpbHdEou -5Kv7362QsRoopNrw7uXZGpUcCBHPoY+0NQBD6B4l9MjiKWiT2ZnBaFFf5eNwIDnU -mCJki+i3VuQS9/wuJg3wex0L6PU+aXHwlgWXNqEWJFK2TcnPUtCbhxpCd+hNxgqq -VzF2yQLGpbGOShA0Xg0UHxOVRwGK95TY0zA9YGBdkYctse6sXU7HtG/M6swRwPxF -nM1WMryYIiPV6iEFYledi5sbHYYWQGvUcrfCuZETAQKBgQD9o5UYZY2DgEdJ7NkM -6DPt7AuJJ+NfgWDOdNtCmBfdjXJ+NkBcFN7Wig4zBKuTgnaRK82m4o0y9lD9zQrR -hU0oujg5lGYnsEx8fgft3vVqSQOX3xZcA/IBiZavIIcsLzpZn2lDKcLLbPbmUx70 -iROM5AiWiaFw3Gs8cCGPVr4ozQKBgQDGDwXww+ru35azJ0PR+9dmSehHxNFzj3qt -t94Ew6/dW3EC10/CO41e+yHtpwLKlhgP7inRP3jZmQpLf5HngF600ZePf6egVczk -uxOX1iZt0ikW1zl33CImy8hyVFSnMVrC2ugLSRIuZfK89AOGYfRr+E5OGwtng7xq -ICXSEbwTAQKBgDrUk4OKIo3K1j42Wo3c2haodnCEuP9xAeRBRI4ouvhfk5vkt37k -NF+su+hnf+iCDUBU2amIyNl2Oojz4zt/4Mq+jsYEPsGb6dHCZdJtsZzKfLPgQc5r -99kVcccDE3dTKQSarg6vBAitKIN56icsGEXIqplIKRMFfTYSiCY4J3lNAoGBAMQX -X7RO5S135Yae24DtLQgzKGzWKuGVLssL/h8Nd/Nbc3pynp8ZwxBE6ASZlCPrkwtC -q9hmVUprQUwak+R2rk2sLbh/lQEjsebMacus1QNqThA1KsrHAnES1fSMFfwq20eM -4K07vWp+uWPm3A6SsSKtBypBkHr+bO9NwORJdsIBAoGBANlDyVt+r2Sae55OkbIy -/Z55KSdEmDt9pRDDQxbVCsOIXcXKV1ELCXNl9TUoxsQy1f1OBcPWJSUg9WKI3DZ6 -wn32rlCsqCg9dDZwwgUhLjnvgAifaiz1ZktpHRPzSL2DF43jX1GFIduOZR8zeeai -qDRMtNANG8tMKZ8KzgymUp2Z +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQClEwN/TWHZEhea +ZefDlGxwvI6bDKfiilGhnB73p1xej9grrDDehhEEA4P3eADYZwggI5+4NAyk3eUQ +PXv80YqOwc8m1sJ+g+4ONnBIIjLkTNhIUBwJnb33HGAKDa5qKWguc5S8AEn6zi5h +xLFH6ci0qmqO4jJ4ZcrFFW+VZUUXbFPAmLBlYfiQaZVlKuL/X4Dl2JZ3nmJLkQoX +JmJaJAhh4T9I+AUgjPnEc4PRbW6k84Qv6zN8TfVH9du9QOIRQGKGHD41SA3K4LB1 +OSKlq+cdGq4mw5p5o6UPGXUZQXoskIGHYKbFHuvz+9TmzrVF9okxwO2xFyo/Hwnp +/JrO7JQfAgMBAAECggEAHODDptyZtojUuj0Dm5J2mg5SgEtpf1clSrluLXMI1L4j +WhiIgBVCGsqmpn9G3pS/tielRGtOnvT2oq2u6B6cN7cuDyRY6BsaZUAeym+5KXlM +CPKCxSfkWLuNDZUxIv9Va3Lq3SzLxGWXdaEcRnFenESH2bE2lRtxqqLCX4dU2/De +h3TKlAqRmiXr7v6gYNZXAkGrIu734bksjM7RacCkINJHhkW272bgCY/PDKfCisp5 +OZ8KEk0lOV8Rt3gqOPAFbEEkhjrGI32zFu8qw0lTNR0xCquYrR+7IyYz/5F1f8A1 +JRlfiJ3YhgA8oTvjCp0kq/jmAO7OqlqaE0PMlevj6QKBgQDVnWsLrxX8kNysDaBU +wlFiCXXelSXZdi8EgM7gU+NZQDCQy3kidgqhaq/UTIkSdRk7QbejkRwg4+kLujcp +jtAlOJjB2VIh1QkRNJa1GxKM6uV1feQa4nfUpCfwM2BiCwmzUydMayMLtDVlrs/y +RnKNzBM2zFHDYHdARFB7o4lV4wKBgQDF0/iFuTI/SASjB8UpFBxCFRuowS0coon2 +RSVf8BnshopV1RvOynGQ/TcAF+5+NClq+tVoi59XP6AL/1WC/Ct1aLKPVJXgkRNt +lDpWcXol3rBtpigxfZK+g0B+Lp3LLl9JKXjosrAWvCE1mY+DarCWsQxHDWQ2osku +mUhcIie9lQKBgQC4X9TjEs4RXx94yZIXVllUGwJHichPeDiA1IS7DuzuPf8tGtKF +Mgle5Wy5+w1chwGuKbzNSxRSNyUQ4Dt4fTGezsjamC7R0MSwuwlRa/qI8r32uSBH +LC1ttfpa0p1gQlKvGxiSVu66zWJBT69gV/nL9dant5bi4cJMECq/bJm/LQKBgQDB +C+28CJIJAK1NrlpukKpWriR0lDYCeHZqtOUY7sNNdajuw2xEandSRlbyp2fbDenQ +9H9masGOMY9rxbnbfVqnUwjUJ3WuU8QCraAUFN5esCW4imk0ila1xH0d5T2kNVdU +nLzZTu3Y8bLyjCxo0KcMFi9l8qJ1UntCFuBu0AG51QKBgQCJHi0B8VDSSi7nOV2G +4hrJHo4qM+Ne9R3oR1/XXKO7iimaefV5gF22XQf6OVxeNE9eu70k3SG37Bx9hZOV +EMryvRoglT7AUESyOBwn2e9w2X2fhLu8N5uDUIAqmzScTHvHOgCR/7VBomallCU/ +SDS1Qy8WgnYf2L+rQV51IcJ56Q== -----END PRIVATE KEY----- diff --git a/tests/tls/root.key.pem b/tests/tls/root.key.pem index 305722bf..8c99674d 100644 --- a/tests/tls/root.key.pem +++ b/tests/tls/root.key.pem @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEO2fJWFsGnlz2 -qv+g2aXjbQPDLlhAY46HUtK0q+6i83R0VjL7/0Sdr2YdZkAhVpTGLlWntaPiMYSj -32Scuo9Sm4meSQQa+tMr6tPS1MePsbRbxWJWauzhlNGu+Pi8wLcu6mFH8KrZ1wYU -tKSMQ8qQQ2z9y3xefCLee7z1yh5RPZHnikLTyhYtlvPVmExvQu6GEiST1/kz3NA8 -4hmbebVaWoOpawVpiiOdtszPTY+6ko8luSKLOjAJT1splUbZIrbrhamhWi+hVMwt -SqFwKlSlHyW1lS9vX4b3e+4wEfWiD4RJLUTud7kECYNuiXCrClF0u/swkD1Xz1h3 -MoUHUV/NAgMBAAECggEAD6Vil1UjlDHEx53R74KNvZuCfl8VMMnErRQEvQdCFKff -hsDHubwm/av6SEj6lIiUKKq8RXi6ti03aPSFz7xNSKt3oSarvItNZ+tGPpbHdEou -5Kv7362QsRoopNrw7uXZGpUcCBHPoY+0NQBD6B4l9MjiKWiT2ZnBaFFf5eNwIDnU -mCJki+i3VuQS9/wuJg3wex0L6PU+aXHwlgWXNqEWJFK2TcnPUtCbhxpCd+hNxgqq -VzF2yQLGpbGOShA0Xg0UHxOVRwGK95TY0zA9YGBdkYctse6sXU7HtG/M6swRwPxF -nM1WMryYIiPV6iEFYledi5sbHYYWQGvUcrfCuZETAQKBgQD9o5UYZY2DgEdJ7NkM -6DPt7AuJJ+NfgWDOdNtCmBfdjXJ+NkBcFN7Wig4zBKuTgnaRK82m4o0y9lD9zQrR -hU0oujg5lGYnsEx8fgft3vVqSQOX3xZcA/IBiZavIIcsLzpZn2lDKcLLbPbmUx70 -iROM5AiWiaFw3Gs8cCGPVr4ozQKBgQDGDwXww+ru35azJ0PR+9dmSehHxNFzj3qt -t94Ew6/dW3EC10/CO41e+yHtpwLKlhgP7inRP3jZmQpLf5HngF600ZePf6egVczk -uxOX1iZt0ikW1zl33CImy8hyVFSnMVrC2ugLSRIuZfK89AOGYfRr+E5OGwtng7xq -ICXSEbwTAQKBgDrUk4OKIo3K1j42Wo3c2haodnCEuP9xAeRBRI4ouvhfk5vkt37k -NF+su+hnf+iCDUBU2amIyNl2Oojz4zt/4Mq+jsYEPsGb6dHCZdJtsZzKfLPgQc5r -99kVcccDE3dTKQSarg6vBAitKIN56icsGEXIqplIKRMFfTYSiCY4J3lNAoGBAMQX -X7RO5S135Yae24DtLQgzKGzWKuGVLssL/h8Nd/Nbc3pynp8ZwxBE6ASZlCPrkwtC -q9hmVUprQUwak+R2rk2sLbh/lQEjsebMacus1QNqThA1KsrHAnES1fSMFfwq20eM -4K07vWp+uWPm3A6SsSKtBypBkHr+bO9NwORJdsIBAoGBANlDyVt+r2Sae55OkbIy -/Z55KSdEmDt9pRDDQxbVCsOIXcXKV1ELCXNl9TUoxsQy1f1OBcPWJSUg9WKI3DZ6 -wn32rlCsqCg9dDZwwgUhLjnvgAifaiz1ZktpHRPzSL2DF43jX1GFIduOZR8zeeai -qDRMtNANG8tMKZ8KzgymUp2Z +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQClEwN/TWHZEhea +ZefDlGxwvI6bDKfiilGhnB73p1xej9grrDDehhEEA4P3eADYZwggI5+4NAyk3eUQ +PXv80YqOwc8m1sJ+g+4ONnBIIjLkTNhIUBwJnb33HGAKDa5qKWguc5S8AEn6zi5h +xLFH6ci0qmqO4jJ4ZcrFFW+VZUUXbFPAmLBlYfiQaZVlKuL/X4Dl2JZ3nmJLkQoX +JmJaJAhh4T9I+AUgjPnEc4PRbW6k84Qv6zN8TfVH9du9QOIRQGKGHD41SA3K4LB1 +OSKlq+cdGq4mw5p5o6UPGXUZQXoskIGHYKbFHuvz+9TmzrVF9okxwO2xFyo/Hwnp +/JrO7JQfAgMBAAECggEAHODDptyZtojUuj0Dm5J2mg5SgEtpf1clSrluLXMI1L4j +WhiIgBVCGsqmpn9G3pS/tielRGtOnvT2oq2u6B6cN7cuDyRY6BsaZUAeym+5KXlM +CPKCxSfkWLuNDZUxIv9Va3Lq3SzLxGWXdaEcRnFenESH2bE2lRtxqqLCX4dU2/De +h3TKlAqRmiXr7v6gYNZXAkGrIu734bksjM7RacCkINJHhkW272bgCY/PDKfCisp5 +OZ8KEk0lOV8Rt3gqOPAFbEEkhjrGI32zFu8qw0lTNR0xCquYrR+7IyYz/5F1f8A1 +JRlfiJ3YhgA8oTvjCp0kq/jmAO7OqlqaE0PMlevj6QKBgQDVnWsLrxX8kNysDaBU +wlFiCXXelSXZdi8EgM7gU+NZQDCQy3kidgqhaq/UTIkSdRk7QbejkRwg4+kLujcp +jtAlOJjB2VIh1QkRNJa1GxKM6uV1feQa4nfUpCfwM2BiCwmzUydMayMLtDVlrs/y +RnKNzBM2zFHDYHdARFB7o4lV4wKBgQDF0/iFuTI/SASjB8UpFBxCFRuowS0coon2 +RSVf8BnshopV1RvOynGQ/TcAF+5+NClq+tVoi59XP6AL/1WC/Ct1aLKPVJXgkRNt +lDpWcXol3rBtpigxfZK+g0B+Lp3LLl9JKXjosrAWvCE1mY+DarCWsQxHDWQ2osku +mUhcIie9lQKBgQC4X9TjEs4RXx94yZIXVllUGwJHichPeDiA1IS7DuzuPf8tGtKF +Mgle5Wy5+w1chwGuKbzNSxRSNyUQ4Dt4fTGezsjamC7R0MSwuwlRa/qI8r32uSBH +LC1ttfpa0p1gQlKvGxiSVu66zWJBT69gV/nL9dant5bi4cJMECq/bJm/LQKBgQDB +C+28CJIJAK1NrlpukKpWriR0lDYCeHZqtOUY7sNNdajuw2xEandSRlbyp2fbDenQ +9H9masGOMY9rxbnbfVqnUwjUJ3WuU8QCraAUFN5esCW4imk0ila1xH0d5T2kNVdU +nLzZTu3Y8bLyjCxo0KcMFi9l8qJ1UntCFuBu0AG51QKBgQCJHi0B8VDSSi7nOV2G +4hrJHo4qM+Ne9R3oR1/XXKO7iimaefV5gF22XQf6OVxeNE9eu70k3SG37Bx9hZOV +EMryvRoglT7AUESyOBwn2e9w2X2fhLu8N5uDUIAqmzScTHvHOgCR/7VBomallCU/ +SDS1Qy8WgnYf2L+rQV51IcJ56Q== -----END PRIVATE KEY----- diff --git a/tests/tls/root.srl b/tests/tls/root.srl index 59334b16..4df69224 100644 --- a/tests/tls/root.srl +++ b/tests/tls/root.srl @@ -1 +1 @@ -5EE97176BA08307517543878B8BD4121D4DBF878 +0B13AF54231CA109FF3593ED31417CE45D42C7A2 diff --git a/tests/tls/root.truststore.jks b/tests/tls/root.truststore.jks index 7a78b9531577a5729a70b730c15846f99ebe3944..80e22dbf36ee7efcf90d2b88f6a4a690b42cb206 100644 GIT binary patch delta 1291 zcmV+m1@!uc3x*4jYZUoMKp~g*fIrBpKk^$Ifgz8OCuEU-B!4g#hz3y24=Ag+TUGhp9b!PH{ep>xRj$W0pJGU)2!)tpe={o}kdBta#G3 zk+6z6wUN|+xSdRx>PfCEemCYFWm+>DgLgwyB_juyp%{bglpVx1lz5Q5KCaCzJslI2 z@s{uyvDb8hdVhZ5`oi8k=k{l(6eG(uXinoMaeVAt&>;okM1!w@H(QFfju-&P)&pC(4U59s+?Tb^5EiJ>KDL5E#TXAV=;~iGKg@bD z@suxe)O^0zUpw-23w$rH7LS;*TC4G=?%J!WmP0sXG!tizspdGEJ6Z)^Il^$$ai9%& zSkt7JzJG$D+_&f|HHj-4f#SEANVaRMAZX5Nf2%p46K;QD)BMQ$CuIV{&@ol%TM&!G0b~D#L1Dpgv4k7j$7~H&MmbZ)hO~~@Sa9>dYCaTr?no}`PGa-nY+5Zr zKQ!xEEVx3p>iZ&#_q=StK@|(rX4-RJB-wU;ihrARg$YY&2*5Ne*FQ@8>O#slP*l0+ zte`wl3y>pU9606AGzz{n2iSAev}1J|E4LgjUij-^@>{VHfXB`dd3wBJ2u|u<_sJ(x z{N3nV`n2-N$*Q9@8nJDSvvk!o{_7KHqpvCE%n+qTD;uUb| zM}M76B5MB+(0AqT&)kb9>(JK+=4U zfCSpWbQ5hdKqAEqyge4FCi%Oswt(o2OLNCv;zXl-3gZ8sQTL3h;CnW;e*`~_&`4P9 zG*4JkfK3ByJHz@mV%=oyQrU5MkRL@za%4~&-J`uqh-_XNWarYZj{v>rLw@!P1%FZd zcYgV$E~+gwv;k%YF(#|)`cCTrOAw5NPAof$I*CGSS$SM9tXvd_3ev=X%ra~+p&N6# zjt1est6JHjnctXpbjC(CS=lOiYgyangEp~hy(MW@cpYH5L?c5qqSZ;cePDfHZ6pt0 zZk(CuWDHJE(N?W}jQ{h@&Z7R}W`8kMHZp(+&Y#JLT*C+96%HuprMSvaiCJkO*oE~B zV!S0qul};t$Vz6Yh|Vl%tsaBaT|V|=M>1D%;k{8t^cE==t!KKprbndZf9j@yOU)aK z#Z%V}#)v(aG2sd75Tx>&>p{g%E=jrqiYve~3wprggsa3&&!VZJ036QM#BA^ckX2*8 z*1jz?IA=u#u@faJsUQZPD~NEfMe_SFO)xPq4F(BdhDZTr0|WvA1povfVKzI~YgvMD zcRT$;fp*Pl`Y0#gGNcHS@A0|5c7DXu1QekheJJx@-3)a2&kzKE*{KpO&qV?PClJ16 Bafbi^ delta 1291 zcmV+m1@!uc3x*4jYZO>ZE51<_Kf{?#-UYHo0%=gLVEmDPB!A$NwNuF;whH9z1QFK0 zN4J221b|Up{P;ulQqAxX!-b!c7>gt*PU9qCROD>0(B*6}@bu7pr7<*KDH$No(QGD) zgRK=-QN@jvUzT-~?^(fhzU-`ViWe~52RGePu*NXZ(rd4l?x39Wi01=?KQM~e@L;Ra zTL(FR1V#Ft6dfxLM#bs4 zx3FfuGt-JqkF+wd;jojXdODDqImZ+uhaif5?=}TiHGkg)xVIdNmC2%*zlsBLH#yuz zSKWlE9Z~3?VL?L|=m-dodVjINKY0Z8#^!xdx^z5e>Upvc3x?q(kMn*n)0ae8Fy>5e z!Dw~barXfJ1*6K+QquTx|SjvORHA~T_st^;?*5^=OW+cwP?o|EeiSSSmbYF(+H zCH0_m%R0E+A-JMJHII?E0ptO;AgoRi!BDwZ_8Y2^C_($%(r3vuwY7vR52YpJ<|V-+ zR-usT;4mk&BZqt-%cd^MnWT?c0Dxhfwi#;RcYh{TH$&Cf7ymGp9!p~sr4;)3bw`nu z?RfU06h#vLQ*-v{pD9$hr4XwT1{Fu%ohdB*jQ?n_6^2nBGi<-FXD)vSYB9DY>!&Zd zES%bpY){u=hb)8*`RkT#7rEUY20o0PmZqN~ETy^+kCmbOt=Hf~2m-kCb%F~a8)|p$ z5`Ug@(iWjIQAi`%=bV^p+jVh8=&!=SzA~cAB~vcbygsDb>bd5*lN-1_-KZ^K9z7E|iFusOK9oa7rq1Pd-Y(Kg2cCh0G=C`P zns=~w#(3bK(r*|SwQU<)T0AuJ*%96BV!@6EZoB1{GEyqC&#iL@4bfLfg$XC~(uHIs zt~N16R%AFv(kv)x^K?hUZJTgaoqI&Z2l`)8Jie`g*#?Q@n42<3&j29@>%DJGe~b4( zsk^rP9^fI!N-jmFgi_-b9)e43>wiLc(FG8ni5o}T^ADW{lSR{*?`Q`{2zMVVQeR^d`3Vuc~O)xPq4F(BdhDZTr0|WvA1povf7&x7 Date: Thu, 11 Jul 2024 12:01:23 -0600 Subject: [PATCH 093/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index ff9db93a..cc163424 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -132,7 +132,7 @@ jobs: - name: Add hosts to /etc/hosts run: | - sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts - name: Run unit tests run: | @@ -158,7 +158,7 @@ jobs: sleep 10 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt -vs working-directory: tests From aaebfcf129d84b68e169683afa35ea58be246af3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 13:42:40 -0600 Subject: [PATCH 094/215] CI/CD tests --- tests/standard/sync/conftest.py | 2 +- tests/tls/brawn.crt | 32 ++++++++--------- tests/tls/brawn.csr | 24 ++++++------- tests/tls/brawn.key | 52 +++++++++++++-------------- tests/tls/brawn.key.encrypted.pem | 56 +++++++++++++++--------------- tests/tls/brawn.key.pem | 52 +++++++++++++-------------- tests/tls/brawn.keystore.jks | Bin 2798 -> 2798 bytes tests/tls/brawn.p12 | Bin 2739 -> 2739 bytes tests/tls/jwt/private_key.pem | 52 +++++++++++++-------------- tests/tls/jwt/public_key.pem | 14 ++++---- tests/tls/root.cert.pem | 34 +++++++++--------- tests/tls/root.crt | 32 ++++++++--------- tests/tls/root.key | 52 +++++++++++++-------------- tests/tls/root.key.pem | 52 +++++++++++++-------------- tests/tls/root.srl | 2 +- tests/tls/root.truststore.jks | Bin 1414 -> 1414 bytes 16 files changed, 228 insertions(+), 228 deletions(-) diff --git a/tests/standard/sync/conftest.py b/tests/standard/sync/conftest.py index 76d8d274..9d7df576 100644 --- a/tests/standard/sync/conftest.py +++ b/tests/standard/sync/conftest.py @@ -27,7 +27,7 @@ def session_admin_client(username, password, root_certificate, host, port, certi @pytest.fixture(scope="module") def session_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): client = AdminClient( - seeds=types.HostPort(host=host, port=port) + seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) yield client client.close() diff --git a/tests/tls/brawn.crt b/tests/tls/brawn.crt index 334e9ce8..979c66f2 100644 --- a/tests/tls/brawn.crt +++ b/tests/tls/brawn.crt @@ -1,23 +1,23 @@ -----BEGIN CERTIFICATE----- -MIIDyTCCArGgAwIBAgIUCxOvVCMcoQn/NZPtMUF85F1Cx6IwDQYJKoZIhvcNAQEL +MIIDyTCCArGgAwIBAgIUNx1xRTf5B6XcaAwZG0UJAvcIjBEwDQYJKoZIhvcNAQEL BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p -QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTc0NjUxWhcNMzQwNzA5MTc0NjUxWjBE +QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTk0MjIzWhcNMzQwNzA5MTk0MjIzWjBE MQswCQYDVQQGEwJJTjELMAkGA1UECAwCS0ExGDAWBgNVBAoMD0Flcm9zcGlrZSwg SW5jLjEOMAwGA1UEAwwFYnJhd24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQDUmOo+Awshph68QwDGvIP0fOrzils5UvY19OiOD8YzgYcyNoM+MOVCBUWq -wk+SF9N8bbcHWP7M/m8c4PENi+QroOKq0wvf1FYpLW5fsa6f/fDS6/DmXEyEz59r -bGmxZZ3psOOxDAjjwo7FTf0Q+DuAlTPScXxRiM9zIlQrl6KC2Pm31T8MKiS2gymW -hJYzD9GzIFH9qsHIIONPX2QMQ9zrF7Q7QyTjxpxGBXe3F4m6aDgML1Y2SNyvBc7p -NXoMeuZ7DPWj4jqZXhIEb4LGVerWEevUB1fArnxst2cGR4Q4lagpv6zVkS2a6t+U -+bfmy0JafOvVzi5TRiIEnnzwXWRdAgMBAAGjXTBbMBkGA1UdEQQSMBCCBWJyYXdu -ggcqLmJyYXduMB0GA1UdDgQWBBT7wcbJl6En5FoWIEwq/QluRAn7hjAfBgNVHSME -GDAWgBRK2F7RZbwAYQjLgtkK99N1ieJxFzANBgkqhkiG9w0BAQsFAAOCAQEARDh/ -XBCtHheYznGl0KrvsdYaVMOXKYVRXBrkA5k2Jp0dnDgvkDbiiT7mGWH632X613Zo -H0qo1Wox8RNu2MR6A8Nwaddz1aLOt3OlgiFYINkpBHugQBcO0iexVXEzL2sDphJe -MAyfz0CAugV9V0c6rIl+m8ejKlwd3AyrdODuO1s9DqNMqn6fxTjiSLVvQMd/UrQU -KDifk6wJT3eiElBUpUV2BTF1v97P1XiVK4BUNJu91syGRqBh9DE1ctEWGIdG5cQC -TXXBr1GMU7RkM1AtA3odDP4fV1omisulDQHeBKG4RGxmw9OQhjSJ7W8Onn2CauU9 -nk2L9U73FU+QOrnqig== +AoIBAQCua5cMw1r9R77OPdhT7UHJcF03ml9AIigvbkZgM4F/ptXClUe8/JUh2MwC +uGnTTMY9P6y76nRi1zSwBmEeZFmcAzVg97PpjCAo5gQGaAKJO+Y2sqMJCk0c8asm +1IZZ0oLTzO7TIQCdeXzgy1Duxp3tz2E/R1HdN+YI/HJ9DfvQPSCbB16BS1eHfeGF +yK5/+uzbFFwaM2S8D62AnePZiWN0Kp3QPIFE5/nMg0FC5//o+9gHVXvpZYjBIt8p +qzscI3Hsw4YiV2EXs98hl7W5iIYOk+8T+2vYQTyc9DbiImOtpQp07c1iU0JHiLQb +6arCZIkcS+1Le7xV0if5pAkhXu1XAgMBAAGjXTBbMBkGA1UdEQQSMBCCBWJyYXdu +ggcqLmJyYXduMB0GA1UdDgQWBBRDjmJl2agIF13hscD6hK7aOEaYczAfBgNVHSME +GDAWgBQXhDBm81fmfqqhlFxKPVzT5Kan5DANBgkqhkiG9w0BAQsFAAOCAQEAI93K +kKCE8tAwrK4TICggTG7BpF0LXd5CsCV1Xfr2jaDCGjuFc9NTQg0R8xAfSxn4vBRQ +rYoiRio0uDuEiImw41ioLX6eNpEcaFvc9LZXJ/F9lZEoVirb1xx+kgUmN4q3ygKx +Jyid/Z3PlHv2czbsT3mpXignXALzHq3Jilbqojy0NyNKtaq3J9g4YDVyXUmI+HC4 +i15/xfTEoT+vO2by2rTu51v8a98zGf5+QXJnR0pIwFWK4SeDepEkGbAsRb0fCMcb +PAdf/DKxqZL0F7s4MMktcbCJ/PY67SH8BJcftNxzF8zw+Iq9s4OAkBBArMLb6Qlv +M9pQCVSzVjT9Gck6dQ== -----END CERTIFICATE----- diff --git a/tests/tls/brawn.csr b/tests/tls/brawn.csr index 6ec23476..a7f12a37 100644 --- a/tests/tls/brawn.csr +++ b/tests/tls/brawn.csr @@ -1,17 +1,17 @@ -----BEGIN CERTIFICATE REQUEST----- MIICtTCCAZ0CAQAwRDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMRgwFgYDVQQK DA9BZXJvc3Bpa2UsIEluYy4xDjAMBgNVBAMMBWJyYXduMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA1JjqPgMLIaYevEMAxryD9Hzq84pbOVL2NfTojg/G -M4GHMjaDPjDlQgVFqsJPkhfTfG23B1j+zP5vHODxDYvkK6DiqtML39RWKS1uX7Gu -n/3w0uvw5lxMhM+fa2xpsWWd6bDjsQwI48KOxU39EPg7gJUz0nF8UYjPcyJUK5ei -gtj5t9U/DCoktoMploSWMw/RsyBR/arByCDjT19kDEPc6xe0O0Mk48acRgV3txeJ -umg4DC9WNkjcrwXO6TV6DHrmewz1o+I6mV4SBG+CxlXq1hHr1AdXwK58bLdnBkeE -OJWoKb+s1ZEtmurflPm35stCWnzr1c4uU0YiBJ588F1kXQIDAQABoCwwKgYJKoZI +AQEFAAOCAQ8AMIIBCgKCAQEArmuXDMNa/Ue+zj3YU+1ByXBdN5pfQCIoL25GYDOB +f6bVwpVHvPyVIdjMArhp00zGPT+su+p0Ytc0sAZhHmRZnAM1YPez6YwgKOYEBmgC +iTvmNrKjCQpNHPGrJtSGWdKC08zu0yEAnXl84MtQ7sad7c9hP0dR3TfmCPxyfQ37 +0D0gmwdegUtXh33hhciuf/rs2xRcGjNkvA+tgJ3j2YljdCqd0DyBROf5zINBQuf/ +6PvYB1V76WWIwSLfKas7HCNx7MOGIldhF7PfIZe1uYiGDpPvE/tr2EE8nPQ24iJj +raUKdO3NYlNCR4i0G+mqwmSJHEvtS3u8VdIn+aQJIV7tVwIDAQABoCwwKgYJKoZI hvcNAQkOMR0wGzAZBgNVHREEEjAQggVicmF3boIHKi5icmF3bjANBgkqhkiG9w0B -AQsFAAOCAQEAa7MmN6+00w5j1CmeNvfau7XzWLRA1x2U0C+xD9VqJl+uT11V90Va -josTghWwQQgk3C9TcHeuHuwW4A4G8mieMmVJiJxSEltVinK90+SZz9BFOH/wRCIw -MyaNFE6caoFKuvcD9MLk+HcU//gKzBDPlJC6w0xtV5CN0I/pSmd9ztj8WpCQQ7Zr -KHkQXXs/CTSKiFPzLQXklQ3LMURSg26uUSqdSNHri19EZzJxDFK1XYy6Xo2+Bn1J -pOuO6A38VnMDO7MpncoUS73JyyE8Kcv2bPg0rP7zheN/ERVtfcLZoKTDs9LWYDHl -1ontL7cx9yfQlLxqU4o6xDr33nRgT7YJ1A== +AQsFAAOCAQEAntwEzWrsB5puHs6LqCyXwihdmBsiuTqbTVW/P/3wYoGWw+lNa1O5 +z5h+4qI1iG97Ojr+whwl4vxFM6NuAat/bON0Sz5ZSUDbqMvJBzjbYkxIyKx505dj +ZfNOSoxe56A6+lQpT/cWhgPrZrJCQNqn/ioOp2kbT0LxPtXPzZWWV93/n6TxUKFt +52YKouPnArv6tWI0Faq99f4aCJsfEB4IMpMZbiHZ0XJi8ngVoMifcCQjL2hUlKfd +Vs17bgkH22+wFMg1J14WPOAIa3VxASHLi/+WLkCclCdUpiYrzvQLaYCXG7G0JvRk +5xc5EH7mQpiKifG4QGfdxaZ1oz1vLYs/Aw== -----END CERTIFICATE REQUEST----- diff --git a/tests/tls/brawn.key b/tests/tls/brawn.key index e87488a5..157c6338 100644 --- a/tests/tls/brawn.key +++ b/tests/tls/brawn.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDUmOo+Awshph68 -QwDGvIP0fOrzils5UvY19OiOD8YzgYcyNoM+MOVCBUWqwk+SF9N8bbcHWP7M/m8c -4PENi+QroOKq0wvf1FYpLW5fsa6f/fDS6/DmXEyEz59rbGmxZZ3psOOxDAjjwo7F -Tf0Q+DuAlTPScXxRiM9zIlQrl6KC2Pm31T8MKiS2gymWhJYzD9GzIFH9qsHIIONP -X2QMQ9zrF7Q7QyTjxpxGBXe3F4m6aDgML1Y2SNyvBc7pNXoMeuZ7DPWj4jqZXhIE -b4LGVerWEevUB1fArnxst2cGR4Q4lagpv6zVkS2a6t+U+bfmy0JafOvVzi5TRiIE -nnzwXWRdAgMBAAECggEAICxcFrJjNt5q/FavgWP6HD/jVqPzlkNF23iK0ST1+8l4 -alLxnbHMoCcoGeV6IUPVz5jTABupw+AldJteH4yyJSAd7Xgu7dq2h1jGwVikcrX9 -gg4O0O3a7qZ1G862WBBmy3znmF2X4tAIxzc8Oxs19gmeZBSkmbo4mtXxIv+5qk9h -IfdtPNY73WEDDJWNsYtseJoePrPGj8sKzapb1wzByzNnbHfSPDLeRJwC9/Zpi0Wh -nVhZiffqU3NFjRqr4m0cM0VY642U92bL2hWL+cElBTeWtWR5Zfc3Uia82khHUjxg -w7Z1C+OKd2ICfzVHMOj5ZayhYyMS5ou+bT50BO/wQQKBgQDyP/52+9csci1g5AEO -HMlMMoAWlpsyoLTgJVIsD6aL9y9+EOjf0JZC9Q2Xcbbtag9X+LJOs+PDRpaZRLxL -HLlnR8/46cgXIS1ixnyODR5c9cqFA/9k87UnzNK++9QBghS8yx2DufznL9RsoJQO -c8HEJaFuZKYQeUDHRj8tSgEn+QKBgQDgqg3VHh8ExQ+d6XohBL8Pv776SM8ZxhIR -tCpmDM8PL41+SViZh7nPSf3tR98Mf9ylj8xZ/sUB/MIxqGQYc7shi64+a5HxXpdU -uT20eHPUigAp0fZTERnR7kGANoIhVosqqFHrGWVXHtPo4ev5uABmPIxtZKbnCZnZ -gUd67QighQKBgArXbFb83Ftj3L4KVjXAeg3L8MmSAe4ZHR8u7GeGZ8i5zklRDmr9 -1cu3Vd1iPHKRnZAtVCWLjXTu0syXM+oUpgOGRjt4kvjeBj72bRqaYbJ9WYvsauCk -u4XFd+UONiW/IZh1aqO7jiL2lAYshZPEAHb7zCa5oGj6VDjW3vry5exZAoGBAKIS -S3RJDHt2ZbO3cMFNGUAVRYJs7+pZ90MKQ+PmraD43wwRgXcQcLzXVfXM+V2dB+Hw -AK2Tmy+51aXZIox5QLAMgiDJnTkQ0f7uu1Lr6jOTcla4/wghuAy34kzKBcpjEnYt -gxsk8PSOarT/9inp0W/vkiaAi970ECbWmmhVgvm5AoGAeBa8pxcfHKjvRagFAuq4 -GFyQKPZcugNDyZnifIYDU78hSeHSpH3RKvi79UszyL3CPob0fsOM5WUEV0eUvprh -qqJmlL38k+u+AhyBYB4AKZfcjF3TUSWteSPGgmkrRjNjRcxgISNZWRxVGcxdY1Ts -uWUUVR7yjiNefy8iYab0TEg= +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCua5cMw1r9R77O +PdhT7UHJcF03ml9AIigvbkZgM4F/ptXClUe8/JUh2MwCuGnTTMY9P6y76nRi1zSw +BmEeZFmcAzVg97PpjCAo5gQGaAKJO+Y2sqMJCk0c8asm1IZZ0oLTzO7TIQCdeXzg +y1Duxp3tz2E/R1HdN+YI/HJ9DfvQPSCbB16BS1eHfeGFyK5/+uzbFFwaM2S8D62A +nePZiWN0Kp3QPIFE5/nMg0FC5//o+9gHVXvpZYjBIt8pqzscI3Hsw4YiV2EXs98h +l7W5iIYOk+8T+2vYQTyc9DbiImOtpQp07c1iU0JHiLQb6arCZIkcS+1Le7xV0if5 +pAkhXu1XAgMBAAECggEAAcGE3VSyJnlI4HhwQN8omblywXaMK9OPwqxCM1cRZ1mW +Z4ykS5RT1c1lmw69HKrLpQHDxBT8Y9wgHTg2xvmM/IHDwyO0JKSoRjoFP+iYJtSl +i4/em96wrdPqyr2Bb2ry5qvaKP5q82PKYdSGnLmp1AbY44/AeFgcYzFwUS7eolcl +IXEApih+91OnEfOZgSQyaqCnwN/RE1ykESKRYQFgL6qxC0jhJpg4q5iqsfyXkfsj +v3JpfqY3xB3hmsAqdYT5Lr9Fc2OgEDuddAI/djfqEv4nbPacN1pygK7pZlM53xja +crThLUq2NFpiWQv2B7eDJoUoSTYb1zo57USqeEPBsQKBgQDxQuOZQSwttRmqVCU/ +IcdkbsuQFhNhBhFQMRDw+bjm5pCr8gyMK0vmQItv2e6q/vPK9L2tUX5bkwM4eSr7 +9zioiis4RKQ8TPuREbgfmJMjRSg002xDijM8b3wmCVQ1XJykPAKGXTR2Oud1Kxiv +SSo49YFBQf8we8/RSHfkcaA38wKBgQC5E14F5kNJRroG+cOMkbT0ZpvbB3tuhEQV +OloMpgKNOJamsISiGP21deSmN3/BP4yYyX+63gdZdLSrL8VcPNlbCkwtcrWDAP5a +y/VZEs0XgYHltPK4UEw5bEuKuCRqShzAlXCgHANQggLsuyaz3CHVcRV16uVq/7/X +yyeWvr8SDQKBgQCVB6+WBJcoqNzwxUe4xsHnfTVLjQdtgJUDRzvizy9zmms1e7Ba +iYg59BbuAd4XTKQF88aTIGsAYEC2CssNl/osyiTGfkhBY4BmbV6iTdpeCCM89njD +A8SAiZFT4aFd0RaFsPgSTdLRUbOWQgfeh0CIrMaqK/1Z0rFd4vkEaVgCFwKBgBiG +BHNrq4bOJGBAQDUkKYIpBoXjW+utAwh9DumWJchosy2rPifsf9HHqWCNAhStQwgL +yy0LtpWX7Uixr8klFvgFSUrMZFjTjOCjHgOLhjmTI484huD9YtxJCUl8VPbwkxbB +tobAr3+/enu74Mj8Zk9OCLXzRisDcHw7oydKZy8RAoGAcfbntj+ZVc8z5oi79O+v +fpD/G9FbvZe/qKSO5cwTS0z1QFF8rQuzelzNXlIGlNpZyz8uxv7qN5X5C9wla7cm +Uz68d6+f0yEa16mhS0rKYeUDEioVjks7Td4/FrIF0EQZZGpfNLgQukK6RTpt8eBo +dDFoxdCwl/KU94yPu3autIk= -----END PRIVATE KEY----- diff --git a/tests/tls/brawn.key.encrypted.pem b/tests/tls/brawn.key.encrypted.pem index f6ae39ea..ccb36c7c 100644 --- a/tests/tls/brawn.key.encrypted.pem +++ b/tests/tls/brawn.key.encrypted.pem @@ -1,30 +1,30 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQckidczYwezC6FwPw -gHKa/wICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEOQA7z5WuNyl+HIA -1rJyQScEggTQSP5iwPr7pjnneKjfUt2WOiZd0YkbDB6J1ePhJq/42rmxuYW0Vzxe -9NhJkzzc7HAq9LN9tRZdFd+yJt3ZmPSyEaJXFgbsEIxL4TGMUvQWjv3anNTj7Meh -ZC/fSF4iyfKxB1OyT0pVJgpcFuSLpiwqyBNPENb4IYmZTOcSlyisOmDD3Bx40Suv -yxg/23+n7KzeQzN11D0qdyx3277Zosj28rwO122KUMsE8rNwOw8uwpqAd0KjlGhE -GF84kbthpGTdMYzzoQfyCthC5vGCZPIWS11G700iF6jfgLMHlAj6dzhLVPxZ085Z -rIFwAcSgUoWNIeSpR/k5MCFSac8aepXbK51wvoD/oZYK7yInYVp1XAcyc5xEvzQb -pmwBOLEK8ZXI+3ZjBHr4oXfwt0UuixjQHCavwEzeYooss6J99jErFPtWOsAQ5iNK -2xtr2i8hWi+TVseI/mKoIe0FI0wddpLcCn42YpwPSvzAmqSZ6i2aHDp6vi0pjlVj -i/nOhHNqYydQ77bQbeEIy7808nlA9z5vORwjwA7aBtnbWtnW7J5qFbQkRDfY8QLY -+3yLaz5TrGTF4cds100cvcNyucQy3FgxXgUQ1qjn0AYIyso8iSTTtpKuXxpUVS/s -G7N6wCmJ/x5Odng1iWYueiA0TRIZmqCxqOMVbvz9EFKAz28UjItX0E63dxCkoGei -K7jsvokxCVJhji+rupvtsfu61mSOORX5AmcwnJkjuSiECj+vkZfUBjvfY48gRKvZ -8UKUyD1WrX7xbl6EzvhE7f8s8S2F3l+T75l2SKIVfDKBCck1aVibtqjSydZsHNkV -kAYXorCPs2jyRxabe1LCqDA1yjNuRzi+YnzO7DHb1ACELSuxfZJnCiFAMr/UM7+y -yUeAUYnYfgTgTwIREY80y/75HtzJlU5dYRMpECdUbBKdjq4lHNPe6aZV9qDPL281 -hbp4NKlbhIZl5Hn3/e8j/5ChDpqi5E0DA6sfcmJFGRIbSpOVvj8nkMry4ANMlO37 -qU/WmCKN0DQpmX6SzTn6PcWyQIxTUmccgU+gVbOTTcHGVr+E5wz0uLXvWpQJmmEo -yz/cP3DrmCrdt6eS76oxNnhvUJmOm6XzVNhoLXmy2dE17lixHfQuyVYHAx3UHkGq -CCV4NH6yJySaUpFsMUwbnUz3VshWVuLM5mGQyD/4EsUuotyuLaKKHX2PBEpgKYoO -jmrhJlo34oyA2ILJwP7pFBC+ekdXbzmMDy0gQY+ESRPiOxGqspSdKTxPzd8jBtPG -xDURGMBAZCAPof/Ny3If+s+v8wmjHSQkaWvhrTsOMbzj6HFzTNPGwcamKQMrJiyC -khEdA3v6wLfw19mtuf2eIwCWMQgj8gibDVoXFd44n1DN+ldJyK9VhL5POvj41yrK -bZKifhfYZSv6J0icbPCkc5GEdnHAgN/qtwdXuzuiZnIzSaVg9+TtvDOGpj7W6wk0 -JiGgVpMnhKn3Y2qVz/tei/YVVR0GfTrPylIuEfr+cigXiqif4yz8IT8Q128Kwiyv -OExk0Mx9fPTI4suFfYNb7RjobSpj/3xpj9eZVdxcwVy18OdQ7/nLtfPm+rh5uuKa -qNBFn4XrH42mZWK6blekMwmBTTIA8A8GwJwbUp5HOc341uvaIVPNSRI= +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQAklzLuIjE11tj/Aj +vNMITQICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEPnLC+VcvZc21rhT +F16LiaMEggTQOFddAvabx1JdMqAMRPec37AmobrnZ7SMcZJIYjQacWursUpuWOLx +VJ+sMftc5GxpkaKbnrhI+W8Iv3zum32Rz18ZUWXgIkxHLmI2kZOlw37oOQPpbB30 +jzL5i5lxHKCU360VFGFm17+2C/+GNpexXbbPdGCy9m5I3XbgyHdvCIGo7A9EiLhX +Raq2gdbXnrfJXSnLhXclMA2+baVYIaAhh6f+3be2v/md2T6rVyP0USRCtO8pq3+e +tBolgDTLfmXDzmHMtENC5/4TNqmi0zZAnQeKl1uknxj7sqTKVkZsoM0yMKJNhpwx +OnG54xGTAQ7utBU0Xq0/Qxs6gY6SRplySkcqZfNZUbIWxZq5pBCVHyLVCwdNqkDl +JFyEo+s9Krzslu8uxGrmj9BV19bKti9Z78LHbiqD+BjPVKmCkTzS7HRdC0WsF32E +GgkowKY2BEtFynlDMMI6XJZE90+TTcXD+u/+c8H9w86YgvCnhyG0B/UJ5fMpan/6 +aWK6Tm+TWK1qcQF5eV9dwdHW9LgPi1n91a31JLh3EOi9/fjJ/OzE5IOZTv20YFPV +Thb12QLQr0Iism1zvCjmFpwcL2SQI5ttUSDGxn/YaTGsuaHAOSeFpU7AnBmxtdYL +6YskDHCHuT/8kU2ajIPYGWBDca8ROVl2mQKCOGPsyZ87GnSzH63CRhLqWaZf5M01 +9xnpXh8F/iq7Ywz5Gb1Co9v4fCUkvBppXYyVAXRuYdmACLAeX9yDgXjRj2olKUqS +wSWp2YyVaOjEQPbnD+nzPWfPAhVUr0REQvagzmfnXLPsWqLaXdz89UXgiU15PlhB +HAPwl967DHthJ5CVOXYBNBPUthTNTskBsKnQqtOiThgqdML0gEx66Su3oJs4jEf8 +wueMuYI3gTvkZTHqWhVErccdG11kFdY2VjVPiUy2YKj2PtNtKQxnKWL2Mn+7DQ5M +ZFFV5JV5Wzs16V6TSWc6oGrLPnG1BSaqmMlvaphqokK4o3wkdP27Te+IbHr7pMMM +wMejBJGieyInohtM/udsUvm6VyaQJeNON643neK8K3NI7ZF2YqchenkKRBtzyMZO +gKgykBqIl/HBajHMlcCu0FhU/5wcX/v0e0yvqPwwU7KnGhTICcFQ5GFD2ujvdQih +seuxETRBn+uqJ+IpbpyaObCqcyy7sC0e1Ijx8W5/3GgN6GA/OlEWtxQQqypPpp0e +tKCnMd6kWG/sI1dx5nNJqNjn6MCiPa4sIUdgqzceI1Ovq5/Bs6+SCazvpKxaMaso +Hq3J59mGvt9IpNES630scxev+Gj0inADrghPt9AMy+ZFqCyeJFzLMMKn43YB9aS+ +xXhHlci+TPVbhyZRsN6LM4W328XSTpaMkvkNvlCsvMui4LK82B8zjhm/buyoYfSM +LyBTvQ+D999lX5i5e4S77xf6ZFOsVd6vhL2NMxvfXfMkWQBnF/FgEwAeBeR5hgv/ +f8xFSeCDBfkiJCmAsT4HCxUJNXrC4W3sG1eA/Fj8evjTEyszoCOJIoduuxQM5efn +rf5QWzORHdDREGl+2u0+K8XxK8N8y6l635VrUGknc4QB3vbW/JkVlzi/NFr9rXgN +Cc9svalB+GST1PDkbymYFY10uMdFxaX+E6CH8xNGctJPX+8Q+O6IA7g= -----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/tls/brawn.key.pem b/tests/tls/brawn.key.pem index e87488a5..157c6338 100644 --- a/tests/tls/brawn.key.pem +++ b/tests/tls/brawn.key.pem @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDUmOo+Awshph68 -QwDGvIP0fOrzils5UvY19OiOD8YzgYcyNoM+MOVCBUWqwk+SF9N8bbcHWP7M/m8c -4PENi+QroOKq0wvf1FYpLW5fsa6f/fDS6/DmXEyEz59rbGmxZZ3psOOxDAjjwo7F -Tf0Q+DuAlTPScXxRiM9zIlQrl6KC2Pm31T8MKiS2gymWhJYzD9GzIFH9qsHIIONP -X2QMQ9zrF7Q7QyTjxpxGBXe3F4m6aDgML1Y2SNyvBc7pNXoMeuZ7DPWj4jqZXhIE -b4LGVerWEevUB1fArnxst2cGR4Q4lagpv6zVkS2a6t+U+bfmy0JafOvVzi5TRiIE -nnzwXWRdAgMBAAECggEAICxcFrJjNt5q/FavgWP6HD/jVqPzlkNF23iK0ST1+8l4 -alLxnbHMoCcoGeV6IUPVz5jTABupw+AldJteH4yyJSAd7Xgu7dq2h1jGwVikcrX9 -gg4O0O3a7qZ1G862WBBmy3znmF2X4tAIxzc8Oxs19gmeZBSkmbo4mtXxIv+5qk9h -IfdtPNY73WEDDJWNsYtseJoePrPGj8sKzapb1wzByzNnbHfSPDLeRJwC9/Zpi0Wh -nVhZiffqU3NFjRqr4m0cM0VY642U92bL2hWL+cElBTeWtWR5Zfc3Uia82khHUjxg -w7Z1C+OKd2ICfzVHMOj5ZayhYyMS5ou+bT50BO/wQQKBgQDyP/52+9csci1g5AEO -HMlMMoAWlpsyoLTgJVIsD6aL9y9+EOjf0JZC9Q2Xcbbtag9X+LJOs+PDRpaZRLxL -HLlnR8/46cgXIS1ixnyODR5c9cqFA/9k87UnzNK++9QBghS8yx2DufznL9RsoJQO -c8HEJaFuZKYQeUDHRj8tSgEn+QKBgQDgqg3VHh8ExQ+d6XohBL8Pv776SM8ZxhIR -tCpmDM8PL41+SViZh7nPSf3tR98Mf9ylj8xZ/sUB/MIxqGQYc7shi64+a5HxXpdU -uT20eHPUigAp0fZTERnR7kGANoIhVosqqFHrGWVXHtPo4ev5uABmPIxtZKbnCZnZ -gUd67QighQKBgArXbFb83Ftj3L4KVjXAeg3L8MmSAe4ZHR8u7GeGZ8i5zklRDmr9 -1cu3Vd1iPHKRnZAtVCWLjXTu0syXM+oUpgOGRjt4kvjeBj72bRqaYbJ9WYvsauCk -u4XFd+UONiW/IZh1aqO7jiL2lAYshZPEAHb7zCa5oGj6VDjW3vry5exZAoGBAKIS -S3RJDHt2ZbO3cMFNGUAVRYJs7+pZ90MKQ+PmraD43wwRgXcQcLzXVfXM+V2dB+Hw -AK2Tmy+51aXZIox5QLAMgiDJnTkQ0f7uu1Lr6jOTcla4/wghuAy34kzKBcpjEnYt -gxsk8PSOarT/9inp0W/vkiaAi970ECbWmmhVgvm5AoGAeBa8pxcfHKjvRagFAuq4 -GFyQKPZcugNDyZnifIYDU78hSeHSpH3RKvi79UszyL3CPob0fsOM5WUEV0eUvprh -qqJmlL38k+u+AhyBYB4AKZfcjF3TUSWteSPGgmkrRjNjRcxgISNZWRxVGcxdY1Ts -uWUUVR7yjiNefy8iYab0TEg= +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCua5cMw1r9R77O +PdhT7UHJcF03ml9AIigvbkZgM4F/ptXClUe8/JUh2MwCuGnTTMY9P6y76nRi1zSw +BmEeZFmcAzVg97PpjCAo5gQGaAKJO+Y2sqMJCk0c8asm1IZZ0oLTzO7TIQCdeXzg +y1Duxp3tz2E/R1HdN+YI/HJ9DfvQPSCbB16BS1eHfeGFyK5/+uzbFFwaM2S8D62A +nePZiWN0Kp3QPIFE5/nMg0FC5//o+9gHVXvpZYjBIt8pqzscI3Hsw4YiV2EXs98h +l7W5iIYOk+8T+2vYQTyc9DbiImOtpQp07c1iU0JHiLQb6arCZIkcS+1Le7xV0if5 +pAkhXu1XAgMBAAECggEAAcGE3VSyJnlI4HhwQN8omblywXaMK9OPwqxCM1cRZ1mW +Z4ykS5RT1c1lmw69HKrLpQHDxBT8Y9wgHTg2xvmM/IHDwyO0JKSoRjoFP+iYJtSl +i4/em96wrdPqyr2Bb2ry5qvaKP5q82PKYdSGnLmp1AbY44/AeFgcYzFwUS7eolcl +IXEApih+91OnEfOZgSQyaqCnwN/RE1ykESKRYQFgL6qxC0jhJpg4q5iqsfyXkfsj +v3JpfqY3xB3hmsAqdYT5Lr9Fc2OgEDuddAI/djfqEv4nbPacN1pygK7pZlM53xja +crThLUq2NFpiWQv2B7eDJoUoSTYb1zo57USqeEPBsQKBgQDxQuOZQSwttRmqVCU/ +IcdkbsuQFhNhBhFQMRDw+bjm5pCr8gyMK0vmQItv2e6q/vPK9L2tUX5bkwM4eSr7 +9zioiis4RKQ8TPuREbgfmJMjRSg002xDijM8b3wmCVQ1XJykPAKGXTR2Oud1Kxiv +SSo49YFBQf8we8/RSHfkcaA38wKBgQC5E14F5kNJRroG+cOMkbT0ZpvbB3tuhEQV +OloMpgKNOJamsISiGP21deSmN3/BP4yYyX+63gdZdLSrL8VcPNlbCkwtcrWDAP5a +y/VZEs0XgYHltPK4UEw5bEuKuCRqShzAlXCgHANQggLsuyaz3CHVcRV16uVq/7/X +yyeWvr8SDQKBgQCVB6+WBJcoqNzwxUe4xsHnfTVLjQdtgJUDRzvizy9zmms1e7Ba +iYg59BbuAd4XTKQF88aTIGsAYEC2CssNl/osyiTGfkhBY4BmbV6iTdpeCCM89njD +A8SAiZFT4aFd0RaFsPgSTdLRUbOWQgfeh0CIrMaqK/1Z0rFd4vkEaVgCFwKBgBiG +BHNrq4bOJGBAQDUkKYIpBoXjW+utAwh9DumWJchosy2rPifsf9HHqWCNAhStQwgL +yy0LtpWX7Uixr8klFvgFSUrMZFjTjOCjHgOLhjmTI484huD9YtxJCUl8VPbwkxbB +tobAr3+/enu74Mj8Zk9OCLXzRisDcHw7oydKZy8RAoGAcfbntj+ZVc8z5oi79O+v +fpD/G9FbvZe/qKSO5cwTS0z1QFF8rQuzelzNXlIGlNpZyz8uxv7qN5X5C9wla7cm +Uz68d6+f0yEa16mhS0rKYeUDEioVjks7Td4/FrIF0EQZZGpfNLgQukK6RTpt8eBo +dDFoxdCwl/KU94yPu3autIk= -----END PRIVATE KEY----- diff --git a/tests/tls/brawn.keystore.jks b/tests/tls/brawn.keystore.jks index 9b5d0c037b6cf70a272f3b870a425e0df6167255..813922f20abea658b577bf31e55cbdb0558e7b12 100644 GIT binary patch delta 2530 zcmV<82_5$C748*~b`-$RjE1vuoUUt;pQV-DRh)AgV#<+{6Ghb0D=Mx14rwfPNQb2lx>1tb($OJlPrE%{8$54I@ed0F4ylf} z%U)n`CR^(-0)Iy9qwWHj?BU~h0tRh_@Q$EYHv}WKM>4%xW5mSt*Xq(uB+%2YelWV0 z`6j3JJE#Ef`C=Z?eurKEy-6H~H0077wS9X=oeQ*G#a}06~ zq!PH@lYgfg^w(hlb0i9F`e)vl??zihab$s1J>bx6%V8uyXDY!>wT_@3c8J#`aUg{a zM30VwjzEY&-|#7H4&?*U0x*#zz?=lhGPYAJ@vR$GPT_BA`6nLJO~`^G-yVo0GAUKX zjnSNR#}16Pl$Zb843FMa8PeqZHx`|@RVEp*7Jpk7B1e4EvCOlo7qa2K%sRg#M+67w48RX#L2p4bnv3$t$lz=rxvnwHYnlw>h+63}Gd; z4_eDv650ZC!`of##|=Re>$rd)DNg2m)=aYwf1{7#y_;Z7-;l^Bg?puY4V^%vna8DQ zMt{hcP5H`-SK7rcz~j`9^D*)4k9=C+yMre0NI3K5#X7cLZu357p=#Lsgss(AgNcx* z*g<$wTZfcz4iOa(Zd3X@+mk$F0=$Y|DlzAqFI**J08~nH6ALFb?O$8y-4^W=ja&o( zQ=~dKCH&*{kx5cAlt`|ETq50#_4p4mX@5vlx-ZSDv?{h0kj--wv?QJ;xHShluk*3HHw=wb$Qj-5l+TFSO! zv~!&X?8|}DI+6jd*bTNk#7RZA3ZEs^jAMIRBNP$=gSAVpI=jv7ujBuubw9D;_!FF zDg9b`^Nmk{o`PvIa0ln$j5slJs_$)U>U2mQk;}qh65F8c(UmL0C(Oo zHZTze2`Yw2hW8Bt2^28|9+RX69|tx$G&C?bG?U5&NfhTvp!mg3KXPHlE-u97@``?W zr%jQHB!2>Y6K1cdq!fz@eBtlisg{6(1VA}79oRf}zQwBLaKr>>d-F0@kYzHM_hnad zRnUO$(ui;pPJj{zf!d!bg&cxw5+;W=jf`o&&8I4f!OKUcn|V>iW9wKPrr>v|d+Q8? zh2)QrdyN-w|1DD8*i|#;T2|8ehYO#IDP|L`1%LHv0wktJ0Y<~oq>q1}A({8_9R4N* zzM@f3+UiBPsSRfl4}uP%8_dT-49!QTNrzZ(n5~D?ly}-!RvzVQG+8DNqfKa2*j~22 zvbBJIVdg49;=a1-+qzd`mU>Q%+1wvA-@R-fTm^V-`vD^%MEfI!#(B)P{U_N;0ZLhfJgN>rJIe`^i zB!J{QI|xts)k?d+R%h1jOd)@Bk@t~(g$h4@2?OE|-TE*CAe!jd`JBV`oO&-}e1H2< zXxw5NSV*Fv)=gQNC>Y^1T&s3v<#6*_VpQQog2h3H_Ve&w@d#yp?LmWFbg_rg8zu(l zW=babV5~>Zr;Ool%E12b+{Q9=Yq?QlLty}lP^sq_XzXDzoDMtZUVD~QLNosu$Qg6i zNRBTv6F}jdgP<@TEG)DDPx@5Qseg2LdR=!{dHNu8bnNQdLmfh5gjb&TWc96{GRDQ> zx7rFNIiYK&g{zk6{O%|D3N(14l4U@!9IY$xF{7=$FoN#@ZC6#$qkXQ=6U4%&nqHzP zz;^#uNU+BPp`*Nij>ZEXVx5=vDS>J##SiWuSodb^X{ht58Z+Nee_=S^S%0v;ku2c= z!_+Am-8Oahy%L<~vrEbyfm1Y_1>WX?A~2eg#_l`Ahur*A9Zl0kdA3A- z;FXR623AdL%odKEi+9QZUnurjC@Jq15IH#jc?vgD5Ggrh*j9!ukMr}_LS%cMrlnvq zQpkvz#?FebH&;8*^ZwtgR)4>CvW5YY%>7-JfN2pfF#_O;jsWIg!K%QoyHUQ1BS`Y0 z$sp;S(+|7XLi$0_uk9z6x_id4l;s7(FB$s=>?_(Cw|w<)+P;d`{WwvZ=p3a^MOIR4 zq{+ydryO(+Ik+-S-(=smt1N8^w89*KyiyDiCn|GC9kfRmS%eKOGh9qYFQsw@MvC0# z8(zb2?S!Tqs7xJeKdWlaqg#HA?|~)4rHC0SR#M?kUCUPwcrzgqMke%rNv&FPl_4e) zxNVhGaUrBzc}KCveG6(lQIw02pH{JjbdRXgfC7`B3KcqGOL#Pt9_2Y)FNOAQww@|* sh)cvC3qsUUVEU>`$w9&d6uX7FEN?$l2Fy~rLVCXt4t?-UngRkR5c|Z>RR910 delta 2530 zcmV<82_5$C748*~b`&svwhsQ@&WtT9$vK86Pu2uxqAZb$B!3ABEIbx#?3;CoCppq0i@8VpkChW-=1h=zVa02- zw<03sl9&)Z5G~MbQZD04TBFDknhwhDfv_ZE+%tTy`Kd8EWgSKC*^u+EcgD!_Xkrgh z!CkcLILcBdeSaQRVXT%H`?QWSD!dfA?l?LWfH7?QWB@^IqOXx?#7TX?7YZxwvqmwQ~v?~=HLbhW)IxR}C?WA1c_zAD_YEA{+)#_4x!4Ty+lISI(=FjCc zii~Ckdd@^st@t)E1YI*6OrtcUt$_x!VbND89)eHeFMp#cZ8=Xr4byz8b;rfbatV8ySai8`YoF?mf6HY9bT{0prWj%g;@*GtN+ zt!2TwH;evIJ_?s}xr)u#Ci-r9Ms46qd1I#c#5$UKTP!Z(5EWG*xmV%h?i=%=&BYgK zYvBIZR)0r;cSNEy)rLmZPIv-YYn)zP?+sh5CtxatMZK0MX*>Ub5qTl@(F_!J(+A6^>MM@o{Cojv%% zK}r}DP2gr=AK2!>bfzk4XLovnC$$nd$0MeI*ng%se6Z=V7}fE9|KBh|1t_(FMQ_3a z>iP?_0xgn05GVK?g$F7C>nEXz~ba|AD|Aw~r-ziXS0O^wdMZG7- z&XP;@M|oa}5V^I6pX6Jpr)Rx%EX2bIgX^q=4-8yA6#Fq8x@i7!3iVxEA8MPoOIqxQ zQ-2(y+xbNUtm#?+C>e)L?Qy|<@Qu#B-v4i&q2lyws?&nEeSt584{RHwj{an%u$8MR z9=0WsJXbd58WT!*ovDit)ofm8qTHOOWRU2MfX3-n_FR`;{Ck^)Hr`(6K#6C$hnZ<= zpdrVav~AYz@1MgqsDCjy zl|*p8^QL{|uhCJQ0)c?^s3~%Q=uIxytpS@#{-Y1b>vh z35ZED+tDLzBn#C%T#E*b(%jCZsI}1pwhCSeoq~-ZOEC5x}J+x*zvV z?;O$WiSZ9c{(40$@>dHZ6T70x7JtObDIVSTM@>iUK`APTB;5&n;RfnZ8K6#RL4&Dt zzV4TdnJbP;ojWBWL45&7h7~Pz@l3$FyTMPKpyWcJ>{4!!I8vGuaSjMvvnAbb+PR?Y zy&vIq_pRtf2jMbR93I}Jo=V9uIv9U48JwQe9G^!UfgogVmg(nnV z6D}cikOHw}oQBlTj~@zhyLZSI&YaQk^PSfTN{I7Frz(^oQs%+_{mG3nJ$}cmMdq|6 z`u+%n497C%0yk+<4z>_}ocYL{k}op^bs!!nVTjG7QxPUt&m6EJ)#JAZ+7M14-#F$m zHZTze2`Yw2hW8Bt2^28|9+RX69|tfnF)=ndF_X##Nfd%j+tO9P?FC@m9fdEdVQ?=F zf7FqRB!6jtxa21wY{t!dOhp`E)Bk{i1VG$=B!+b#ceVx3znwyV4%v;Qy1km<)+})- z#*)a$ThUz)0d1RkO84xqni1^$0KV_K$jRNlP(Mz=U#Rcn7jH`b{z^Zj3xAB$h+L%& zVrZtQ6wuhKnqwUXjleS%Y5j;j)1gTP@ES!*e}9*Nn&NLsG!oH>l@c@*n0%M-mI~7@ zs6Nd-@6{0m0i7fu8q#pZP<9kK%48!yXA1HmKJ8$BKGw8=dQIXxaksZ#qJofQ zp05_I0Ki4C7da9EWY9d^!}}E6VcvOI%*TtO9|$ivrLFikSN7epTSKc7dU3mM_gLX< z0DphE3j%OaFD1Cnbgog*Z$sE>OShYC4SQ9$7xOGM%5G|1s2BRNHTraJrma*out^fm zkR`t0`_VYo&#{T!$?h=f$2g)@gi|yH;wynH$^v*1Z&~JPl__uCtRr@I_nI~56g5Zv zf;OBv3BW4je9U7kU2c&+#-Jf|Ud2c@jejo0Io1lHDblMzeFecV3Y&X>9*@1#hnc4t z964@I4{LNsVGaOa1)U5FR_@-%PLJHsE)OZu)@};qk(p_k{5i|=*h^@CxkU}Cq}DwP z3T>AKaylNfiW;4adoVH-v4a7ys+r;rtjHfhz5+M9gS2QP62qFI>Aa5(SkE7(x_{lC z;Q8>k4}OS5X_KgIueiuPni|4YbbyC+>2-n`?Mtj%Sw{#z7T(5b^`5=H_?+>{>MP)x z1Vv@;#KG~=Ke$CW!b4AEHzB$9w#pw%Z`yY%t5P}f_0QP}(DU25(r{VH$HB<(Mn=?dtR&{w=_rl*s8h<)%g)}y7JAvkvkn-pq$5x0&MnX;8NwtSt7<+i< zr{D0aX8O6qm&9?+91@&R{&AE#*Jj5e1BY6?zRLX`A|ZG22*yy0S{wi+-OTpx0pPP5 zcKrxtfjV4&{o;;IgQAI(^rTt`X>KKX<$^Z^X#BVK^0A#_lyjcq3pt>m#(z358QCWc z&_%qZS0%AXZZxOUixSW7hHWdNnu)PwUDf={3E31Pbm}FBqX}jpuuAYhm!j zKNFZPaDQJexpd!RbSJ4Z&UI<<2uUjb41Z#dJ72|`UR;{d&ZQQkL%8;Ulk-FATpC^P z$Dml;+(%Bqtv*|Wh!ZLqIDc!qg`;U0R7Hp~(vD?qwT5%oB=l9$ zmt+}eva-;{e>Bt7pHP0i^)WL0y^O5eod&7(Vz*?wzit6k?8pKHkPk%}vlHDV=_kf( zzcCJ2SOI=p6#OYt3KNxQ8Z@^3%;ii|3z}juum}l;2=mQg@Gfx`DqL+-29qCTo4>X; z!v4adZzE_eNYECpBao%xt@f8bNdrLiy!Le0ecROkj|2n-FG@Xu(s>FvlX89nSBTU( zW@O>A;HmR|S=CZ{&u&Xd(SS#?h|)Nk9DUx{QOT2^3Kcru+6WS#gkR}uHT9me(ZQMz sNyWKrlF48s0-I2p0lH=c6jn^uJk+OFg{xC6(t$xV6<>>GRa9?@LtC%t$LR(ZAA zHR^AbPk+n>eLI|Hc6_Eqm9ucEDjocCtj7rNwk?bczV5;U1(f4}qT6ibrNaXl+%^Uh z=4yA{2oVk|x;Zc1bQ7`3HkjF0!m%G=;EaI9KS^}lU@3~b+z?w|Vt6dyvSM%hw*lz-=5P`rjWXZB9t^;{bln;3D>GIWU2 z3i#3ykhl4PW|^2`VMEa)I!{0WrB{5asdm+=br+GkD&t&5(Uc!N@B3Y`} zQ%3@;MWCkm;YLHMOC+sK5`e7W`mY+tjpG*T(d1)9oH|4QKeU3K`<0~kb8w{#SGM2| zVON9Yt3iLSK{c|yn22zUyU6#(y>S?5g@0yn@?>~v_eAz=Z-vr`V3}ZF&i6q^0uSB) zhN4FmUuDb}`B;~Rr2aAb`5A`6P`)Ah>fPsniJz*DrUJ9BS%LIrkTU@6cQKxq%cX)K z)2qiY>YpqOl0rhX8)Om07)u@v!ZnTY1feJPW&4P_VAbJ77GY#j%xIGEDC4uAWq)!5 zG7q3O-LP{GCoKdCntB%gSPdOsDP2Y!m(3X7TkPEGw4TVJiG1gL=9M4RHquX~RN8Ml zse7Io6IFR?I)vOdB4<((li~OZ==_)50-w5%F^xPdsR*vL0+YA)TqK zF{y=D{M?h~3)lypx`#h&WYi>&taKNXx_em->9-ads0b8r)s9cw zVU&QLL(#0CgEwL$e{~nVce!-OImMHXrtdAVkIdJ4n{q%;KGa`%ETXlI#a+D>rQQ0G zB}1dMlC!;6-=IX#CqE9Tkp_j{mwX6Mq_pfMp&j zEt)Lxw1#j?0q!2cR)dnGOueP z2*2lh-vVHkM=rY~9mD5y?5m(alybhPbnK5uIPi%AxY`Ht13}lqm6AOBOcVRia|MIq z+o0|7b7xQ`x0ijz3Z&ij158Ok%5L7k^#e8leXRJp{piUL<&F{=1Myliq{M-zuF1X4 z%Z*%{()}hNt>EhiX~+OVML$OR9;UvtZ^=;7!y%%VDm~>UNkIc7@92}@1XK`Ww(*Oa ze{{_=d+^0!+I)GDdm(=lfry}TR?vVkL^%jUFvpn$f&|c#>bq`Y->E3I4-&!MJSTQ( z96MPlzcbI1`>p<1c&-i{ojGN?Zr3KZ$I?|m0;RJ#N+<31+bqSMX$l{R0j(zy>}OtL z4=5I|uooh#l01MV%BHPi+%X*$ds;swXo^BzNf_)$-qrLz{l^tbzt* z2luXvotWYt$YmYM!D*+u+mCiNLfc=et4L1_LL{h$XT(_ap#MeUw(PJkME^Zhtgk5j z&ScEH5_viqp}v1w$`>41S-Wx5BpLh}CbtJX4pS)6;arFz3~)%s zKd0M(UY}V~ztYj!!dU@W&ZEZJ#0P&>R=%&W&cP$LPj6cmgv_ew zsMt?-YABP;R@}k*7z+H|SnN_(^$hMpK2nFsdD;D7o&E>U9TQw;2S1-4^QGAacgu(Z3PSwvr%Le>9GV296CeZPM&LnhQIJA4Im_xcp-Jh_ybFa zyG4{#wiN>bl;lL&>xt&mZw(PA0r%>Az6d)}nmTLZ{f*v|>l;9+qQXzte=6h`C zrgcOnxWQN2;4aTYwbSVmcAQ*)FPotF^;ew;F(oh~1_>&LNQUST;p2MQ$gc~q(Ys-ir*G8R>q0^;<_5@Xnx7pRS&kL5FZRk9~ggD{_4qbT&gZ(aGFS z>8t+~)fAoXF$H?D1lm6=3*rbn=veEzA69x`Arg@rhixd>a8VfvZwfrp{ft(ew9Dh0 z(?7LQp?{1Ya?`g4!F7~_-2^o*yu8!$Ud)N^>&sE!;vIo%PzMV01x0rOP3G4LHHB#- z^+xtAz-0(=*GSa-pD;tQ1U{YJ2OMeq%ihhCbd7urnOf4-}lPG6XA^tD@ z)i221NAh@O1K$7V9d{w?LPprf-LgW_>(N{-Yy|n8NByyw&o~a93!|=0V4pte`JL0X z!{+mKs8FNh8m_rIZr#EVAlEZih2aeu`e^3Fvt@=H(g`lv591F}*#hRzT?dHb=LQv~ zR)6CP)))0t+(Jh%sr%Dv!7(hrVYw|_jLzO)rm?+xy&N9}Yi8idV`+)s5sdUiS}g`# zqor*Qe~z#fUx@vOgu3=c=uMI!7hyYDPVH?jWG^A#9;05jo*}FmMKypNW>hY}H>jXp zeygaZu#$DL0OJBQv)+LZD!sgQ#OFO(p?^AzszMSF7MrU}8;>*9+cRVHTGr#z>UM8z z!sl6>n0pV^%}`qyakmayrXn|S+)%_g?VWyl>t)1b`L(!hYUc_dA=uZuc@Q9DSE^bJ z7%G66pBXk~G${x4s*Fs+NZ;?7w-e3Rr`iKK zs80s8_Q&DJFCcf|?S|pq6pLfpS_j~;%hEl+66B0ZQJi_*asfbUwik^K;>aU$!%@g2 zxJYKxpkj5k3a3OJSRnudZ0OHfQh%)R1y%gb$&h^iMK7P~4?Kzoh;X}cYd^VDK5Rq~ z7n-nUrb8uYHWV&5{D2K-g5RJm9ZtgI{U#_x3Uoz6sR58Rb*a8fUyq4`?ZqrwPx_R+ zy>Jjth0mMvX0{0T$T~Ft-YU z41Bg>yX6ox20>(c!w>ahrEypb4wVBhxFU}>dB5qr_rP&w=g8IfFqy0vJ29)h+dsbD z&g8uP?$7EYbxeG#ojt1rEG5>G#+Voss4Nh!ximRN8K(?TOczPhas@W=ozb2)?L7c{ z*4i}>f>||4N>L~zL1Ubm<4oi$W2!E)B{iZo9&2Fp9wNMnxYBWj2#35K>xq0YUZCWv z*PSgvp_Na*#Wt4!w8H`&k+WoHg~bQ?ifhRwPggff0Wakg5sU%e$fJ|s1XK{O^*7Ne zu(<6^<@Lt)4$K6Rdm(@Q6BogK`vEP2&I&wR2(4WNf&|b)>de65mmnOMd1o!4h@$=M z#%W@Czn0BGZhjO)2cPID!1xng>8Omlx(+N0?_>{m>%nSWl3=fCF&wPE5YTFC=`B8O z2Y-s4oHHjZ7y|(Tc1vcYKn|`QEZ|BD8Fip70zR153drvsK|X&JL2k@efAX4n!GtA@ zhtqD!I|C12W*qW|l1~hpO!wwM4gOTPBX-fjgR6FLMdwN40tP5`CWYDwJ|$pj5T|U! zt;MGs)XSt=$M|b1S2JAA<=3`ItRt&%c!l{BJ&p5c?Dqu2LH(0pu1lM5{8?<^aHPv> zfk7~y%Cz4Ddgy=p<4tM+d=oFC^}!>wCnAvN53qsywF8C62>{M!)E>;1t2JO(iOFxO zo8Z&jV@&oC{o#9XOZYos)0L*%OFP=cpZPfC#GN5ZEG(}v4~dzBRkgLx84+H=GY7r5 zj*>C=cs{ffec>avYEiB!jDJ7zn7ESt)J8uKvKYWMFS&o`Fau;PG&1DvVh$zQL#ZZ0 zM6`}rZSm*nCB1sD-Zak$staLF=@x}KQILeUege(2tDnt77SK>EDtV|+n}Ar&UDCWZnn9v zCc-E^f|q^tJ-`(#t`J8dB$~;++4v4}z{l@$tbw#xhD2?Z0G&=N|h4n$-|LbO})f80A-k{j~tubQzES ztYb}W(~@Iv8Iw?%ZFz&ER(7hZNQKB5@Z`3~KtPk`PYG*p?r~JruVSS)j60e!<&!JP zj4i*RuDatS6HwL!x!*t^z#jKM0Q46)Lf5RgM`x>`HTac`G6Lk>e$evr0TCXxV0|o) zTxown=2(0K+%AA?h%sU>W%=Cr3QZ8*Tn(D1f^10o3vQ#EZ=*|75T>c1ok;TBWv>(v z22BfT#oSvAa|Pd+pDjEBEk+uCA;g%KHLv+gw9#Gp&U1KOr$&Wev}Eo)Sx)|ty@G9B zsOR>79zG9^6)4^KKP~yOon(|&>0Q(TcTj&(QmDFxqlYY1fK!Rlp@0au2 zwt7A%eR?bk+FBowK~WyPJEGhf;SS}z@sBJO9pTTeFn+@Izo6vFuAo6Jqf!3e@5Fyp zqy~i$-rs<0E?r7QhiiI@TAhC0Epxlfg6Zc9hez;JJ`z`h)!S!=g--OcoU#MkA$agR zuzAc2zyH7VmB`6nf9otMQ-k^@6Qb_iB(2K!rcHb%Qp^zH_F@j1`61~x5-6yQPd|3c zB>!WcZzXEP87RF60^>La-w{z|j>LbqI^`f4w3UGOlPocZht)mRdk@LsjUdV zT&LNQU|bNGa~7G(L~oJwpZY^p8S!2B!AGbc8{PYdD%cp;~Gi5 z=*)nE1b`R-kKWWL`MbhjTdX>6r$bGVtTRsRd2O2fpVZhQCbGFsj9WZ5jPz7`^tG;q z^FKv5{V7sf4wBd7__g>v)fZCzh8Q3a4B3J$ZMdw_?ngt(LMGO?VJRez#!the@{fIq7`^~Ld4=`NXv+toa z+a&k_FGW7fM?-S+yvY9k?LqBX4aG+#w-K&^O}W5BcJo z2oBX}{(@=j@Kk+bq(;zdVyb>!7Fl$`eSZP6roDj!V1GNr(9oF04bFmSUoi$xOdB@CzIYOv0*Da}1@RR>F8jZ{vntQg-@Zy`XPb z-#Z*7K!2&Ya>r1afdwU{)9T(+*IgeMnK$#JUM+n_%1WWfKiEADr^3JmvjJVVIJ?B! z?Y+cujS&jSR|VCWH#8>dm{)rbUd;1rUzEWV<}>@tihL zntB9;O=1k{J^6+48bc!<=EnfWbEuCy1GsQHW^v>XNudREk|)-5yAK{0QDd=oD8mG) z?K8vX!lICHS2)%iFEIL24^iANpKXH0@| zSARY{->aw`uT;nO3nDI%%CY|K=B*4C$4p{hMUWj(d$&p%%x%J_*s~9x=S5`A>W8gx0GVa~l!!$q2u`P$~x* zf5;k+XcULV7btxJ(xJ$iWpX`8Z$T{J=YOQvtNTOJna-;R|OFvE$h2c{+nHB2}j$T})pQn@*g58_%ip4->c2Gijk1co+Lvk-a@~O~4NPo!q zkMBaU_-Bd%bQJ{YMac|cscT5Hh*)ysE0;^}`IZY%6rEeA^j$OY4-ZstupV1D)0271 z$T^}AG%2|$H{**Pw@-9w^g6n>uEfex-Dm3io;R#zJM$B%1Z&qko}e%D}Jq zwIMV!g;A*UMQrdeVpX>|)9*F6y_sBPRv~3>f>tD?;O>sr4&L@&MLYj@-E0bvMVNyH z8U8tn+-Ud-_VZ1tgWoO)xPq4F(BdhDZTr0|WvA1povf=6RV9+1>)x z?+8o$7JbvH8rC&d0)RL8i%wgb4Ki@S1QfCcn;j^(Q>d?UVR~l!Y6ai)ZQud|ClH3` Bb@2cI delta 1291 zcmV+m1@!uc3x*4jYZUoMKp~g*fIrBpKk^$Ifgz8OCuEU-B!4g#hz3y24=Ag+TUGhp9b!PH{ep>xRj$W0pJGU)2!)tpe={o}kdBta#G3 zk+6z6wUN|+xSdRx>PfCEemCYFWm+>DgLgwyB_juyp%{bglpVx1lz5Q5KCaCzJslI2 z@s{uyvDb8hdVhZ5`oi8k=k{l(6eG(uXinoMaeVAt&>;okM1!w@H(QFfju-&P)&pC(4U59s+?Tb^5EiJ>KDL5E#TXAV=;~iGKg@bD z@suxe)O^0zUpw-23w$rH7LS;*TC4G=?%J!WmP0sXG!tizspdGEJ6Z)^Il^$$ai9%& zSkt7JzJG$D+_&f|HHj-4f#SEANVaRMAZX5Nf2%p46K;QD)BMQ$CuIV{&@ol%TM&!G0b~D#L1Dpgv4k7j$7~H&MmbZ)hO~~@Sa9>dYCaTr?no}`PGa-nY+5Zr zKQ!xEEVx3p>iZ&#_q=StK@|(rX4-RJB-wU;ihrARg$YY&2*5Ne*FQ@8>O#slP*l0+ zte`wl3y>pU9606AGzz{n2iSAev}1J|E4LgjUij-^@>{VHfXB`dd3wBJ2u|u<_sJ(x z{N3nV`n2-N$*Q9@8nJDSvvk!o{_7KHqpvCE%n+qTD;uUb| zM}M76B5MB+(0AqT&)kb9>(JK+=4U zfCSpWbQ5hdKqAEqyge4FCi%Oswt(o2OLNCv;zXl-3gZ8sQTL3h;CnW;e*`~_&`4P9 zG*4JkfK3ByJHz@mV%=oyQrU5MkRL@za%4~&-J`uqh-_XNWarYZj{v>rLw@!P1%FZd zcYgV$E~+gwv;k%YF(#|)`cCTrOAw5NPAof$I*CGSS$SM9tXvd_3ev=X%ra~+p&N6# zjt1est6JHjnctXpbjC(CS=lOiYgyangEp~hy(MW@cpYH5L?c5qqSZ;cePDfHZ6pt0 zZk(CuWDHJE(N?W}jQ{h@&Z7R}W`8kMHZp(+&Y#JLT*C+96%HuprMSvaiCJkO*oE~B zV!S0qul};t$Vz6Yh|Vl%tsaBaT|V|=M>1D%;k{8t^cE==t!KKprbndZf9j@yOU)aK z#Z%V}#)v(aG2sd75Tx>&>p{g%E=jrqiYve~3wprggsa3&&!VZJ036QM#BA^ckX2*8 z*1jz?IA=u#u@faJsUQZPD~NEfMe_SFO)xPq4F(BdhDZTr0|WvA1povfVKzI~YgvMD zcRT$;fp*Pl`Y0#gGNcHS@A0|5c7DXu1QekheJJx@-3)a2&kzKE*{KpO&qV?PClJ16 Bafbi^ From f6824e954bf187b655d18e6435fcf5e85c45ada5 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 22:35:46 -0600 Subject: [PATCH 095/215] Ci/CD update --- tests/assets/call_gen.sh | 2 +- tests/assets/call_gen_tls.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/assets/call_gen.sh b/tests/assets/call_gen.sh index f89dd648..da5596ea 100755 --- a/tests/assets/call_gen.sh +++ b/tests/assets/call_gen.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 127.0.0.1 + --host 0.0.0.0 diff --git a/tests/assets/call_gen_tls.sh b/tests/assets/call_gen_tls.sh index 9bc0f270..aec49e02 100755 --- a/tests/assets/call_gen_tls.sh +++ b/tests/assets/call_gen_tls.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 127.0.0.1 + --host 0.0.0.0 From 6ff0b66931689f97bc74683276353fa2952c7281 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 22:37:25 -0600 Subject: [PATCH 096/215] Update call_gen_normal.sh --- tests/assets/call_gen_normal.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/assets/call_gen_normal.sh b/tests/assets/call_gen_normal.sh index b5aeecb1..61cd71aa 100755 --- a/tests/assets/call_gen_normal.sh +++ b/tests/assets/call_gen_normal.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 0.0.0.0 + --host localhost From 70a1761b894edaf5178190c0a813d56c5449564a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 22:42:34 -0600 Subject: [PATCH 097/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 40 ++------------------------ 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index cc163424..0f679d0b 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -64,7 +64,7 @@ jobs: docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - sleep 10 + sleep 40 docker ps python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 @@ -118,10 +118,6 @@ jobs: - name: Create .rnd file if it doesn't exist run: touch $HOME/.rnd - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - - name: create config run: | assets/call_gen_tls.sh @@ -140,22 +136,7 @@ jobs: docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - sleep 1 - docker logs aerospike-proximus - - sleep 1 - docker logs aerospike-proximus - - sleep 1 - docker logs aerospike-proximus - - sleep 1 - docker logs aerospike-proximus - - sleep 1 - docker logs aerospike-proximus - - sleep 10 + sleep 40 docker ps python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt -vs @@ -227,22 +208,7 @@ jobs: docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - sleep 1 - docker logs aerospike-proximus - - sleep 1 - docker logs aerospike-proximus - - sleep 1 - docker logs aerospike-proximus - - sleep 1 - docker logs aerospike-proximus - - sleep 1 - docker logs aerospike-proximus - - sleep 10 + sleep 40 docker ps echo " From 739c70b9e0c71f6021850e5efb544727bc4931cc Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 22:46:21 -0600 Subject: [PATCH 098/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 0f679d0b..df3ee498 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -223,5 +223,6 @@ jobs: python -m pytest rbac/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs - + docker logs aerospike-proximus + working-directory: tests \ No newline at end of file From f7da12543f05a0378858d2576834fca5e7ce15d9 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 22:51:33 -0600 Subject: [PATCH 099/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index df3ee498..e410584f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -223,6 +223,7 @@ jobs: python -m pytest rbac/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + docker ps docker logs aerospike-proximus - + working-directory: tests \ No newline at end of file From 488438523357e25d57d91d80f35b60de20f37d0e Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 22:55:32 -0600 Subject: [PATCH 100/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index e410584f..ff5c24a6 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -67,7 +67,7 @@ jobs: sleep 40 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 + python -m pytest standard/sync -s --host localhost --port 5000 working-directory: tests test-tls: From 40a05ab108a0269dd25d52d1c6f0f0595d641b75 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 22:58:55 -0600 Subject: [PATCH 101/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index ff5c24a6..691acf36 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -194,7 +194,7 @@ jobs: - name: Add hosts to /etc/hosts run: | - sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + #sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - name: create config run: | From 4e206341cc92bbca3bed7b26321d93d0c1b8b25c Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 23:13:57 -0600 Subject: [PATCH 102/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 691acf36..e410584f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -67,7 +67,7 @@ jobs: sleep 40 docker ps - python -m pytest standard/sync -s --host localhost --port 5000 + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 working-directory: tests test-tls: @@ -194,7 +194,7 @@ jobs: - name: Add hosts to /etc/hosts run: | - #sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - name: create config run: | From 6ce99a73c137153f636d366957891f36f90d1db8 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 23:41:29 -0600 Subject: [PATCH 103/215] Update aerospike-proximus.yml --- tests/assets/aerospike-proximus.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/assets/aerospike-proximus.yml b/tests/assets/aerospike-proximus.yml index 0b6fe595..37d4333f 100755 --- a/tests/assets/aerospike-proximus.yml +++ b/tests/assets/aerospike-proximus.yml @@ -51,7 +51,7 @@ service: ports: 5000: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -68,7 +68,7 @@ manage: ports: 5040: addresses: - localhost + 0.0.0.0 # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -81,14 +81,14 @@ interconnect: ports: 5001: addresses: - localhost + 0.0.0.0 # If interconnect TLS needs to be enabled. #tls-id: interconnect-tls #heartbeat: # # Seed nodes to discover and form a cluster. # seeds: -# - address: localhost +# - address: 0.0.0.0 # port: 6001 # To enable client authentication @@ -102,7 +102,7 @@ interconnect: # Target Aerospike cluster aerospike: seeds: - - localhost: + - 0.0.0.0: port: 3000 client-policy: From d25cdaffe8156af4ead0da77b29c16df8141f75d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 11 Jul 2024 23:47:20 -0600 Subject: [PATCH 104/215] CI/CD changes --- .github/workflows/integration_test.yml | 2 +- tests/assets/aerospike-proximus.yml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index e410584f..11de4b4f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -67,7 +67,7 @@ jobs: sleep 40 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 + python -m pytest standard/sync -s --host 127.0.0.1 --port 5000 working-directory: tests test-tls: diff --git a/tests/assets/aerospike-proximus.yml b/tests/assets/aerospike-proximus.yml index 37d4333f..0b6fe595 100755 --- a/tests/assets/aerospike-proximus.yml +++ b/tests/assets/aerospike-proximus.yml @@ -51,7 +51,7 @@ service: ports: 5000: addresses: - 0.0.0.0 + localhost # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -68,7 +68,7 @@ manage: ports: 5040: addresses: - 0.0.0.0 + localhost # If TLS needs to be enabled, tls configuration id. #tls-id: service-tls @@ -81,14 +81,14 @@ interconnect: ports: 5001: addresses: - 0.0.0.0 + localhost # If interconnect TLS needs to be enabled. #tls-id: interconnect-tls #heartbeat: # # Seed nodes to discover and form a cluster. # seeds: -# - address: 0.0.0.0 +# - address: localhost # port: 6001 # To enable client authentication @@ -102,7 +102,7 @@ interconnect: # Target Aerospike cluster aerospike: seeds: - - 0.0.0.0: + - localhost: port: 3000 client-policy: From 2690853ac4e8c8603b148c54964ca339f639f02c Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 00:13:25 -0600 Subject: [PATCH 105/215] CI/CD update --- .github/workflows/integration_test.yml | 2 +- tests/assets/call_gen.sh | 2 +- tests/assets/call_gen_normal.sh | 2 +- tests/assets/call_gen_tls.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 11de4b4f..e410584f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -67,7 +67,7 @@ jobs: sleep 40 docker ps - python -m pytest standard/sync -s --host 127.0.0.1 --port 5000 + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 working-directory: tests test-tls: diff --git a/tests/assets/call_gen.sh b/tests/assets/call_gen.sh index da5596ea..f89dd648 100755 --- a/tests/assets/call_gen.sh +++ b/tests/assets/call_gen.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 0.0.0.0 + --host 127.0.0.1 diff --git a/tests/assets/call_gen_normal.sh b/tests/assets/call_gen_normal.sh index 61cd71aa..c7e16289 100755 --- a/tests/assets/call_gen_normal.sh +++ b/tests/assets/call_gen_normal.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host localhost + --host 127.0.0.1 diff --git a/tests/assets/call_gen_tls.sh b/tests/assets/call_gen_tls.sh index aec49e02..9bc0f270 100755 --- a/tests/assets/call_gen_tls.sh +++ b/tests/assets/call_gen_tls.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 0.0.0.0 + --host 127.0.0.1 From 242933f8c642637744fc624c3cfb79e2aadb781f Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 00:41:19 -0600 Subject: [PATCH 106/215] Ci?CD --- .github/workflows/integration_test.yml | 4 +- tests/aerospike-proximus.yml | 51 +++++++++++++------------ tests/tls/brawn.crt | 23 ----------- tests/tls/brawn.csr | 17 --------- tests/tls/brawn.key | 28 -------------- tests/tls/brawn.key.encrypted.pem | 30 --------------- tests/tls/brawn.key.pem | 28 -------------- tests/tls/brawn.keystore.jks | Bin 2798 -> 0 bytes tests/tls/brawn.p12 | Bin 2739 -> 0 bytes tests/tls/jwt/private_key.pem | 28 -------------- tests/tls/jwt/public_key.pem | 9 ----- tests/tls/keypass | 1 - tests/tls/root.cert.pem | 25 ------------ tests/tls/root.crt | 24 ------------ tests/tls/root.key | 28 -------------- tests/tls/root.key.pem | 28 -------------- tests/tls/root.srl | 1 - tests/tls/root.truststore.jks | Bin 1414 -> 0 bytes tests/tls/storepass | 1 - 19 files changed, 28 insertions(+), 298 deletions(-) delete mode 100644 tests/tls/brawn.crt delete mode 100644 tests/tls/brawn.csr delete mode 100644 tests/tls/brawn.key delete mode 100644 tests/tls/brawn.key.encrypted.pem delete mode 100644 tests/tls/brawn.key.pem delete mode 100644 tests/tls/brawn.keystore.jks delete mode 100755 tests/tls/brawn.p12 delete mode 100755 tests/tls/jwt/private_key.pem delete mode 100755 tests/tls/jwt/public_key.pem delete mode 100755 tests/tls/keypass delete mode 100644 tests/tls/root.cert.pem delete mode 100644 tests/tls/root.crt delete mode 100644 tests/tls/root.key delete mode 100644 tests/tls/root.key.pem delete mode 100644 tests/tls/root.srl delete mode 100644 tests/tls/root.truststore.jks delete mode 100755 tests/tls/storepass diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index e410584f..c9ac1561 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -50,7 +50,7 @@ jobs: - name: create config run: | - assets/call_gen_normal.sh + #assets/call_gen_normal.sh cat aerospike-proximus.yml cat aerospike.conf cat /etc/hosts @@ -198,7 +198,7 @@ jobs: - name: create config run: | - #assets/call_gen.sh + assets/call_gen.sh cat /etc/hosts working-directory: tests diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-proximus.yml index 450eee96..0b6fe595 100755 --- a/tests/aerospike-proximus.yml +++ b/tests/aerospike-proximus.yml @@ -12,19 +12,19 @@ cluster: # If TLS is desired, TLS configuration ids used # and associated TLS configurations. # -tls: - service-tls: - trust-store: - store-file: /etc/aerospike-proximus/tls/root.truststore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass - key-store: - store-file: /etc/aerospike-proximus/tls/brawn.keystore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass - key-password-file: /etc/aerospike-proximus/tls/keypass - mutual-auth: true - # Client certificate subject names that are allowed - allowed-peer-names: - - brawn +#tls: +# service-tls: +# trust-store: +# store-file: /etc/aerospike-proximus/tls/$root_certificate_name.truststore.jks +# store-password-file: /etc/aerospike-proximus/tls/storepass +# key-store: +# store-file: /etc/aerospike-proximus/tls/$server_name.keystore.jks +# store-password-file: /etc/aerospike-proximus/tls/storepass +# key-password-file: /etc/aerospike-proximus/tls/keypass +# mutual-auth: true +# # Client certificate subject names that are allowed +# allowed-peer-names: +# - $client_name # interconnect-tls: # trust-store: # store-file: tls/ca.aerospike.com.truststore.jks @@ -53,15 +53,16 @@ service: addresses: localhost # If TLS needs to be enabled, tls configuration id. - tls-id: service-tls + #tls-id: service-tls # Required when running behind NAT - advertised-listeners: - default: - # List of externally accessible addresses and - # ports for this Proximus instance. - - address: brawn - port: 5000 + #advertised-listeners: + # default: + # # List of externally accessible addresses and + # # ports for this Proximus instance. + # - address: $server_name + # port: 5000 + # Management API listening ports, TLS and network interface. manage: ports: @@ -92,11 +93,11 @@ interconnect: # To enable client authentication -security: - auth-token: - private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem - public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem - token-expiry: 300_000 +#security: +# auth-token: +# private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem +# public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem +# token-expiry: 300_000 # Target Aerospike cluster aerospike: diff --git a/tests/tls/brawn.crt b/tests/tls/brawn.crt deleted file mode 100644 index 979c66f2..00000000 --- a/tests/tls/brawn.crt +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDyTCCArGgAwIBAgIUNx1xRTf5B6XcaAwZG0UJAvcIjBEwDQYJKoZIhvcNAQEL -BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm -aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG -A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p -QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTk0MjIzWhcNMzQwNzA5MTk0MjIzWjBE -MQswCQYDVQQGEwJJTjELMAkGA1UECAwCS0ExGDAWBgNVBAoMD0Flcm9zcGlrZSwg -SW5jLjEOMAwGA1UEAwwFYnJhd24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCua5cMw1r9R77OPdhT7UHJcF03ml9AIigvbkZgM4F/ptXClUe8/JUh2MwC -uGnTTMY9P6y76nRi1zSwBmEeZFmcAzVg97PpjCAo5gQGaAKJO+Y2sqMJCk0c8asm -1IZZ0oLTzO7TIQCdeXzgy1Duxp3tz2E/R1HdN+YI/HJ9DfvQPSCbB16BS1eHfeGF -yK5/+uzbFFwaM2S8D62AnePZiWN0Kp3QPIFE5/nMg0FC5//o+9gHVXvpZYjBIt8p -qzscI3Hsw4YiV2EXs98hl7W5iIYOk+8T+2vYQTyc9DbiImOtpQp07c1iU0JHiLQb -6arCZIkcS+1Le7xV0if5pAkhXu1XAgMBAAGjXTBbMBkGA1UdEQQSMBCCBWJyYXdu -ggcqLmJyYXduMB0GA1UdDgQWBBRDjmJl2agIF13hscD6hK7aOEaYczAfBgNVHSME -GDAWgBQXhDBm81fmfqqhlFxKPVzT5Kan5DANBgkqhkiG9w0BAQsFAAOCAQEAI93K -kKCE8tAwrK4TICggTG7BpF0LXd5CsCV1Xfr2jaDCGjuFc9NTQg0R8xAfSxn4vBRQ -rYoiRio0uDuEiImw41ioLX6eNpEcaFvc9LZXJ/F9lZEoVirb1xx+kgUmN4q3ygKx -Jyid/Z3PlHv2czbsT3mpXignXALzHq3Jilbqojy0NyNKtaq3J9g4YDVyXUmI+HC4 -i15/xfTEoT+vO2by2rTu51v8a98zGf5+QXJnR0pIwFWK4SeDepEkGbAsRb0fCMcb -PAdf/DKxqZL0F7s4MMktcbCJ/PY67SH8BJcftNxzF8zw+Iq9s4OAkBBArMLb6Qlv -M9pQCVSzVjT9Gck6dQ== ------END CERTIFICATE----- diff --git a/tests/tls/brawn.csr b/tests/tls/brawn.csr deleted file mode 100644 index a7f12a37..00000000 --- a/tests/tls/brawn.csr +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICtTCCAZ0CAQAwRDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMRgwFgYDVQQK -DA9BZXJvc3Bpa2UsIEluYy4xDjAMBgNVBAMMBWJyYXduMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEArmuXDMNa/Ue+zj3YU+1ByXBdN5pfQCIoL25GYDOB -f6bVwpVHvPyVIdjMArhp00zGPT+su+p0Ytc0sAZhHmRZnAM1YPez6YwgKOYEBmgC -iTvmNrKjCQpNHPGrJtSGWdKC08zu0yEAnXl84MtQ7sad7c9hP0dR3TfmCPxyfQ37 -0D0gmwdegUtXh33hhciuf/rs2xRcGjNkvA+tgJ3j2YljdCqd0DyBROf5zINBQuf/ -6PvYB1V76WWIwSLfKas7HCNx7MOGIldhF7PfIZe1uYiGDpPvE/tr2EE8nPQ24iJj -raUKdO3NYlNCR4i0G+mqwmSJHEvtS3u8VdIn+aQJIV7tVwIDAQABoCwwKgYJKoZI -hvcNAQkOMR0wGzAZBgNVHREEEjAQggVicmF3boIHKi5icmF3bjANBgkqhkiG9w0B -AQsFAAOCAQEAntwEzWrsB5puHs6LqCyXwihdmBsiuTqbTVW/P/3wYoGWw+lNa1O5 -z5h+4qI1iG97Ojr+whwl4vxFM6NuAat/bON0Sz5ZSUDbqMvJBzjbYkxIyKx505dj -ZfNOSoxe56A6+lQpT/cWhgPrZrJCQNqn/ioOp2kbT0LxPtXPzZWWV93/n6TxUKFt -52YKouPnArv6tWI0Faq99f4aCJsfEB4IMpMZbiHZ0XJi8ngVoMifcCQjL2hUlKfd -Vs17bgkH22+wFMg1J14WPOAIa3VxASHLi/+WLkCclCdUpiYrzvQLaYCXG7G0JvRk -5xc5EH7mQpiKifG4QGfdxaZ1oz1vLYs/Aw== ------END CERTIFICATE REQUEST----- diff --git a/tests/tls/brawn.key b/tests/tls/brawn.key deleted file mode 100644 index 157c6338..00000000 --- a/tests/tls/brawn.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCua5cMw1r9R77O -PdhT7UHJcF03ml9AIigvbkZgM4F/ptXClUe8/JUh2MwCuGnTTMY9P6y76nRi1zSw -BmEeZFmcAzVg97PpjCAo5gQGaAKJO+Y2sqMJCk0c8asm1IZZ0oLTzO7TIQCdeXzg -y1Duxp3tz2E/R1HdN+YI/HJ9DfvQPSCbB16BS1eHfeGFyK5/+uzbFFwaM2S8D62A -nePZiWN0Kp3QPIFE5/nMg0FC5//o+9gHVXvpZYjBIt8pqzscI3Hsw4YiV2EXs98h -l7W5iIYOk+8T+2vYQTyc9DbiImOtpQp07c1iU0JHiLQb6arCZIkcS+1Le7xV0if5 -pAkhXu1XAgMBAAECggEAAcGE3VSyJnlI4HhwQN8omblywXaMK9OPwqxCM1cRZ1mW -Z4ykS5RT1c1lmw69HKrLpQHDxBT8Y9wgHTg2xvmM/IHDwyO0JKSoRjoFP+iYJtSl -i4/em96wrdPqyr2Bb2ry5qvaKP5q82PKYdSGnLmp1AbY44/AeFgcYzFwUS7eolcl -IXEApih+91OnEfOZgSQyaqCnwN/RE1ykESKRYQFgL6qxC0jhJpg4q5iqsfyXkfsj -v3JpfqY3xB3hmsAqdYT5Lr9Fc2OgEDuddAI/djfqEv4nbPacN1pygK7pZlM53xja -crThLUq2NFpiWQv2B7eDJoUoSTYb1zo57USqeEPBsQKBgQDxQuOZQSwttRmqVCU/ -IcdkbsuQFhNhBhFQMRDw+bjm5pCr8gyMK0vmQItv2e6q/vPK9L2tUX5bkwM4eSr7 -9zioiis4RKQ8TPuREbgfmJMjRSg002xDijM8b3wmCVQ1XJykPAKGXTR2Oud1Kxiv -SSo49YFBQf8we8/RSHfkcaA38wKBgQC5E14F5kNJRroG+cOMkbT0ZpvbB3tuhEQV -OloMpgKNOJamsISiGP21deSmN3/BP4yYyX+63gdZdLSrL8VcPNlbCkwtcrWDAP5a -y/VZEs0XgYHltPK4UEw5bEuKuCRqShzAlXCgHANQggLsuyaz3CHVcRV16uVq/7/X -yyeWvr8SDQKBgQCVB6+WBJcoqNzwxUe4xsHnfTVLjQdtgJUDRzvizy9zmms1e7Ba -iYg59BbuAd4XTKQF88aTIGsAYEC2CssNl/osyiTGfkhBY4BmbV6iTdpeCCM89njD -A8SAiZFT4aFd0RaFsPgSTdLRUbOWQgfeh0CIrMaqK/1Z0rFd4vkEaVgCFwKBgBiG -BHNrq4bOJGBAQDUkKYIpBoXjW+utAwh9DumWJchosy2rPifsf9HHqWCNAhStQwgL -yy0LtpWX7Uixr8klFvgFSUrMZFjTjOCjHgOLhjmTI484huD9YtxJCUl8VPbwkxbB -tobAr3+/enu74Mj8Zk9OCLXzRisDcHw7oydKZy8RAoGAcfbntj+ZVc8z5oi79O+v -fpD/G9FbvZe/qKSO5cwTS0z1QFF8rQuzelzNXlIGlNpZyz8uxv7qN5X5C9wla7cm -Uz68d6+f0yEa16mhS0rKYeUDEioVjks7Td4/FrIF0EQZZGpfNLgQukK6RTpt8eBo -dDFoxdCwl/KU94yPu3autIk= ------END PRIVATE KEY----- diff --git a/tests/tls/brawn.key.encrypted.pem b/tests/tls/brawn.key.encrypted.pem deleted file mode 100644 index ccb36c7c..00000000 --- a/tests/tls/brawn.key.encrypted.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQAklzLuIjE11tj/Aj -vNMITQICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEPnLC+VcvZc21rhT -F16LiaMEggTQOFddAvabx1JdMqAMRPec37AmobrnZ7SMcZJIYjQacWursUpuWOLx -VJ+sMftc5GxpkaKbnrhI+W8Iv3zum32Rz18ZUWXgIkxHLmI2kZOlw37oOQPpbB30 -jzL5i5lxHKCU360VFGFm17+2C/+GNpexXbbPdGCy9m5I3XbgyHdvCIGo7A9EiLhX -Raq2gdbXnrfJXSnLhXclMA2+baVYIaAhh6f+3be2v/md2T6rVyP0USRCtO8pq3+e -tBolgDTLfmXDzmHMtENC5/4TNqmi0zZAnQeKl1uknxj7sqTKVkZsoM0yMKJNhpwx -OnG54xGTAQ7utBU0Xq0/Qxs6gY6SRplySkcqZfNZUbIWxZq5pBCVHyLVCwdNqkDl -JFyEo+s9Krzslu8uxGrmj9BV19bKti9Z78LHbiqD+BjPVKmCkTzS7HRdC0WsF32E -GgkowKY2BEtFynlDMMI6XJZE90+TTcXD+u/+c8H9w86YgvCnhyG0B/UJ5fMpan/6 -aWK6Tm+TWK1qcQF5eV9dwdHW9LgPi1n91a31JLh3EOi9/fjJ/OzE5IOZTv20YFPV -Thb12QLQr0Iism1zvCjmFpwcL2SQI5ttUSDGxn/YaTGsuaHAOSeFpU7AnBmxtdYL -6YskDHCHuT/8kU2ajIPYGWBDca8ROVl2mQKCOGPsyZ87GnSzH63CRhLqWaZf5M01 -9xnpXh8F/iq7Ywz5Gb1Co9v4fCUkvBppXYyVAXRuYdmACLAeX9yDgXjRj2olKUqS -wSWp2YyVaOjEQPbnD+nzPWfPAhVUr0REQvagzmfnXLPsWqLaXdz89UXgiU15PlhB -HAPwl967DHthJ5CVOXYBNBPUthTNTskBsKnQqtOiThgqdML0gEx66Su3oJs4jEf8 -wueMuYI3gTvkZTHqWhVErccdG11kFdY2VjVPiUy2YKj2PtNtKQxnKWL2Mn+7DQ5M -ZFFV5JV5Wzs16V6TSWc6oGrLPnG1BSaqmMlvaphqokK4o3wkdP27Te+IbHr7pMMM -wMejBJGieyInohtM/udsUvm6VyaQJeNON643neK8K3NI7ZF2YqchenkKRBtzyMZO -gKgykBqIl/HBajHMlcCu0FhU/5wcX/v0e0yvqPwwU7KnGhTICcFQ5GFD2ujvdQih -seuxETRBn+uqJ+IpbpyaObCqcyy7sC0e1Ijx8W5/3GgN6GA/OlEWtxQQqypPpp0e -tKCnMd6kWG/sI1dx5nNJqNjn6MCiPa4sIUdgqzceI1Ovq5/Bs6+SCazvpKxaMaso -Hq3J59mGvt9IpNES630scxev+Gj0inADrghPt9AMy+ZFqCyeJFzLMMKn43YB9aS+ -xXhHlci+TPVbhyZRsN6LM4W328XSTpaMkvkNvlCsvMui4LK82B8zjhm/buyoYfSM -LyBTvQ+D999lX5i5e4S77xf6ZFOsVd6vhL2NMxvfXfMkWQBnF/FgEwAeBeR5hgv/ -f8xFSeCDBfkiJCmAsT4HCxUJNXrC4W3sG1eA/Fj8evjTEyszoCOJIoduuxQM5efn -rf5QWzORHdDREGl+2u0+K8XxK8N8y6l635VrUGknc4QB3vbW/JkVlzi/NFr9rXgN -Cc9svalB+GST1PDkbymYFY10uMdFxaX+E6CH8xNGctJPX+8Q+O6IA7g= ------END ENCRYPTED PRIVATE KEY----- diff --git a/tests/tls/brawn.key.pem b/tests/tls/brawn.key.pem deleted file mode 100644 index 157c6338..00000000 --- a/tests/tls/brawn.key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCua5cMw1r9R77O -PdhT7UHJcF03ml9AIigvbkZgM4F/ptXClUe8/JUh2MwCuGnTTMY9P6y76nRi1zSw -BmEeZFmcAzVg97PpjCAo5gQGaAKJO+Y2sqMJCk0c8asm1IZZ0oLTzO7TIQCdeXzg -y1Duxp3tz2E/R1HdN+YI/HJ9DfvQPSCbB16BS1eHfeGFyK5/+uzbFFwaM2S8D62A -nePZiWN0Kp3QPIFE5/nMg0FC5//o+9gHVXvpZYjBIt8pqzscI3Hsw4YiV2EXs98h -l7W5iIYOk+8T+2vYQTyc9DbiImOtpQp07c1iU0JHiLQb6arCZIkcS+1Le7xV0if5 -pAkhXu1XAgMBAAECggEAAcGE3VSyJnlI4HhwQN8omblywXaMK9OPwqxCM1cRZ1mW -Z4ykS5RT1c1lmw69HKrLpQHDxBT8Y9wgHTg2xvmM/IHDwyO0JKSoRjoFP+iYJtSl -i4/em96wrdPqyr2Bb2ry5qvaKP5q82PKYdSGnLmp1AbY44/AeFgcYzFwUS7eolcl -IXEApih+91OnEfOZgSQyaqCnwN/RE1ykESKRYQFgL6qxC0jhJpg4q5iqsfyXkfsj -v3JpfqY3xB3hmsAqdYT5Lr9Fc2OgEDuddAI/djfqEv4nbPacN1pygK7pZlM53xja -crThLUq2NFpiWQv2B7eDJoUoSTYb1zo57USqeEPBsQKBgQDxQuOZQSwttRmqVCU/ -IcdkbsuQFhNhBhFQMRDw+bjm5pCr8gyMK0vmQItv2e6q/vPK9L2tUX5bkwM4eSr7 -9zioiis4RKQ8TPuREbgfmJMjRSg002xDijM8b3wmCVQ1XJykPAKGXTR2Oud1Kxiv -SSo49YFBQf8we8/RSHfkcaA38wKBgQC5E14F5kNJRroG+cOMkbT0ZpvbB3tuhEQV -OloMpgKNOJamsISiGP21deSmN3/BP4yYyX+63gdZdLSrL8VcPNlbCkwtcrWDAP5a -y/VZEs0XgYHltPK4UEw5bEuKuCRqShzAlXCgHANQggLsuyaz3CHVcRV16uVq/7/X -yyeWvr8SDQKBgQCVB6+WBJcoqNzwxUe4xsHnfTVLjQdtgJUDRzvizy9zmms1e7Ba -iYg59BbuAd4XTKQF88aTIGsAYEC2CssNl/osyiTGfkhBY4BmbV6iTdpeCCM89njD -A8SAiZFT4aFd0RaFsPgSTdLRUbOWQgfeh0CIrMaqK/1Z0rFd4vkEaVgCFwKBgBiG -BHNrq4bOJGBAQDUkKYIpBoXjW+utAwh9DumWJchosy2rPifsf9HHqWCNAhStQwgL -yy0LtpWX7Uixr8klFvgFSUrMZFjTjOCjHgOLhjmTI484huD9YtxJCUl8VPbwkxbB -tobAr3+/enu74Mj8Zk9OCLXzRisDcHw7oydKZy8RAoGAcfbntj+ZVc8z5oi79O+v -fpD/G9FbvZe/qKSO5cwTS0z1QFF8rQuzelzNXlIGlNpZyz8uxv7qN5X5C9wla7cm -Uz68d6+f0yEa16mhS0rKYeUDEioVjks7Td4/FrIF0EQZZGpfNLgQukK6RTpt8eBo -dDFoxdCwl/KU94yPu3autIk= ------END PRIVATE KEY----- diff --git a/tests/tls/brawn.keystore.jks b/tests/tls/brawn.keystore.jks deleted file mode 100644 index 813922f20abea658b577bf31e55cbdb0558e7b12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2798 zcma);X*d*&7RP7C7-8(GWY3nR%#0}}yD*}$8_P&z-?C(vZ46_EFqAF3tR+iic`2`K z8A}Zb$&$i&vrP#h^>&|opWf$wy7$9*&U1eM^FJT|&w&v+K7oKNFd|15gk2%YC~1!i z$ObGWa*)78j`&|V21aD9_%Dey8%$)){DsqgRWgM0KQ1T-5L8NJ)%gWAU>?66tXwdA znA$%h6s8D1-u)^ysrhDMy>DhoW%jI1Ven~}ArMH87X*}mK_SQfeG$aY3V?}1*zrk5 zKz9}}Pyx(~bv(dyyMJf7xPsLYz5a3pOa#+$x<*4X!4%E#LuWjUq|68?ZtD*Ar)|DoKxA`33S2HWL@Ha@PC;@|saYco?BW`b{P$P0BPlv^w zcjIG{-e#SePQn@iCZBmYS-2mhw+%bt17&e*${@qF@=Z|Q`r^k35X3K$nO~fY%U18G*8sK-3o*LeAH9QTTvVTbg&yp)`#4{z&ea|Erb*7& z)N_qK6Hs%~Nk0XZ|MYecSZLSawy#6XYfXvskJETB$0Z1~SF*R5Q6}F6@v}5HcI(W^ zH9|uK^7qHiQjwW7!Z*M6+%u&T-*!~c4xVxcRd()}FYI=Q&1(el?iJ;;JVi&1$_(*2 zDUd4wFeqXhmi;m&5Kt8i4dSZcZ=btcefsN^GcZ`1!|%XzK5xqqr+?Ee-dgiL{l>7f zw2r63b4*KmsaP0gO8TY*iA$fFPE6OK=qxbhZ*VWOjDcX8(%pq%8lu%o>2sa1jp<^5 z&%T`4Ys?_=%z_w28X<4fpEgz)@`5|HH7ob$J1BMDT4;RfyXuLeHXB)?#uK;`XH2BS zoZXk^9t9@Uk_>9rBn<>~w8f|y(8G+lEWT&mki$l=#2=O9lZ+gg*U?}-*SP*XO|jwf z>V=%>7NK)OQi4B1?M=-#u;*zS&_m4Z7S1b`(M)gF;GjnM>-*^z-Mphl#j2sI_Gnw54 z`Gcem>L~{ahbtep7{lpO^?zsq%cdwrUB0*_rr+i<&7-`d%L|me9gC7=UAxv+ugTE? z=~WjX*vH zoRPXeffFZ0(;DIv6J4gf2hO?A-;B5q%C}Wh8i1tQIq&+e1j#S$gK4b>ok&j^h7NjR zt8tIr^K_d(+btor=ab}j5xtN|sh;BUqr&3VM_;Kyv^#iQ#@O;kwMA{H<6dI^C(b_k zlW(2wHWbTld|-z6${#sIZl{?MiizHcKsLtv)Jw*bWu1LZH?#v2CqUCCE}WZvgVYZ= z`qK*|w?IePsZSk+49$E_x}vRl55vTVc%}bpmgZzW6jsU9NVR*YXL0C`4_Hmm+johM3nkI^s`EcI(w^9di7{-uPZZ45Dhg<`m(k?3kjW~(eM)XR z092?GxyXOyJalUQ5tkraOHryw9@U;jf9zc7gEL;+c zpm#*mUjRV(Jp3Yz?{{3XABTg*Kma&Q@*gA!KMv-%_V#m^fU6>4s)&myBod~Igb~4G zzn9n`r9^PgFVqDB0)Dl&e-z;V3TMWZ(r^8y+Ck0(=g;>oe@Tgrtj7F5;S7ov@Mx&1 zIDVTwdU0#+K@Nck)B6)A`v&auwaMyhc^O;Wu?GLy-`FM!j zWx^vb^q`~Ysw-r>fV?{L>#Xn@Tddf!57J(iyBy{m|919tKOk z_{9)+p}Q9s6vLpC!+kal`5Yn#cXHb84F^LdL6);@w9&hZ&7)y(E%STk0lBI5eu4m; z0iM>>-sX_Ct&TtKnUmL{<_8868?Y^pEE%n z2)+Tgq1QD;CPo{g27t?-w%iCV_UwONB&6s;izd(cWcNm(;gpvd!d`Y+H%UFH9R>Z1bLpviO?fw%~yr82rVM$&6nAx{C#+`p+JtsG=O2!3e z?q$Z1IJ9HgSw3*j9l%&5@>i$#3ww78Zz;P(A6j_Lx}3H%x?ehpvA=ir)FRTcHq3oF zaNEJfdQqR)uS?$DW;%U7<{rDDo8TDom^>yd3t@N|%YMT@Lcgp|UGyL7{;@SXfC%yZ z!@~8lGa$wM0ppa{x--0xTbz?%Lb zB>dL3aNEcOiQtg+PcxTA^;{Bdi}&1i>WUEq{flig95Sdf-zrjV&g%C~xqS{~#Qi(& zI*lTAicENU-7^?*3*cvKLobi1e^IPpnbn3zo9-r*Y{6EMhK2xx4c5 zJ_`Ljo8oqR9_!vU+Ye5wESSeRt1Z|!c4aCp0(vJj7dH)T{I6ZI*Pgo=y8Dd3kkM>1 zBpPppEMT2qi9Z9&zca9@-bi`u2~7N7z5Znv#Hb zMvks!6TJD(!$I$p(*Y~jpFiww=(Olckuv&HMw9rf=rvF0l-_|Zy?x zud>h~WLhHZHwR3!NgWxvK=sdEU*mXzgh_sh1vDOrJwL_Z#g;q=k4$hw_Tf_+R1 zq1KEOKrjpp4&(a$1A>680I-C!Ndz)WY#HUKOxpEtEmjDmnDmKp>P=YS4;~uRbbG+Z cJ4t^i1!!ACMl3t@ZvDy29mBku|E~!98?H_Q2><{9 diff --git a/tests/tls/brawn.p12 b/tests/tls/brawn.p12 deleted file mode 100755 index 1ca0496da6ad2fc94cae90defc81543582c6bc31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2739 zcmai$c{CJ?7st&Q+Zfpg$ru@XlNn_!5i?^+)|53Nnb4E5WeLw1jGgS+vSi61B4lit zvI~)vB}(Yoq71S=@BDtJ_vicLo_p@+`^Wv~p3k``GPoKDU`CO_1Xd1t$|cG+7k~{= zKn7ca$YAqhY=R<#X#Ym61!PdgF)9NBn2uY)zX<^4@Oxn4LYbq`|Bet80>lF&X$4E) zUH#_B(A+wO^{oQ}*_lufR`&mG1#+-3p~P4@94VIo1ZEIG9>inJ>KCy8Q;XwbKV9|Q zT2~{93_|674B=E*gxto5!g=%B&}JOjKTRAh?U>ErwqDNBFJzeb2D8&~;zh(*QMn*s z;CYu3@aSH94gL#RqulD;d(3q>$II&J6ldxn@5Ca7Dq#=Tk_C^ihz2oWZ|#<3S_8N& z1M5F3FA>vC2UtQbQX8+!RjOT1yqcgLl&5?>G-M^N+Viuml zu<|Y3@tNC`5)8hZzyt#|u|AWWn;KKi%E(VtYqgD^Ch`+c zt0ED=qE`DP4tc41@38d_0J@35Gr#d;Dsl#NF5pvJ96x<2wQHGwnULUYPYwxNz+ z)dyDS7L@LM*27Z`5miQfq{`Xd>XY3GbI_%?UvKH;s^gEeo|E(T(u=o!JWDvO8fH)2 zvknUvx~^zJVaN{3mS#O~7cA}J=Hnpg^~dukK5NqBIMX~iG?D6_wW3?HrN zMlI!^fu!JY&qbYiUke+;xai6W8=yj&Ey7+j&2j9r4)mt;l>yh3b=kSPe1bQ#5_bV+ zy2j^(3=+hVeII&g%_U|pcSG+~<{RNp*H@;NozhZ!*~y*5F-P#*M1 zgx@0Yj(Wrt2C7ANfAiVYpvuJ4#1;^KST@G}Uk|t%bR(OXQVTpvxnz z_NP)8I6tuEedX?|mJ*G855Kudi_-eT`5hvu(pM;z7G%TqS0nV~6Lta5u|(6!n`xv+ z__vk$;VMp&q4$JZ{hNHd)jCrXOTQy)k_N`_=Xh(IUVP^ec&4a6q4P$oV9E4uvJ}2r z^lT;6JfjR@8nUsghJ1;I@8j!$_Z3oDXLbF1UH2zXiwPzsCLYm{{3j_S0!$8>eP-i1 z#nTY52BTX>nb&@^#mss+#k%fY-nwvmjy3D~_CTg``B3m8#S4Zr|KOoi{f7j5`(n@x z&@n^*Y_p`;t3{uciURF4@3tqtD@ppQ>oLF=6KosI*l~J#ipHK1|K6|r>ZYW8rNDVMG1=IfZ&knwXnb-_li{oGLMUe%#>z|#|_^3(`4k8$aS?hy-Z zU`d_YWtr8j$upgKZea0fK$Q&dii^Dyw=A@}M(8v(MS~>OS6byXg%%SGvelAujm6zC z5MI&$G`4y1plew9&$(tpHR8uPo54Hm_0-}Bb-9Sjh0$jvYoDm2HEnh;I}juvGb$X( zC$Z6KEF5=G(0uUCIh)D@oU^VZvl7_0pT^}q`~vGCi1l^2mC+`X{FHH%4%CWErVt$B z3B~2L^=845?w5v@8bzHW&1;p_vIm3C1I>Ja>LP`0wtYgUtZkaTMiCt7#r0U@yaS6XM#^?!VbnbU5p16y@AhB$tA|czfma=q@?M9;rC~O+KGzs_a`t-J) zcd#J^ZW($$F>3zGNr4G&)%nSbF91aeByycXITjI~tEo1gn=>rLtpLBmX#DJ_^o70) zkvxpaCsol9i^9q|be85`Qk-5`wcstjlP%AwYS3xF3EgmwehDD`Awuf-5QocW91EcWh|2RLQ5{v}MI z!CylyysKEFu{SQzcLAw(b8_~ngjG$4Q|jL$Gw+$*TGL2SfS5%6QPC=Wo^H+M!5~r` zQ3yGsWaICsBwV_hYwGK*pLkpTsoJzUXj3{k!{JW(rRDqWS}i4_)YH}*PThAs!75yZ zf}Q!v(2TouBTtb{Bbt$!F$wW94|O}qRh4fuWI?YX?%5lA0m$Pxrubkgx=MfUV`a z&*`7nX;E)}E5iW2K4VgdA$7;Ta(^ZSFS=3{Fp*zmLlH4vevP{<07pt?+&L^I!_+;~ zW)a!u66C0bAos=6dpgoDI;-U=n1h6oH;Ocu$c5}AFSFv-HVq6|Qb_S|s d*)s#{)b*G#I6fdI5WBb-K>Jplamzod{Tq}X<52(r diff --git a/tests/tls/jwt/private_key.pem b/tests/tls/jwt/private_key.pem deleted file mode 100755 index 8f98230f..00000000 --- a/tests/tls/jwt/private_key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCj3/WTL4tf+jyp -lKniBuSoWjYxKHJ7Fd6frdoclVrxN89aHUwuJPPhsAfhZ5sWb2e7+God9+uZWcWH -4mE5gtnIygw4ij3hdBU5S2ItlG7nZ3oZEwTfQvUqesEFdQ9KIgP+Qj7eTa+fTbfx -qOoq0Y3f99I+XK2h7mpGCo62ryifz/UYBG82yHEfC2zEmuKg+d1RKP73VxHJ11uo -PMxLnnUTuuEtmKQaTaoJT/m0W84owjWOna1/OgYocTsu3KsKY2SFCHcY0BjlxvzS -wpHt5AiavoF3B0bSAnAU6W0yaBQ4niAY1gGMPwB5qsKQcajPg8c4s+qc3agFQFfI -7wtPUHqZAgMBAAECggEAAvGgKr0amo3IezHbpFUhrQw+vvnwpmMYQ9/EzOlEGzH9 -izUcTBPqBB/P9G3Np6dKYCc6MWfIDXlqhsTstDKguFDpfPt0T28Ofe7rl0dopu4o -j5VeHPYsbcV3hqwcDaqkdWn+x0gGcnuhArAeNCssnknDe88oGOStxl24L61WUHzr -Lq5G8V1uNgVNEV96jAwV5KUhMpj5oGV87f13SlbhPDsm8veV51qGQyGRQHChmgM6 -E6m0aEYF+VHbImmiqwI7lcRuS7PMNeEGPWatvk51mf19z+jcClBjWGg9b47QBp6Y -/QHuoJ3Izm6d97Q+OuOJvuilS++kYa4Xcn40G6ODJQKBgQDgCrAhXbBp6Yz4Hhsq -jRsCSq0YUtkZ6ygiLEdESm7JQKBPIdaF9RUSEKVqDMc2TyhzzsyKftuJkUC/PVBf -Pq0gdHLwf0GaHETtg7Wk50A5FcxOUMTVAb/00i6IXClXe3opPvU3muaaDzt0Lntq -aPZcW5szaSgOzjH1RzgcIvgFHwKBgQC7QClqWCJwzlSNl/p+H3EKvOYdiBHMjQiw -3/K13Grs7wlaZ3iIQVQ1htzCCI2TYLi7URnmEkGpxy5x8xY0rGNS1ZYH1W8inEdO -l9y401h6O7JuUw7Jga9+4nmpN5tGhZtGxdcZk2LlY+LiKK2Dp0BA7vE60FmmgnC1 -k9ampdARRwKBgALkYG2t1e8oEqfJS7R66dRXvnBH8YGCJZx7Udgx1chHS0p6N1i3 -VzRKfrglvhSXZQBJtR48kPzvoRRW6EiyeG2o0ysDmYcxwjoGrzuXuJ6EB4UjSccu -JJo2dF9SQT5d26/YnjW/jCaE99GCIBm5jSSYEiLRwrCePMrbxn+me+klAoGAHo62 -84LUhAI37C98Em8BHJZ9Gx6kgPQXEf5J9oG09VuA9D7kfZ/jpSSQDB4nNIDZRMBU -cKZUDufRXYkk+42SW+c9J6QeEdDdFidUPtlGnBP352coh5vhTtyYrBPGBDkzgNYy -ZxsVTYgCc5Pd1RlLNA2KUmXD65dn20n4ApQWo2sCgYAj4j0mnWfs3q3yLXaQETQ5 -EGszs4yFPUnWueJaNaNNuliECmJxjUHnPnAreKFHoWdmntKYSE54mUr9yHIrySio -UYITxsjtpneuTWeBRgyPdd2IcClO+QvhR9HoJpVowr9JKPxkmynNnBfFTvojKQXB -UtVSAliQTDsSdp3B9I/KQQ== ------END PRIVATE KEY----- diff --git a/tests/tls/jwt/public_key.pem b/tests/tls/jwt/public_key.pem deleted file mode 100755 index c7cb5f92..00000000 --- a/tests/tls/jwt/public_key.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo9/1ky+LX/o8qZSp4gbk -qFo2MShyexXen63aHJVa8TfPWh1MLiTz4bAH4WebFm9nu/hqHffrmVnFh+JhOYLZ -yMoMOIo94XQVOUtiLZRu52d6GRME30L1KnrBBXUPSiID/kI+3k2vn0238ajqKtGN -3/fSPlytoe5qRgqOtq8on8/1GARvNshxHwtsxJrioPndUSj+91cRyddbqDzMS551 -E7rhLZikGk2qCU/5tFvOKMI1jp2tfzoGKHE7LtyrCmNkhQh3GNAY5cb80sKR7eQI -mr6BdwdG0gJwFOltMmgUOJ4gGNYBjD8AearCkHGoz4PHOLPqnN2oBUBXyO8LT1B6 -mQIDAQAB ------END PUBLIC KEY----- diff --git a/tests/tls/keypass b/tests/tls/keypass deleted file mode 100755 index b1f833ed..00000000 --- a/tests/tls/keypass +++ /dev/null @@ -1 +0,0 @@ -citrusstore diff --git a/tests/tls/root.cert.pem b/tests/tls/root.cert.pem deleted file mode 100644 index e2f92909..00000000 --- a/tests/tls/root.cert.pem +++ /dev/null @@ -1,25 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEJTCCAw2gAwIBAgIUexcLL2txw6HRtuNmsKSyqISOYPcwDQYJKoZIhvcNAQEL -BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm -aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG -A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p -QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTk0MjIzWhcNNDQwNzA2MTk0MjIzWjCB -mTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNEMRIwEAYDVQQHDAlTcGVhcmZpc2gx -EjAQBgNVBAoMCUFlcm9zcGlrZTESMBAGA1UECwwJIFNESyBUZWFtMRswGQYDVQQD -DBJhZXJvc3Bpa2UtcHJveGltdXMxJDAiBgkqhkiG9w0BCQEWFWRwZWxpbmlAYWVy -b3NwaWtlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMW00aMN -8jC06HvfZ49VYEWfLwUAfBvJKgxTZCK8+F/zdz77SJSHanz9DCM2Rn7tHOCOBl8A -iu9QrxcCfIaxPv3PO0qSxfP9dWj8iJOdXxzFHXnBbzr6YfAfPNhLqkgKEeGg28Cv -IVOF8Ptfw46HidDgHzMdoKHsyS9dLYThQpW5vrVdq6pnVlasDZsBh3pxQuHbwa9M -KYuD/kdnlXi92mKnHTjxEyd3exGv+HBSDEpGA3UNhwCZvz7e1tUlmVvObb/q0qXD -rSBkbgNjei4KOPylKnu5PNsJJFmGCkqH7sqVguC8JadzgdpZyTEWfDpfgMQ/lVnp -f9iXYACPJsalvRUCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E -BAMCAYYwHQYDVR0OBBYEFBeEMGbzV+Z+qqGUXEo9XNPkpqfkMB8GA1UdIwQYMBaA -FBeEMGbzV+Z+qqGUXEo9XNPkpqfkMA0GCSqGSIb3DQEBCwUAA4IBAQCt3MVsVYgX -qYc0ei/3KWUSXyGO5oHlIQjIeTrX6hm5KhIddV72iHFEO6pKsRMZs7YLO7kDiQFc -7LMUlMo7YvfF0fOZqfqOYXi3hhO/HlqPT+CXnaWiGPrtxLaAariXJAfjZYCs+o03 -gxcddEZzOj8Menvgf18nRi6NQFURK+q+OXkfrb2gqZxRNSmfD27duO9FvY7wCZ5T -trVGdz3JBVEbLBotBjW+Qvqr9UP6IE1/mlZrQrxlXo41GnUnhQP8iXmT6rjSIuAZ -TKe1uPb5d/DyQVmyhYdGdUNL6wpsIque3Bw30eE3VuOVfdMB12cwCu3UBSm7GGBD -ki9t/rZSSOT+ ------END CERTIFICATE----- diff --git a/tests/tls/root.crt b/tests/tls/root.crt deleted file mode 100644 index ae466fc6..00000000 --- a/tests/tls/root.crt +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIUKWDLcZS1wltTraR8mFMs+NDX56kwDQYJKoZIhvcNAQEL -BQAwgZkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm -aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEbMBkG -A1UEAwwSYWVyb3NwaWtlLXByb3hpbXVzMSQwIgYJKoZIhvcNAQkBFhVkcGVsaW5p -QGFlcm9zcGlrZS5jb20wHhcNMjQwNzExMTk0MjIzWhcNMzQwNzA5MTk0MjIzWjCB -mTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNEMRIwEAYDVQQHDAlTcGVhcmZpc2gx -EjAQBgNVBAoMCUFlcm9zcGlrZTESMBAGA1UECwwJIFNESyBUZWFtMRswGQYDVQQD -DBJhZXJvc3Bpa2UtcHJveGltdXMxJDAiBgkqhkiG9w0BCQEWFWRwZWxpbmlAYWVy -b3NwaWtlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMW00aMN -8jC06HvfZ49VYEWfLwUAfBvJKgxTZCK8+F/zdz77SJSHanz9DCM2Rn7tHOCOBl8A -iu9QrxcCfIaxPv3PO0qSxfP9dWj8iJOdXxzFHXnBbzr6YfAfPNhLqkgKEeGg28Cv -IVOF8Ptfw46HidDgHzMdoKHsyS9dLYThQpW5vrVdq6pnVlasDZsBh3pxQuHbwa9M -KYuD/kdnlXi92mKnHTjxEyd3exGv+HBSDEpGA3UNhwCZvz7e1tUlmVvObb/q0qXD -rSBkbgNjei4KOPylKnu5PNsJJFmGCkqH7sqVguC8JadzgdpZyTEWfDpfgMQ/lVnp -f9iXYACPJsalvRUCAwEAAaNTMFEwHQYDVR0OBBYEFBeEMGbzV+Z+qqGUXEo9XNPk -pqfkMB8GA1UdIwQYMBaAFBeEMGbzV+Z+qqGUXEo9XNPkpqfkMA8GA1UdEwEB/wQF -MAMBAf8wDQYJKoZIhvcNAQELBQADggEBACAoV+WmSvwBwvkrONAzqVRfEz3dH8wc -VXQoyUbzNWQ9UiU70N9v36MIwnm0q0x3DZO4ju4qCLUpLHLrCnS/piXti/AtE0wp -/Hl+jLcDgolDx9s/y1ieLxonqZ8QcjXc+JzQ/emIruVUbKdGSzxT4mqnUOf2ldBD -w1GxqukRCapLa49WDf1yWNTneLscjx9RshKkUM0DILG7I9iWlD0jhrpVCUmOJYqb -pRhEqJszFBHYFqMSd2+qhu9Q5GsYbA4WgfLZXUaYnHuDDHHY9NayJZY3f98fX508 -1HRfGtGH5eKDYjzZCIPWTEVTj2w0XtIdxkBnq8kK53ys2m4BqZhrh9k= ------END CERTIFICATE----- diff --git a/tests/tls/root.key b/tests/tls/root.key deleted file mode 100644 index 5d9123dd..00000000 --- a/tests/tls/root.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDFtNGjDfIwtOh7 -32ePVWBFny8FAHwbySoMU2QivPhf83c++0iUh2p8/QwjNkZ+7RzgjgZfAIrvUK8X -AnyGsT79zztKksXz/XVo/IiTnV8cxR15wW86+mHwHzzYS6pIChHhoNvAryFThfD7 -X8OOh4nQ4B8zHaCh7MkvXS2E4UKVub61XauqZ1ZWrA2bAYd6cULh28GvTCmLg/5H -Z5V4vdpipx048RMnd3sRr/hwUgxKRgN1DYcAmb8+3tbVJZlbzm2/6tKlw60gZG4D -Y3ouCjj8pSp7uTzbCSRZhgpKh+7KlYLgvCWnc4HaWckxFnw6X4DEP5VZ6X/Yl2AA -jybGpb0VAgMBAAECggEAGHZoHgHCvs4Tmggpey24LMUmfzrxIEsCveWvlTDGlrC8 -R3m2IFKlFXQGBXFYxam3Ef3gwe6CQlw8Xd974vqZbbQvhOmmPqtU1LmyeHlXZGrr -W75Ycfa7GYfz8ltiZWmBjuZlanEA8aG4EJJn0wHoRoUEt0FqN77hoc+oqzFoGLhc -NTXrQSQBHijkUzxh5GPy2lO+MIX4AjhgGu19HzJlnGyTC7nsQrHeZQP2tqMWM8+b -XnZvfSJ3+PfJvlH9hG5RFg+3yOt3QfQSiWC4oVg1+H7OffgMCg6NqHl5FX1Ehq6U -QG8w26DO1daprHJe45DBXgfgCAZIKNPm7xkYD6Yc4QKBgQDmSRRYZd9XF4KFe2LX -IZACzx5BCSKvLABujIrB7SE3AxUaK7vEuRv+8AXRT1WIdOBwyo8OXIkqC4CwNO+4 -heSqsIHJ7R7CZOihNY4hxOHyleRBEj7s1dJ571uSTfjf1DMGxOznTlX2HOkrhJId -88TWLWETe31MxwCwFYF8bV/47QKBgQDbyG9SGQURlWkpSJtWogAuWpMOa8C2YaYG -hIsvZFqpyaOlBu1DrYZKcbbqZqrZS+JtEGhfttml2xMOJ9/jGGeNMKjXc8A4IOAl -J2ORPAR2/yX3oCPHgk5iNqvbHfruovE22AvxcxujFM8/BiR64U7GSGkQwdeQEe8X -Hrt76uYXyQKBgCy8B4rAh2lItN8vP90gtPQGvg7OMoGq346aGJ5hbTFdlOzXkAtA -FlMo10h4y9nNMohWoQGeMjsLrv0L24GR6QDLdvr96BrFNXeTir++mlHgkk2duMGT -K+bp+3TpVq5Mb3kiKg8o5YQAy77bavMMlrEwcYoyU/3lLpoGI3hDWwBlAoGAW4Mh -lvWD/sZPezkYNQJPQP3FrYOAQnB2SNB3g8wtU/T5hoVT1ZIzEFw45XDKQqAuL2td -ij0Acua9EG/Z8R0AQPG527v+lWBa9B1qf9aVpVan4Gt1emTvbkWFWT8qdKKz/ToH -/wkGwOixQnS0S9X0jusnlCqiLwLIor/RIM+17sECgYEA0tg9cQFip9U2UpjteUj5 -8gbC0Vfd6W4JVHtsM04RQMUHKtsS3KPw5pNMFYeWgw1Ifgu3KDbOODfcqGNkkPxg -EjRiiL+497nqXmbyXfk+EinELS5wCf+Dgfs2xpXQF55H6L0+DQfQThcA1jDsF9Qq -Euad4yRd9vu6dSCyW2SLveY= ------END PRIVATE KEY----- diff --git a/tests/tls/root.key.pem b/tests/tls/root.key.pem deleted file mode 100644 index 5d9123dd..00000000 --- a/tests/tls/root.key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDFtNGjDfIwtOh7 -32ePVWBFny8FAHwbySoMU2QivPhf83c++0iUh2p8/QwjNkZ+7RzgjgZfAIrvUK8X -AnyGsT79zztKksXz/XVo/IiTnV8cxR15wW86+mHwHzzYS6pIChHhoNvAryFThfD7 -X8OOh4nQ4B8zHaCh7MkvXS2E4UKVub61XauqZ1ZWrA2bAYd6cULh28GvTCmLg/5H -Z5V4vdpipx048RMnd3sRr/hwUgxKRgN1DYcAmb8+3tbVJZlbzm2/6tKlw60gZG4D -Y3ouCjj8pSp7uTzbCSRZhgpKh+7KlYLgvCWnc4HaWckxFnw6X4DEP5VZ6X/Yl2AA -jybGpb0VAgMBAAECggEAGHZoHgHCvs4Tmggpey24LMUmfzrxIEsCveWvlTDGlrC8 -R3m2IFKlFXQGBXFYxam3Ef3gwe6CQlw8Xd974vqZbbQvhOmmPqtU1LmyeHlXZGrr -W75Ycfa7GYfz8ltiZWmBjuZlanEA8aG4EJJn0wHoRoUEt0FqN77hoc+oqzFoGLhc -NTXrQSQBHijkUzxh5GPy2lO+MIX4AjhgGu19HzJlnGyTC7nsQrHeZQP2tqMWM8+b -XnZvfSJ3+PfJvlH9hG5RFg+3yOt3QfQSiWC4oVg1+H7OffgMCg6NqHl5FX1Ehq6U -QG8w26DO1daprHJe45DBXgfgCAZIKNPm7xkYD6Yc4QKBgQDmSRRYZd9XF4KFe2LX -IZACzx5BCSKvLABujIrB7SE3AxUaK7vEuRv+8AXRT1WIdOBwyo8OXIkqC4CwNO+4 -heSqsIHJ7R7CZOihNY4hxOHyleRBEj7s1dJ571uSTfjf1DMGxOznTlX2HOkrhJId -88TWLWETe31MxwCwFYF8bV/47QKBgQDbyG9SGQURlWkpSJtWogAuWpMOa8C2YaYG -hIsvZFqpyaOlBu1DrYZKcbbqZqrZS+JtEGhfttml2xMOJ9/jGGeNMKjXc8A4IOAl -J2ORPAR2/yX3oCPHgk5iNqvbHfruovE22AvxcxujFM8/BiR64U7GSGkQwdeQEe8X -Hrt76uYXyQKBgCy8B4rAh2lItN8vP90gtPQGvg7OMoGq346aGJ5hbTFdlOzXkAtA -FlMo10h4y9nNMohWoQGeMjsLrv0L24GR6QDLdvr96BrFNXeTir++mlHgkk2duMGT -K+bp+3TpVq5Mb3kiKg8o5YQAy77bavMMlrEwcYoyU/3lLpoGI3hDWwBlAoGAW4Mh -lvWD/sZPezkYNQJPQP3FrYOAQnB2SNB3g8wtU/T5hoVT1ZIzEFw45XDKQqAuL2td -ij0Acua9EG/Z8R0AQPG527v+lWBa9B1qf9aVpVan4Gt1emTvbkWFWT8qdKKz/ToH -/wkGwOixQnS0S9X0jusnlCqiLwLIor/RIM+17sECgYEA0tg9cQFip9U2UpjteUj5 -8gbC0Vfd6W4JVHtsM04RQMUHKtsS3KPw5pNMFYeWgw1Ifgu3KDbOODfcqGNkkPxg -EjRiiL+497nqXmbyXfk+EinELS5wCf+Dgfs2xpXQF55H6L0+DQfQThcA1jDsF9Qq -Euad4yRd9vu6dSCyW2SLveY= ------END PRIVATE KEY----- diff --git a/tests/tls/root.srl b/tests/tls/root.srl deleted file mode 100644 index b9bc7599..00000000 --- a/tests/tls/root.srl +++ /dev/null @@ -1 +0,0 @@ -371D714537F907A5DC680C191B450902F7088C11 diff --git a/tests/tls/root.truststore.jks b/tests/tls/root.truststore.jks deleted file mode 100644 index e17958179565de0114bd76c6d58cfdf450902c7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1414 zcmV;11$p`~f(3#C0Ru3C1uO;$Duzgg_YDCD0ic2f9Rz{}88Ctc6)=JY5e5k=hDe6@ z4FLxRpn?SgFoFdB0s#Opf&}*l2`Yw2hW8Bt2LUi<1_>&LNQU|bNGa~7G(L~oJwpZY^p8Ns=ClCSwATSID2r7n1hW8Bu2?YQ! z9R>+thDZTr0|Wso1Q5`$c8{PYdD%cp;~Gi5=*)nE1b`R-kKWWL`MbhjTdX>6r$bGV ztTRsRd2O2fpVZhQCbGFsj9WZ5jPz7`^tG;q^FKv5{V7sf4wBd7__g>v)fZCzh8Q3a z4B3J$ZMdw_?ngt(LMGO?VJRez#!thLli z?)&H-aD9XFTOh?FZ*36VAt6f8H{#z9`Qn=h4%KJ=f@$pVRDEKkM$nDJ8ZzX;fL}0T zs(xJ-S#-gD0kWpOfdgQFJH*h?n8gjwim)e<{wAMITGAcl7}N2dtaT>5V(>-IBoWkg zFl*CJ(K^95flF2anrFxE1WxUE#G`YsI@oFHo6q{vVTHA=V2k^}4=R>oqL9fAct&sIhFwy2`d_`EZ&%+t93?=hxN^r(nSli*rPJ!(Q`cP|7nwKn zqh2k2M#@T|$3NIT4X47u1+xKNw>Z1R+U>o>a*YuR$X5l`m^U;g>X=u14_?g+Q4fWl zxm#@r+I)9Xkf6c?7%cE^Re$E}MLw)@G5O@S=V*wT9F!+SBWQ58Y_fm|9|MY5AUXLa zyHp){y_4Yjh{a(>1rUzEWV<}>@tihLntB9;O=1k{J^6+48bc!<=EnfWbEuCy1GsQH zW^v>XNudREk|)-5yAK{0QDd=oD8mG)?K8vX!lICHS2)%iFEIL24^iANpKXH0@|S3W%7tEe2WRLAxUA})~1vHtDmtqc~&Ok!U} zkR4Eaw@MkzZPbI4=f4#{*_6(DR)KC0e5weQq_>l!q&*$iUk5#WT9W>Y>vvo}3DM;q zF}$PsPkZfz)~gtE8xix#2*18iDhC;V$Qq7l6o|IK`h|sq}Qwa zL(-Yfs|Vw>G_zt{V={aW^J8(*Cmw71rP@)$SF6ZFdjZvf$hOT~eVGhMv zJS?{YQwd2qlHQnVB50zlvKpcZnRqyyrz=Z8P7;OTQ#P3u>kf`yT&16b>GvG`|-0dy4v=|#y5V5w_Jvxr!7;wzU+@A;Ms zP!ye8r}SMj@edDFZ?GO)IMb7P%E&pQ5Hu;dDL3Pb9k)+(Y4kd}wywm=U`uHeLZPbc z*lW{H16V1Xp%Kvbp&En;nZF07C^_uJVt!#y>y2_QsPzxn0^cVI(!)BDsD z(}9rfj{238B*JlZp90LSdrP(x-Dm z3io;R#zJM$B%1Z&qko}e%D}JqwIMV!g;A*UMQrdeVpX>|)9*F6y_sBPRv~3>f>tD? z;O>sr4&L@&MLYj@-3pIIn1clw{yB==X!r^C^G&Ja-(OU`w?LJ3;;ArAFflL<1_@w> zNC9O71OfpC00bcBd6^H{-U8L{2uu7HebcEL)-_fFfH(MyPFtD{GH}5J6tV`J9VoX` UsIPKidS?4-1>f{--~s|C5Mx)2SO5S3 diff --git a/tests/tls/storepass b/tests/tls/storepass deleted file mode 100755 index b1f833ed..00000000 --- a/tests/tls/storepass +++ /dev/null @@ -1 +0,0 @@ -citrusstore From f75591a3835c8af79dd9234e92f4f5a6d9be3969 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 00:42:50 -0600 Subject: [PATCH 107/215] Update gen.sh --- tests/gen.sh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tests/gen.sh b/tests/gen.sh index 109bd83d..25c41485 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -403,13 +403,6 @@ EOF line="$host $server_name" - # Check if the line exists in /etc/hosts - if ! grep -qF "$line" /etc/hosts; then - # Add the line to /etc/hosts - echo "$line" | sudo tee -a /etc/hosts > /dev/null - echo "Entry added to /etc/hosts." - fi - elif [[ "$mutual_auth_maybe" == "n" ]]; then generate_derivative_certs "child" "child" @@ -469,12 +462,6 @@ EOF line="$host $server_name" - # Check if the line exists in /etc/hosts - if ! grep -qF "$line" /etc/hosts; then - # Add the line to /etc/hosts - echo "$line" | sudo tee -a /etc/hosts > /dev/null - echo "Entry added to /etc/hosts." - fi fi fi From f0b0ee5ab134c69e0b77a17096814f5387707e2f Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 01:20:40 -0600 Subject: [PATCH 108/215] Update gen.sh --- tests/gen.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/gen.sh b/tests/gen.sh index 25c41485..4ba567ca 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -445,8 +445,8 @@ EOF default: # List of externally accessible addresses and # ports for this Proximus instance. - - address: $host - port: $port + #- address: $host + # port: $port EOF ) From 86d4d7efe08a2cc0487176f656cbf5f446d4a8a7 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 01:24:25 -0600 Subject: [PATCH 109/215] Update gen.sh --- tests/gen.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/gen.sh b/tests/gen.sh index 4ba567ca..c752440c 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -385,7 +385,7 @@ EOF default: # List of externally accessible addresses and # ports for this Proximus instance. - - address: $server_name + - address: $host port: $port EOF @@ -445,8 +445,8 @@ EOF default: # List of externally accessible addresses and # ports for this Proximus instance. - #- address: $host - # port: $port + - address: $host + port: $port EOF ) From 1f33ea81a28dec147cb570835ff0142b1e9f2775 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 01:27:11 -0600 Subject: [PATCH 110/215] Update gen.sh --- tests/gen.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gen.sh b/tests/gen.sh index c752440c..25c41485 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -385,7 +385,7 @@ EOF default: # List of externally accessible addresses and # ports for this Proximus instance. - - address: $host + - address: $server_name port: $port EOF From 0635fe35880cb71d81fc0b1f55e9a12288bd4ff0 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 02:54:58 -0600 Subject: [PATCH 111/215] CI/CD Pipeline --- .github/workflows/integration_test.yml | 3 +++ tests/assets/call_gen.sh | 2 +- tests/assets/call_gen_normal.sh | 2 +- tests/assets/call_gen_tls.sh | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c9ac1561..f5e3bfc8 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -129,6 +129,8 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts + sudo sed -i.bak 's/127.0.0.1 localhost/0.0.0.0 localhost/' "$hostsPath" + - name: Run unit tests run: | @@ -195,6 +197,7 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + sudo sed -i.bak 's/127.0.0.1 localhost/0.0.0.0 localhost/' "$hostsPath" - name: create config run: | diff --git a/tests/assets/call_gen.sh b/tests/assets/call_gen.sh index f89dd648..da5596ea 100755 --- a/tests/assets/call_gen.sh +++ b/tests/assets/call_gen.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 127.0.0.1 + --host 0.0.0.0 diff --git a/tests/assets/call_gen_normal.sh b/tests/assets/call_gen_normal.sh index c7e16289..b5aeecb1 100755 --- a/tests/assets/call_gen_normal.sh +++ b/tests/assets/call_gen_normal.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 127.0.0.1 + --host 0.0.0.0 diff --git a/tests/assets/call_gen_tls.sh b/tests/assets/call_gen_tls.sh index 9bc0f270..aec49e02 100755 --- a/tests/assets/call_gen_tls.sh +++ b/tests/assets/call_gen_tls.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 127.0.0.1 + --host 0.0.0.0 From a2c943d3882f75179207cc3e6febb7e0d7213dc8 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 02:58:57 -0600 Subject: [PATCH 112/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index f5e3bfc8..027af4cf 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -129,7 +129,7 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts - sudo sed -i.bak 's/127.0.0.1 localhost/0.0.0.0 localhost/' "$hostsPath" + sudo sed -i.bak 's/127.0.0.1 localhost/0.0.0.0 localhost/' /etc/hosts - name: Run unit tests @@ -197,7 +197,7 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - sudo sed -i.bak 's/127.0.0.1 localhost/0.0.0.0 localhost/' "$hostsPath" + sudo sed -i.bak 's/127.0.0.1 localhost/0.0.0.0 localhost/' /etc/hosts - name: create config run: | From 016c5d81677848b5f6a5ac1ebc539ca8fd17cd56 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 03:01:26 -0600 Subject: [PATCH 113/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 027af4cf..c9ac1561 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -129,8 +129,6 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts - sudo sed -i.bak 's/127.0.0.1 localhost/0.0.0.0 localhost/' /etc/hosts - - name: Run unit tests run: | @@ -197,7 +195,6 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - sudo sed -i.bak 's/127.0.0.1 localhost/0.0.0.0 localhost/' /etc/hosts - name: create config run: | From d351bdfafd5ff6c99ce2c62eb3daa8649d57d6ac Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 03:24:33 -0600 Subject: [PATCH 114/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c9ac1561..25f4087c 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -67,7 +67,7 @@ jobs: sleep 40 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 + python -m pytest standard -s --host 0.0.0.0 --port 5000 working-directory: tests test-tls: @@ -139,7 +139,7 @@ jobs: sleep 40 docker ps - python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt -vs working-directory: tests @@ -221,7 +221,7 @@ jobs: cat tls/brawn.key.pem cat tls/brawn.crt - python -m pytest rbac/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs docker ps docker logs aerospike-proximus From 62984a760235c51812662036a6bfc54f908ff25b Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 03:33:24 -0600 Subject: [PATCH 115/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 25f4087c..f3c24a5a 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -7,7 +7,7 @@ on: jobs: test-normal: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 strategy: @@ -71,7 +71,7 @@ jobs: working-directory: tests test-tls: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 strategy: @@ -145,7 +145,7 @@ jobs: test-tls-auth: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 strategy: From c07a2adbf5cb5e9e688c62c9ac75911ac1e80f65 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 12 Jul 2024 03:42:46 -0600 Subject: [PATCH 116/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index f3c24a5a..fd2d7df8 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -8,6 +8,7 @@ on: jobs: test-normal: runs-on: ubuntu-24.04 + continue-on-error: true strategy: @@ -72,6 +73,8 @@ jobs: test-tls: runs-on: ubuntu-24.04 + continue-on-error: true + strategy: @@ -146,6 +149,7 @@ jobs: test-tls-auth: runs-on: ubuntu-24.04 + continue-on-error: true strategy: From 8648ffc623623cf38d40ef8a32146b33a3c11a0b Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 02:05:52 -0600 Subject: [PATCH 117/215] Added service configuration and index_storage for index_create command Added timeouts --- .github/workflows/integration_test.yml | 2 +- src/aerospike_vector_search/admin.py | 153 ++++++--- src/aerospike_vector_search/aio/admin.py | 144 ++++++--- src/aerospike_vector_search/aio/client.py | 79 +++-- .../aio/internal/channel_provider.py | 16 +- src/aerospike_vector_search/client.py | 89 ++++-- .../internal/channel_provider.py | 13 +- .../shared/admin_helpers.py | 56 ++-- .../shared/base_channel_provider.py | 13 +- .../shared/client_helpers.py | 44 ++- src/aerospike_vector_search/types.py | 11 + templates/service.config.json.template | 193 ++++++++++++ tests/service_configs/backoff_multiplier.json | 18 ++ tests/service_configs/client_timeout.json | 9 + .../service_configs/index_create_timeout.json | 21 ++ tests/service_configs/initial_backoff.json | 18 ++ tests/service_configs/master.json | 27 ++ tests/service_configs/max_backoff.json | 18 ++ .../max_backoff_lower_than_initial.json | 18 ++ tests/service_configs/retries.json | 21 ++ .../retryable_status_codes.json | 18 ++ tests/service_configs/transact_timeout.json | 13 + tests/standard/aio/conftest.py | 8 + .../aio/test_admin_client_index_create.py | 132 +++++++- .../aio/test_admin_client_index_drop.py | 19 ++ .../aio/test_admin_client_index_get.py | 20 +- .../aio/test_admin_client_index_get_status.py | 33 +- .../aio/test_admin_client_index_list.py | 12 + tests/standard/aio/test_service_config.py | 297 ++++++++++++++++++ .../standard/aio/test_vector_client_delete.py | 33 +- .../standard/aio/test_vector_client_exists.py | 31 +- tests/standard/aio/test_vector_client_get.py | 37 ++- .../standard/aio/test_vector_client_insert.py | 73 ++++- .../standard/aio/test_vector_client_update.py | 65 +++- .../standard/aio/test_vector_client_upsert.py | 45 ++- tests/standard/aio/test_vector_search.py | 39 ++- .../sync/test_admin_client_index_create.py | 143 ++++++++- .../sync/test_admin_client_index_drop.py | 42 ++- .../sync/test_admin_client_index_get.py | 53 +++- .../test_admin_client_index_get_status.py | 25 +- .../sync/test_admin_client_index_list.py | 26 ++ tests/standard/sync/test_service_config.py | 297 ++++++++++++++++++ .../sync/test_vector_client_delete.py | 39 ++- .../sync/test_vector_client_exists.py | 39 ++- tests/standard/sync/test_vector_client_get.py | 44 ++- .../sync/test_vector_client_insert.py | 54 +++- .../sync/test_vector_client_update.py | 76 ++++- .../sync/test_vector_client_upsert.py | 48 ++- tests/standard/sync/test_vector_search.py | 45 ++- 49 files changed, 2496 insertions(+), 273 deletions(-) create mode 100644 templates/service.config.json.template create mode 100644 tests/service_configs/backoff_multiplier.json create mode 100644 tests/service_configs/client_timeout.json create mode 100644 tests/service_configs/index_create_timeout.json create mode 100644 tests/service_configs/initial_backoff.json create mode 100644 tests/service_configs/master.json create mode 100644 tests/service_configs/max_backoff.json create mode 100644 tests/service_configs/max_backoff_lower_than_initial.json create mode 100644 tests/service_configs/retries.json create mode 100644 tests/service_configs/retryable_status_codes.json create mode 100644 tests/service_configs/transact_timeout.json create mode 100644 tests/standard/aio/test_service_config.py create mode 100644 tests/standard/sync/test_service_config.py diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index fd2d7df8..dc9f38b7 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -9,7 +9,7 @@ jobs: test-normal: runs-on: ubuntu-24.04 continue-on-error: true - + strategy: matrix: diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index 827d0c5d..c7691a11 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -28,6 +28,7 @@ def __init__( root_certificate: Optional[str] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, + service_config_path: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Admin Client. @@ -44,7 +45,7 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key + seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path ) def index_create( @@ -60,6 +61,8 @@ def index_create( sets: Optional[str] = None, index_params: Optional[types.HnswParams] = None, index_meta_data: Optional[dict[str, str]] = None, + index_storage: Optional[types.IndexStorage] = None, + timeout: Optional[int] = None, ) -> None: """ Create an index. @@ -98,11 +101,19 @@ def index_create( sets, index_params, index_meta_data, + index_storage, + timeout, logger, ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + + try: - index_stub.Create(index_create_request, credentials=self._channel_provider._token) + index_stub.Create(index_create_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -114,7 +125,7 @@ def index_create( logger.error("Failed waiting for creation with error: %s", e) raise types.AVSServerError(rpc_error=e) - def index_drop(self, *, namespace: str, name: str) -> None: + def index_drop(self, *, namespace: str, name: str, timeout: Optional[int] = None) -> None: """ Drop an index. @@ -133,10 +144,16 @@ def index_drop(self, *, namespace: str, name: str) -> None: (index_stub, index_drop_request) = self._prepare_index_drop( - namespace, name, logger + namespace, name, timeout, logger ) + + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - index_stub.Drop(index_drop_request, credentials=self._channel_provider._token) + index_stub.Drop(index_drop_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -148,7 +165,7 @@ def index_drop(self, *, namespace: str, name: str) -> None: logger.error("Failed waiting for deletion with error: %s", e) raise types.AVSServerError(rpc_error=e) - def index_list(self) -> list[dict]: + def index_list(self, timeout: Optional[int] = None) -> list[dict]: """ List all indices. @@ -161,16 +178,22 @@ def index_list(self) -> list[dict]: """ - (index_stub, index_list_request) = self._prepare_index_list(logger) + (index_stub, index_list_request) = self._prepare_index_list(timeout, logger) + + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = index_stub.List(index_list_request, credentials=self._channel_provider._token) + response = index_stub.List(index_list_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_list(response) def index_get( - self, *, namespace: str, name: str + self, *, namespace: str, name: str, timeout: Optional[int] = None ) -> dict[str, Union[int, str]]: """ Retrieve the information related with an index. @@ -190,16 +213,21 @@ def index_get( (index_stub, index_get_request) = self._prepare_index_get( - namespace, name, logger + namespace, name, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = index_stub.Get(index_get_request, credentials=self._channel_provider._token) + response = index_stub.Get(index_get_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get(response) - def index_get_status(self, *, namespace: str, name: str) -> int: + def index_get_status(self, *, namespace: str, name: str, timeout: Optional[int] = None) -> int: """ Retrieve the number of records queued to be merged into an index. @@ -223,17 +251,23 @@ def index_get_status(self, *, namespace: str, name: str) -> int: (index_stub, index_get_status_request) = self._prepare_index_get_status( - namespace, name, logger + namespace, name, timeout, logger ) + + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = index_stub.GetStatus(index_get_status_request) + response = index_stub.GetStatus(index_get_status_request, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get_status(response) - def add_user(self, *, username: str, password: str, roles: list[str]) -> int: + def add_user(self, *, username: str, password: str, roles: list[str], timeout: Optional[int] = None) -> int: (user_admin_stub, add_user_request) = self._prepare_add_user( @@ -241,96 +275,143 @@ def add_user(self, *, username: str, password: str, roles: list[str]) -> int: ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + + try: - user_admin_stub.AddUser(add_user_request, credentials=self._channel_provider._token) + user_admin_stub.AddUser(add_user_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - def update_credentials(self, *, username: str, password: str) -> int: + def update_credentials(self, *, username: str, password: str, timeout: Optional[int] = None) -> int: (user_admin_stub, update_credentials_request) = self._prepare_update_credentials( - username, password, logger + username, password, timeout, logger ) + + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + + try: user_admin_stub.UpdateCredentials(update_credentials_request, credentials=self._channel_provider._token) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - def drop_user(self, *, username: str) -> int: + def drop_user(self, *, username: str, timeout: Optional[int] = None) -> int: (user_admin_stub, drop_user_request) = self._prepare_drop_user( - username, logger + username, timeout, logger ) + + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + + try: - user_admin_stub.DropUser(drop_user_request, credentials=self._channel_provider._token) + user_admin_stub.DropUser(drop_user_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - def get_user(self, *, username: str) -> int: + def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: (user_admin_stub, get_user_request) = self._prepare_get_user( - username, logger + username, timeout, logger ) + + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = user_admin_stub.GetUser(get_user_request, credentials=self._channel_provider._token) + response = user_admin_stub.GetUser(get_user_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_get_user(response) - def list_users(self) -> int: + def list_users(self, timeout: Optional[int] = None) -> int: (user_admin_stub, list_users_request) = self._prepare_list_users( - logger + timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = user_admin_stub.ListUsers(list_users_request, credentials=self._channel_provider._token) + response = user_admin_stub.ListUsers(list_users_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_list_users(response) - def grant_roles(self, *, username: str, roles: list[str]) -> int: + def grant_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: (user_admin_stub, grant_roles_request) = self._prepare_grant_roles( - username, roles, logger + username, roles, timeout, logger ) + + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - user_admin_stub.GrantRoles(grant_roles_request, credentials=self._channel_provider._token) + user_admin_stub.GrantRoles(grant_roles_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - def revoke_roles(self, *, username: str, roles: list[str]) -> int: + def revoke_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: (user_admin_stub, revoke_roles_request) = self._prepare_revoke_roles( - username, roles, logger + username, roles, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - user_admin_stub.RevokeRoles(revoke_roles_request, credentials=self._channel_provider._token) + user_admin_stub.RevokeRoles(revoke_roles_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - def list_roles(self) -> int: + def list_roles(self, timeout: Optional[int] = None) -> int: (user_admin_stub, list_roles_request) = self._prepare_list_roles( - logger + timeout, logger ) + + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + + try: - response = user_admin_stub.ListRoles(list_roles_request, credentials=self._channel_provider._token) + response = user_admin_stub.ListRoles(list_roles_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index 053a4528..fb1ca302 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -24,6 +24,7 @@ def __init__( seeds: Union[types.HostPort, tuple[types.HostPort, ...]], listener_name: Optional[str] = None, is_loadbalancer: Optional[bool] = False, + service_config_path: Optional[str] = None, username: Optional[str] = None, password: Optional[str] = None, root_certificate: Optional[str] = None, @@ -45,7 +46,7 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key + seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path ) async def index_create( @@ -61,6 +62,8 @@ async def index_create( sets: Optional[str] = None, index_params: Optional[types.HnswParams] = None, index_meta_data: Optional[dict[str, str]] = None, + index_storage: Optional[types.IndexStorage] = None, + timeout: Optional[int] = None, ) -> None: """ Create an index. @@ -99,11 +102,17 @@ async def index_create( sets, index_params, index_meta_data, + index_storage, + timeout, logger, ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await index_stub.Create(index_create_request, credentials=self._channel_provider._token) + await index_stub.Create(index_create_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -115,7 +124,7 @@ async def index_create( logger.error("Failed waiting for creation with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def index_drop(self, *, namespace: str, name: str) -> None: + async def index_drop(self, *, namespace: str, name: str, timeout: Optional[int] = None) -> None: """ Drop an index. @@ -134,10 +143,15 @@ async def index_drop(self, *, namespace: str, name: str) -> None: await self._channel_provider._is_ready() (index_stub, index_drop_request) = self._prepare_index_drop( - namespace, name, logger + namespace, name, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await index_stub.Drop(index_drop_request, credentials=self._channel_provider._token) + await index_stub.Drop(index_drop_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -149,7 +163,7 @@ async def index_drop(self, *, namespace: str, name: str) -> None: logger.error("Failed waiting for deletion with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def index_list(self) -> list[dict]: + async def index_list(self, timeout: Optional[int] = None) -> list[dict]: """ List all indices. @@ -162,16 +176,21 @@ async def index_list(self) -> list[dict]: """ await self._channel_provider._is_ready() - (index_stub, index_list_request) = self._prepare_index_list(logger) + (index_stub, index_list_request) = self._prepare_index_list(timeout, logger) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = await index_stub.List(index_list_request, credentials=self._channel_provider._token) + response = await index_stub.List(index_list_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_list(response) async def index_get( - self, *, namespace: str, name: str + self, *, namespace: str, name: str, timeout: Optional[int] = None ) -> dict[str, Union[int, str]]: """ Retrieve the information related with an index. @@ -191,16 +210,21 @@ async def index_get( await self._channel_provider._is_ready() (index_stub, index_get_request) = self._prepare_index_get( - namespace, name, logger + namespace, name, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = await index_stub.Get(index_get_request, credentials=self._channel_provider._token) + response = await index_stub.Get(index_get_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get(response) - async def index_get_status(self, *, namespace: str, name: str) -> int: + async def index_get_status(self, *, namespace: str, name: str, timeout: Optional[int] = None) -> int: """ Retrieve the number of records queued to be merged into an index. @@ -224,114 +248,156 @@ async def index_get_status(self, *, namespace: str, name: str) -> int: await self._channel_provider._is_ready() (index_stub, index_get_status_request) = self._prepare_index_get_status( - namespace, name, logger + namespace, name, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = await index_stub.GetStatus(index_get_status_request) + response = await index_stub.GetStatus(index_get_status_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get_status(response) - async def add_user(self, *, username: str, password: str, roles: list[str]) -> int: + async def add_user(self, *, username: str, password: str, roles: list[str], timeout: Optional[int] = None) -> int: await self._channel_provider._is_ready() (user_admin_stub, add_user_request) = self._prepare_add_user( - username, password, roles, logger + username, password, roles, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout try: - await user_admin_stub.AddUser(add_user_request, credentials=self._channel_provider._token) + await user_admin_stub.AddUser(add_user_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def update_credentials(self, *, username: str, password: str) -> int: + async def update_credentials(self, *, username: str, password: str, timeout: Optional[int] = None) -> int: await self._channel_provider._is_ready() (user_admin_stub, update_credentials_request) = self._prepare_update_credentials( - username, password, logger + username, password, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await user_admin_stub.UpdateCredentials(update_credentials_request, credentials=self._channel_provider._token) + await user_admin_stub.UpdateCredentials(update_credentials_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def drop_user(self, *, username: str) -> int: + async def drop_user(self, *, username: str, timeout: Optional[int] = None) -> int: await self._channel_provider._is_ready() (user_admin_stub, drop_user_request) = self._prepare_drop_user( - username, logger + username, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await user_admin_stub.DropUser(drop_user_request, credentials=self._channel_provider._token) + await user_admin_stub.DropUser(drop_user_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def get_user(self, *, username: str) -> int: + async def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: await self._channel_provider._is_ready() (user_admin_stub, get_user_request) = self._prepare_get_user( - username, logger + username, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = await user_admin_stub.GetUser(get_user_request, credentials=self._channel_provider._token) + response = await user_admin_stub.GetUser(get_user_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_get_user(response) - async def list_users(self) -> int: + async def list_users(self, timeout: Optional[int] = None) -> int: await self._channel_provider._is_ready() (user_admin_stub, list_users_request) = self._prepare_list_users( - logger + timeout, logger ) - + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = await user_admin_stub.ListUsers(list_users_request, credentials=self._channel_provider._token) + response = await user_admin_stub.ListUsers(list_users_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_list_users(response) - async def grant_roles(self, *, username: str, roles: list[str]) -> int: + async def grant_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: await self._channel_provider._is_ready() (user_admin_stub, grant_roles_request) = self._prepare_grant_roles( - username, roles, logger + username, roles, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await user_admin_stub.GrantRoles(grant_roles_request, credentials=self._channel_provider._token) + await user_admin_stub.GrantRoles(grant_roles_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def revoke_roles(self, *, username: str, roles: list[str]) -> int: + async def revoke_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: await self._channel_provider._is_ready() (user_admin_stub, revoke_roles_request) = self._prepare_revoke_roles( - username, roles, logger + username, roles, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await user_admin_stub.RevokeRoles(revoke_roles_request, credentials=self._channel_provider._token) + await user_admin_stub.RevokeRoles(revoke_roles_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def list_roles(self) -> int: + async def list_roles(self, timeout: Optional[int] = None) -> int: await self._channel_provider._is_ready() (user_admin_stub, list_roles_request) = self._prepare_list_roles( - logger + timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = await user_admin_stub.ListRoles(list_roles_request, credentials=self._channel_provider._token) + response = await user_admin_stub.ListRoles(list_roles_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index 39928d11..9cda4a0c 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -32,6 +32,7 @@ def __init__( root_certificate: Optional[str] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, + service_config_path: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Vector Client. @@ -49,7 +50,7 @@ def __init__( """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key + seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path ) async def insert( @@ -59,6 +60,7 @@ async def insert( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> None: """ Insert a record into Aerospike Vector Search. @@ -81,11 +83,15 @@ async def insert( await self._channel_provider._is_ready() (transact_stub, insert_request) = self._prepare_insert( - namespace, key, record_data, set_name, logger + namespace, key, record_data, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await transact_stub.Put(insert_request, credentials=self._channel_provider._token) + await transact_stub.Put(insert_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -97,6 +103,7 @@ async def update( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> None: """ Update a record in Aerospike Vector Search. @@ -119,11 +126,15 @@ async def update( await self._channel_provider._is_ready() (transact_stub, update_request) = self._prepare_update( - namespace, key, record_data, set_name, logger + namespace, key, record_data, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await transact_stub.Put(update_request, credentials=self._channel_provider._token) + await transact_stub.Put(update_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -135,6 +146,7 @@ async def upsert( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> None: """ Update a record in Aerospike Vector Search. @@ -157,11 +169,15 @@ async def upsert( await self._channel_provider._is_ready() (transact_stub, upsert_request) = self._prepare_upsert( - namespace, key, record_data, set_name, logger + namespace, key, record_data, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await transact_stub.Put(upsert_request, credentials=self._channel_provider._token) + await transact_stub.Put(upsert_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -173,6 +189,7 @@ async def get( key: Union[int, str, bytes, bytearray], field_names: Optional[list[str]] = None, set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> types.RecordWithKey: """ Read a record from Aerospike Vector Search. @@ -195,10 +212,15 @@ async def get( await self._channel_provider._is_ready() (transact_stub, key, get_request) = self._prepare_get( - namespace, key, field_names, set_name, logger + namespace, key, field_names, set_name, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = await transact_stub.Get(get_request, credentials=self._channel_provider._token) + response = await transact_stub.Get(get_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -206,7 +228,7 @@ async def get( return self._respond_get(response, key) async def exists( - self, *, namespace: str, key: Any, set_name: Optional[str] = None + self, *, namespace: str, key: Any, set_name: Optional[str] = None, timeout: Optional[int] = None, ) -> bool: """ Check if a record exists in Aerospike Vector Search. @@ -227,11 +249,15 @@ async def exists( await self._channel_provider._is_ready() (transact_stub, exists_request) = self._prepare_exists( - namespace, key, set_name, logger + namespace, key, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = await transact_stub.Exists(exists_request, credentials=self._channel_provider._token) + response = await transact_stub.Exists(exists_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -239,7 +265,7 @@ async def exists( return self._respond_exists(response) async def delete( - self, *, namespace: str, key: Any, set_name: Optional[str] = None + self, *, namespace: str, key: Any, set_name: Optional[str] = None, timeout: Optional[int] = None, ) -> None: """ Delete a record from Aerospike Vector Search. @@ -257,11 +283,15 @@ async def delete( await self._channel_provider._is_ready() (transact_stub, delete_request) = self._prepare_delete( - namespace, key, set_name, logger + namespace, key, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - await transact_stub.Delete(delete_request, credentials=self._channel_provider._token) + await transact_stub.Delete(delete_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -274,6 +304,7 @@ async def is_indexed( index_name: str, index_namespace: Optional[str] = None, set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> bool: """ Check if a record is indexed in the Vector DB. @@ -297,10 +328,15 @@ async def is_indexed( await self._channel_provider._is_ready() (transact_stub, is_indexed_request) = self._prepare_is_indexed( - namespace, key, index_name, index_namespace, set_name, logger + namespace, key, index_name, index_namespace, set_name, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = await transact_stub.IsIndexed(is_indexed_request, credentials=self._channel_provider._token) + response = await transact_stub.IsIndexed(is_indexed_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -315,6 +351,7 @@ async def vector_search( limit: int, search_params: Optional[types.HnswSearchParams] = None, field_names: Optional[list[str]] = None, + timeout: Optional[int] = None, ) -> list[types.Neighbor]: """ Perform a Hierarchical Navigable Small World (HNSW) vector search in Aerospike Vector Search. @@ -339,11 +376,15 @@ async def vector_search( await self._channel_provider._is_ready() (transact_stub, vector_search_request) = self._prepare_vector_search( - namespace, index_name, query, limit, search_params, field_names, logger + namespace, index_name, query, limit, search_params, field_names, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - return [self._respond_neighbor(result) async for result in transact_stub.VectorSearch(vector_search_request, credentials=self._channel_provider._token)] + return [self._respond_neighbor(result) async for result in transact_stub.VectorSearch(vector_search_request, credentials=self._channel_provider._token, **kwargs)] except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 4ab9eb0c..6acd6183 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -32,9 +32,11 @@ def __init__( root_certificate: Optional[str] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, + service_config_path: Optional[str] = None, + ) -> None: - super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key) + super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path) self._tend_initalized: asyncio.Event = asyncio.Event() self._tend_ended: asyncio.Event = asyncio.Event() @@ -161,6 +163,13 @@ async def _tend(self): def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: host = re.sub(r"%.*", "", host) + + if self.service_config_json: + options = [] + options.append(("grpc.service_config", self.service_config_json)) + else: + options = None + if self._root_certificate: with open(self._root_certificate, 'rb') as f: root_certificate = f.read() @@ -180,10 +189,11 @@ def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate, certificate_chain=certificate_chain, private_key=private_key) - return grpc.aio.secure_channel(f"{host}:{port}", ssl_credentials) + + return grpc.aio.secure_channel(f"{host}:{port}", ssl_credentials, options=options) else: - return grpc.aio.insecure_channel(f"{host}:{port}") + return grpc.aio.insecure_channel(f"{host}:{port}", options=options) async def _update_token_and_ttl( diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index f8c786d9..572242f5 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -31,6 +31,7 @@ def __init__( root_certificate: Optional[str] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, + service_config_path: Optional[str] = None, ) -> None: """ Initialize the Aerospike Vector Search Vector Client. @@ -48,7 +49,7 @@ def __init__( """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key + seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path ) def insert( @@ -58,6 +59,7 @@ def insert( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> None: """ Insert a record into Aerospike Vector Search. @@ -80,11 +82,15 @@ def insert( (transact_stub, insert_request) = self._prepare_insert( - namespace, key, record_data, set_name, logger + namespace, key, record_data, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - transact_stub.Put(insert_request, credentials=self._channel_provider._token) + transact_stub.Put(insert_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -96,6 +102,7 @@ def update( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> None: """ Update a record in Aerospike Vector Search. @@ -114,15 +121,16 @@ def update( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - - - (transact_stub, update_request) = self._prepare_update( - namespace, key, record_data, set_name, logger + namespace, key, record_data, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - transact_stub.Put(update_request, credentials=self._channel_provider._token) + transact_stub.Put(update_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -134,6 +142,7 @@ def upsert( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> None: """ Update a record in Aerospike Vector Search. @@ -156,11 +165,15 @@ def upsert( (transact_stub, upsert_request) = self._prepare_upsert( - namespace, key, record_data, set_name, logger + namespace, key, record_data, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - transact_stub.Put(upsert_request, credentials=self._channel_provider._token) + transact_stub.Put(upsert_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -172,6 +185,7 @@ def get( key: Union[int, str, bytes, bytearray], field_names: Optional[list[str]] = None, set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> types.RecordWithKey: """ Read a record from Aerospike Vector Search. @@ -194,10 +208,15 @@ def get( (transact_stub, key, get_request) = self._prepare_get( - namespace, key, field_names, set_name, logger + namespace, key, field_names, set_name, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = transact_stub.Get(get_request, credentials=self._channel_provider._token) + response = transact_stub.Get(get_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -205,7 +224,7 @@ def get( return self._respond_get(response, key) def exists( - self, *, namespace: str, key: Any, set_name: Optional[str] = None + self, *, namespace: str, key: Any, set_name: Optional[str] = None, timeout: Optional[int] = None, ) -> bool: """ Check if a record exists in Aerospike Vector Search. @@ -226,11 +245,16 @@ def exists( (transact_stub, exists_request) = self._prepare_exists( - namespace, key, set_name, logger + namespace, key, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + + try: - response = transact_stub.Exists(exists_request, credentials=self._channel_provider._token) + response = transact_stub.Exists(exists_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -238,7 +262,7 @@ def exists( return self._respond_exists(response) def delete( - self, *, namespace: str, key: Any, set_name: Optional[str] = None + self, *, namespace: str, key: Any, set_name: Optional[str] = None, timeout: Optional[int] = None, ) -> None: """ Delete a record from Aerospike Vector Search. @@ -256,11 +280,15 @@ def delete( (transact_stub, delete_request) = self._prepare_delete( - namespace, key, set_name, logger + namespace, key, set_name, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - transact_stub.Delete(delete_request, credentials=self._channel_provider._token) + transact_stub.Delete(delete_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -273,6 +301,7 @@ def is_indexed( index_name: str, index_namespace: Optional[str] = None, set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> bool: """ Check if a record is indexed in the Vector DB. @@ -296,10 +325,15 @@ def is_indexed( (transact_stub, is_indexed_request) = self._prepare_is_indexed( - namespace, key, index_name, index_namespace, set_name, logger + namespace, key, index_name, index_namespace, set_name, timeout, logger ) + + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - response = transact_stub.IsIndexed(is_indexed_request, credentials=self._channel_provider._token) + response = transact_stub.IsIndexed(is_indexed_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -314,6 +348,7 @@ def vector_search( limit: int, search_params: Optional[types.HnswSearchParams] = None, field_names: Optional[list[str]] = None, + timeout: Optional[int] = None, ) -> list[types.Neighbor]: """ Perform a Hierarchical Navigable Small World (HNSW) vector search in Aerospike Vector Search. @@ -338,11 +373,15 @@ def vector_search( (transact_stub, vector_search_request) = self._prepare_vector_search( - namespace, index_name, query, limit, search_params, field_names, logger + namespace, index_name, query, limit, search_params, field_names, timeout, logger ) + kwargs = {} + if timeout is not None: + kwargs['timeout'] = timeout + try: - return [self._respond_neighbor(result) for result in transact_stub.VectorSearch(vector_search_request, credentials=self._channel_provider._token)] + return [self._respond_neighbor(result) for result in transact_stub.VectorSearch(vector_search_request, credentials=self._channel_provider._token, **kwargs)] except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -354,7 +393,7 @@ def wait_for_index_completion( name: str, timeout: Optional[int] = sys.maxsize, wait_interval: Optional[int] = 12, - validation_threshold: Optional[int] = 2, + validation_threshold: Optional[int] = 3, ) -> None: """ Wait for the index to have no pending index update operations. @@ -387,10 +426,10 @@ def wait_for_index_completion( validation_count, index_completion_request, ) = self._prepare_wait_for_index_waiting(namespace, name, wait_interval) + while True: try: index_status = index_stub.GetStatus(index_completion_request, credentials=self._channel_provider._token) - except grpc.RpcError as e: if e.code() == grpc.StatusCode.UNAVAILABLE: continue @@ -406,7 +445,7 @@ def wait_for_index_completion( validation_count += 1 else: validation_count = 0 - time.sleep(wait_interval) + time.sleep(wait_interval) def close(self): """ diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index 3e6dd2cd..4672fa18 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -30,8 +30,9 @@ def __init__( root_certificate: Optional[str] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, + service_config_path: Optional[str] = None, ) -> None: - super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key) + super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path) self._tend_ended = threading.Event() self._timer = None self._tend() @@ -124,6 +125,12 @@ def _tend(self): def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: host = re.sub(r"%.*", "", host) + if self.service_config_json: + options = [] + options.append(("grpc.service_config", self.service_config_json)) + else: + options = None + if self._root_certificate: with open(self._root_certificate, 'rb') as f: root_certificate = f.read() @@ -142,10 +149,10 @@ def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate, certificate_chain=certificate_chain, private_key=private_key) - return grpc.secure_channel(f"{host}:{port}", ssl_credentials) + return grpc.secure_channel(f"{host}:{port}", ssl_credentials, options=options) else: - return grpc.insecure_channel(f"{host}:{port}") + return grpc.insecure_channel(f"{host}:{port}", options=options) def _update_token_and_ttl( self, diff --git a/src/aerospike_vector_search/shared/admin_helpers.py b/src/aerospike_vector_search/shared/admin_helpers.py index 392b6b12..4d9f582a 100644 --- a/src/aerospike_vector_search/shared/admin_helpers.py +++ b/src/aerospike_vector_search/shared/admin_helpers.py @@ -32,12 +32,14 @@ def _prepare_index_create( sets, index_params, index_meta_data, + index_storage, + timeout, logger, ) -> None: logger.debug( "Creating index: namespace=%s, name=%s, vector_field=%s, dimensions=%d, vector_distance_metric=%s, " - "sets=%s, index_params=%s, index_meta_data=%s", + "sets=%s, index_params=%s, index_meta_data=%s, index_storage=%s, timeout=%s", namespace, name, vector_field, @@ -46,12 +48,17 @@ def _prepare_index_create( sets, index_params, index_meta_data, + index_storage, + timeout ) if sets and not sets.strip(): sets = None if index_params != None: index_params = index_params._to_pb2() + if index_storage != None: + index_storage = index_storage._to_pb2() + id = self._get_index_id(namespace, name) vector_distance_metric = vector_distance_metric.value @@ -65,31 +72,32 @@ def _prepare_index_create( field=vector_field, dimensions=dimensions, labels=index_meta_data, + storage=index_storage ) return (index_stub, index_create_request) - def _prepare_index_drop(self, namespace, name, logger) -> None: + def _prepare_index_drop(self, namespace, name, timeout, logger) -> None: - logger.debug("Dropping index: namespace=%s, name=%s", namespace, name) + logger.debug("Dropping index: namespace=%s, name=%s, timeout=%s", namespace, name, timeout) index_stub = self._get_index_stub() index_drop_request = self._get_index_id(namespace, name) return (index_stub, index_drop_request) - def _prepare_index_list(self, logger) -> None: + def _prepare_index_list(self, timeout, logger) -> None: - logger.debug("Getting index list") + logger.debug("Getting index list: timeout=%s", timeout) index_stub = self._get_index_stub() index_list_request = empty return (index_stub, index_list_request) - def _prepare_index_get(self, namespace, name, logger) -> None: + def _prepare_index_get(self, namespace, name, timeout, logger) -> None: logger.debug( - "Getting index information: namespace=%s, name=%s", namespace, name + "Getting index information: namespace=%s, name=%s, timeout=%s", namespace, name, timeout ) index_stub = self._get_index_stub() @@ -97,17 +105,17 @@ def _prepare_index_get(self, namespace, name, logger) -> None: return (index_stub, index_get_request) - def _prepare_index_get_status(self, namespace, name, logger) -> None: + def _prepare_index_get_status(self, namespace, name, timeout, logger) -> None: - logger.debug("Getting index status: namespace=%s, name=%s", namespace, name) + logger.debug("Getting index status: namespace=%s, name=%s, timeout=%s", namespace, name, timeout) index_stub = self._get_index_stub() index_get_status_request = self._get_index_id(namespace, name) return (index_stub, index_get_status_request) - def _prepare_add_user(self, username, password, roles, logger) -> None: - logger.debug("Getting index status: username=%s, password=%s, roles=%s", username, password, roles) + def _prepare_add_user(self, username, password, roles, timeout, logger) -> None: + logger.debug("Getting index status: username=%s, password=%s, roles=%s, timeout=%s", username, password, roles, timeout) user_admin_stub = self._get_user_admin_stub() credentials = helpers._get_credentials(username, password) @@ -115,8 +123,8 @@ def _prepare_add_user(self, username, password, roles, logger) -> None: return (user_admin_stub, add_user_request) - def _prepare_update_credentials(self, username, password, logger) -> None: - logger.debug("Getting index status: username=%s, password=%s", username, password) + def _prepare_update_credentials(self, username, password, timeout, logger) -> None: + logger.debug("Getting index status: username=%s, password=%s, timeout=%s", username, password, timeout) user_admin_stub = self._get_user_admin_stub() credentials = helpers._get_credentials(username, password) @@ -124,23 +132,23 @@ def _prepare_update_credentials(self, username, password, logger) -> None: return (user_admin_stub, update_user_request) - def _prepare_drop_user(self, username, logger) -> None: - logger.debug("Getting index status: username=%s", username) + def _prepare_drop_user(self, username, timeout, logger) -> None: + logger.debug("Getting index status: username=%s, timeout=%s", username, timeout) user_admin_stub = self._get_user_admin_stub() drop_user_request = user_admin_pb2.DropUserRequest(username=username) return (user_admin_stub, drop_user_request) - def _prepare_get_user(self, username, logger) -> None: - logger.debug("Getting index status: username=%s", username) + def _prepare_get_user(self, username, timeout, logger) -> None: + logger.debug("Getting index status: username=%s, timeout=%s", username, timeout) user_admin_stub = self._get_user_admin_stub() get_user_request = user_admin_pb2.GetUserRequest(username=username) return (user_admin_stub, get_user_request) - def _prepare_list_users(self, logger) -> None: + def _prepare_list_users(self, timeout, logger) -> None: logger.debug("Getting index status") user_admin_stub = self._get_user_admin_stub() @@ -148,24 +156,24 @@ def _prepare_list_users(self, logger) -> None: return (user_admin_stub, list_users_request) - def _prepare_grant_roles(self, username, roles, logger) -> None: - logger.debug("Getting index status: username=%s, roles=%s", username, roles) + def _prepare_grant_roles(self, username, roles, timeout, logger) -> None: + logger.debug("Getting index status: username=%s, roles=%s, timeout=%s", username, roles, timeout) user_admin_stub = self._get_user_admin_stub() grant_roles_request = user_admin_pb2.GrantRolesRequest(username=username, roles=roles) return (user_admin_stub, grant_roles_request) - def _prepare_revoke_roles(self, username, roles, logger) -> None: - logger.debug("Getting index status: username=%s, roles=%s", username, roles) + def _prepare_revoke_roles(self, username, roles, timeout, logger) -> None: + logger.debug("Getting index status: username=%s, roles=%s, timeout=%s", username, roles, timeout) user_admin_stub = self._get_user_admin_stub() revoke_roles_request = user_admin_pb2.RevokeRolesRequest(username=username, roles=roles) return (user_admin_stub, revoke_roles_request) - def _prepare_list_roles(self, logger) -> None: - logger.debug("Getting index status") + def _prepare_list_roles(self, timeout, logger) -> None: + logger.debug("Getting index status: timeout=%s", timeout) user_admin_stub = self._get_user_admin_stub() list_roles_request = empty diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index e2f8ed55..acb455bf 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -1,13 +1,15 @@ import logging import random import time -import jwt from typing import Optional, Union +import json +import jwt import re import grpc + from .. import types from . import helpers @@ -40,10 +42,19 @@ def __init__( root_certificate: Optional[str] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, + service_config_path: Optional[str] = None + ) -> None: self.seeds: tuple[types.HostPort, ...] = seeds self.listener_name: Optional[str] = listener_name self._is_loadbalancer: Optional[bool] = is_loadbalancer + + if service_config_path: + with open(service_config_path, 'rb') as f: + self.service_config_json = f.read() + else: + self.service_config_json = None + self._credentials = helpers._get_credentials(username, password) if self._credentials: self._token = True diff --git a/src/aerospike_vector_search/shared/client_helpers.py b/src/aerospike_vector_search/shared/client_helpers.py index acdd90ac..ad3f1b67 100644 --- a/src/aerospike_vector_search/shared/client_helpers.py +++ b/src/aerospike_vector_search/shared/client_helpers.py @@ -16,15 +16,16 @@ def _prepare_seeds(self, seeds) -> None: return helpers._prepare_seeds(seeds) def _prepare_put( - self, namespace, key, record_data, set_name, write_type, logger + self, namespace, key, record_data, set_name, write_type, timeout, logger ) -> None: logger.debug( - "Putting record: namespace=%s, key=%s, record_data:%s, set_name:%s", + "Putting record: namespace=%s, key=%s, record_data:%s, set_name:%s, timeout:%s", namespace, key, record_data, set_name, + timeout ) key = self._get_key(namespace, set_name, key) @@ -50,39 +51,42 @@ def _prepare_put( return (transact_stub, put_request) - def _prepare_insert(self, namespace, key, record_data, set_name, logger) -> None: + def _prepare_insert(self, namespace, key, record_data, set_name, timeout, logger) -> None: return self._prepare_put( namespace, key, record_data, set_name, transact_pb2.WriteType.INSERT_ONLY, + timeout, logger, ) - def _prepare_update(self, namespace, key, record_data, set_name, logger) -> None: + def _prepare_update(self, namespace, key, record_data, set_name, timeout, logger) -> None: return self._prepare_put( namespace, key, record_data, set_name, transact_pb2.WriteType.UPDATE_ONLY, + timeout, logger, ) - def _prepare_upsert(self, namespace, key, record_data, set_name, logger) -> None: + def _prepare_upsert(self, namespace, key, record_data, set_name, timeout, logger) -> None: return self._prepare_put( - namespace, key, record_data, set_name, transact_pb2.WriteType.UPSERT, logger + namespace, key, record_data, set_name, transact_pb2.WriteType.UPSERT, timeout, logger ) - def _prepare_get(self, namespace, key, field_names, set_name, logger) -> None: + def _prepare_get(self, namespace, key, field_names, set_name, timeout, logger) -> None: logger.debug( - "Getting record: namespace=%s, key=%s, field_names:%s, set_name:%s", + "Getting record: namespace=%s, key=%s, field_names:%s, set_name:%s, timeout:%s", namespace, key, field_names, set_name, + timeout, ) key = self._get_key(namespace, set_name, key) @@ -93,13 +97,14 @@ def _prepare_get(self, namespace, key, field_names, set_name, logger) -> None: return (transact_stub, key, get_request) - def _prepare_exists(self, namespace, key, set_name, logger) -> None: + def _prepare_exists(self, namespace, key, set_name, timeout, logger) -> None: logger.debug( - "Getting record existence: namespace=%s, key=%s, set_name:%s", + "Getting record existence: namespace=%s, key=%s, set_name:%s, timeout:%s", namespace, key, set_name, + timeout, ) key = self._get_key(namespace, set_name, key) @@ -109,13 +114,14 @@ def _prepare_exists(self, namespace, key, set_name, logger) -> None: return (transact_stub, exists_request) - def _prepare_delete(self, namespace, key, set_name, logger) -> None: + def _prepare_delete(self, namespace, key, set_name, timeout, logger) -> None: logger.debug( - "Deleting record: key=%s", + "Deleting record: namespace=%s, key=%s, set_name=%s, timeout:%s", namespace, key, set_name, + timeout, ) key = self._get_key(namespace, set_name, key) @@ -126,16 +132,17 @@ def _prepare_delete(self, namespace, key, set_name, logger) -> None: return (transact_stub, delete_request) def _prepare_is_indexed( - self, namespace, key, index_name, index_namespace, set_name, logger + self, namespace, key, index_name, index_namespace, set_name, timeout, logger ) -> None: logger.debug( - "Checking if index exists: namespace=%s, key=%s, index_name=%s, index_namespace=%s, set_name=%s", + "Checking if index exists: namespace=%s, key=%s, index_name=%s, index_namespace=%s, set_name=%s, timeout:%s", namespace, key, index_name, index_namespace, set_name, + timeout, ) if not index_namespace: @@ -149,17 +156,18 @@ def _prepare_is_indexed( return (transact_stub, is_indexed_request) def _prepare_vector_search( - self, namespace, index_name, query, limit, search_params, field_names, logger + self, namespace, index_name, query, limit, search_params, field_names, timeout, logger ) -> None: logger.debug( - "Performing vector search: namespace=%s, index_name=%s, query=%s, limit=%s, search_params=%s, field_names=%s", + "Performing vector search: namespace=%s, index_name=%s, query=%s, limit=%s, search_params=%s, field_names=%s, timeout:%s", namespace, index_name, query, limit, search_params, field_names, + timeout ) if search_params != None: @@ -241,7 +249,9 @@ def _get_key( self, namespace: str, set: str, key: Union[int, str, bytes, bytearray] ): if isinstance(key, str): - key = types_pb2.Key(namespace=namespace, set=set, stringValue=key) + key = types_pb2.Key(namespace=namespace, set=None, stringValue=key) + + elif isinstance(key, int): key = types_pb2.Key(namespace=namespace, set=set, longValue=key) elif isinstance(key, (bytes, bytearray)): diff --git a/src/aerospike_vector_search/types.py b/src/aerospike_vector_search/types.py index 55395e85..db3face7 100644 --- a/src/aerospike_vector_search/types.py +++ b/src/aerospike_vector_search/types.py @@ -244,6 +244,17 @@ def _to_pb2(self): params.ef = self.ef return params +class IndexStorage(object): + def __init__(self, *, namespace: Optional[str] = None, set_name: Optional[str] = None) -> None: + self.namespace = namespace + self.set_name = set_name + + def _to_pb2(self): + index_storage = types_pb2.IndexStorage() + index_storage.namespace = self.namespace + index_storage.set = self.set_name + return index_storage + class AVSError(Exception): """ diff --git a/templates/service.config.json.template b/templates/service.config.json.template new file mode 100644 index 00000000..aef01618 --- /dev/null +++ b/templates/service.config.json.template @@ -0,0 +1,193 @@ +# Service Configs for the AVS Client + +The AVS Client leverages the gRPC framework for client-server communications. + +gRPC uses a service config to specify how gRPC clients should behave when interacting with a gRPC server. + +The following document provides several JSON examples detailing how to create +service configs for various situations. + +For more detailed info on Servivce Configs see [the gRPC documentation](https://grpc.io/docs/guides/service-config/) + +## Method Configs + +Service configs use a list of method configs. + +Method configs contain expected behaviors for client-server interactions as well as a scope which determines which methods the behaviors will apply to. + +### Scoping + +Method configs can have one of three scopes: + +#### Client-level +Client-level configurations apply to all methods. + +The following specifies a 1 second timeout for all methods: + +```JSON +{ + "methodConfig": [ + + { + "name": [{}], + "timeout": "1s" + }, + ] +} +``` +#### Service-Level +Service-level configuration apply to a group of methods defined by the service. + +AVS Clients contain 5 different services. + +Publicly exposed services and their associated methods are list below + +- IndexService + - index_create + - index_drop + - index_list + - index_get + - index_get_status +- Transact + - get + - insert + - update + - upsert + - exists + - delete + - is_indexed + - vector_serach +- UserAdminService + - add_user + - update_credentials + - drop_user + - get_user + - list_users + - grant_roles + - revoke_roles + - list_roles + +Private services include: + +- AuthService + - Used internally to faciliate role-based access control (RBAC) authentication. +- About + - Used internally to discover the server version. +- ClusterInfo + - Used internally to gather information about the cluster in order to tend to the connection. + +The following specifies a 2 second timeout for all `Transact` methods: + +```JSON +{ + "methodConfig": [ + { + "name": [ + { + "service": "Transact" + } + ], + "timeout": "2s" + }, + ] +} +``` + +#### Method-Level + +Method level configurations only apply the behavior to one gRPC method (ex. put, vector_search, index_create). + +While AVS Python Client methods follow the lowercase_underscore convention, gRPC methods use UpperCamelCase convention. + +For example, `client.vector_search` use the gRPC method `VectorSearch`. + +However, the AVS Python Client method name and the gRPC method name may not be consistent. Please consult this chart determine which gRPC methods correspond with a given AVS Client method. + +| Methods | | +|-----------------------|-----------------------| +| - index_create | - Create | +| - index_drop | - Drop | +| - index_list | - List | +| - index_get | - Get | +| - index_get_status | - GetStatus | +| - insert | - Put | +| - update | - Put | +| - upsert | - Put | +| - get | - Get | +| - exists | - Exists | +| - delete | - Delete | +| - is_indexed | - IsIndexed | +| - vector_search | - VectorSearch | +| - add_user | - AddUser | +| - update_credentials | - UpdateCredentials | +| - drop_user | - DropUser | +| - get_user | - GetUser | +| - list_users | - ListUsers | +| - grant_roles | - GrantRoles | +| - revoke_roles | - RevokeRoles | +| - list_roles | - ListRoles | + +The following specifies a 2 second timeout for `client.get` and `client.exists`: + +```JSON +{ + "methodConfig": [ + { + "name": [ + { + "service": "Transact", + "method" : "Get", + }, + { + "service": "Transact", + "method" : "Exists", + } + ], + "timeout": "2s" + }, + ] +} +``` + +### Specificity over Generality + +When deciding which service config to use, gRPC will select the configuration which is most specific to the stub call +being made. + +Consider the following configuration: + +```JSON +{ + "methodConfig": [ + + { + "name": [{}], + "timeout": "1s" + }, + { + "name": [ + { + "service": "Transact" + } + ], + "timeout": "2s" + }, + { + "name": [ + { + "service": "IndexService", + "method": "Create" + } + ], + "timeout": "3s", + }, + + ] +} +``` + +For this configuration, `client.index_create` will have a 3 second timeout, all Transact Service methods will have a 2 second timeout, and all other methods will have a 1 second timeout + + +### Behaviors + diff --git a/tests/service_configs/backoff_multiplier.json b/tests/service_configs/backoff_multiplier.json new file mode 100644 index 00000000..b23d7dff --- /dev/null +++ b/tests/service_configs/backoff_multiplier.json @@ -0,0 +1,18 @@ +{ + "methodConfig": [ + { + "name": [ + {} + ], + "retryPolicy": { + "maxAttempts": 4, + "initialBackoff": "1s", + "maxBackoff": "5s", + "backoffMultiplier": 3, + "retryableStatusCodes": [ + "ALREADY_EXISTS" + ] + } + } + ] +} \ No newline at end of file diff --git a/tests/service_configs/client_timeout.json b/tests/service_configs/client_timeout.json new file mode 100644 index 00000000..38c1718e --- /dev/null +++ b/tests/service_configs/client_timeout.json @@ -0,0 +1,9 @@ +{ + "methodConfig": [ + + { + "name": [{}], + "timeout": "1s" + }, + ] +} \ No newline at end of file diff --git a/tests/service_configs/index_create_timeout.json b/tests/service_configs/index_create_timeout.json new file mode 100644 index 00000000..ef48a926 --- /dev/null +++ b/tests/service_configs/index_create_timeout.json @@ -0,0 +1,21 @@ +{ + "methodConfig": [ + { + "name": [ + { + "service": "IndexService", + "method": "Create" + } + ], + "timeout": "3s", + "retryPolicy": { + "maxAttempts": 5, + "initialBackoff": "1s", + "maxBackoff": "1s", + "backoffMultiplier": 1, + "retryableStatusCodes": ["ALREADY_EXISTS"], + }, + }, + + ] +} \ No newline at end of file diff --git a/tests/service_configs/initial_backoff.json b/tests/service_configs/initial_backoff.json new file mode 100644 index 00000000..e5e4ca11 --- /dev/null +++ b/tests/service_configs/initial_backoff.json @@ -0,0 +1,18 @@ +{ + "methodConfig": [ + { + "name": [ + {} + ], + "retryPolicy": { + "maxAttempts": 2, + "initialBackoff": "5s", + "maxBackoff": "1s", + "backoffMultiplier": 1, + "retryableStatusCodes": [ + "ALREADY_EXISTS" + ] + } + } + ] +} \ No newline at end of file diff --git a/tests/service_configs/master.json b/tests/service_configs/master.json new file mode 100644 index 00000000..40489578 --- /dev/null +++ b/tests/service_configs/master.json @@ -0,0 +1,27 @@ +{ + "methodConfig": [ + + { + "name": [{}], + "timeout": "1s" + }, + { + "name": [ + { + "service": "Transact" + } + ], + "timeout": "2s" + }, + { + "name": [ + { + "service": "IndexService", + "method": "Create" + } + ], + "timeout": "3s" + } + + ] +} \ No newline at end of file diff --git a/tests/service_configs/max_backoff.json b/tests/service_configs/max_backoff.json new file mode 100644 index 00000000..e78512d6 --- /dev/null +++ b/tests/service_configs/max_backoff.json @@ -0,0 +1,18 @@ +{ + "methodConfig": [ + { + "name": [ + {} + ], + "retryPolicy": { + "maxAttempts": 4, + "initialBackoff": "1s", + "maxBackoff": "1s", + "backoffMultiplier": 2, + "retryableStatusCodes": [ + "ALREADY_EXISTS" + ] + } + } + ] +} \ No newline at end of file diff --git a/tests/service_configs/max_backoff_lower_than_initial.json b/tests/service_configs/max_backoff_lower_than_initial.json new file mode 100644 index 00000000..8b0a56ec --- /dev/null +++ b/tests/service_configs/max_backoff_lower_than_initial.json @@ -0,0 +1,18 @@ +{ + "methodConfig": [ + { + "name": [ + {} + ], + "retryPolicy": { + "maxAttempts": 5, + "initialBackoff": "2s", + "maxBackoff": "1s", + "backoffMultiplier": 2, + "retryableStatusCodes": [ + "ALREADY_EXISTS" + ] + } + } + ] +} \ No newline at end of file diff --git a/tests/service_configs/retries.json b/tests/service_configs/retries.json new file mode 100644 index 00000000..cdc9d078 --- /dev/null +++ b/tests/service_configs/retries.json @@ -0,0 +1,21 @@ +{ + "methodConfig": [ + { + "name": [ + { + "service": "aerospike.vector.IndexService", + "method": "Create" + } + ], + "retryPolicy": { + "maxAttempts": 5, + "initialBackoff": "1s", + "maxBackoff": "1s", + "backoffMultiplier": 1, + "retryableStatusCodes": [ + "ALREADY_EXISTS" + ] + } + } + ] +} \ No newline at end of file diff --git a/tests/service_configs/retryable_status_codes.json b/tests/service_configs/retryable_status_codes.json new file mode 100644 index 00000000..ddcb3ceb --- /dev/null +++ b/tests/service_configs/retryable_status_codes.json @@ -0,0 +1,18 @@ +{ + "methodConfig": [ + { + "name": [ + {} + ], + "retryPolicy": { + "maxAttempts": 2, + "initialBackoff": "5s", + "maxBackoff": "1s", + "backoffMultiplier": 1, + "retryableStatusCodes": [ + "NOT_FOUND" + ] + } + } + ] +} \ No newline at end of file diff --git a/tests/service_configs/transact_timeout.json b/tests/service_configs/transact_timeout.json new file mode 100644 index 00000000..cb7ca540 --- /dev/null +++ b/tests/service_configs/transact_timeout.json @@ -0,0 +1,13 @@ +{ + "methodConfig": [ + + { + "name": [ + { + "service": "Transact" + } + ], + "timeout": "2s" + }, + ] +} \ No newline at end of file diff --git a/tests/standard/aio/conftest.py b/tests/standard/aio/conftest.py index 638263ff..d55d9d6e 100644 --- a/tests/standard/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -24,6 +24,14 @@ def username(request): def password(request): return request.config.getoption("--password") +@pytest.fixture(scope="module", autouse=True) +def host(request): + return request.config.getoption("--host") + +@pytest.fixture(scope="module", autouse=True) +def port(request): + return request.config.getoption("--port") + @pytest.fixture(scope="module", autouse=True) async def drop_all_indexes(host, port, username, password, root_certificate, certificate_chain, private_key): async with AdminClient( diff --git a/tests/standard/aio/test_admin_client_index_create.py b/tests/standard/aio/test_admin_client_index_create.py index 66b8d0ca..ab2c621a 100644 --- a/tests/standard/aio/test_admin_client_index_create.py +++ b/tests/standard/aio/test_admin_client_index_create.py @@ -1,5 +1,7 @@ import pytest -from aerospike_vector_search import types +from aerospike_vector_search import types, AVSServerError +import grpc + from ...utils import index_strategy from .aio_utils import drop_specified_index from hypothesis import given, settings, Verbosity @@ -15,6 +17,8 @@ def __init__( sets, index_params, index_meta_data, + index_storage, + timeout ): self.namespace = namespace self.vector_field = vector_field @@ -26,6 +30,8 @@ def __init__( self.sets = sets self.index_params = index_params self.index_meta_data = index_meta_data + self.index_storage = index_storage + self.timeout = timeout @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @@ -41,6 +47,8 @@ def __init__( sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ) ], ) @@ -56,6 +64,8 @@ async def test_index_create(session_admin_client, test_case, random_name): sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = await session_admin_client.index_list() found = False @@ -91,6 +101,8 @@ async def test_index_create(session_admin_client, test_case, random_name): sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -100,6 +112,8 @@ async def test_index_create(session_admin_client, test_case, random_name): sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), ], ) @@ -113,6 +127,8 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) @@ -154,6 +170,8 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -163,6 +181,8 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -172,6 +192,8 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -181,6 +203,8 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), ], ) @@ -198,6 +222,8 @@ async def test_index_create_with_vector_distance_metric( sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = await session_admin_client.index_list() found = False @@ -233,6 +259,8 @@ async def test_index_create_with_vector_distance_metric( sets="Demo", index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -242,6 +270,8 @@ async def test_index_create_with_vector_distance_metric( sets="Cheese", index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), ], ) @@ -256,6 +286,8 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = await session_admin_client.index_list() found = False @@ -295,6 +327,8 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na ef=400, ), index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -308,6 +342,8 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na ef=25, ), index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -321,6 +357,8 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na ) ), index_meta_data=None, + index_storage=None, + timeout=None, ), ], ) @@ -334,6 +372,8 @@ async def test_index_create_with_index_params(session_admin_client, test_case, r sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = await session_admin_client.index_list() found = False @@ -369,6 +409,8 @@ async def test_index_create_with_index_params(session_admin_client, test_case, r sets=None, index_params=None, index_meta_data={"size": "large", "price": "$4.99", "currencyType": "CAN"}, + index_storage=None, + timeout=None, ) ], ) @@ -384,6 +426,8 @@ async def test_index_create_index_meta_data(session_admin_client, test_case, ran sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = await session_admin_client.index_list() found = False @@ -404,3 +448,89 @@ async def test_index_create_index_meta_data(session_admin_client, test_case, ran assert found == True await drop_specified_index(session_admin_client, test_case.namespace, random_name) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + index_create_test_case( + namespace="test", + vector_field="example_14", + dimensions=1024, + vector_distance_metric=None, + sets=None, + index_params=None, + index_meta_data=None, + index_storage=types.IndexStorage(namespace="test", set_name="foo"), + timeout=None, + ), + ], +) +async def test_index_create_index_storage(session_admin_client, test_case, random_name): + await session_admin_client.index_create( + namespace=test_case.namespace, + name=random_name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + vector_distance_metric=test_case.vector_distance_metric, + sets=test_case.sets, + index_params=test_case.index_params, + index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout + ) + results = await session_admin_client.index_list() + found = False + for result in results: + if result['id']['name'] == test_case.name: + found = True + assert result['id']['namespace'] == test_case.namespace + assert result['dimensions'] == test_case.dimensions + assert result['field'] == test_case.vector_field + assert result['hnsw_params']['m'] == 16 + assert result['hnsw_params']['ef_construction'] == 100 + assert result['hnsw_params']['ef'] == 100 + assert result['hnsw_params']['batching_params']['max_records'] == 100000 + assert result['hnsw_params']['batching_params']['interval'] == 30000 + assert result['hnsw_params']['batching_params']['disabled'] == False + assert result['storage']['namespace'] == test_case.index_storage.namespace + assert result['storage']['set'] == test_case.index_storage.set_name + assert found == True + + +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + index_create_test_case( + namespace="test", + vector_field="example_15", + dimensions=1024, + vector_distance_metric=None, + sets=None, + index_params=None, + index_meta_data=None, + index_storage=None, + timeout=0, + ), + ], +) +async def test_index_create_timeout(session_admin_client, test_case, random_name): + + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + + await session_admin_client.index_create( + namespace=test_case.namespace, + name=random_name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + vector_distance_metric=test_case.vector_distance_metric, + sets=test_case.sets, + index_params=test_case.index_params, + index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/aio/test_admin_client_index_drop.py b/tests/standard/aio/test_admin_client_index_drop.py index ac8d6bf4..bb257f00 100644 --- a/tests/standard/aio/test_admin_client_index_drop.py +++ b/tests/standard/aio/test_admin_client_index_drop.py @@ -1,4 +1,6 @@ import pytest +from aerospike_vector_search import AVSServerError +import grpc from ...utils import index_strategy @@ -24,3 +26,20 @@ async def test_index_drop(session_admin_client, empty_test_case, random_name): for index in result: assert index["id"]["name"] != random_name + +@pytest.mark.parametrize("empty_test_case",[None, None]) +@given(random_name=index_strategy()) +@settings(max_examples=1, deadline=1000) +async def test_index_drop_timeout(session_admin_client, empty_test_case, random_name): + await session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="art", + dimensions=1024, + ) + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + + await session_admin_client.index_drop(namespace="test", name=random_name, timeout=0) + + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/aio/test_admin_client_index_get.py b/tests/standard/aio/test_admin_client_index_get.py index e6911405..bf566be4 100644 --- a/tests/standard/aio/test_admin_client_index_get.py +++ b/tests/standard/aio/test_admin_client_index_get.py @@ -3,7 +3,8 @@ from .aio_utils import drop_specified_index from hypothesis import given, settings, Verbosity - +from aerospike_vector_search import AVSServerError +import grpc @pytest.mark.parametrize("empty_test_case",[None, None]) @@ -34,3 +35,20 @@ async def test_index_get(session_admin_client, empty_test_case, random_name): assert result["storage"]["set"] == random_name await drop_specified_index(session_admin_client, "test", random_name) + +@pytest.mark.parametrize("empty_test_case",[None, None]) +@given(random_name=index_strategy()) +@settings(max_examples=1, deadline=1000) +async def test_index_get_timeout(session_admin_client, empty_test_case, random_name): + + + for i in range(10): + try: + result = await session_admin_client.index_get( + namespace="test", name=random_name, timeout=0 + ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/aio/test_admin_client_index_get_status.py b/tests/standard/aio/test_admin_client_index_get_status.py index 7cf06ab1..be42960c 100644 --- a/tests/standard/aio/test_admin_client_index_get_status.py +++ b/tests/standard/aio/test_admin_client_index_get_status.py @@ -3,6 +3,10 @@ from .aio_utils import drop_specified_index from hypothesis import given, settings, Verbosity +from aerospike_vector_search import types, AVSServerError +import grpc + + @pytest.mark.parametrize("empty_test_case",[None, None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @@ -18,4 +22,31 @@ async def test_index_get_status(session_admin_client, empty_test_case, random_na namespace="test", name=random_name ) assert result == 0 - await drop_specified_index(session_admin_client, "test", random_name) \ No newline at end of file + await drop_specified_index(session_admin_client, "test", random_name) + +@pytest.mark.parametrize("empty_test_case",[None, None]) +@given(random_name=index_strategy()) +@settings(max_examples=1, deadline=1000) +async def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name): + try: + await session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="science", + dimensions=1024, + ) + except Exception as e: + pass + + for i in range(25): + try: + result = await session_admin_client.index_get_status( + namespace="test", name=random_name, timeout=0 + ) + print(result) + except AVSServerError as se: + print(se.rpc_error.code()) + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/aio/test_admin_client_index_list.py b/tests/standard/aio/test_admin_client_index_list.py index 16dff127..d1642daa 100644 --- a/tests/standard/aio/test_admin_client_index_list.py +++ b/tests/standard/aio/test_admin_client_index_list.py @@ -1,5 +1,10 @@ import pytest +from aerospike_vector_search import AVSServerError + +import pytest +import grpc + from ...utils import index_strategy from .aio_utils import drop_specified_index from hypothesis import given, settings, Verbosity @@ -30,3 +35,10 @@ async def test_index_list(session_admin_client, empty_test_case, random_name): assert isinstance(index['storage']['namespace'], str) assert isinstance(index['storage']['set'], str) await drop_specified_index(session_admin_client, "test", random_name) + +async def test_index_list_timeout(session_admin_client): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + result = await session_admin_client.index_list(timeout=0) + + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_service_config.py b/tests/standard/aio/test_service_config.py new file mode 100644 index 00000000..3289216d --- /dev/null +++ b/tests/standard/aio/test_service_config.py @@ -0,0 +1,297 @@ +import pytest +import time + +import os +import json + +from aerospike_vector_search import AVSServerError, types +from aerospike_vector_search.aio import AdminClient + +class service_config_parse_test_case: + def __init__( + self, + *, + service_config_path + ): + self.service_config_path = service_config_path + +@pytest.mark.parametrize( + "test_case", + [ + service_config_parse_test_case( + service_config_path="service_configs/master.json" + ), + ], +) +async def test_admin_client_service_config_parse(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path, + ) + await client.close() + +class service_config_test_case: + def __init__( + self, + *, + service_config_path, + namespace, + name, + vector_field, + dimensions + ): + + script_dir = os.path.dirname(os.path.abspath(__file__)) + + self.service_config_path = os.path.abspath(os.path.join(script_dir, '..', '..', service_config_path)) + + with open(self.service_config_path, 'rb') as f: + self.service_config = json.load(f) + + + + + self.max_attempts = self.service_config["methodConfig"][0]["retryPolicy"]["maxAttempts"] + self.initial_backoff = int(self.service_config["methodConfig"][0]["retryPolicy"]["initialBackoff"][:-1]) + self.max_backoff = int(self.service_config["methodConfig"][0]["retryPolicy"]["maxBackoff"][:-1]) + self.backoff_multiplier = self.service_config["methodConfig"][0]["retryPolicy"]["backoffMultiplier"] + self.retryable_status_codes = self.service_config["methodConfig"][0]["retryPolicy"]["retryableStatusCodes"] + self.namespace = namespace + self.name = name + self.vector_field = vector_field + self.dimensions = dimensions + + +def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, max_backoff, retryable_status_codes): + + current_backkoff = initial_backoff + + expected_time = 0 + for attempt in range(max_attempts-1): + expected_time += current_backkoff + current_backkoff *= backoff_multiplier + current_backkoff = min(current_backkoff, max_backoff) + + return expected_time + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/retries.json", + namespace="test", + name="service_config_index_1", + vector_field="example_1", + dimensions=1024 + ) + ], +) +async def test_admin_client_service_config_retries(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + ) + + + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + + assert abs(elapsed_time - expected_time) < 1.2 + await client.close() + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/initial_backoff.json", + namespace="test", + name="service_config_index_2", + vector_field="example_1", + dimensions=1024 + ) + ], +) +async def test_admin_client_service_config_initial_backoff(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + + ) + + + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + + assert abs(elapsed_time - expected_time) < 1.2 + await client.close() + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/max_backoff.json", + namespace="test", + name="service_config_index_3", + vector_field="example_1", + dimensions=1024 + ), + service_config_test_case( + service_config_path="service_configs/max_backoff_lower_than_initial.json", + namespace="test", + name="service_config_index_4", + vector_field="example_1", + dimensions=1024 + ) + ], +) +async def test_admin_client_service_config_max_backoff(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + + ) + + + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 + + await client.close() + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/backoff_multiplier.json", + namespace="test", + name="service_config_index_5", + vector_field="example_1", + dimensions=1024 + ) + ], +) +async def test_admin_client_service_config_backoff_multiplier(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + + ) + + + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 + + await client.close() + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/retryable_status_codes.json", + namespace="test", + name="service_config_index_6", + vector_field=None, + dimensions=None + ) + ], +) +async def test_admin_client_service_config_retryable_status_codes(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + await client.index_get_status( + namespace=test_case.namespace, + name=test_case.name, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 + + + await client.close() \ No newline at end of file diff --git a/tests/standard/aio/test_vector_client_delete.py b/tests/standard/aio/test_vector_client_delete.py index fd6342a1..3bdc198e 100644 --- a/tests/standard/aio/test_vector_client_delete.py +++ b/tests/standard/aio/test_vector_client_delete.py @@ -2,6 +2,7 @@ from aerospike_vector_search import AVSServerError from ...utils import key_strategy from hypothesis import given, settings, Verbosity +import grpc class delete_test_case: def __init__( @@ -10,11 +11,13 @@ def __init__( namespace, record_data, set_name, + timeout, ): self.namespace = namespace self.set_name = set_name self.record_data = record_data + self.timeout = timeout @given(random_key=key_strategy()) @@ -27,11 +30,13 @@ def __init__( namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, + timeout=None ), delete_test_case( namespace="test", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, + timeout=None ) ], ) @@ -60,6 +65,7 @@ async def test_vector_delete(session_vector_client, test_case, random_key): namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, + timeout=None ), ], ) @@ -67,4 +73,29 @@ async def test_vector_delete_without_record(session_vector_client, test_case, ra await session_vector_client.delete( namespace=test_case.namespace, key=random_key, - ) \ No newline at end of file + ) + + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + delete_test_case( + namespace="test", + set_name=None, + record_data={"skills": [i for i in range(1024)]}, + timeout=0 + ), + ], +) +async def test_vector_delete_timeout(session_vector_client, test_case, random_key): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + + await session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/aio/test_vector_client_exists.py b/tests/standard/aio/test_vector_client_exists.py index 86df1302..f46c4885 100644 --- a/tests/standard/aio/test_vector_client_exists.py +++ b/tests/standard/aio/test_vector_client_exists.py @@ -1,4 +1,5 @@ import pytest +import grpc from ...utils import key_strategy from hypothesis import given, settings, Verbosity @@ -9,11 +10,12 @@ def __init__( namespace, record_data, set_name, - + timeout, ): self.namespace = namespace self.set_name = set_name self.record_data = record_data + self.timeout = timeout @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -25,11 +27,14 @@ def __init__( namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, + timeout=None + ), exists_test_case( namespace="test", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, + timeout=None ) ], ) @@ -50,4 +55,26 @@ async def test_vector_exists(session_vector_client, test_case, random_key): await session_vector_client.delete( namespace=test_case.namespace, key=random_key, - ) \ No newline at end of file + ) +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + exists_test_case( + namespace="test", + set_name=None, + record_data=None, + timeout=0 + ), + ], +) +async def test_vector_exists_timeout(session_vector_client, test_case, random_key): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + result = await session_vector_client.exists( + namespace=test_case.namespace, + key=random_key, + timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_vector_client_get.py b/tests/standard/aio/test_vector_client_get.py index e5ecc2a4..368292f5 100644 --- a/tests/standard/aio/test_vector_client_get.py +++ b/tests/standard/aio/test_vector_client_get.py @@ -1,4 +1,7 @@ import pytest +from aerospike_vector_search import AVSServerError +import grpc + from ...utils import key_strategy from hypothesis import given, settings, Verbosity class get_test_case: @@ -9,13 +12,15 @@ def __init__( field_names, set_name, record_data, - expected_fields + expected_fields, + timeout, ): self.namespace = namespace self.field_names = field_names self.set_name = set_name self.record_data = record_data self.expected_fields = expected_fields + self.timeout = timeout @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -28,14 +33,16 @@ def __init__( field_names=['skills'], set_name=None, record_data={"skills": [i for i in range(1024)]}, - expected_fields={"skills": [i for i in range(1024)]} + expected_fields={"skills": [i for i in range(1024)]}, + timeout=None ), get_test_case( namespace="test", field_names=['english'], set_name=None, record_data={"english": [float(i) for i in range(1024)]}, - expected_fields={"english": [float(i) for i in range(1024)]} + expected_fields={"english": [float(i) for i in range(1024)]}, + timeout=None ) ], ) @@ -61,4 +68,26 @@ async def test_vector_get(session_vector_client, test_case, random_key): await session_vector_client.delete( namespace=test_case.namespace, key=random_key, - ) \ No newline at end of file + ) + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + get_test_case( + namespace="test", + field_names=['skills'], + set_name=None, + record_data=None, + expected_fields=None, + timeout=0 + ), ], +) +async def test_vector_get_timeout(session_vector_client, test_case, random_key): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + result = await session_vector_client.get( + namespace=test_case.namespace, key=random_key, field_names=test_case.field_names, timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/aio/test_vector_client_insert.py b/tests/standard/aio/test_vector_client_insert.py index 24f0e2e1..881207a1 100644 --- a/tests/standard/aio/test_vector_client_insert.py +++ b/tests/standard/aio/test_vector_client_insert.py @@ -5,17 +5,22 @@ import asyncio from hypothesis import given, settings +import grpc + + class insert_test_case: def __init__( self, *, namespace, record_data, - set_name + set_name, + timeout, ): self.namespace = namespace self.record_data = record_data self.set_name = set_name + self.timeout = timeout @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -26,21 +31,28 @@ def __init__( insert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), insert_test_case( namespace="test", record_data={"homeSkills": [float(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), insert_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) async def test_vector_insert_without_existing_record(session_vector_client, test_case, random_key): + await session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) await session_vector_client.insert( namespace=test_case.namespace, key=random_key, @@ -48,11 +60,6 @@ async def test_vector_insert_without_existing_record(session_vector_client, test set_name=test_case.set_name ) - await session_vector_client.delete( - namespace=test_case.namespace, - key=random_key, - ) - @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -62,17 +69,23 @@ async def test_vector_insert_without_existing_record(session_vector_client, test insert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None + ) ], ) async def test_vector_insert_with_existing_record(session_vector_client, test_case, random_key): - await session_vector_client.insert( - namespace=test_case.namespace, - key=random_key, - record_data=test_case.record_data, - set_name=test_case.set_name - ) + try: + await session_vector_client.insert( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name + ) + except Exception as e: + pass + with pytest.raises(AVSServerError) as e_info: await session_vector_client.insert( namespace=test_case.namespace, @@ -83,4 +96,30 @@ async def test_vector_insert_with_existing_record(session_vector_client, test_ca await session_vector_client.delete( namespace=test_case.namespace, key=random_key, - ) \ No newline at end of file + ) + + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + insert_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=0 + ) + ], +) +async def test_vector_insert_timeout(session_vector_client, test_case, random_key): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + await session_vector_client.insert( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name, + timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_vector_client_update.py b/tests/standard/aio/test_vector_client_update.py index f913d956..95f2fa10 100644 --- a/tests/standard/aio/test_vector_client_update.py +++ b/tests/standard/aio/test_vector_client_update.py @@ -2,6 +2,7 @@ from aerospike_vector_search import AVSServerError from ...utils import key_strategy from hypothesis import given, settings, Verbosity +import grpc class update_test_case: def __init__( @@ -9,11 +10,13 @@ def __init__( *, namespace, record_data, - set_name + set_name, + timeout, ): self.namespace = namespace self.record_data = record_data self.set_name = set_name + self.timeout = timeout @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -24,27 +27,33 @@ def __init__( update_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), update_test_case( namespace="test", record_data={"english": [float(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), update_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) async def test_vector_update_with_existing_record(session_vector_client, test_case, random_key): - await session_vector_client.insert( - namespace=test_case.namespace, - key=random_key, - record_data=test_case.record_data, - set_name=test_case.set_name - ) + try: + await session_vector_client.insert( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name + ) + except Exception as e: + pass await session_vector_client.update( namespace=test_case.namespace, key=random_key, @@ -55,7 +64,7 @@ async def test_vector_update_with_existing_record(session_vector_client, test_ca namespace=test_case.namespace, key=random_key, ) - + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -65,15 +74,45 @@ async def test_vector_update_with_existing_record(session_vector_client, test_ca update_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) async def test_vector_update_without_existing_record(session_vector_client, test_case, random_key): + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) with pytest.raises(AVSServerError) as e_info: await session_vector_client.update( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, set_name=test_case.set_name - ) \ No newline at end of file + ) + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + update_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=0 + ) + ], +) +async def test_vector_update_timeout(session_vector_client, test_case, random_key): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + await session_vector_client.update( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name, + timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/aio/test_vector_client_upsert.py b/tests/standard/aio/test_vector_client_upsert.py index 430834f3..9ee33dcb 100644 --- a/tests/standard/aio/test_vector_client_upsert.py +++ b/tests/standard/aio/test_vector_client_upsert.py @@ -2,17 +2,21 @@ from ...utils import key_strategy from hypothesis import given, settings, Verbosity +from aerospike_vector_search import AVSServerError +import grpc class upsert_test_case: def __init__( self, *, namespace, record_data, - set_name + set_name, + timeout, ): self.namespace = namespace self.record_data = record_data self.set_name = set_name + self.timeout = timeout @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -23,17 +27,20 @@ def __init__( upsert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), upsert_test_case( namespace="test", record_data={"english": [float(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), upsert_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) @@ -59,7 +66,8 @@ async def test_vector_upsert_without_existing_record(session_vector_client, test upsert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) @@ -74,4 +82,29 @@ async def test_vector_upsert_with_existing_record(session_vector_client, test_ca await session_vector_client.delete( namespace=test_case.namespace, key=random_key, - ) \ No newline at end of file + ) + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + upsert_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=0 + ) + ], +) +async def test_vector_upsert_timeout(session_vector_client, test_case, random_key): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + await session_vector_client.upsert( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name, + timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index 72daf7b6..7eb73114 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -2,7 +2,9 @@ import asyncio import pytest import random -from aerospike_vector_search import types +from aerospike_vector_search import types, AVSServerError + +import grpc dimensions = 128 truth_vector_dimensions = 100 @@ -68,12 +70,12 @@ def query_numpy(): async def put_vector(client, vector, j): await client.upsert( - namespace="test", key="aio/" + str(j), record_data={"unit_test": vector}, set_name="demo" + namespace="test", key="aio/" + str(j), record_data={"unit_test": vector} ) async def get_vector(client, j): - result = await client.get(namespace="test", key="aio/" + str(j), set_name="demo") + result = await client.get(namespace="test", key="aio/" + str(j)) async def vector_search(client, vector): @@ -111,7 +113,6 @@ async def test_vector_search( name="demo", vector_field="unit_test", dimensions=128, - sets="demo", ) # Put base vectors for search tasks = [] @@ -145,7 +146,6 @@ async def test_vector_search( for j, result in enumerate(results[i]): field_list.append(result.fields["unit_test"]) - field_list.append(result.fields["unit_test"]) for j, index in enumerate(outside): vector = base_numpy[index].tolist() if vector in field_list: @@ -171,7 +171,34 @@ async def test_vector_is_indexed(session_vector_client, session_admin_client): result = await session_vector_client.is_indexed( namespace="test", key="aio/" + str(random.randrange(10_000)), - set_name="demo", index_name="demo", ) assert result is True + +async def test_vector_is_indexed_timeout(session_vector_client, session_admin_client): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + result = await session_vector_client.is_indexed( + namespace="test", + key="aio/" + str(random.randrange(10_000)), + index_name="demo", + timeout=0 + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + +async def test_vector_vector_search_timeout(session_vector_client, session_admin_client): + for i in range(10): + try: + result = await session_vector_client.vector_search( + namespace="test", + index_name="demo", + query=[0, 1, 2], + limit=100, + field_names=["unit_test"], + timeout=0 + ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_create.py b/tests/standard/sync/test_admin_client_index_create.py index d29aaf5f..234e4ceb 100644 --- a/tests/standard/sync/test_admin_client_index_create.py +++ b/tests/standard/sync/test_admin_client_index_create.py @@ -1,5 +1,7 @@ import pytest -from aerospike_vector_search import types +import grpc + +from aerospike_vector_search import types, AVSServerError from ...utils import index_strategy from .sync_utils import drop_specified_index from hypothesis import given, settings, Verbosity @@ -15,6 +17,8 @@ def __init__( sets, index_params, index_meta_data, + index_storage, + timeout ): self.namespace = namespace self.vector_field = vector_field @@ -26,6 +30,8 @@ def __init__( self.sets = sets self.index_params = index_params self.index_meta_data = index_meta_data + self.index_storage = index_storage + self.timeout = timeout @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @@ -40,6 +46,8 @@ def __init__( sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ) ], ) @@ -55,6 +63,8 @@ def test_index_create(session_admin_client, test_case, random_name): sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = session_admin_client.index_list() found = False @@ -89,6 +99,8 @@ def test_index_create(session_admin_client, test_case, random_name): sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -98,6 +110,8 @@ def test_index_create(session_admin_client, test_case, random_name): sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), ], ) @@ -111,6 +125,8 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) @@ -151,6 +167,8 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -160,6 +178,8 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -169,6 +189,8 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -178,6 +200,8 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na sets=None, index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), ], ) @@ -195,6 +219,8 @@ def test_index_create_with_vector_distance_metric( sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = session_admin_client.index_list() found = False @@ -229,6 +255,8 @@ def test_index_create_with_vector_distance_metric( sets="Demo", index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -238,6 +266,8 @@ def test_index_create_with_vector_distance_metric( sets="Cheese", index_params=None, index_meta_data=None, + index_storage=None, + timeout=None, ), ], ) @@ -252,6 +282,8 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = session_admin_client.index_list() found = False @@ -290,6 +322,8 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): ef=400, ), index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -303,6 +337,8 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): ef=25, ), index_meta_data=None, + index_storage=None, + timeout=None, ), index_create_test_case( namespace="test", @@ -316,6 +352,8 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): ) ), index_meta_data=None, + index_storage=None, + timeout=None, ), ], ) @@ -329,6 +367,8 @@ def test_index_create_with_index_params(session_admin_client, test_case, random_ sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = session_admin_client.index_list() found = False @@ -363,6 +403,8 @@ def test_index_create_with_index_params(session_admin_client, test_case, random_ sets=None, index_params=None, index_meta_data={"size": "large", "price": "$4.99", "currencyType": "CAN"}, + index_storage=None, + timeout=None, ) ], ) @@ -378,6 +420,8 @@ def test_index_create_index_meta_data(session_admin_client, test_case, random_na sets=test_case.sets, index_params=test_case.index_params, index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout ) results = session_admin_client.index_list() found = False @@ -398,3 +442,100 @@ def test_index_create_index_meta_data(session_admin_client, test_case, random_na assert found == True drop_specified_index(session_admin_client, test_case.namespace, random_name) +@given(random_name=index_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + index_create_test_case( + namespace="test", + vector_field="example_14", + dimensions=1024, + vector_distance_metric=None, + sets=None, + index_params=None, + index_meta_data=None, + index_storage=types.IndexStorage(namespace="test", set_name="foo"), + timeout=None, + ), + ], +) +def test_index_create_index_storage(session_admin_client, test_case, random_name): + + + try: + session_admin_client.index_create( + namespace=test_case.namespace, + name=random_name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + vector_distance_metric=test_case.vector_distance_metric, + sets=test_case.sets, + index_params=test_case.index_params, + index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout + ) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: + raise se + + + results = session_admin_client.index_list() + found = False + for result in results: + if result['id']['name'] == random_name: + found = True + assert result['id']['namespace'] == test_case.namespace + assert result['dimensions'] == test_case.dimensions + assert result['field'] == test_case.vector_field + assert result['hnsw_params']['m'] == 16 + assert result['hnsw_params']['ef_construction'] == 100 + assert result['hnsw_params']['ef'] == 100 + assert result['hnsw_params']['batching_params']['max_records'] == 100000 + assert result['hnsw_params']['batching_params']['interval'] == 30000 + assert result['hnsw_params']['batching_params']['disabled'] == False + assert result['storage']['namespace'] == test_case.index_storage.namespace + assert result['storage']['set'] == test_case.index_storage.set_name + assert found == True + +@given(random_name=index_strategy()) +@settings(max_examples=1, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + index_create_test_case( + namespace="test", + vector_field="example_15", + dimensions=1024, + vector_distance_metric=None, + sets=None, + index_params=None, + index_meta_data=None, + index_storage=None, + timeout=0, + ), + ], +) +def test_index_create_timeout(session_admin_client, test_case, random_name): + + try: + session_admin_client.index_drop(namespace="test", name=random_name) + except: + pass + + + with pytest.raises(AVSServerError) as e_info: + session_admin_client.index_create( + namespace=test_case.namespace, + name=random_name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + vector_distance_metric=test_case.vector_distance_metric, + sets=test_case.sets, + index_params=test_case.index_params, + index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_drop.py b/tests/standard/sync/test_admin_client_index_drop.py index 69375310..d6b8c97d 100644 --- a/tests/standard/sync/test_admin_client_index_drop.py +++ b/tests/standard/sync/test_admin_client_index_drop.py @@ -1,5 +1,8 @@ import pytest +from aerospike_vector_search import AVSServerError +import grpc + from ...utils import index_strategy from hypothesis import given, settings, Verbosity @@ -11,12 +14,19 @@ @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) def test_index_drop(session_admin_client, empty_test_case, random_name): - session_admin_client.index_create( - namespace="test", - name=random_name, - vector_field="art", - dimensions=1024, - ) + try: + + session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="art", + dimensions=1024, + ) + + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: + raise se + session_admin_client.index_drop(namespace="test", name=random_name) result = session_admin_client.index_list() @@ -24,3 +34,23 @@ def test_index_drop(session_admin_client, empty_test_case, random_name): for index in result: assert index["id"]["name"] != random_name +@pytest.mark.parametrize("empty_test_case",[None]) +@given(random_name=index_strategy()) +@settings(max_examples=1, deadline=1000) +def test_index_drop_timeout(session_admin_client, empty_test_case, random_name): + try: + session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="art", + dimensions=1024, + ) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: + raise se + + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + session_admin_client.index_drop(namespace="test", name=random_name, timeout=0) + + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_get.py b/tests/standard/sync/test_admin_client_index_get.py index d97e748d..aafd0f35 100644 --- a/tests/standard/sync/test_admin_client_index_get.py +++ b/tests/standard/sync/test_admin_client_index_get.py @@ -3,19 +3,28 @@ from .sync_utils import drop_specified_index from hypothesis import given, settings, Verbosity - +from aerospike_vector_search import AVSServerError +import grpc @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) def test_index_get(session_admin_client, empty_test_case, random_name): - session_admin_client.index_create( - namespace="test", - name=random_name, - vector_field="science", - dimensions=1024, - ) + + + try: + session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="science", + dimensions=1024, + ) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: + raise se + + result = session_admin_client.index_get( namespace="test", name=random_name ) @@ -34,3 +43,33 @@ def test_index_get(session_admin_client, empty_test_case, random_name): assert result["storage"]["set"] == random_name drop_specified_index(session_admin_client, "test", random_name) + +@pytest.mark.parametrize("empty_test_case",[None]) +@given(random_name=index_strategy()) +@settings(max_examples=1, deadline=1000) +def test_index_get_timeout(session_admin_client, empty_test_case, random_name): + + try: + session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="science", + dimensions=1024, + ) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: + raise se + + + + for i in range(10): + try: + result = session_admin_client.index_get( + namespace="test", name=random_name, timeout=0 + ) + + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_get_status.py b/tests/standard/sync/test_admin_client_index_get_status.py index 9d56f6de..9db11746 100644 --- a/tests/standard/sync/test_admin_client_index_get_status.py +++ b/tests/standard/sync/test_admin_client_index_get_status.py @@ -1,8 +1,13 @@ import pytest +import grpc + from ...utils import index_strategy from .sync_utils import drop_specified_index from hypothesis import given, settings, Verbosity +from aerospike_vector_search import AVSServerError +import grpc + @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @@ -19,4 +24,22 @@ def test_index_get_status(session_admin_client, empty_test_case, random_name): ) assert result == 0 - drop_specified_index(session_admin_client, "test", random_name) \ No newline at end of file + drop_specified_index(session_admin_client, "test", random_name) + +@pytest.mark.parametrize("empty_test_case",[None]) +@given(random_name=index_strategy()) +@settings(max_examples=1, deadline=1000) +def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name): + + + for i in range(10): + try: + result = session_admin_client.index_get_status( + namespace="test", name=random_name, timeout=0 + ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_list.py b/tests/standard/sync/test_admin_client_index_list.py index 483bb4ec..9b6f9a06 100644 --- a/tests/standard/sync/test_admin_client_index_list.py +++ b/tests/standard/sync/test_admin_client_index_list.py @@ -1,4 +1,7 @@ +from aerospike_vector_search import AVSServerError + import pytest +import grpc from ...utils import index_strategy from .sync_utils import drop_specified_index @@ -30,3 +33,26 @@ def test_index_list(session_admin_client, empty_test_case, random_name): assert isinstance(index['storage']['namespace'], str) assert isinstance(index['storage']['set'], str) drop_specified_index(session_admin_client, "test", random_name) + + +@pytest.mark.parametrize("empty_test_case",[None]) +@given(random_name=index_strategy()) +@settings(max_examples=1, deadline=1000) +def test_index_list_timeout(session_admin_client, empty_test_case, random_name): + + + try: + session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="science", + dimensions=1024, + ) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: + raise se + + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + result = session_admin_client.index_list(timeout=0) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/sync/test_service_config.py b/tests/standard/sync/test_service_config.py new file mode 100644 index 00000000..53a10a0d --- /dev/null +++ b/tests/standard/sync/test_service_config.py @@ -0,0 +1,297 @@ +import pytest +import time + +import os +import json + +from aerospike_vector_search import AVSServerError, types +from aerospike_vector_search import AdminClient + +class service_config_parse_test_case: + def __init__( + self, + *, + service_config_path + ): + self.service_config_path = service_config_path + +@pytest.mark.parametrize( + "test_case", + [ + service_config_parse_test_case( + service_config_path="service_configs/master.json" + ), + ], +) +def test_admin_client_service_config_parse(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path, + ) + client.close() + +class service_config_test_case: + def __init__( + self, + *, + service_config_path, + namespace, + name, + vector_field, + dimensions + ): + + script_dir = os.path.dirname(os.path.abspath(__file__)) + + self.service_config_path = os.path.abspath(os.path.join(script_dir, '..', '..', service_config_path)) + + with open(self.service_config_path, 'rb') as f: + self.service_config = json.load(f) + + + + + self.max_attempts = self.service_config["methodConfig"][0]["retryPolicy"]["maxAttempts"] + self.initial_backoff = int(self.service_config["methodConfig"][0]["retryPolicy"]["initialBackoff"][:-1]) + self.max_backoff = int(self.service_config["methodConfig"][0]["retryPolicy"]["maxBackoff"][:-1]) + self.backoff_multiplier = self.service_config["methodConfig"][0]["retryPolicy"]["backoffMultiplier"] + self.retryable_status_codes = self.service_config["methodConfig"][0]["retryPolicy"]["retryableStatusCodes"] + self.namespace = namespace + self.name = name + self.vector_field = vector_field + self.dimensions = dimensions + + +def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, max_backoff, retryable_status_codes): + + current_backkoff = initial_backoff + + expected_time = 0 + for attempt in range(max_attempts-1): + expected_time += current_backkoff + current_backkoff *= backoff_multiplier + current_backkoff = min(current_backkoff, max_backoff) + + return expected_time + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/retries.json", + namespace="test", + name="service_config_index_1", + vector_field="example_1", + dimensions=1024 + ) + ], +) +def test_admin_client_service_config_retries(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + ) + + + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + + assert abs(elapsed_time - expected_time) < 1.2 + client.close() + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/initial_backoff.json", + namespace="test", + name="service_config_index_2", + vector_field="example_1", + dimensions=1024 + ) + ], +) +def test_admin_client_service_config_initial_backoff(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + + ) + + + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + + assert abs(elapsed_time - expected_time) < 1.2 + client.close() + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/max_backoff.json", + namespace="test", + name="service_config_index_3", + vector_field="example_1", + dimensions=1024 + ), + service_config_test_case( + service_config_path="service_configs/max_backoff_lower_than_initial.json", + namespace="test", + name="service_config_index_4", + vector_field="example_1", + dimensions=1024 + ) + ], +) +def test_admin_client_service_config_max_backoff(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + + ) + + + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 + + client.close() + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/backoff_multiplier.json", + namespace="test", + name="service_config_index_5", + vector_field="example_1", + dimensions=1024 + ) + ], +) +def test_admin_client_service_config_backoff_multiplier(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + + ) + + + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 + + client.close() + +@pytest.mark.parametrize( + "test_case", + [ + + service_config_test_case( + service_config_path="service_configs/retryable_status_codes.json", + namespace="test", + name="service_config_index_6", + vector_field=None, + dimensions=None + ) + ], +) +def test_admin_client_service_config_retryable_status_codes(host, port, test_case): + client = AdminClient( + seeds=types.HostPort(host=host, port=port), + service_config_path=test_case.service_config_path + + ) + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_get_status( + namespace=test_case.namespace, + name=test_case.name, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 + + + client.close() \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_delete.py b/tests/standard/sync/test_vector_client_delete.py index 55ab3981..08be765b 100644 --- a/tests/standard/sync/test_vector_client_delete.py +++ b/tests/standard/sync/test_vector_client_delete.py @@ -1,4 +1,7 @@ import pytest + +import grpc + from aerospike_vector_search import AVSServerError from ...utils import key_strategy from hypothesis import given, settings, Verbosity @@ -10,11 +13,13 @@ def __init__( namespace, record_data, set_name, + timeout, ): self.namespace = namespace self.set_name = set_name self.record_data = record_data + self.timeout = timeout @given(random_key=key_strategy()) @@ -26,11 +31,14 @@ def __init__( namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, + timeout=None + ), delete_test_case( namespace="test", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, + timeout=None ) ], ) @@ -48,7 +56,8 @@ def test_vector_delete(session_vector_client, test_case, random_key): with pytest.raises(AVSServerError) as e_info: result = session_vector_client.get( namespace=test_case.namespace, key=random_key - ) + ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -58,6 +67,8 @@ def test_vector_delete(session_vector_client, test_case, random_key): namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, + timeout=None + ), ], ) @@ -65,4 +76,28 @@ def test_vector_delete_without_record(session_vector_client, test_case, random_k session_vector_client.delete( namespace=test_case.namespace, key=random_key, - ) \ No newline at end of file + ) + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + delete_test_case( + namespace="test", + set_name=None, + record_data={"skills": [i for i in range(1024)]}, + timeout=0 + ), + ], +) +def test_vector_delete_timeout(session_vector_client, test_case, random_key): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_exists.py b/tests/standard/sync/test_vector_client_exists.py index 301cdd0f..a0ea6b92 100644 --- a/tests/standard/sync/test_vector_client_exists.py +++ b/tests/standard/sync/test_vector_client_exists.py @@ -1,6 +1,9 @@ import pytest +import grpc + from ...utils import key_strategy from hypothesis import given, settings, Verbosity +from aerospike_vector_search import types, AVSServerError class exists_test_case: def __init__( @@ -9,11 +12,12 @@ def __init__( namespace, record_data, set_name, - + timeout, ): self.namespace = namespace self.set_name = set_name self.record_data = record_data + self.timeout = timeout @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -24,11 +28,13 @@ def __init__( namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, + timeout=None ), exists_test_case( namespace="test", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, + timeout=None ) ], ) @@ -37,7 +43,8 @@ def test_vector_exists(session_vector_client, test_case, random_key): namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, + timeout=None ) result = session_vector_client.exists( @@ -50,3 +57,31 @@ def test_vector_exists(session_vector_client, test_case, random_key): namespace=test_case.namespace, key=random_key, ) + +@given(random_key=key_strategy()) +@settings(max_examples=1, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + exists_test_case( + namespace="test", + set_name=None, + record_data=None, + timeout=0 + ), + ], +) +def test_vector_exists_timeout(session_vector_client, test_case, random_key): + for i in range(10): + try: + result = session_vector_client.exists( + namespace=test_case.namespace, + key=random_key, + timeout=test_case.timeout + ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_get.py b/tests/standard/sync/test_vector_client_get.py index 328fcfe6..55f48fba 100644 --- a/tests/standard/sync/test_vector_client_get.py +++ b/tests/standard/sync/test_vector_client_get.py @@ -1,6 +1,10 @@ import pytest +import grpc from ...utils import key_strategy from hypothesis import given, settings, Verbosity + +from aerospike_vector_search import types, AVSServerError + class get_test_case: def __init__( self, @@ -9,13 +13,16 @@ def __init__( field_names, set_name, record_data, - expected_fields + expected_fields, + timeout, ): self.namespace = namespace self.field_names = field_names self.set_name = set_name self.record_data = record_data self.expected_fields = expected_fields + self.timeout = timeout + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -27,14 +34,16 @@ def __init__( field_names=['skills'], set_name=None, record_data={"skills": [i for i in range(1024)]}, - expected_fields={"skills": [i for i in range(1024)]} + expected_fields={"skills": [i for i in range(1024)]}, + timeout=None ), get_test_case( namespace="test", field_names=['english'], set_name=None, record_data={"english": [float(i) for i in range(1024)]}, - expected_fields={"english": [float(i) for i in range(1024)]} + expected_fields={"english": [float(i) for i in range(1024)]}, + timeout=None ) ], ) @@ -60,4 +69,31 @@ def test_vector_get(session_vector_client, test_case, random_key): session_vector_client.delete( namespace=test_case.namespace, key=random_key, - ) \ No newline at end of file + ) + +@given(random_key=key_strategy()) +@settings(max_examples=1, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + get_test_case( + namespace="test", + field_names=['skills'], + set_name=None, + record_data=None, + expected_fields=None, + timeout=0 + ), + ], +) +def test_vector_get_timeout(session_vector_client, test_case, random_key): + for i in range(10): + try: + result = session_vector_client.get( + namespace=test_case.namespace, key=random_key, field_names=test_case.field_names, timeout=test_case.timeout + ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_insert.py b/tests/standard/sync/test_vector_client_insert.py index c9707bd8..1570f23a 100644 --- a/tests/standard/sync/test_vector_client_insert.py +++ b/tests/standard/sync/test_vector_client_insert.py @@ -1,5 +1,7 @@ import pytest from aerospike_vector_search import AVSServerError +import grpc + from ...utils import key_strategy from hypothesis import given, settings, Verbosity @@ -11,11 +13,13 @@ def __init__( *, namespace, record_data, - set_name + set_name, + timeout, ): self.namespace = namespace self.record_data = record_data self.set_name = set_name + self.timeout = timeout @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -25,21 +29,29 @@ def __init__( insert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), insert_test_case( namespace="test", record_data={"homeSkills": [float(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), insert_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) def test_vector_insert_without_existing_record(session_vector_client, test_case, random_key): + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) + session_vector_client.insert( namespace=test_case.namespace, key=random_key, @@ -60,7 +72,8 @@ def test_vector_insert_without_existing_record(session_vector_client, test_case, insert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) @@ -81,4 +94,33 @@ def test_vector_insert_with_existing_record(session_vector_client, test_case, ra session_vector_client.delete( namespace=test_case.namespace, key=random_key, - ) \ No newline at end of file + ) + +@given(random_key=key_strategy()) +@settings(max_examples=1, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + insert_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=0 + ) + ], +) +def test_vector_insert_timeout(session_vector_client, test_case, random_key): + for i in range(10): + try: + session_vector_client.insert( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name, + timeout=test_case.timeout + ) + except AVSServerError as e: + if e.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert e.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_update.py b/tests/standard/sync/test_vector_client_update.py index 2f259e81..3923a32c 100644 --- a/tests/standard/sync/test_vector_client_update.py +++ b/tests/standard/sync/test_vector_client_update.py @@ -1,4 +1,6 @@ import pytest +import grpc + from aerospike_vector_search import AVSServerError from ...utils import key_strategy from hypothesis import given, settings, Verbosity @@ -9,11 +11,13 @@ def __init__( *, namespace, record_data, - set_name + set_name, + timeout ): self.namespace = namespace self.record_data = record_data self.set_name = set_name + self.timeout = timeout @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -23,32 +27,42 @@ def __init__( update_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), update_test_case( namespace="test", record_data={"english": [float(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), update_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) def test_vector_update_with_existing_record(session_vector_client, test_case, random_key): - session_vector_client.insert( - namespace=test_case.namespace, - key=random_key, - record_data=test_case.record_data, - set_name=test_case.set_name - ) + try: + session_vector_client.insert( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name, + timeout=None + ) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: + raise se + session_vector_client.update( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, + timeout=None ) @given(random_key=key_strategy()) @@ -59,11 +73,17 @@ def test_vector_update_with_existing_record(session_vector_client, test_case, ra update_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None + ) ], ) def test_vector_update_without_existing_record(session_vector_client, test_case, random_key): + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) with pytest.raises(AVSServerError) as e_info: session_vector_client.update( namespace=test_case.namespace, @@ -71,4 +91,34 @@ def test_vector_update_without_existing_record(session_vector_client, test_case, record_data=test_case.record_data, set_name=test_case.set_name ) - \ No newline at end of file + +@given(random_key=key_strategy()) +@settings(max_examples=1, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + update_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=0 + ) + ], +) +def test_vector_update_timeout(session_vector_client, test_case, random_key): + for i in range(10): + try: + session_vector_client.update( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name, + timeout=test_case.timeout + ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 + + diff --git a/tests/standard/sync/test_vector_client_upsert.py b/tests/standard/sync/test_vector_client_upsert.py index c5488609..b8875841 100644 --- a/tests/standard/sync/test_vector_client_upsert.py +++ b/tests/standard/sync/test_vector_client_upsert.py @@ -2,17 +2,24 @@ from ...utils import key_strategy from hypothesis import given, settings, Verbosity +from aerospike_vector_search import AVSServerError +import grpc + class upsert_test_case: def __init__( self, *, namespace, record_data, - set_name + set_name, + timeout, + ): self.namespace = namespace self.record_data = record_data self.set_name = set_name + self.timeout = timeout + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -22,17 +29,20 @@ def __init__( upsert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), upsert_test_case( namespace="test", record_data={"english": [float(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ), upsert_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) @@ -56,7 +66,8 @@ def test_vector_upsert_without_existing_record(session_vector_client, test_case, upsert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, - set_name=None + set_name=None, + timeout=None ) ], ) @@ -71,4 +82,29 @@ def test_vector_upsert_with_existing_record(session_vector_client, test_case, ra session_vector_client.delete( namespace=test_case.namespace, key=random_key, - ) \ No newline at end of file + ) + +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + upsert_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=0 + ) + ], +) +def test_vector_upsert_timeout(session_vector_client, test_case, random_key): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + session_vector_client.upsert( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name, + timeout=test_case.timeout + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index c3e148e0..90b10f6c 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -1,7 +1,10 @@ import numpy as np import pytest import random +import time from aerospike_vector_search import types +from aerospike_vector_search import AVSServerError +import grpc dimensions = 128 truth_vector_dimensions = 100 @@ -67,12 +70,12 @@ def query_numpy(): def put_vector(client, vector, j): client.upsert( - namespace="test", key=str(j), record_data={"unit_test": vector}, set_name="demo" + namespace="test", key=str(j), record_data={"unit_test": vector} ) def get_vector(client, j): - result = client.get(namespace="test", key=str(j), set_name="demo") + result = client.get(namespace="test", key=str(j)) def vector_search(client, vector): @@ -110,7 +113,6 @@ def test_vector_search( name="demo", vector_field="unit_test", dimensions=128, - sets="demo", ) # Put base vectors for search @@ -119,6 +121,9 @@ def test_vector_search( session_vector_client.wait_for_index_completion(namespace='test', name='demo') + for j, vector in enumerate(base_numpy): + get_vector(session_vector_client, j) + # Vector search all query vectors results = [] @@ -129,6 +134,9 @@ def test_vector_search( else: results.append(vector_search_ef_80(session_vector_client, i)) count += 1 + + print(len(results)) + print(len(results[0])) # Get recall numbers for each query recall_for_each_query = [] for i, outside in enumerate(truth_numpy): @@ -163,8 +171,35 @@ def test_vector_search( def test_vector_is_indexed(session_vector_client, session_admin_client): result = session_vector_client.is_indexed( namespace="test", - key=str(random.randrange(10_000)), - set_name="demo", + key="" + str(random.randrange(10_000)), index_name="demo", ) assert result is True + +def test_vector_is_indexed_timeout(session_vector_client, session_admin_client): + with pytest.raises(AVSServerError) as e_info: + for i in range(10): + result = session_vector_client.is_indexed( + namespace="test", + key="" + str(random.randrange(10_000)), + index_name="demo", + timeout=0 + ) + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + +def test_vector_vector_search_timeout(session_vector_client, session_admin_client): + for i in range(10): + try: + result = session_vector_client.vector_search( + namespace="test", + index_name="demo", + query=[0, 1, 2], + limit=100, + field_names=["unit_test"], + timeout=0 + ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 \ No newline at end of file From d6104ea8989de0f594f705743d6f1834b4fe97e2 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 09:14:54 -0600 Subject: [PATCH 118/215] Flaky test fixes --- .github/workflows/integration_test.yml | 8 ++--- src/aerospike_vector_search/admin.py | 2 +- .../aio/test_admin_client_index_list.py | 12 +++++-- .../sync/test_admin_client_index_create.py | 33 +++++++++++-------- .../sync/test_admin_client_index_drop.py | 11 ++++--- .../sync/test_vector_client_delete.py | 9 +++-- .../sync/test_vector_client_upsert.py | 8 +++-- 7 files changed, 52 insertions(+), 31 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index dc9f38b7..30fd80b5 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -65,7 +65,7 @@ jobs: docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - sleep 40 + sleep 5 docker ps python -m pytest standard -s --host 0.0.0.0 --port 5000 @@ -139,8 +139,8 @@ jobs: docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - sleep 40 - + sleep 5 + cat /home/runner/work/avs-client-python/avs-client-python/tests/service_configs/retries.json docker ps python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt -vs @@ -212,7 +212,7 @@ jobs: docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - sleep 40 + sleep 5 docker ps echo " diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index c7691a11..2ed80b22 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -271,7 +271,7 @@ def add_user(self, *, username: str, password: str, roles: list[str], timeout: O (user_admin_stub, add_user_request) = self._prepare_add_user( - username, password, roles, logger + username, password, roles, timeout, logger ) diff --git a/tests/standard/aio/test_admin_client_index_list.py b/tests/standard/aio/test_admin_client_index_list.py index d1642daa..530d8f62 100644 --- a/tests/standard/aio/test_admin_client_index_list.py +++ b/tests/standard/aio/test_admin_client_index_list.py @@ -37,8 +37,14 @@ async def test_index_list(session_admin_client, empty_test_case, random_name): await drop_specified_index(session_admin_client, "test", random_name) async def test_index_list_timeout(session_admin_client): - with pytest.raises(AVSServerError) as e_info: - for i in range(10): + for i in range(10): + try: result = await session_admin_client.index_list(timeout=0) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + + assert 1 == 2 diff --git a/tests/standard/sync/test_admin_client_index_create.py b/tests/standard/sync/test_admin_client_index_create.py index 234e4ceb..8b787965 100644 --- a/tests/standard/sync/test_admin_client_index_create.py +++ b/tests/standard/sync/test_admin_client_index_create.py @@ -525,17 +525,22 @@ def test_index_create_timeout(session_admin_client, test_case, random_name): pass - with pytest.raises(AVSServerError) as e_info: - session_admin_client.index_create( - namespace=test_case.namespace, - name=random_name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - vector_distance_metric=test_case.vector_distance_metric, - sets=test_case.sets, - index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, - index_storage=test_case.index_storage, - timeout=test_case.timeout - ) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + for i in range(10) + try: + session_admin_client.index_create( + namespace=test_case.namespace, + name=random_name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + vector_distance_metric=test_case.vector_distance_metric, + sets=test_case.sets, + index_params=test_case.index_params, + index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout + ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_drop.py b/tests/standard/sync/test_admin_client_index_drop.py index d6b8c97d..5aaafb07 100644 --- a/tests/standard/sync/test_admin_client_index_drop.py +++ b/tests/standard/sync/test_admin_client_index_drop.py @@ -49,8 +49,11 @@ def test_index_drop_timeout(session_admin_client, empty_test_case, random_name): if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: raise se - with pytest.raises(AVSServerError) as e_info: - for i in range(10): + for i in range(10): + try: session_admin_client.index_drop(namespace="test", name=random_name, timeout=0) - - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert 1 == 2 \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_delete.py b/tests/standard/sync/test_vector_client_delete.py index 08be765b..4b6eb48f 100644 --- a/tests/standard/sync/test_vector_client_delete.py +++ b/tests/standard/sync/test_vector_client_delete.py @@ -92,12 +92,15 @@ def test_vector_delete_without_record(session_vector_client, test_case, random_k ], ) def test_vector_delete_timeout(session_vector_client, test_case, random_key): - with pytest.raises(AVSServerError) as e_info: - for i in range(10): - + for i in range(10) + try: session_vector_client.delete( namespace=test_case.namespace, key=random_key, timeout=test_case.timeout ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_upsert.py b/tests/standard/sync/test_vector_client_upsert.py index b8875841..ab3af916 100644 --- a/tests/standard/sync/test_vector_client_upsert.py +++ b/tests/standard/sync/test_vector_client_upsert.py @@ -98,8 +98,8 @@ def test_vector_upsert_with_existing_record(session_vector_client, test_case, ra ], ) def test_vector_upsert_timeout(session_vector_client, test_case, random_key): - with pytest.raises(AVSServerError) as e_info: - for i in range(10): + for i in range(10): + try: session_vector_client.upsert( namespace=test_case.namespace, key=random_key, @@ -107,4 +107,8 @@ def test_vector_upsert_timeout(session_vector_client, test_case, random_key): set_name=test_case.set_name, timeout=test_case.timeout ) + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file From 66fd91c5baae78e4d4e0411b4267d7a1fa3fc6c6 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 09:19:19 -0600 Subject: [PATCH 119/215] Flaky test fixes --- .github/workflows/integration_test.yml | 4 +++- tests/standard/sync/test_vector_client_delete.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 30fd80b5..fae101fe 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -140,7 +140,9 @@ jobs: docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 5 - cat /home/runner/work/avs-client-python/avs-client-python/tests/service_configs/retries.json + ls /home/runner/work/avs-client-python/avs-client-python/tests/service_configs/ + ls /home/runner/work/avs-client-python/avs-client-python/tests/ + docker ps python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt -vs diff --git a/tests/standard/sync/test_vector_client_delete.py b/tests/standard/sync/test_vector_client_delete.py index 4b6eb48f..75abd5ea 100644 --- a/tests/standard/sync/test_vector_client_delete.py +++ b/tests/standard/sync/test_vector_client_delete.py @@ -92,7 +92,7 @@ def test_vector_delete_without_record(session_vector_client, test_case, random_k ], ) def test_vector_delete_timeout(session_vector_client, test_case, random_key): - for i in range(10) + for i in range(10): try: session_vector_client.delete( namespace=test_case.namespace, From 7df8dbe82bdd3663e9731d068e073536b2fde629 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 09:21:59 -0600 Subject: [PATCH 120/215] Flaky test fix --- .github/workflows/integration_test.yml | 3 ++- tests/standard/sync/test_admin_client_index_create.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index fae101fe..d1daf371 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -140,9 +140,10 @@ jobs: docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 5 - ls /home/runner/work/avs-client-python/avs-client-python/tests/service_configs/ + ls /home/runner/work/avs-client-python/avs-client-python/tests/ + docker ps python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt -vs diff --git a/tests/standard/sync/test_admin_client_index_create.py b/tests/standard/sync/test_admin_client_index_create.py index 8b787965..b1f8f30c 100644 --- a/tests/standard/sync/test_admin_client_index_create.py +++ b/tests/standard/sync/test_admin_client_index_create.py @@ -525,7 +525,7 @@ def test_index_create_timeout(session_admin_client, test_case, random_name): pass - for i in range(10) + for i in range(10): try: session_admin_client.index_create( namespace=test_case.namespace, From 3aa0ffe4c4231ec08a12c0a66403200f6b8b995d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 09:30:09 -0600 Subject: [PATCH 121/215] Updated checkout and changed how files are moved in gen.sh --- .github/workflows/integration_test.yml | 6 +++--- tests/gen.sh | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index d1daf371..79ebad37 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v2 @@ -84,7 +84,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v2 @@ -162,7 +162,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v2 diff --git a/tests/gen.sh b/tests/gen.sh index 25c41485..f2877582 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -40,6 +40,7 @@ function generate_derivative_certs() { openssl x509 -noout -text -in $2.crt fi } +ls > keep_files.txt tls_maybe="" rbac_maybe="" @@ -469,7 +470,7 @@ fi shopt -s extglob # Enable extended globbing -mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|siftsmall) tls/ +mv $(comm -23 <(ls | sort) <(sort keep_files.txt)) tls/ mv tls/gen.sh gen.sh From 0d349843d63bae434a65a3b710d42d3f9f5631bf Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 09:37:37 -0600 Subject: [PATCH 122/215] Fixed deletion issue --- src/aerospike_vector_search/client.py | 2 +- tests/gen.sh | 1 + tests/standard/aio/test_admin_client_index_get_status.py | 3 +-- tests/standard/sync/test_vector_search.py | 2 -- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index 572242f5..cd55dcaf 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -393,7 +393,7 @@ def wait_for_index_completion( name: str, timeout: Optional[int] = sys.maxsize, wait_interval: Optional[int] = 12, - validation_threshold: Optional[int] = 3, + validation_threshold: Optional[int] = 2, ) -> None: """ Wait for the index to have no pending index update operations. diff --git a/tests/gen.sh b/tests/gen.sh index f2877582..34f085ae 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -470,6 +470,7 @@ fi shopt -s extglob # Enable extended globbing +grep -v 'tls' keep_files.txt > temp && mv temp keep_files.txt mv $(comm -23 <(ls | sort) <(sort keep_files.txt)) tls/ mv tls/gen.sh gen.sh diff --git a/tests/standard/aio/test_admin_client_index_get_status.py b/tests/standard/aio/test_admin_client_index_get_status.py index be42960c..5de335d1 100644 --- a/tests/standard/aio/test_admin_client_index_get_status.py +++ b/tests/standard/aio/test_admin_client_index_get_status.py @@ -38,12 +38,11 @@ async def test_index_get_status_timeout(session_admin_client, empty_test_case, r except Exception as e: pass - for i in range(25): + for i in range(10): try: result = await session_admin_client.index_get_status( namespace="test", name=random_name, timeout=0 ) - print(result) except AVSServerError as se: print(se.rpc_error.code()) if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index 90b10f6c..953c540c 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -135,8 +135,6 @@ def test_vector_search( results.append(vector_search_ef_80(session_vector_client, i)) count += 1 - print(len(results)) - print(len(results[0])) # Get recall numbers for each query recall_for_each_query = [] for i, outside in enumerate(truth_numpy): From 53a8a6090f466a078e59750e3c716ebfb2d73ea5 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 09:40:27 -0600 Subject: [PATCH 123/215] Update gen.sh --- tests/gen.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/gen.sh b/tests/gen.sh index 34f085ae..a75d248a 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -42,6 +42,9 @@ function generate_derivative_certs() { } ls > keep_files.txt +sed -i '/tls/d' keep_files.txt + +cat keep_files.txt tls_maybe="" rbac_maybe="" root_certificate_maybe="" @@ -470,7 +473,6 @@ fi shopt -s extglob # Enable extended globbing -grep -v 'tls' keep_files.txt > temp && mv temp keep_files.txt mv $(comm -23 <(ls | sort) <(sort keep_files.txt)) tls/ mv tls/gen.sh gen.sh From 370fd629ac6daadcec0a74d40330a6a752dfaf54 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 09:53:37 -0600 Subject: [PATCH 124/215] Update gen.sh --- tests/gen.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/gen.sh b/tests/gen.sh index a75d248a..8baebe97 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -42,9 +42,6 @@ function generate_derivative_certs() { } ls > keep_files.txt -sed -i '/tls/d' keep_files.txt - -cat keep_files.txt tls_maybe="" rbac_maybe="" root_certificate_maybe="" @@ -473,7 +470,9 @@ fi shopt -s extglob # Enable extended globbing -mv $(comm -23 <(ls | sort) <(sort keep_files.txt)) tls/ +ls + +#mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|siftsmall|) tls/ mv tls/gen.sh gen.sh From 5e2b631d9163dc58b64c3b4002d9fa006398b638 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 10:04:10 -0600 Subject: [PATCH 125/215] Update gen.sh --- tests/gen.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/gen.sh b/tests/gen.sh index 8baebe97..35fc3d53 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -470,9 +470,9 @@ fi shopt -s extglob # Enable extended globbing -ls + -#mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|siftsmall|) tls/ +mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|siftsmall|service_configs) tls/ mv tls/gen.sh gen.sh From b7e3d2965159ff5a1a29f19f36c8305ac2de5807 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 10:06:02 -0600 Subject: [PATCH 126/215] Update gen.sh --- tests/gen.sh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/gen.sh b/tests/gen.sh index 35fc3d53..3c3e994d 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -40,7 +40,23 @@ function generate_derivative_certs() { openssl x509 -noout -text -in $2.crt fi } -ls > keep_files.txt + +file_count=$(find . -type f | wc -l) +dir_count=$(find . -type d | wc -l) +total_count=$((file_count + dir_count)) + +if test -f "features.yml"; then + echo "features.yml exists." +else + echo "features.yml does not exist." +fi + +echo "Number of files: $file_count" +echo "Number of directories: $dir_count" +echo "Total count: $total_count" + + + tls_maybe="" rbac_maybe="" From 8a256e4f98d09c13f69d5a808792158165cddfb2 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 16 Jul 2024 10:32:28 -0600 Subject: [PATCH 127/215] Made test folder alert dev to fix command if files are added. --- tests/assets/call_gen_normal.sh | 2 +- tests/assets/call_gen_tls.sh | 3 +- tests/gen.sh | 49 ++++++++++++++++++++------------- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/tests/assets/call_gen_normal.sh b/tests/assets/call_gen_normal.sh index b5aeecb1..c7e16289 100755 --- a/tests/assets/call_gen_normal.sh +++ b/tests/assets/call_gen_normal.sh @@ -12,4 +12,4 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 0.0.0.0 + --host 127.0.0.1 diff --git a/tests/assets/call_gen_tls.sh b/tests/assets/call_gen_tls.sh index aec49e02..5dfbcb35 100755 --- a/tests/assets/call_gen_tls.sh +++ b/tests/assets/call_gen_tls.sh @@ -12,4 +12,5 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 0.0.0.0 + --host 127.0.0.1 \ + --for_testing y diff --git a/tests/gen.sh b/tests/gen.sh index 3c3e994d..85da9451 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -41,21 +41,6 @@ function generate_derivative_certs() { fi } -file_count=$(find . -type f | wc -l) -dir_count=$(find . -type d | wc -l) -total_count=$((file_count + dir_count)) - -if test -f "features.yml"; then - echo "features.yml exists." -else - echo "features.yml does not exist." -fi - -echo "Number of files: $file_count" -echo "Number of directories: $dir_count" -echo "Total count: $total_count" - - tls_maybe="" @@ -73,7 +58,7 @@ client_name="" server_name="" port="" host="" - +for_testing="" while [[ $# -gt 0 ]]; do case $1 in @@ -137,7 +122,10 @@ while [[ $# -gt 0 ]]; do host="$2" shift 2 ;; - + --for_testing) + for_testing="$2" + shift 2 + ;; *) echo "Unknown parameter passed: $1" exit 1 @@ -145,6 +133,31 @@ while [[ $# -gt 0 ]]; do esac done +if [[ "$for_testing" == "y" ]]; then + mv_command="mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|siftsmall|service_configs) tls/" + file_count=$(find . -type f | wc -l) + dir_count=$(find . -type d | wc -l) + total_count=$((file_count + dir_count)) + + echo "Number of files: $file_count" + echo "Number of directories: $dir_count" + echo "Total count: $total_count" + + if test -f "features.yml"; then + if [ "$total_count" -ne 100 ]; then + echo "Total count matches 100." + fi + else + if [ "$total_count" -ne 99 ]; then + echo "File number has changed, update the following command in the script below to reflect changes $mv_command" + fi + fi + +fi + + + + echo "Final values:" echo "tls_maybe: $tls_maybe" @@ -486,8 +499,6 @@ fi shopt -s extglob # Enable extended globbing - - mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|siftsmall|service_configs) tls/ mv tls/gen.sh gen.sh From f2f0d2383d125428c3917dd5303a717aad49b449 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 17 Jul 2024 11:30:15 -0600 Subject: [PATCH 128/215] Development Release Candidate changes --- proto/auth.proto | 4 +- proto/index.proto | 26 ++- proto/transact.proto | 10 +- proto/types.proto | 89 +++++++- proto/vector-db.proto | 7 +- pyproject.toml | 2 +- src/aerospike_vector_search/aio/client.py | 9 +- .../aio/internal/channel_provider.py | 2 +- src/aerospike_vector_search/client.py | 9 +- .../internal/channel_provider.py | 2 +- .../shared/admin_helpers.py | 40 ++++ .../shared/client_helpers.py | 21 +- .../shared/proto_generated/auth_pb2.py | 21 +- .../shared/proto_generated/auth_pb2_grpc.py | 44 +++- .../shared/proto_generated/index_pb2.py | 20 +- .../shared/proto_generated/index_pb2_grpc.py | 204 ++++++++++++++++-- .../shared/proto_generated/transact_pb2.py | 50 ++--- .../proto_generated/transact_pb2_grpc.py | 156 +++++++++++--- .../shared/proto_generated/types_pb2.py | 72 ++++--- .../shared/proto_generated/types_pb2_grpc.py | 25 +++ .../shared/proto_generated/user_admin_pb2.py | 6 +- .../proto_generated/user_admin_pb2_grpc.py | 170 ++++++++++++--- .../shared/proto_generated/vector_db_pb2.py | 18 +- .../proto_generated/vector_db_pb2_grpc.py | 147 ++++++++++--- src/aerospike_vector_search/types.py | 76 ++++++- ...oximus.yml => aerospike-vector-search.yml} | 18 +- tests/aerospike.conf | 4 +- tests/assets/aerospike-proximus.yml | 18 +- tests/assets/aerospike-vector-search.yml | 122 +++++++++++ tests/assets/aerospike.conf | 4 +- tests/assets/call_gen.sh | 5 +- tests/assets/call_gen_normal.sh | 3 +- tests/assets/security_stanza.txt | 4 +- tests/assets/tls_stanza.txt | 10 +- tests/gen.sh | 92 ++++---- tests/service_configs/backoff_multiplier.json | 2 +- tests/service_configs/initial_backoff.json | 2 +- tests/service_configs/max_backoff.json | 2 +- .../max_backoff_lower_than_initial.json | 2 +- tests/service_configs/retries.json | 2 +- .../retryable_status_codes.json | 2 +- tests/standard/aio/conftest.py | 28 --- .../aio/test_admin_client_index_create.py | 16 +- .../aio/test_admin_client_index_drop.py | 6 +- .../aio/test_admin_client_index_get.py | 9 +- .../aio/test_admin_client_index_get_status.py | 8 +- .../aio/test_admin_client_index_list.py | 9 +- tests/standard/aio/test_service_config.py | 103 ++++++--- .../standard/aio/test_vector_client_delete.py | 6 +- .../standard/aio/test_vector_client_exists.py | 6 +- tests/standard/aio/test_vector_client_get.py | 6 +- .../standard/aio/test_vector_client_insert.py | 6 +- .../standard/aio/test_vector_client_update.py | 8 +- .../standard/aio/test_vector_client_upsert.py | 6 +- tests/standard/aio/test_vector_search.py | 39 ++-- tests/standard/conftest.py | 4 + .../sync/test_admin_client_index_create.py | 159 ++++++++++---- .../sync/test_admin_client_index_drop.py | 9 +- .../sync/test_admin_client_index_get.py | 10 +- .../test_admin_client_index_get_status.py | 9 +- .../sync/test_admin_client_index_list.py | 20 +- tests/standard/sync/test_service_config.py | 98 +++++---- .../sync/test_vector_client_delete.py | 9 +- .../sync/test_vector_client_exists.py | 9 +- tests/standard/sync/test_vector_client_get.py | 9 +- .../sync/test_vector_client_insert.py | 54 ++++- .../sync/test_vector_client_update.py | 28 +-- .../sync/test_vector_client_upsert.py | 9 +- tests/standard/sync/test_vector_search.py | 28 ++- tests/utils.py | 2 +- 70 files changed, 1653 insertions(+), 582 deletions(-) rename tests/{aerospike-proximus.yml => aerospike-vector-search.yml} (81%) create mode 100755 tests/assets/aerospike-vector-search.yml diff --git a/proto/auth.proto b/proto/auth.proto index ef9178a3..379949be 100644 --- a/proto/auth.proto +++ b/proto/auth.proto @@ -6,7 +6,6 @@ option go_package = "aerospike.com/vector/protos/"; option java_package = "com.aerospike.vector.client.proto"; option java_multiple_files = true; -import "google/protobuf/empty.proto"; import "types.proto"; // An auth request to get an access token to perform operations on Aerospike @@ -24,5 +23,4 @@ message AuthResponse { service AuthService { // Request authentication. rpc Authenticate(AuthRequest) returns (AuthResponse) {} -} - +} \ No newline at end of file diff --git a/proto/index.proto b/proto/index.proto index ec5e720a..99d7b740 100644 --- a/proto/index.proto +++ b/proto/index.proto @@ -14,11 +14,32 @@ message IndexStatusResponse { int64 unmergedRecordCount = 2; } +message GcInvalidVerticesRequest { + IndexId indexId = 1; + + // Vertices identified as invalid before cutoff timestamp (Unix timestamp) are garbage collected. + int64 cutoffTimestamp = 2; +} + +message IndexUpdateRequest { + IndexId indexId = 1; + + // Optional labels associated with the index. + map labels = 2; + + oneof update { + HnswIndexUpdate hnswIndexUpdate = 3; + } +} + // Service to manage indices. service IndexService { // Create an index. rpc Create(IndexDefinition) returns (google.protobuf.Empty) {} + // Create an index. + rpc Update(IndexUpdateRequest) returns (google.protobuf.Empty) {} + // Drop an index. rpc Drop(IndexId) returns (google.protobuf.Empty) {} @@ -31,4 +52,7 @@ service IndexService { // Query status of an index. // NOTE: API is subject to change. rpc GetStatus(IndexId) returns (IndexStatusResponse) {} -} + + // Garbage collect vertices identified as invalid before cutoff timestamp. + rpc GcInvalidVertices(GcInvalidVerticesRequest) returns (google.protobuf.Empty) {} +} \ No newline at end of file diff --git a/proto/transact.proto b/proto/transact.proto index 7c4dc441..baf7600c 100644 --- a/proto/transact.proto +++ b/proto/transact.proto @@ -42,6 +42,10 @@ message PutRequest { // The record fields. repeated Field fields = 3; + + // Ignore the in-memory queue full error. These records would be written to + // storage and later, the index healer would pick for indexing. + bool ignoreMemQueueFull = 4; } // Get request to insert/update a record. @@ -50,7 +54,7 @@ message GetRequest { Key key = 1; // The field selector. - ProjectionSpec projectionSpec = 2; + ProjectionSpec projection = 2; } // Check if a record exists. @@ -122,7 +126,7 @@ message VectorSearchRequest { } // Record transaction services. -service Transact { +service TransactService { // Update/insert records. rpc Put(PutRequest) returns (google.protobuf.Empty) {} @@ -140,4 +144,4 @@ service Transact { // Perform a vector nearest neighbor search. rpc VectorSearch(VectorSearchRequest) returns (stream Neighbor) {} -} +} \ No newline at end of file diff --git a/proto/types.proto b/proto/types.proto index 6d796a41..3a7048cc 100644 --- a/proto/types.proto +++ b/proto/types.proto @@ -186,9 +186,25 @@ message HnswParams { // Configures batching behaviour for batch based index update. HnswBatchingParams batchingParams = 4; + + // Maximum size of in-memory queue for inserted/updated vector records. + // If the queue is full the record upsert will either be rejected with + // a RESOURCE_EXHAUSTED error or written to storage for index healer to + // later pick the record for indexing based on the put option. + // Defaults to global indexing config configured for the VectorDB. + optional uint32 maxMemQueueSize = 5; + + // Configures caching for Hnsw Index. + HnswCachingParams cachingParams = 6; + + // Configures index healer params. + HnswHealerParams healerParams = 7; + + // Configures merge of batch indices to main index. + HnswIndexMergeParams mergeParams = 8; } -// Params for the HNSW index search +// Params for the HNSW index search. message HnswSearchParams { // The default number of candidate nearest neighbors shortlisted during search. // Larger values provide better recall at the cost of longer search times. @@ -196,6 +212,51 @@ message HnswSearchParams { optional uint32 ef = 1; } +// Params to configure Hnsw batch index into main index. +message HnswIndexMergeParams { + // The number of vectors merged in parallel from a batch index to main index. + // Defaults to global indexing config configured for the VectorDB. + optional uint32 parallelism = 1; +} + +// Params to configure Hnsw index cache +message HnswCachingParams { + // Maximum number of entries to cache. + // Defaults to the global cache config configured for the VectorDB. + optional uint64 maxEntries = 1; + + // A cache entry will expire after this time in milliseconds has + // expired after the entry was added to cache. + // Defaults to the global cache config configured for the VectorDB. + optional uint64 expiry = 2; +} + +// Params to configure Hnsw index cache +message HnswHealerParams { + // Maximum allowed record scan rate per vector db node. + // Defaults to the global healer config configured for the VectorDB. + optional uint32 maxScanRatePerNode = 1; + + // Maximum number of records in a single scanned page. + // Defaults to the global healer config configured for the VectorDB. + optional uint32 maxScanPageSize = 2; + + // Percentage of good records randomly selected for reindexing in a healer cycle. + // Defaults to the global healer config configured for the VectorDB. + optional float reindexPercent = 3; + + // The time delay, in milliseconds, between the termination of a healer run + // and the commencement of the next one for an index. It only guarantees + // that the next index healer run for an index will not be scheduled before + // this time delay. + // Defaults to the global healer config configured for the VectorDB. + optional uint64 scheduleDelay = 4; + + // Maximum number of records to heal in parallel. + // Defaults to the global healer config configured for the VectorDB. + optional uint32 parallelism = 5; +} + // Configures batching behaviour for batch based index update. message HnswBatchingParams { // Maximum number of records to fit in a batch. @@ -205,10 +266,28 @@ message HnswBatchingParams { // The maximum amount of time in milliseconds to wait before finalizing a batch. // The default value is 10000. optional uint32 interval = 2; +} + +// Message to update a HNSW index parameters. +message HnswIndexUpdate { + // Configures batching behaviour for batch based index update. + optional HnswBatchingParams batchingParams = 1; - // Disables batching for index updates. - // Default is false meaning batching is enabled. - optional bool disabled = 3; + // Maximum size of in-memory queue for inserted/updated vector records. + // If the queue is full the record upsert will either be rejected with + // a RESOURCE_EXHAUSTED error or written to storage for index healer to + // later pick the record for indexing based on the put option. + // Defaults to global indexing config configured for the VectorDB. + optional uint32 maxMemQueueSize = 2; + + // Configures caching for Hnsw Index. + optional HnswCachingParams cachingParams = 3; + + // Configures index healer params. + optional HnswHealerParams healerParams = 4; + + // Configures merge of batch indices to main index. + optional HnswIndexMergeParams mergeParams = 5; } // Index storage configuration @@ -292,4 +371,4 @@ message PasswordCredentials { // A boolean type message Boolean { bool value = 1; -} +} \ No newline at end of file diff --git a/proto/vector-db.proto b/proto/vector-db.proto index 6e002a90..8e9a79d9 100644 --- a/proto/vector-db.proto +++ b/proto/vector-db.proto @@ -1,3 +1,4 @@ + syntax = "proto3"; package aerospike.vector; @@ -15,7 +16,7 @@ message AboutRequest { // The about response message. message AboutResponse { - // Proximus server version. + // AVS server version. string version = 1; } @@ -72,12 +73,12 @@ message ClusteringState { } // Information about the service. -service About { +service AboutService { rpc Get (AboutRequest) returns (AboutResponse) {} } // Vector DB cluster service. -service ClusterInfo { +service ClusterInfoService { // Get the internal cluster node-Id for this server. rpc GetNodeId(google.protobuf.Empty) returns (NodeId) {} diff --git a/pyproject.toml b/pyproject.toml index 49fcad2a..0f97d113 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Topic :: Database" ] -version = "0.6.1" +version = "1.0.0.dev1" requires-python = ">3.8" dependencies = [ "grpcio", diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index 9cda4a0c..06e60207 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -60,6 +60,7 @@ async def insert( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + ignore_mem_queue_full: Optional[bool] = False, timeout: Optional[int] = None, ) -> None: """ @@ -83,7 +84,7 @@ async def insert( await self._channel_provider._is_ready() (transact_stub, insert_request) = self._prepare_insert( - namespace, key, record_data, set_name, timeout, logger + namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger ) kwargs = {} @@ -103,6 +104,7 @@ async def update( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + ignore_mem_queue_full: Optional[bool] = False, timeout: Optional[int] = None, ) -> None: """ @@ -126,7 +128,7 @@ async def update( await self._channel_provider._is_ready() (transact_stub, update_request) = self._prepare_update( - namespace, key, record_data, set_name, timeout, logger + namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger ) kwargs = {} @@ -146,6 +148,7 @@ async def upsert( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + ignore_mem_queue_full: Optional[bool] = False, timeout: Optional[int] = None, ) -> None: """ @@ -169,7 +172,7 @@ async def upsert( await self._channel_provider._is_ready() (transact_stub, upsert_request) = self._prepare_upsert( - namespace, key, record_data, set_name, timeout, logger + namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger ) kwargs = {} diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 6acd6183..8726a56a 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -80,7 +80,7 @@ async def _tend(self): for channel in channels: - stub = vector_db_pb2_grpc.ClusterInfoStub(channel) + stub = vector_db_pb2_grpc.ClusterInfoServiceStub(channel) stubs.append(stub) try: tasks.append(await stub.GetClusterId(empty, credentials=self._token)) diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index cd55dcaf..f888ec73 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -59,6 +59,7 @@ def insert( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + ignore_mem_queue_full: Optional[bool] = False, timeout: Optional[int] = None, ) -> None: """ @@ -82,7 +83,7 @@ def insert( (transact_stub, insert_request) = self._prepare_insert( - namespace, key, record_data, set_name, timeout, logger + namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger ) kwargs = {} @@ -102,6 +103,7 @@ def update( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + ignore_mem_queue_full: Optional[bool] = False, timeout: Optional[int] = None, ) -> None: """ @@ -122,7 +124,7 @@ def update( """ (transact_stub, update_request) = self._prepare_update( - namespace, key, record_data, set_name, timeout, logger + namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger ) kwargs = {} @@ -142,6 +144,7 @@ def upsert( key: Union[int, str, bytes, bytearray], record_data: dict[str, Any], set_name: Optional[str] = None, + ignore_mem_queue_full: Optional[bool] = False, timeout: Optional[int] = None, ) -> None: """ @@ -165,7 +168,7 @@ def upsert( (transact_stub, upsert_request) = self._prepare_upsert( - namespace, key, record_data, set_name, timeout, logger + namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger ) kwargs = {} diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index 4672fa18..9ad749b7 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -62,7 +62,7 @@ def _tend(self): return for channel in channels: - stub = vector_db_pb2_grpc.ClusterInfoStub(channel) + stub = vector_db_pb2_grpc.ClusterInfoServiceStub(channel) try: new_cluster_id = stub.GetClusterId(empty, credentials=self._credentials).id diff --git a/src/aerospike_vector_search/shared/admin_helpers.py b/src/aerospike_vector_search/shared/admin_helpers.py index 4d9f582a..a951b299 100644 --- a/src/aerospike_vector_search/shared/admin_helpers.py +++ b/src/aerospike_vector_search/shared/admin_helpers.py @@ -198,6 +198,46 @@ def _respond_index_list(self, response) -> None: ) hnsw_params_dict["batching_params"] = batching_params_dict + + + caching_params_dict = hnsw_params_dict.pop("cachingParams", None) + if caching_params_dict: + caching_params_dict["max_entries"] = caching_params_dict.pop( + "maxEntries", None + ) + caching_params_dict["expiry"] = caching_params_dict.pop( + "expiry", None + ) + hnsw_params_dict["caching_params"] = caching_params_dict + + healer_params_dict = hnsw_params_dict.pop("healerParams", None) + + if healer_params_dict: + + healer_params_dict["max_scan_rate_per_node"] = healer_params_dict.pop( + "maxScanRatePerNode", None + ) + healer_params_dict["max_scan_page_size"] = healer_params_dict.pop( + "maxScanPageSize", None + ) + healer_params_dict["re_index_percent"] = healer_params_dict.pop( + "reindexPercent", None + ) + healer_params_dict["schedule_delay"] = healer_params_dict.pop( + "scheduleDelay", None + ) + healer_params_dict["parallelism"] = healer_params_dict.pop( + "parallelism", None + ) + hnsw_params_dict["healer_params"] = healer_params_dict + + merge_params_dict = hnsw_params_dict.pop("mergeParams", None) + if merge_params_dict: + merge_params_dict["parallelism"] = merge_params_dict.pop( + "parallelism", None + ) + hnsw_params_dict["merge_params"] = merge_params_dict + response_dict["hnsw_params"] = hnsw_params_dict response_list.append(response_dict) return response_list diff --git a/src/aerospike_vector_search/shared/client_helpers.py b/src/aerospike_vector_search/shared/client_helpers.py index ad3f1b67..9dc56be0 100644 --- a/src/aerospike_vector_search/shared/client_helpers.py +++ b/src/aerospike_vector_search/shared/client_helpers.py @@ -16,15 +16,16 @@ def _prepare_seeds(self, seeds) -> None: return helpers._prepare_seeds(seeds) def _prepare_put( - self, namespace, key, record_data, set_name, write_type, timeout, logger + self, namespace, key, record_data, set_name, write_type, ignore_mem_queue_full, timeout, logger ) -> None: logger.debug( - "Putting record: namespace=%s, key=%s, record_data:%s, set_name:%s, timeout:%s", + "Putting record: namespace=%s, key=%s, record_data:%s, set_name:%s, ignore_mem_queue_full %s, timeout:%s", namespace, key, record_data, set_name, + ignore_mem_queue_full, timeout ) @@ -46,36 +47,38 @@ def _prepare_put( transact_stub = self._get_transact_stub() put_request = transact_pb2.PutRequest( - key=key, writeType=write_type, fields=field_list + key=key, writeType=write_type, fields=field_list, ignoreMemQueueFull=ignore_mem_queue_full ) return (transact_stub, put_request) - def _prepare_insert(self, namespace, key, record_data, set_name, timeout, logger) -> None: + def _prepare_insert(self, namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger) -> None: return self._prepare_put( namespace, key, record_data, set_name, transact_pb2.WriteType.INSERT_ONLY, + ignore_mem_queue_full, timeout, logger, ) - def _prepare_update(self, namespace, key, record_data, set_name, timeout, logger) -> None: + def _prepare_update(self, namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger) -> None: return self._prepare_put( namespace, key, record_data, set_name, transact_pb2.WriteType.UPDATE_ONLY, + ignore_mem_queue_full, timeout, logger, ) - def _prepare_upsert(self, namespace, key, record_data, set_name, timeout, logger) -> None: + def _prepare_upsert(self, namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger) -> None: return self._prepare_put( - namespace, key, record_data, set_name, transact_pb2.WriteType.UPSERT, timeout, logger + namespace, key, record_data, set_name, transact_pb2.WriteType.UPSERT, ignore_mem_queue_full, timeout, logger ) def _prepare_get(self, namespace, key, field_names, set_name, timeout, logger) -> None: @@ -93,7 +96,7 @@ def _prepare_get(self, namespace, key, field_names, set_name, timeout, logger) - projection_spec = self._get_projection_spec(field_names=field_names) transact_stub = self._get_transact_stub() - get_request = transact_pb2.GetRequest(key=key, projectionSpec=projection_spec) + get_request = transact_pb2.GetRequest(key=key, projection=projection_spec) return (transact_stub, key, get_request) @@ -195,7 +198,7 @@ def _prepare_vector_search( return (transact_stub, vector_search_request) def _get_transact_stub(self): - return transact_pb2_grpc.TransactStub(self._channel_provider.get_channel()) + return transact_pb2_grpc.TransactServiceStub(self._channel_provider.get_channel()) def _respond_get(self, response, key) -> None: return types.RecordWithKey( diff --git a/src/aerospike_vector_search/shared/proto_generated/auth_pb2.py b/src/aerospike_vector_search/shared/proto_generated/auth_pb2.py index 484692e4..a335babd 100644 --- a/src/aerospike_vector_search/shared/proto_generated/auth_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/auth_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: auth.proto -# Protobuf Python Version: 4.25.1 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -12,22 +12,21 @@ _sym_db = _symbol_database.Default() -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from . import types_pb2 as types__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nauth.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"A\n\x0b\x41uthRequest\x12\x32\n\x0b\x63redentials\x18\x01 \x01(\x0b\x32\x1d.aerospike.vector.Credentials\"\x1d\n\x0c\x41uthResponse\x12\r\n\x05token\x18\x01 \x01(\t2^\n\x0b\x41uthService\x12O\n\x0c\x41uthenticate\x12\x1d.aerospike.vector.AuthRequest\x1a\x1e.aerospike.vector.AuthResponse\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nauth.proto\x12\x10\x61\x65rospike.vector\x1a\x0btypes.proto\"A\n\x0b\x41uthRequest\x12\x32\n\x0b\x63redentials\x18\x01 \x01(\x0b\x32\x1d.aerospike.vector.Credentials\"\x1d\n\x0c\x41uthResponse\x12\r\n\x05token\x18\x01 \x01(\t2^\n\x0b\x41uthService\x12O\n\x0c\x41uthenticate\x12\x1d.aerospike.vector.AuthRequest\x1a\x1e.aerospike.vector.AuthResponse\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'auth_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals['DESCRIPTOR']._options = None +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' - _globals['_AUTHREQUEST']._serialized_start=74 - _globals['_AUTHREQUEST']._serialized_end=139 - _globals['_AUTHRESPONSE']._serialized_start=141 - _globals['_AUTHRESPONSE']._serialized_end=170 - _globals['_AUTHSERVICE']._serialized_start=172 - _globals['_AUTHSERVICE']._serialized_end=266 + _globals['_AUTHREQUEST']._serialized_start=45 + _globals['_AUTHREQUEST']._serialized_end=110 + _globals['_AUTHRESPONSE']._serialized_start=112 + _globals['_AUTHRESPONSE']._serialized_end=141 + _globals['_AUTHSERVICE']._serialized_start=143 + _globals['_AUTHSERVICE']._serialized_end=237 # @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/auth_pb2_grpc.py b/src/aerospike_vector_search/shared/proto_generated/auth_pb2_grpc.py index 3b13742d..5df4d3dc 100644 --- a/src/aerospike_vector_search/shared/proto_generated/auth_pb2_grpc.py +++ b/src/aerospike_vector_search/shared/proto_generated/auth_pb2_grpc.py @@ -1,9 +1,34 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings from . import auth_pb2 as auth__pb2 +GRPC_GENERATED_VERSION = '1.64.1' +GRPC_VERSION = grpc.__version__ +EXPECTED_ERROR_RELEASE = '1.65.0' +SCHEDULED_RELEASE_DATE = 'June 25, 2024' +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + warnings.warn( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in auth_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + + f' This warning will become an error in {EXPECTED_ERROR_RELEASE},' + + f' scheduled for release on {SCHEDULED_RELEASE_DATE}.', + RuntimeWarning + ) + class AuthServiceStub(object): """Auth service @@ -19,7 +44,7 @@ def __init__(self, channel): '/aerospike.vector.AuthService/Authenticate', request_serializer=auth__pb2.AuthRequest.SerializeToString, response_deserializer=auth__pb2.AuthResponse.FromString, - ) + _registered_method=True) class AuthServiceServicer(object): @@ -45,6 +70,7 @@ def add_AuthServiceServicer_to_server(servicer, server): generic_handler = grpc.method_handlers_generic_handler( 'aerospike.vector.AuthService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('aerospike.vector.AuthService', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. @@ -63,8 +89,18 @@ def Authenticate(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.AuthService/Authenticate', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.AuthService/Authenticate', auth__pb2.AuthRequest.SerializeToString, auth__pb2.AuthResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/aerospike_vector_search/shared/proto_generated/index_pb2.py b/src/aerospike_vector_search/shared/proto_generated/index_pb2.py index fc4b6c66..c5fd948e 100644 --- a/src/aerospike_vector_search/shared/proto_generated/index_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/index_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: index.proto -# Protobuf Python Version: 4.25.1 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -16,16 +16,24 @@ from . import types_pb2 as types__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0bindex.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"2\n\x13IndexStatusResponse\x12\x1b\n\x13unmergedRecordCount\x18\x02 \x01(\x03\x32\xf3\x02\n\x0cIndexService\x12\x45\n\x06\x43reate\x12!.aerospike.vector.IndexDefinition\x1a\x16.google.protobuf.Empty\"\x00\x12;\n\x04\x44rop\x12\x19.aerospike.vector.IndexId\x1a\x16.google.protobuf.Empty\"\x00\x12G\n\x04List\x12\x16.google.protobuf.Empty\x1a%.aerospike.vector.IndexDefinitionList\"\x00\x12\x45\n\x03Get\x12\x19.aerospike.vector.IndexId\x1a!.aerospike.vector.IndexDefinition\"\x00\x12O\n\tGetStatus\x12\x19.aerospike.vector.IndexId\x1a%.aerospike.vector.IndexStatusResponse\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0bindex.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"2\n\x13IndexStatusResponse\x12\x1b\n\x13unmergedRecordCount\x18\x02 \x01(\x03\"_\n\x18GcInvalidVerticesRequest\x12*\n\x07indexId\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12\x17\n\x0f\x63utoffTimestamp\x18\x02 \x01(\x03\"\xf9\x01\n\x12IndexUpdateRequest\x12*\n\x07indexId\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12@\n\x06labels\x18\x02 \x03(\x0b\x32\x30.aerospike.vector.IndexUpdateRequest.LabelsEntry\x12<\n\x0fhnswIndexUpdate\x18\x03 \x01(\x0b\x32!.aerospike.vector.HnswIndexUpdateH\x00\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x08\n\x06update2\x98\x04\n\x0cIndexService\x12\x45\n\x06\x43reate\x12!.aerospike.vector.IndexDefinition\x1a\x16.google.protobuf.Empty\"\x00\x12H\n\x06Update\x12$.aerospike.vector.IndexUpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12;\n\x04\x44rop\x12\x19.aerospike.vector.IndexId\x1a\x16.google.protobuf.Empty\"\x00\x12G\n\x04List\x12\x16.google.protobuf.Empty\x1a%.aerospike.vector.IndexDefinitionList\"\x00\x12\x45\n\x03Get\x12\x19.aerospike.vector.IndexId\x1a!.aerospike.vector.IndexDefinition\"\x00\x12O\n\tGetStatus\x12\x19.aerospike.vector.IndexId\x1a%.aerospike.vector.IndexStatusResponse\"\x00\x12Y\n\x11GcInvalidVertices\x12*.aerospike.vector.GcInvalidVerticesRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'index_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals['DESCRIPTOR']._options = None +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' + _globals['_INDEXUPDATEREQUEST_LABELSENTRY']._loaded_options = None + _globals['_INDEXUPDATEREQUEST_LABELSENTRY']._serialized_options = b'8\001' _globals['_INDEXSTATUSRESPONSE']._serialized_start=75 _globals['_INDEXSTATUSRESPONSE']._serialized_end=125 - _globals['_INDEXSERVICE']._serialized_start=128 - _globals['_INDEXSERVICE']._serialized_end=499 + _globals['_GCINVALIDVERTICESREQUEST']._serialized_start=127 + _globals['_GCINVALIDVERTICESREQUEST']._serialized_end=222 + _globals['_INDEXUPDATEREQUEST']._serialized_start=225 + _globals['_INDEXUPDATEREQUEST']._serialized_end=474 + _globals['_INDEXUPDATEREQUEST_LABELSENTRY']._serialized_start=419 + _globals['_INDEXUPDATEREQUEST_LABELSENTRY']._serialized_end=464 + _globals['_INDEXSERVICE']._serialized_start=477 + _globals['_INDEXSERVICE']._serialized_end=1013 # @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/index_pb2_grpc.py b/src/aerospike_vector_search/shared/proto_generated/index_pb2_grpc.py index 9ae221c2..8adb9df5 100644 --- a/src/aerospike_vector_search/shared/proto_generated/index_pb2_grpc.py +++ b/src/aerospike_vector_search/shared/proto_generated/index_pb2_grpc.py @@ -1,11 +1,36 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from . import index_pb2 as index__pb2 from . import types_pb2 as types__pb2 +GRPC_GENERATED_VERSION = '1.64.1' +GRPC_VERSION = grpc.__version__ +EXPECTED_ERROR_RELEASE = '1.65.0' +SCHEDULED_RELEASE_DATE = 'June 25, 2024' +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + warnings.warn( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in index_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + + f' This warning will become an error in {EXPECTED_ERROR_RELEASE},' + + f' scheduled for release on {SCHEDULED_RELEASE_DATE}.', + RuntimeWarning + ) + class IndexServiceStub(object): """Service to manage indices. @@ -21,27 +46,37 @@ def __init__(self, channel): '/aerospike.vector.IndexService/Create', request_serializer=types__pb2.IndexDefinition.SerializeToString, response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) + _registered_method=True) + self.Update = channel.unary_unary( + '/aerospike.vector.IndexService/Update', + request_serializer=index__pb2.IndexUpdateRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + _registered_method=True) self.Drop = channel.unary_unary( '/aerospike.vector.IndexService/Drop', request_serializer=types__pb2.IndexId.SerializeToString, response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) + _registered_method=True) self.List = channel.unary_unary( '/aerospike.vector.IndexService/List', request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, response_deserializer=types__pb2.IndexDefinitionList.FromString, - ) + _registered_method=True) self.Get = channel.unary_unary( '/aerospike.vector.IndexService/Get', request_serializer=types__pb2.IndexId.SerializeToString, response_deserializer=types__pb2.IndexDefinition.FromString, - ) + _registered_method=True) self.GetStatus = channel.unary_unary( '/aerospike.vector.IndexService/GetStatus', request_serializer=types__pb2.IndexId.SerializeToString, response_deserializer=index__pb2.IndexStatusResponse.FromString, - ) + _registered_method=True) + self.GcInvalidVertices = channel.unary_unary( + '/aerospike.vector.IndexService/GcInvalidVertices', + request_serializer=index__pb2.GcInvalidVerticesRequest.SerializeToString, + response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, + _registered_method=True) class IndexServiceServicer(object): @@ -55,6 +90,13 @@ def Create(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def Update(self, request, context): + """Create an index. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def Drop(self, request, context): """Drop an index. """ @@ -84,6 +126,13 @@ def GetStatus(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def GcInvalidVertices(self, request, context): + """Garbage collect vertices identified as invalid before cutoff timestamp. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_IndexServiceServicer_to_server(servicer, server): rpc_method_handlers = { @@ -92,6 +141,11 @@ def add_IndexServiceServicer_to_server(servicer, server): request_deserializer=types__pb2.IndexDefinition.FromString, response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, ), + 'Update': grpc.unary_unary_rpc_method_handler( + servicer.Update, + request_deserializer=index__pb2.IndexUpdateRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), 'Drop': grpc.unary_unary_rpc_method_handler( servicer.Drop, request_deserializer=types__pb2.IndexId.FromString, @@ -112,10 +166,16 @@ def add_IndexServiceServicer_to_server(servicer, server): request_deserializer=types__pb2.IndexId.FromString, response_serializer=index__pb2.IndexStatusResponse.SerializeToString, ), + 'GcInvalidVertices': grpc.unary_unary_rpc_method_handler( + servicer.GcInvalidVertices, + request_deserializer=index__pb2.GcInvalidVerticesRequest.FromString, + response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'aerospike.vector.IndexService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('aerospike.vector.IndexService', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. @@ -134,11 +194,48 @@ def Create(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.IndexService/Create', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.IndexService/Create', types__pb2.IndexDefinition.SerializeToString, google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Update(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.IndexService/Update', + index__pb2.IndexUpdateRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def Drop(request, @@ -151,11 +248,21 @@ def Drop(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.IndexService/Drop', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.IndexService/Drop', types__pb2.IndexId.SerializeToString, google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def List(request, @@ -168,11 +275,21 @@ def List(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.IndexService/List', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.IndexService/List', google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, types__pb2.IndexDefinitionList.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def Get(request, @@ -185,11 +302,21 @@ def Get(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.IndexService/Get', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.IndexService/Get', types__pb2.IndexId.SerializeToString, types__pb2.IndexDefinition.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def GetStatus(request, @@ -202,8 +329,45 @@ def GetStatus(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.IndexService/GetStatus', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.IndexService/GetStatus', types__pb2.IndexId.SerializeToString, index__pb2.IndexStatusResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GcInvalidVertices(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.IndexService/GcInvalidVertices', + index__pb2.GcInvalidVerticesRequest.SerializeToString, + google_dot_protobuf_dot_empty__pb2.Empty.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/aerospike_vector_search/shared/proto_generated/transact_pb2.py b/src/aerospike_vector_search/shared/proto_generated/transact_pb2.py index 0ac82fdf..440b5c89 100644 --- a/src/aerospike_vector_search/shared/proto_generated/transact_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/transact_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: transact.proto -# Protobuf Python Version: 4.25.1 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -16,34 +16,34 @@ from . import types_pb2 as types__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0etransact.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"\x89\x01\n\nPutRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12.\n\twriteType\x18\x02 \x01(\x0e\x32\x1b.aerospike.vector.WriteType\x12\'\n\x06\x66ields\x18\x03 \x03(\x0b\x32\x17.aerospike.vector.Field\"j\n\nGetRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12\x38\n\x0eprojectionSpec\x18\x02 \x01(\x0b\x32 .aerospike.vector.ProjectionSpec\"3\n\rExistsRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\"3\n\rDeleteRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\"b\n\x10IsIndexedRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12*\n\x07indexId\x18\x02 \x01(\x0b\x32\x19.aerospike.vector.IndexId\"R\n\x10ProjectionFilter\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .aerospike.vector.ProjectionType\x12\x0e\n\x06\x66ields\x18\x02 \x03(\t\"z\n\x0eProjectionSpec\x12\x33\n\x07include\x18\x01 \x01(\x0b\x32\".aerospike.vector.ProjectionFilter\x12\x33\n\x07\x65xclude\x18\x02 \x01(\x0b\x32\".aerospike.vector.ProjectionFilter\"\x83\x02\n\x13VectorSearchRequest\x12(\n\x05index\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12-\n\x0bqueryVector\x18\x02 \x01(\x0b\x32\x18.aerospike.vector.Vector\x12\r\n\x05limit\x18\x03 \x01(\r\x12\x34\n\nprojection\x18\x04 \x01(\x0b\x32 .aerospike.vector.ProjectionSpec\x12>\n\x10hnswSearchParams\x18\x05 \x01(\x0b\x32\".aerospike.vector.HnswSearchParamsH\x00\x42\x0e\n\x0csearchParams*X\n\tWriteType\x12\n\n\x06UPSERT\x10\x00\x12\x0f\n\x0bUPDATE_ONLY\x10\x01\x12\x0f\n\x0bINSERT_ONLY\x10\x02\x12\x0b\n\x07REPLACE\x10\x03\x12\x10\n\x0cREPLACE_ONLY\x10\x04*2\n\x0eProjectionType\x12\x07\n\x03\x41LL\x10\x00\x12\x08\n\x04NONE\x10\x01\x12\r\n\tSPECIFIED\x10\x02\x32\xbc\x03\n\x08Transact\x12=\n\x03Put\x12\x1c.aerospike.vector.PutRequest\x1a\x16.google.protobuf.Empty\"\x00\x12?\n\x03Get\x12\x1c.aerospike.vector.GetRequest\x1a\x18.aerospike.vector.Record\"\x00\x12\x43\n\x06\x44\x65lete\x12\x1f.aerospike.vector.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\x06\x45xists\x12\x1f.aerospike.vector.ExistsRequest\x1a\x19.aerospike.vector.Boolean\"\x00\x12L\n\tIsIndexed\x12\".aerospike.vector.IsIndexedRequest\x1a\x19.aerospike.vector.Boolean\"\x00\x12U\n\x0cVectorSearch\x12%.aerospike.vector.VectorSearchRequest\x1a\x1a.aerospike.vector.Neighbor\"\x00\x30\x01\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0etransact.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\x1a\x0btypes.proto\"\xa5\x01\n\nPutRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12.\n\twriteType\x18\x02 \x01(\x0e\x32\x1b.aerospike.vector.WriteType\x12\'\n\x06\x66ields\x18\x03 \x03(\x0b\x32\x17.aerospike.vector.Field\x12\x1a\n\x12ignoreMemQueueFull\x18\x04 \x01(\x08\"f\n\nGetRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12\x34\n\nprojection\x18\x02 \x01(\x0b\x32 .aerospike.vector.ProjectionSpec\"3\n\rExistsRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\"3\n\rDeleteRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\"b\n\x10IsIndexedRequest\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12*\n\x07indexId\x18\x02 \x01(\x0b\x32\x19.aerospike.vector.IndexId\"R\n\x10ProjectionFilter\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .aerospike.vector.ProjectionType\x12\x0e\n\x06\x66ields\x18\x02 \x03(\t\"z\n\x0eProjectionSpec\x12\x33\n\x07include\x18\x01 \x01(\x0b\x32\".aerospike.vector.ProjectionFilter\x12\x33\n\x07\x65xclude\x18\x02 \x01(\x0b\x32\".aerospike.vector.ProjectionFilter\"\x83\x02\n\x13VectorSearchRequest\x12(\n\x05index\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12-\n\x0bqueryVector\x18\x02 \x01(\x0b\x32\x18.aerospike.vector.Vector\x12\r\n\x05limit\x18\x03 \x01(\r\x12\x34\n\nprojection\x18\x04 \x01(\x0b\x32 .aerospike.vector.ProjectionSpec\x12>\n\x10hnswSearchParams\x18\x05 \x01(\x0b\x32\".aerospike.vector.HnswSearchParamsH\x00\x42\x0e\n\x0csearchParams*X\n\tWriteType\x12\n\n\x06UPSERT\x10\x00\x12\x0f\n\x0bUPDATE_ONLY\x10\x01\x12\x0f\n\x0bINSERT_ONLY\x10\x02\x12\x0b\n\x07REPLACE\x10\x03\x12\x10\n\x0cREPLACE_ONLY\x10\x04*2\n\x0eProjectionType\x12\x07\n\x03\x41LL\x10\x00\x12\x08\n\x04NONE\x10\x01\x12\r\n\tSPECIFIED\x10\x02\x32\xc3\x03\n\x0fTransactService\x12=\n\x03Put\x12\x1c.aerospike.vector.PutRequest\x1a\x16.google.protobuf.Empty\"\x00\x12?\n\x03Get\x12\x1c.aerospike.vector.GetRequest\x1a\x18.aerospike.vector.Record\"\x00\x12\x43\n\x06\x44\x65lete\x12\x1f.aerospike.vector.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\x06\x45xists\x12\x1f.aerospike.vector.ExistsRequest\x1a\x19.aerospike.vector.Boolean\"\x00\x12L\n\tIsIndexed\x12\".aerospike.vector.IsIndexedRequest\x1a\x19.aerospike.vector.Boolean\"\x00\x12U\n\x0cVectorSearch\x12%.aerospike.vector.VectorSearchRequest\x1a\x1a.aerospike.vector.Neighbor\"\x00\x30\x01\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'transact_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals['DESCRIPTOR']._options = None +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' - _globals['_WRITETYPE']._serialized_start=1002 - _globals['_WRITETYPE']._serialized_end=1090 - _globals['_PROJECTIONTYPE']._serialized_start=1092 - _globals['_PROJECTIONTYPE']._serialized_end=1142 + _globals['_WRITETYPE']._serialized_start=1026 + _globals['_WRITETYPE']._serialized_end=1114 + _globals['_PROJECTIONTYPE']._serialized_start=1116 + _globals['_PROJECTIONTYPE']._serialized_end=1166 _globals['_PUTREQUEST']._serialized_start=79 - _globals['_PUTREQUEST']._serialized_end=216 - _globals['_GETREQUEST']._serialized_start=218 - _globals['_GETREQUEST']._serialized_end=324 - _globals['_EXISTSREQUEST']._serialized_start=326 - _globals['_EXISTSREQUEST']._serialized_end=377 - _globals['_DELETEREQUEST']._serialized_start=379 - _globals['_DELETEREQUEST']._serialized_end=430 - _globals['_ISINDEXEDREQUEST']._serialized_start=432 - _globals['_ISINDEXEDREQUEST']._serialized_end=530 - _globals['_PROJECTIONFILTER']._serialized_start=532 - _globals['_PROJECTIONFILTER']._serialized_end=614 - _globals['_PROJECTIONSPEC']._serialized_start=616 - _globals['_PROJECTIONSPEC']._serialized_end=738 - _globals['_VECTORSEARCHREQUEST']._serialized_start=741 - _globals['_VECTORSEARCHREQUEST']._serialized_end=1000 - _globals['_TRANSACT']._serialized_start=1145 - _globals['_TRANSACT']._serialized_end=1589 + _globals['_PUTREQUEST']._serialized_end=244 + _globals['_GETREQUEST']._serialized_start=246 + _globals['_GETREQUEST']._serialized_end=348 + _globals['_EXISTSREQUEST']._serialized_start=350 + _globals['_EXISTSREQUEST']._serialized_end=401 + _globals['_DELETEREQUEST']._serialized_start=403 + _globals['_DELETEREQUEST']._serialized_end=454 + _globals['_ISINDEXEDREQUEST']._serialized_start=456 + _globals['_ISINDEXEDREQUEST']._serialized_end=554 + _globals['_PROJECTIONFILTER']._serialized_start=556 + _globals['_PROJECTIONFILTER']._serialized_end=638 + _globals['_PROJECTIONSPEC']._serialized_start=640 + _globals['_PROJECTIONSPEC']._serialized_end=762 + _globals['_VECTORSEARCHREQUEST']._serialized_start=765 + _globals['_VECTORSEARCHREQUEST']._serialized_end=1024 + _globals['_TRANSACTSERVICE']._serialized_start=1169 + _globals['_TRANSACTSERVICE']._serialized_end=1620 # @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/transact_pb2_grpc.py b/src/aerospike_vector_search/shared/proto_generated/transact_pb2_grpc.py index 57feafca..a483ee02 100644 --- a/src/aerospike_vector_search/shared/proto_generated/transact_pb2_grpc.py +++ b/src/aerospike_vector_search/shared/proto_generated/transact_pb2_grpc.py @@ -1,13 +1,38 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from . import transact_pb2 as transact__pb2 from . import types_pb2 as types__pb2 +GRPC_GENERATED_VERSION = '1.64.1' +GRPC_VERSION = grpc.__version__ +EXPECTED_ERROR_RELEASE = '1.65.0' +SCHEDULED_RELEASE_DATE = 'June 25, 2024' +_version_not_supported = False -class TransactStub(object): +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + warnings.warn( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in transact_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + + f' This warning will become an error in {EXPECTED_ERROR_RELEASE},' + + f' scheduled for release on {SCHEDULED_RELEASE_DATE}.', + RuntimeWarning + ) + + +class TransactServiceStub(object): """Record transaction services. """ @@ -18,38 +43,38 @@ def __init__(self, channel): channel: A grpc.Channel. """ self.Put = channel.unary_unary( - '/aerospike.vector.Transact/Put', + '/aerospike.vector.TransactService/Put', request_serializer=transact__pb2.PutRequest.SerializeToString, response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) + _registered_method=True) self.Get = channel.unary_unary( - '/aerospike.vector.Transact/Get', + '/aerospike.vector.TransactService/Get', request_serializer=transact__pb2.GetRequest.SerializeToString, response_deserializer=types__pb2.Record.FromString, - ) + _registered_method=True) self.Delete = channel.unary_unary( - '/aerospike.vector.Transact/Delete', + '/aerospike.vector.TransactService/Delete', request_serializer=transact__pb2.DeleteRequest.SerializeToString, response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) + _registered_method=True) self.Exists = channel.unary_unary( - '/aerospike.vector.Transact/Exists', + '/aerospike.vector.TransactService/Exists', request_serializer=transact__pb2.ExistsRequest.SerializeToString, response_deserializer=types__pb2.Boolean.FromString, - ) + _registered_method=True) self.IsIndexed = channel.unary_unary( - '/aerospike.vector.Transact/IsIndexed', + '/aerospike.vector.TransactService/IsIndexed', request_serializer=transact__pb2.IsIndexedRequest.SerializeToString, response_deserializer=types__pb2.Boolean.FromString, - ) + _registered_method=True) self.VectorSearch = channel.unary_stream( - '/aerospike.vector.Transact/VectorSearch', + '/aerospike.vector.TransactService/VectorSearch', request_serializer=transact__pb2.VectorSearchRequest.SerializeToString, response_deserializer=types__pb2.Neighbor.FromString, - ) + _registered_method=True) -class TransactServicer(object): +class TransactServiceServicer(object): """Record transaction services. """ @@ -96,7 +121,7 @@ def VectorSearch(self, request, context): raise NotImplementedError('Method not implemented!') -def add_TransactServicer_to_server(servicer, server): +def add_TransactServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'Put': grpc.unary_unary_rpc_method_handler( servicer.Put, @@ -130,12 +155,13 @@ def add_TransactServicer_to_server(servicer, server): ), } generic_handler = grpc.method_handlers_generic_handler( - 'aerospike.vector.Transact', rpc_method_handlers) + 'aerospike.vector.TransactService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('aerospike.vector.TransactService', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. -class Transact(object): +class TransactService(object): """Record transaction services. """ @@ -150,11 +176,21 @@ def Put(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.Transact/Put', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.TransactService/Put', transact__pb2.PutRequest.SerializeToString, google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def Get(request, @@ -167,11 +203,21 @@ def Get(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.Transact/Get', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.TransactService/Get', transact__pb2.GetRequest.SerializeToString, types__pb2.Record.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def Delete(request, @@ -184,11 +230,21 @@ def Delete(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.Transact/Delete', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.TransactService/Delete', transact__pb2.DeleteRequest.SerializeToString, google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def Exists(request, @@ -201,11 +257,21 @@ def Exists(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.Transact/Exists', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.TransactService/Exists', transact__pb2.ExistsRequest.SerializeToString, types__pb2.Boolean.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def IsIndexed(request, @@ -218,11 +284,21 @@ def IsIndexed(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.Transact/IsIndexed', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.TransactService/IsIndexed', transact__pb2.IsIndexedRequest.SerializeToString, types__pb2.Boolean.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def VectorSearch(request, @@ -235,8 +311,18 @@ def VectorSearch(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_stream(request, target, '/aerospike.vector.Transact/VectorSearch', + return grpc.experimental.unary_stream( + request, + target, + '/aerospike.vector.TransactService/VectorSearch', transact__pb2.VectorSearchRequest.SerializeToString, types__pb2.Neighbor.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/aerospike_vector_search/shared/proto_generated/types_pb2.py b/src/aerospike_vector_search/shared/proto_generated/types_pb2.py index 2e582055..10429ec1 100644 --- a/src/aerospike_vector_search/shared/proto_generated/types_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/types_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: types.proto -# Protobuf Python Version: 4.25.1 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -14,20 +14,20 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btypes.proto\x12\x10\x61\x65rospike.vector\"\x91\x01\n\x03Key\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x10\n\x03set\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x15\n\x0bstringValue\x18\x03 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x04 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x05 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x06 \x01(\x03H\x00\x42\x07\n\x05valueB\x06\n\x04_set\"\x19\n\x08\x42oolData\x12\r\n\x05value\x18\x01 \x03(\x08\"\x1a\n\tFloatData\x12\r\n\x05value\x18\x01 \x03(\x02\"\x94\x01\n\x06MapKey\x12\x15\n\x0bstringValue\x18\x01 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x03 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x04 \x01(\x03H\x00\x12\x14\n\nfloatValue\x18\x05 \x01(\x02H\x00\x12\x15\n\x0b\x64oubleValue\x18\x06 \x01(\x01H\x00\x42\x07\n\x05value\"Y\n\x08MapEntry\x12%\n\x03key\x18\x01 \x01(\x0b\x32\x18.aerospike.vector.MapKey\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.aerospike.vector.Value\"2\n\x03Map\x12+\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x1a.aerospike.vector.MapEntry\"0\n\x04List\x12(\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x17.aerospike.vector.Value\"r\n\x06Vector\x12.\n\x08\x62oolData\x18\x01 \x01(\x0b\x32\x1a.aerospike.vector.BoolDataH\x00\x12\x30\n\tfloatData\x18\x02 \x01(\x0b\x32\x1b.aerospike.vector.FloatDataH\x00\x42\x06\n\x04\x64\x61ta\"\xb4\x02\n\x05Value\x12\x15\n\x0bstringValue\x18\x01 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x03 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x04 \x01(\x03H\x00\x12\x14\n\nfloatValue\x18\x05 \x01(\x02H\x00\x12\x15\n\x0b\x64oubleValue\x18\x06 \x01(\x01H\x00\x12)\n\x08mapValue\x18\x07 \x01(\x0b\x32\x15.aerospike.vector.MapH\x00\x12+\n\tlistValue\x18\x08 \x01(\x0b\x32\x16.aerospike.vector.ListH\x00\x12/\n\x0bvectorValue\x18\t \x01(\x0b\x32\x18.aerospike.vector.VectorH\x00\x12\x16\n\x0c\x62ooleanValue\x18\n \x01(\x08H\x00\x42\x07\n\x05value\"=\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.aerospike.vector.Value\"A\n\x17\x41\x65rospikeRecordMetadata\x12\x12\n\ngeneration\x18\x01 \x01(\r\x12\x12\n\nexpiration\x18\x02 \x01(\r\"\x85\x01\n\x06Record\x12\'\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x17.aerospike.vector.Field\x12\x46\n\x11\x61\x65rospikeMetadata\x18\x02 \x01(\x0b\x32).aerospike.vector.AerospikeRecordMetadataH\x00\x42\n\n\x08metadata\"z\n\x08Neighbor\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12-\n\x06record\x18\x02 \x01(\x0b\x32\x18.aerospike.vector.RecordH\x00\x88\x01\x01\x12\x10\n\x08\x64istance\x18\x03 \x01(\x02\x42\t\n\x07_record\"*\n\x07IndexId\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xa8\x01\n\nHnswParams\x12\x0e\n\x01m\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1b\n\x0e\x65\x66\x43onstruction\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x0f\n\x02\x65\x66\x18\x03 \x01(\rH\x02\x88\x01\x01\x12<\n\x0e\x62\x61tchingParams\x18\x04 \x01(\x0b\x32$.aerospike.vector.HnswBatchingParamsB\x04\n\x02_mB\x11\n\x0f_efConstructionB\x05\n\x03_ef\"*\n\x10HnswSearchParams\x12\x0f\n\x02\x65\x66\x18\x01 \x01(\rH\x00\x88\x01\x01\x42\x05\n\x03_ef\"\x84\x01\n\x12HnswBatchingParams\x12\x17\n\nmaxRecords\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x15\n\x08interval\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x15\n\x08\x64isabled\x18\x03 \x01(\x08H\x02\x88\x01\x01\x42\r\n\x0b_maxRecordsB\x0b\n\t_intervalB\x0b\n\t_disabled\"N\n\x0cIndexStorage\x12\x16\n\tnamespace\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x03set\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x0c\n\n_namespaceB\x06\n\x04_set\"\xe0\x03\n\x0fIndexDefinition\x12%\n\x02id\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12)\n\x04type\x18\x02 \x01(\x0e\x32\x1b.aerospike.vector.IndexType\x12\x12\n\ndimensions\x18\x03 \x01(\r\x12\x44\n\x14vectorDistanceMetric\x18\x04 \x01(\x0e\x32&.aerospike.vector.VectorDistanceMetric\x12\r\n\x05\x66ield\x18\x05 \x01(\t\x12\x16\n\tsetFilter\x18\x06 \x01(\tH\x01\x88\x01\x01\x12\x32\n\nhnswParams\x18\x07 \x01(\x0b\x32\x1c.aerospike.vector.HnswParamsH\x00\x12=\n\x06labels\x18\x08 \x03(\x0b\x32-.aerospike.vector.IndexDefinition.LabelsEntry\x12\x34\n\x07storage\x18\t \x01(\x0b\x32\x1e.aerospike.vector.IndexStorageH\x02\x88\x01\x01\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x08\n\x06paramsB\x0c\n\n_setFilterB\n\n\x08_storage\"I\n\x13IndexDefinitionList\x12\x32\n\x07indices\x18\x01 \x03(\x0b\x32!.aerospike.vector.IndexDefinition\"\x12\n\x04Role\x12\n\n\x02id\x18\x01 \x01(\t\"\'\n\x04User\x12\x10\n\x08username\x18\x01 \x01(\t\x12\r\n\x05roles\x18\x02 \x03(\t\"t\n\x0b\x43redentials\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x44\n\x13passwordCredentials\x18\x02 \x01(\x0b\x32%.aerospike.vector.PasswordCredentialsH\x00\x42\r\n\x0b\x63redentials\"\'\n\x13PasswordCredentials\x12\x10\n\x08password\x18\x01 \x01(\t\"\x18\n\x07\x42oolean\x12\r\n\x05value\x18\x01 \x01(\x08*f\n\x14VectorDistanceMetric\x12\x15\n\x11SQUARED_EUCLIDEAN\x10\x00\x12\n\n\x06\x43OSINE\x10\x01\x12\x0f\n\x0b\x44OT_PRODUCT\x10\x02\x12\r\n\tMANHATTAN\x10\x03\x12\x0b\n\x07HAMMING\x10\x04*\x15\n\tIndexType\x12\x08\n\x04HNSW\x10\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btypes.proto\x12\x10\x61\x65rospike.vector\"\x91\x01\n\x03Key\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x10\n\x03set\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x15\n\x0bstringValue\x18\x03 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x04 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x05 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x06 \x01(\x03H\x00\x42\x07\n\x05valueB\x06\n\x04_set\"\x19\n\x08\x42oolData\x12\r\n\x05value\x18\x01 \x03(\x08\"\x1a\n\tFloatData\x12\r\n\x05value\x18\x01 \x03(\x02\"\x94\x01\n\x06MapKey\x12\x15\n\x0bstringValue\x18\x01 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x03 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x04 \x01(\x03H\x00\x12\x14\n\nfloatValue\x18\x05 \x01(\x02H\x00\x12\x15\n\x0b\x64oubleValue\x18\x06 \x01(\x01H\x00\x42\x07\n\x05value\"Y\n\x08MapEntry\x12%\n\x03key\x18\x01 \x01(\x0b\x32\x18.aerospike.vector.MapKey\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.aerospike.vector.Value\"2\n\x03Map\x12+\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x1a.aerospike.vector.MapEntry\"0\n\x04List\x12(\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x17.aerospike.vector.Value\"r\n\x06Vector\x12.\n\x08\x62oolData\x18\x01 \x01(\x0b\x32\x1a.aerospike.vector.BoolDataH\x00\x12\x30\n\tfloatData\x18\x02 \x01(\x0b\x32\x1b.aerospike.vector.FloatDataH\x00\x42\x06\n\x04\x64\x61ta\"\xb4\x02\n\x05Value\x12\x15\n\x0bstringValue\x18\x01 \x01(\tH\x00\x12\x14\n\nbytesValue\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08intValue\x18\x03 \x01(\x05H\x00\x12\x13\n\tlongValue\x18\x04 \x01(\x03H\x00\x12\x14\n\nfloatValue\x18\x05 \x01(\x02H\x00\x12\x15\n\x0b\x64oubleValue\x18\x06 \x01(\x01H\x00\x12)\n\x08mapValue\x18\x07 \x01(\x0b\x32\x15.aerospike.vector.MapH\x00\x12+\n\tlistValue\x18\x08 \x01(\x0b\x32\x16.aerospike.vector.ListH\x00\x12/\n\x0bvectorValue\x18\t \x01(\x0b\x32\x18.aerospike.vector.VectorH\x00\x12\x16\n\x0c\x62ooleanValue\x18\n \x01(\x08H\x00\x42\x07\n\x05value\"=\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.aerospike.vector.Value\"A\n\x17\x41\x65rospikeRecordMetadata\x12\x12\n\ngeneration\x18\x01 \x01(\r\x12\x12\n\nexpiration\x18\x02 \x01(\r\"\x85\x01\n\x06Record\x12\'\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x17.aerospike.vector.Field\x12\x46\n\x11\x61\x65rospikeMetadata\x18\x02 \x01(\x0b\x32).aerospike.vector.AerospikeRecordMetadataH\x00\x42\n\n\x08metadata\"z\n\x08Neighbor\x12\"\n\x03key\x18\x01 \x01(\x0b\x32\x15.aerospike.vector.Key\x12-\n\x06record\x18\x02 \x01(\x0b\x32\x18.aerospike.vector.RecordH\x00\x88\x01\x01\x12\x10\n\x08\x64istance\x18\x03 \x01(\x02\x42\t\n\x07_record\"*\n\x07IndexId\x12\x11\n\tnamespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x8d\x03\n\nHnswParams\x12\x0e\n\x01m\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1b\n\x0e\x65\x66\x43onstruction\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x0f\n\x02\x65\x66\x18\x03 \x01(\rH\x02\x88\x01\x01\x12<\n\x0e\x62\x61tchingParams\x18\x04 \x01(\x0b\x32$.aerospike.vector.HnswBatchingParams\x12\x1c\n\x0fmaxMemQueueSize\x18\x05 \x01(\rH\x03\x88\x01\x01\x12:\n\rcachingParams\x18\x06 \x01(\x0b\x32#.aerospike.vector.HnswCachingParams\x12\x38\n\x0chealerParams\x18\x07 \x01(\x0b\x32\".aerospike.vector.HnswHealerParams\x12;\n\x0bmergeParams\x18\x08 \x01(\x0b\x32&.aerospike.vector.HnswIndexMergeParamsB\x04\n\x02_mB\x11\n\x0f_efConstructionB\x05\n\x03_efB\x12\n\x10_maxMemQueueSize\"*\n\x10HnswSearchParams\x12\x0f\n\x02\x65\x66\x18\x01 \x01(\rH\x00\x88\x01\x01\x42\x05\n\x03_ef\"@\n\x14HnswIndexMergeParams\x12\x18\n\x0bparallelism\x18\x01 \x01(\rH\x00\x88\x01\x01\x42\x0e\n\x0c_parallelism\"[\n\x11HnswCachingParams\x12\x17\n\nmaxEntries\x18\x01 \x01(\x04H\x00\x88\x01\x01\x12\x13\n\x06\x65xpiry\x18\x02 \x01(\x04H\x01\x88\x01\x01\x42\r\n\x0b_maxEntriesB\t\n\x07_expiry\"\x84\x02\n\x10HnswHealerParams\x12\x1f\n\x12maxScanRatePerNode\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x0fmaxScanPageSize\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0ereindexPercent\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1a\n\rscheduleDelay\x18\x04 \x01(\x04H\x03\x88\x01\x01\x12\x18\n\x0bparallelism\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x15\n\x13_maxScanRatePerNodeB\x12\n\x10_maxScanPageSizeB\x11\n\x0f_reindexPercentB\x10\n\x0e_scheduleDelayB\x0e\n\x0c_parallelism\"`\n\x12HnswBatchingParams\x12\x17\n\nmaxRecords\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x15\n\x08interval\x18\x02 \x01(\rH\x01\x88\x01\x01\x42\r\n\x0b_maxRecordsB\x0b\n\t_interval\"\x8e\x03\n\x0fHnswIndexUpdate\x12\x41\n\x0e\x62\x61tchingParams\x18\x01 \x01(\x0b\x32$.aerospike.vector.HnswBatchingParamsH\x00\x88\x01\x01\x12\x1c\n\x0fmaxMemQueueSize\x18\x02 \x01(\rH\x01\x88\x01\x01\x12?\n\rcachingParams\x18\x03 \x01(\x0b\x32#.aerospike.vector.HnswCachingParamsH\x02\x88\x01\x01\x12=\n\x0chealerParams\x18\x04 \x01(\x0b\x32\".aerospike.vector.HnswHealerParamsH\x03\x88\x01\x01\x12@\n\x0bmergeParams\x18\x05 \x01(\x0b\x32&.aerospike.vector.HnswIndexMergeParamsH\x04\x88\x01\x01\x42\x11\n\x0f_batchingParamsB\x12\n\x10_maxMemQueueSizeB\x10\n\x0e_cachingParamsB\x0f\n\r_healerParamsB\x0e\n\x0c_mergeParams\"N\n\x0cIndexStorage\x12\x16\n\tnamespace\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x03set\x18\x02 \x01(\tH\x01\x88\x01\x01\x42\x0c\n\n_namespaceB\x06\n\x04_set\"\xe0\x03\n\x0fIndexDefinition\x12%\n\x02id\x18\x01 \x01(\x0b\x32\x19.aerospike.vector.IndexId\x12)\n\x04type\x18\x02 \x01(\x0e\x32\x1b.aerospike.vector.IndexType\x12\x12\n\ndimensions\x18\x03 \x01(\r\x12\x44\n\x14vectorDistanceMetric\x18\x04 \x01(\x0e\x32&.aerospike.vector.VectorDistanceMetric\x12\r\n\x05\x66ield\x18\x05 \x01(\t\x12\x16\n\tsetFilter\x18\x06 \x01(\tH\x01\x88\x01\x01\x12\x32\n\nhnswParams\x18\x07 \x01(\x0b\x32\x1c.aerospike.vector.HnswParamsH\x00\x12=\n\x06labels\x18\x08 \x03(\x0b\x32-.aerospike.vector.IndexDefinition.LabelsEntry\x12\x34\n\x07storage\x18\t \x01(\x0b\x32\x1e.aerospike.vector.IndexStorageH\x02\x88\x01\x01\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x08\n\x06paramsB\x0c\n\n_setFilterB\n\n\x08_storage\"I\n\x13IndexDefinitionList\x12\x32\n\x07indices\x18\x01 \x03(\x0b\x32!.aerospike.vector.IndexDefinition\"\x12\n\x04Role\x12\n\n\x02id\x18\x01 \x01(\t\"\'\n\x04User\x12\x10\n\x08username\x18\x01 \x01(\t\x12\r\n\x05roles\x18\x02 \x03(\t\"t\n\x0b\x43redentials\x12\x10\n\x08username\x18\x01 \x01(\t\x12\x44\n\x13passwordCredentials\x18\x02 \x01(\x0b\x32%.aerospike.vector.PasswordCredentialsH\x00\x42\r\n\x0b\x63redentials\"\'\n\x13PasswordCredentials\x12\x10\n\x08password\x18\x01 \x01(\t\"\x18\n\x07\x42oolean\x12\r\n\x05value\x18\x01 \x01(\x08*f\n\x14VectorDistanceMetric\x12\x15\n\x11SQUARED_EUCLIDEAN\x10\x00\x12\n\n\x06\x43OSINE\x10\x01\x12\x0f\n\x0b\x44OT_PRODUCT\x10\x02\x12\r\n\tMANHATTAN\x10\x03\x12\x0b\n\x07HAMMING\x10\x04*\x15\n\tIndexType\x12\x08\n\x04HNSW\x10\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'types_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals['DESCRIPTOR']._options = None +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' - _globals['_INDEXDEFINITION_LABELSENTRY']._options = None + _globals['_INDEXDEFINITION_LABELSENTRY']._loaded_options = None _globals['_INDEXDEFINITION_LABELSENTRY']._serialized_options = b'8\001' - _globals['_VECTORDISTANCEMETRIC']._serialized_start=2675 - _globals['_VECTORDISTANCEMETRIC']._serialized_end=2777 - _globals['_INDEXTYPE']._serialized_start=2779 - _globals['_INDEXTYPE']._serialized_end=2800 + _globals['_VECTORDISTANCEMETRIC']._serialized_start=3690 + _globals['_VECTORDISTANCEMETRIC']._serialized_end=3792 + _globals['_INDEXTYPE']._serialized_start=3794 + _globals['_INDEXTYPE']._serialized_end=3815 _globals['_KEY']._serialized_start=34 _globals['_KEY']._serialized_end=179 _globals['_BOOLDATA']._serialized_start=181 @@ -57,27 +57,35 @@ _globals['_INDEXID']._serialized_start=1397 _globals['_INDEXID']._serialized_end=1439 _globals['_HNSWPARAMS']._serialized_start=1442 - _globals['_HNSWPARAMS']._serialized_end=1610 - _globals['_HNSWSEARCHPARAMS']._serialized_start=1612 - _globals['_HNSWSEARCHPARAMS']._serialized_end=1654 - _globals['_HNSWBATCHINGPARAMS']._serialized_start=1657 - _globals['_HNSWBATCHINGPARAMS']._serialized_end=1789 - _globals['_INDEXSTORAGE']._serialized_start=1791 - _globals['_INDEXSTORAGE']._serialized_end=1869 - _globals['_INDEXDEFINITION']._serialized_start=1872 - _globals['_INDEXDEFINITION']._serialized_end=2352 - _globals['_INDEXDEFINITION_LABELSENTRY']._serialized_start=2271 - _globals['_INDEXDEFINITION_LABELSENTRY']._serialized_end=2316 - _globals['_INDEXDEFINITIONLIST']._serialized_start=2354 - _globals['_INDEXDEFINITIONLIST']._serialized_end=2427 - _globals['_ROLE']._serialized_start=2429 - _globals['_ROLE']._serialized_end=2447 - _globals['_USER']._serialized_start=2449 - _globals['_USER']._serialized_end=2488 - _globals['_CREDENTIALS']._serialized_start=2490 - _globals['_CREDENTIALS']._serialized_end=2606 - _globals['_PASSWORDCREDENTIALS']._serialized_start=2608 - _globals['_PASSWORDCREDENTIALS']._serialized_end=2647 - _globals['_BOOLEAN']._serialized_start=2649 - _globals['_BOOLEAN']._serialized_end=2673 + _globals['_HNSWPARAMS']._serialized_end=1839 + _globals['_HNSWSEARCHPARAMS']._serialized_start=1841 + _globals['_HNSWSEARCHPARAMS']._serialized_end=1883 + _globals['_HNSWINDEXMERGEPARAMS']._serialized_start=1885 + _globals['_HNSWINDEXMERGEPARAMS']._serialized_end=1949 + _globals['_HNSWCACHINGPARAMS']._serialized_start=1951 + _globals['_HNSWCACHINGPARAMS']._serialized_end=2042 + _globals['_HNSWHEALERPARAMS']._serialized_start=2045 + _globals['_HNSWHEALERPARAMS']._serialized_end=2305 + _globals['_HNSWBATCHINGPARAMS']._serialized_start=2307 + _globals['_HNSWBATCHINGPARAMS']._serialized_end=2403 + _globals['_HNSWINDEXUPDATE']._serialized_start=2406 + _globals['_HNSWINDEXUPDATE']._serialized_end=2804 + _globals['_INDEXSTORAGE']._serialized_start=2806 + _globals['_INDEXSTORAGE']._serialized_end=2884 + _globals['_INDEXDEFINITION']._serialized_start=2887 + _globals['_INDEXDEFINITION']._serialized_end=3367 + _globals['_INDEXDEFINITION_LABELSENTRY']._serialized_start=3286 + _globals['_INDEXDEFINITION_LABELSENTRY']._serialized_end=3331 + _globals['_INDEXDEFINITIONLIST']._serialized_start=3369 + _globals['_INDEXDEFINITIONLIST']._serialized_end=3442 + _globals['_ROLE']._serialized_start=3444 + _globals['_ROLE']._serialized_end=3462 + _globals['_USER']._serialized_start=3464 + _globals['_USER']._serialized_end=3503 + _globals['_CREDENTIALS']._serialized_start=3505 + _globals['_CREDENTIALS']._serialized_end=3621 + _globals['_PASSWORDCREDENTIALS']._serialized_start=3623 + _globals['_PASSWORDCREDENTIALS']._serialized_end=3662 + _globals['_BOOLEAN']._serialized_start=3664 + _globals['_BOOLEAN']._serialized_end=3688 # @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/types_pb2_grpc.py b/src/aerospike_vector_search/shared/proto_generated/types_pb2_grpc.py index 2daafffe..73b6811f 100644 --- a/src/aerospike_vector_search/shared/proto_generated/types_pb2_grpc.py +++ b/src/aerospike_vector_search/shared/proto_generated/types_pb2_grpc.py @@ -1,4 +1,29 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings + +GRPC_GENERATED_VERSION = '1.64.1' +GRPC_VERSION = grpc.__version__ +EXPECTED_ERROR_RELEASE = '1.65.0' +SCHEDULED_RELEASE_DATE = 'June 25, 2024' +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + warnings.warn( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in types_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + + f' This warning will become an error in {EXPECTED_ERROR_RELEASE},' + + f' scheduled for release on {SCHEDULED_RELEASE_DATE}.', + RuntimeWarning + ) diff --git a/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2.py b/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2.py index c59c7b46..7dcd615c 100644 --- a/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: user-admin.proto -# Protobuf Python Version: 4.25.1 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -21,8 +21,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'user_admin_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals['DESCRIPTOR']._options = None +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' _globals['_ADDUSERREQUEST']._serialized_start=80 _globals['_ADDUSERREQUEST']._serialized_end=163 diff --git a/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2_grpc.py b/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2_grpc.py index 8f465e4e..d947a8db 100644 --- a/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2_grpc.py +++ b/src/aerospike_vector_search/shared/proto_generated/user_admin_pb2_grpc.py @@ -1,11 +1,36 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from . import types_pb2 as types__pb2 from . import user_admin_pb2 as user__admin__pb2 +GRPC_GENERATED_VERSION = '1.64.1' +GRPC_VERSION = grpc.__version__ +EXPECTED_ERROR_RELEASE = '1.65.0' +SCHEDULED_RELEASE_DATE = 'June 25, 2024' +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + warnings.warn( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in user_admin_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + + f' This warning will become an error in {EXPECTED_ERROR_RELEASE},' + + f' scheduled for release on {SCHEDULED_RELEASE_DATE}.', + RuntimeWarning + ) + class UserAdminServiceStub(object): """User admin service @@ -21,42 +46,42 @@ def __init__(self, channel): '/aerospike.vector.UserAdminService/AddUser', request_serializer=user__admin__pb2.AddUserRequest.SerializeToString, response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) + _registered_method=True) self.UpdateCredentials = channel.unary_unary( '/aerospike.vector.UserAdminService/UpdateCredentials', request_serializer=user__admin__pb2.UpdateCredentialsRequest.SerializeToString, response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) + _registered_method=True) self.DropUser = channel.unary_unary( '/aerospike.vector.UserAdminService/DropUser', request_serializer=user__admin__pb2.DropUserRequest.SerializeToString, response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) + _registered_method=True) self.GetUser = channel.unary_unary( '/aerospike.vector.UserAdminService/GetUser', request_serializer=user__admin__pb2.GetUserRequest.SerializeToString, response_deserializer=types__pb2.User.FromString, - ) + _registered_method=True) self.ListUsers = channel.unary_unary( '/aerospike.vector.UserAdminService/ListUsers', request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, response_deserializer=user__admin__pb2.ListUsersResponse.FromString, - ) + _registered_method=True) self.GrantRoles = channel.unary_unary( '/aerospike.vector.UserAdminService/GrantRoles', request_serializer=user__admin__pb2.GrantRolesRequest.SerializeToString, response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) + _registered_method=True) self.RevokeRoles = channel.unary_unary( '/aerospike.vector.UserAdminService/RevokeRoles', request_serializer=user__admin__pb2.RevokeRolesRequest.SerializeToString, response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) + _registered_method=True) self.ListRoles = channel.unary_unary( '/aerospike.vector.UserAdminService/ListRoles', request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, response_deserializer=user__admin__pb2.ListRolesResponse.FromString, - ) + _registered_method=True) class UserAdminServiceServicer(object): @@ -166,6 +191,7 @@ def add_UserAdminServiceServicer_to_server(servicer, server): generic_handler = grpc.method_handlers_generic_handler( 'aerospike.vector.UserAdminService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('aerospike.vector.UserAdminService', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. @@ -184,11 +210,21 @@ def AddUser(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/AddUser', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.UserAdminService/AddUser', user__admin__pb2.AddUserRequest.SerializeToString, google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def UpdateCredentials(request, @@ -201,11 +237,21 @@ def UpdateCredentials(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/UpdateCredentials', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.UserAdminService/UpdateCredentials', user__admin__pb2.UpdateCredentialsRequest.SerializeToString, google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def DropUser(request, @@ -218,11 +264,21 @@ def DropUser(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/DropUser', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.UserAdminService/DropUser', user__admin__pb2.DropUserRequest.SerializeToString, google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def GetUser(request, @@ -235,11 +291,21 @@ def GetUser(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/GetUser', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.UserAdminService/GetUser', user__admin__pb2.GetUserRequest.SerializeToString, types__pb2.User.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def ListUsers(request, @@ -252,11 +318,21 @@ def ListUsers(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/ListUsers', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.UserAdminService/ListUsers', google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, user__admin__pb2.ListUsersResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def GrantRoles(request, @@ -269,11 +345,21 @@ def GrantRoles(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/GrantRoles', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.UserAdminService/GrantRoles', user__admin__pb2.GrantRolesRequest.SerializeToString, google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def RevokeRoles(request, @@ -286,11 +372,21 @@ def RevokeRoles(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/RevokeRoles', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.UserAdminService/RevokeRoles', user__admin__pb2.RevokeRolesRequest.SerializeToString, google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def ListRoles(request, @@ -303,8 +399,18 @@ def ListRoles(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.UserAdminService/ListRoles', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.UserAdminService/ListRoles', google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, user__admin__pb2.ListRolesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2.py b/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2.py index 21cd88f9..0344359f 100644 --- a/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2.py +++ b/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: vector-db.proto -# Protobuf Python Version: 4.25.1 +# Protobuf Python Version: 5.26.1 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -15,15 +15,15 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fvector-db.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\"\x0e\n\x0c\x41\x62outRequest\" \n\rAboutResponse\x12\x0f\n\x07version\x18\x01 \x01(\t\"\x17\n\tClusterId\x12\n\n\x02id\x18\x01 \x01(\x04\"\x14\n\x06NodeId\x12\n\n\x02id\x18\x01 \x01(\x04\">\n\x0eServerEndpoint\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\r\n\x05isTls\x18\x03 \x01(\x08\"I\n\x12ServerEndpointList\x12\x33\n\tendpoints\x18\x01 \x03(\x0b\x32 .aerospike.vector.ServerEndpoint\"\xb8\x01\n\x14\x43lusterNodeEndpoints\x12H\n\tendpoints\x18\x01 \x03(\x0b\x32\x35.aerospike.vector.ClusterNodeEndpoints.EndpointsEntry\x1aV\n\x0e\x45ndpointsEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x33\n\x05value\x18\x02 \x01(\x0b\x32$.aerospike.vector.ServerEndpointList:\x02\x38\x01\"I\n\x1b\x43lusterNodeEndpointsRequest\x12\x19\n\x0clistenerName\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x0f\n\r_listenerName\"\x81\x01\n\x0f\x43lusteringState\x12\x13\n\x0bisInCluster\x18\x01 \x01(\x08\x12.\n\tclusterId\x18\x02 \x01(\x0b\x32\x1b.aerospike.vector.ClusterId\x12)\n\x07members\x18\x03 \x03(\x0b\x32\x18.aerospike.vector.NodeId2Q\n\x05\x41\x62out\x12H\n\x03Get\x12\x1e.aerospike.vector.AboutRequest\x1a\x1f.aerospike.vector.AboutResponse\"\x00\x32\xd8\x02\n\x0b\x43lusterInfo\x12?\n\tGetNodeId\x12\x16.google.protobuf.Empty\x1a\x18.aerospike.vector.NodeId\"\x00\x12\x45\n\x0cGetClusterId\x12\x16.google.protobuf.Empty\x1a\x1b.aerospike.vector.ClusterId\"\x00\x12Q\n\x12GetClusteringState\x12\x16.google.protobuf.Empty\x1a!.aerospike.vector.ClusteringState\"\x00\x12n\n\x13GetClusterEndpoints\x12-.aerospike.vector.ClusterNodeEndpointsRequest\x1a&.aerospike.vector.ClusterNodeEndpoints\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fvector-db.proto\x12\x10\x61\x65rospike.vector\x1a\x1bgoogle/protobuf/empty.proto\"\x0e\n\x0c\x41\x62outRequest\" \n\rAboutResponse\x12\x0f\n\x07version\x18\x01 \x01(\t\"\x17\n\tClusterId\x12\n\n\x02id\x18\x01 \x01(\x04\"\x14\n\x06NodeId\x12\n\n\x02id\x18\x01 \x01(\x04\">\n\x0eServerEndpoint\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\r\n\x05isTls\x18\x03 \x01(\x08\"I\n\x12ServerEndpointList\x12\x33\n\tendpoints\x18\x01 \x03(\x0b\x32 .aerospike.vector.ServerEndpoint\"\xb8\x01\n\x14\x43lusterNodeEndpoints\x12H\n\tendpoints\x18\x01 \x03(\x0b\x32\x35.aerospike.vector.ClusterNodeEndpoints.EndpointsEntry\x1aV\n\x0e\x45ndpointsEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\x33\n\x05value\x18\x02 \x01(\x0b\x32$.aerospike.vector.ServerEndpointList:\x02\x38\x01\"I\n\x1b\x43lusterNodeEndpointsRequest\x12\x19\n\x0clistenerName\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x0f\n\r_listenerName\"\x81\x01\n\x0f\x43lusteringState\x12\x13\n\x0bisInCluster\x18\x01 \x01(\x08\x12.\n\tclusterId\x18\x02 \x01(\x0b\x32\x1b.aerospike.vector.ClusterId\x12)\n\x07members\x18\x03 \x03(\x0b\x32\x18.aerospike.vector.NodeId2X\n\x0c\x41\x62outService\x12H\n\x03Get\x12\x1e.aerospike.vector.AboutRequest\x1a\x1f.aerospike.vector.AboutResponse\"\x00\x32\xdf\x02\n\x12\x43lusterInfoService\x12?\n\tGetNodeId\x12\x16.google.protobuf.Empty\x1a\x18.aerospike.vector.NodeId\"\x00\x12\x45\n\x0cGetClusterId\x12\x16.google.protobuf.Empty\x1a\x1b.aerospike.vector.ClusterId\"\x00\x12Q\n\x12GetClusteringState\x12\x16.google.protobuf.Empty\x1a!.aerospike.vector.ClusteringState\"\x00\x12n\n\x13GetClusterEndpoints\x12-.aerospike.vector.ClusterNodeEndpointsRequest\x1a&.aerospike.vector.ClusterNodeEndpoints\"\x00\x42\x43\n!com.aerospike.vector.client.protoP\x01Z\x1c\x61\x65rospike.com/vector/protos/b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'vector_db_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals['DESCRIPTOR']._options = None +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None _globals['DESCRIPTOR']._serialized_options = b'\n!com.aerospike.vector.client.protoP\001Z\034aerospike.com/vector/protos/' - _globals['_CLUSTERNODEENDPOINTS_ENDPOINTSENTRY']._options = None + _globals['_CLUSTERNODEENDPOINTS_ENDPOINTSENTRY']._loaded_options = None _globals['_CLUSTERNODEENDPOINTS_ENDPOINTSENTRY']._serialized_options = b'8\001' _globals['_ABOUTREQUEST']._serialized_start=66 _globals['_ABOUTREQUEST']._serialized_end=80 @@ -45,8 +45,8 @@ _globals['_CLUSTERNODEENDPOINTSREQUEST']._serialized_end=562 _globals['_CLUSTERINGSTATE']._serialized_start=565 _globals['_CLUSTERINGSTATE']._serialized_end=694 - _globals['_ABOUT']._serialized_start=696 - _globals['_ABOUT']._serialized_end=777 - _globals['_CLUSTERINFO']._serialized_start=780 - _globals['_CLUSTERINFO']._serialized_end=1124 + _globals['_ABOUTSERVICE']._serialized_start=696 + _globals['_ABOUTSERVICE']._serialized_end=784 + _globals['_CLUSTERINFOSERVICE']._serialized_start=787 + _globals['_CLUSTERINFOSERVICE']._serialized_end=1138 # @@protoc_insertion_point(module_scope) diff --git a/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2_grpc.py b/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2_grpc.py index 7db60972..4fafd697 100644 --- a/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2_grpc.py +++ b/src/aerospike_vector_search/shared/proto_generated/vector_db_pb2_grpc.py @@ -1,12 +1,37 @@ # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! """Client and server classes corresponding to protobuf-defined services.""" import grpc +import warnings from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from . import vector_db_pb2 as vector__db__pb2 +GRPC_GENERATED_VERSION = '1.64.1' +GRPC_VERSION = grpc.__version__ +EXPECTED_ERROR_RELEASE = '1.65.0' +SCHEDULED_RELEASE_DATE = 'June 25, 2024' +_version_not_supported = False -class AboutStub(object): +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + warnings.warn( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in vector_db_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + + f' This warning will become an error in {EXPECTED_ERROR_RELEASE},' + + f' scheduled for release on {SCHEDULED_RELEASE_DATE}.', + RuntimeWarning + ) + + +class AboutServiceStub(object): """Information about the service. """ @@ -17,13 +42,13 @@ def __init__(self, channel): channel: A grpc.Channel. """ self.Get = channel.unary_unary( - '/aerospike.vector.About/Get', + '/aerospike.vector.AboutService/Get', request_serializer=vector__db__pb2.AboutRequest.SerializeToString, response_deserializer=vector__db__pb2.AboutResponse.FromString, - ) + _registered_method=True) -class AboutServicer(object): +class AboutServiceServicer(object): """Information about the service. """ @@ -34,7 +59,7 @@ def Get(self, request, context): raise NotImplementedError('Method not implemented!') -def add_AboutServicer_to_server(servicer, server): +def add_AboutServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'Get': grpc.unary_unary_rpc_method_handler( servicer.Get, @@ -43,12 +68,13 @@ def add_AboutServicer_to_server(servicer, server): ), } generic_handler = grpc.method_handlers_generic_handler( - 'aerospike.vector.About', rpc_method_handlers) + 'aerospike.vector.AboutService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('aerospike.vector.AboutService', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. -class About(object): +class AboutService(object): """Information about the service. """ @@ -63,14 +89,24 @@ def Get(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.About/Get', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.AboutService/Get', vector__db__pb2.AboutRequest.SerializeToString, vector__db__pb2.AboutResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) -class ClusterInfoStub(object): +class ClusterInfoServiceStub(object): """Vector DB cluster service. """ @@ -81,28 +117,28 @@ def __init__(self, channel): channel: A grpc.Channel. """ self.GetNodeId = channel.unary_unary( - '/aerospike.vector.ClusterInfo/GetNodeId', + '/aerospike.vector.ClusterInfoService/GetNodeId', request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, response_deserializer=vector__db__pb2.NodeId.FromString, - ) + _registered_method=True) self.GetClusterId = channel.unary_unary( - '/aerospike.vector.ClusterInfo/GetClusterId', + '/aerospike.vector.ClusterInfoService/GetClusterId', request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, response_deserializer=vector__db__pb2.ClusterId.FromString, - ) + _registered_method=True) self.GetClusteringState = channel.unary_unary( - '/aerospike.vector.ClusterInfo/GetClusteringState', + '/aerospike.vector.ClusterInfoService/GetClusteringState', request_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, response_deserializer=vector__db__pb2.ClusteringState.FromString, - ) + _registered_method=True) self.GetClusterEndpoints = channel.unary_unary( - '/aerospike.vector.ClusterInfo/GetClusterEndpoints', + '/aerospike.vector.ClusterInfoService/GetClusterEndpoints', request_serializer=vector__db__pb2.ClusterNodeEndpointsRequest.SerializeToString, response_deserializer=vector__db__pb2.ClusterNodeEndpoints.FromString, - ) + _registered_method=True) -class ClusterInfoServicer(object): +class ClusterInfoServiceServicer(object): """Vector DB cluster service. """ @@ -135,7 +171,7 @@ def GetClusterEndpoints(self, request, context): raise NotImplementedError('Method not implemented!') -def add_ClusterInfoServicer_to_server(servicer, server): +def add_ClusterInfoServiceServicer_to_server(servicer, server): rpc_method_handlers = { 'GetNodeId': grpc.unary_unary_rpc_method_handler( servicer.GetNodeId, @@ -159,12 +195,13 @@ def add_ClusterInfoServicer_to_server(servicer, server): ), } generic_handler = grpc.method_handlers_generic_handler( - 'aerospike.vector.ClusterInfo', rpc_method_handlers) + 'aerospike.vector.ClusterInfoService', rpc_method_handlers) server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('aerospike.vector.ClusterInfoService', rpc_method_handlers) # This class is part of an EXPERIMENTAL API. -class ClusterInfo(object): +class ClusterInfoService(object): """Vector DB cluster service. """ @@ -179,11 +216,21 @@ def GetNodeId(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.ClusterInfo/GetNodeId', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.ClusterInfoService/GetNodeId', google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, vector__db__pb2.NodeId.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def GetClusterId(request, @@ -196,11 +243,21 @@ def GetClusterId(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.ClusterInfo/GetClusterId', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.ClusterInfoService/GetClusterId', google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, vector__db__pb2.ClusterId.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def GetClusteringState(request, @@ -213,11 +270,21 @@ def GetClusteringState(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.ClusterInfo/GetClusteringState', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.ClusterInfoService/GetClusteringState', google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, vector__db__pb2.ClusteringState.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) @staticmethod def GetClusterEndpoints(request, @@ -230,8 +297,18 @@ def GetClusterEndpoints(request, wait_for_ready=None, timeout=None, metadata=None): - return grpc.experimental.unary_unary(request, target, '/aerospike.vector.ClusterInfo/GetClusterEndpoints', + return grpc.experimental.unary_unary( + request, + target, + '/aerospike.vector.ClusterInfoService/GetClusterEndpoints', vector__db__pb2.ClusterNodeEndpointsRequest.SerializeToString, vector__db__pb2.ClusterNodeEndpoints.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/aerospike_vector_search/types.py b/src/aerospike_vector_search/types.py index db3face7..1b29d6a0 100644 --- a/src/aerospike_vector_search/types.py +++ b/src/aerospike_vector_search/types.py @@ -174,17 +174,70 @@ def __init__( *, max_records: Optional[int] = 10000, interval: Optional[int] = 10000, - disabled: Optional[bool] = False, ) -> None: self.max_records = max_records self.interval = interval - self.disabled = disabled def _to_pb2(self): params = types_pb2.HnswBatchingParams() params.maxRecords = self.max_records params.interval = self.interval - params.disabled = self.disabled + return params + + +class HnswHealerParams(object): + def __init__(self, *, max_scan_rate_per_node: Optional[int] = None, max_scan_page_size: Optional[int] = None, re_index_percent: Optional[int] = None, schedule_delay: Optional[int] = None, parallelism: Optional[int] = None) -> None: + self.max_scan_rate_per_node = max_scan_rate_per_node + self.max_scan_page_size = max_scan_page_size + self.re_index_percent = re_index_percent + self.schedule_delay = schedule_delay + self.parallelism = parallelism + + def _to_pb2(self): + params = types_pb2.HnswHealerParams() + if self.max_scan_rate_per_node: + params.maxScanRatePerNode = self.max_scan_rate_per_node + + if self.max_scan_page_size: + + params.maxScanPageSize = self.max_scan_page_size + + if self.re_index_percent: + + params.reindexPercent = self.re_index_percent + + if self.schedule_delay: + + params.scheduleDelay = self.schedule_delay + + if self.parallelism: + + params.parallelism = self.parallelism + + return params + + +class HnswCachingParams(object): + def __init__(self, *, max_entries: Optional[int] = None, expiry: Optional[int] = None) -> None: + self.max_entries = max_entries + self.expiry = expiry + + def _to_pb2(self): + params = types_pb2.HnswCachingParams() + if self.max_entries: + params.maxEntries = self.max_entries + if self.expiry: + params.expiry = self.expiry + return params + +class HnswIndexMergeParams(object): + def __init__(self, *, parallelism: Optional[int] = None) -> None: + self.parallelism = parallelism + + def _to_pb2(self): + params = types_pb2.HnswIndexMergeParams() + if self.parallelism: + params.parallelism = self.parallelism return params @@ -206,22 +259,39 @@ def __init__( ef_construction: Optional[int] = 100, ef: Optional[int] = 100, batching_params: Optional[HnswBatchingParams] = HnswBatchingParams(), + max_mem_queue_size: Optional[int] = None, + caching_params: Optional[HnswCachingParams] = HnswCachingParams(), + healer_params: Optional[HnswHealerParams] = HnswHealerParams(), + merge_params: Optional[HnswIndexMergeParams] = HnswIndexMergeParams() ) -> None: self.m = m self.ef_construction = ef_construction self.ef = ef self.batching_params = batching_params + self.max_mem_queue_size = max_mem_queue_size + self.caching_params = caching_params + self.healer_params = healer_params + self.merge_params = merge_params def _to_pb2(self): params = types_pb2.HnswParams() params.m = self.m params.efConstruction = self.ef_construction params.ef = self.ef + if self.max_mem_queue_size: + params.maxMemQueueSize = self.max_mem_queue_size params.batchingParams.CopyFrom(self.batching_params._to_pb2()) + params.cachingParams.CopyFrom(self.caching_params._to_pb2()) + + params.healerParams.CopyFrom(self.healer_params._to_pb2()) + + params.mergeParams.CopyFrom(self.merge_params._to_pb2()) + return params + class HnswSearchParams(object): def __init__(self, *, ef: Optional[int] = None) -> None: """ diff --git a/tests/aerospike-proximus.yml b/tests/aerospike-vector-search.yml similarity index 81% rename from tests/aerospike-proximus.yml rename to tests/aerospike-vector-search.yml index 0b6fe595..545f5ebe 100755 --- a/tests/aerospike-proximus.yml +++ b/tests/aerospike-vector-search.yml @@ -3,7 +3,7 @@ cluster: # Unique identifier for this cluster. - cluster-name: aerospike-proximus + cluster-name: aerospike-vector-search # Custom node-id as 8 byte long in Hexadecimal format. # It will be auto-generated if not specified. @@ -15,12 +15,12 @@ cluster: #tls: # service-tls: # trust-store: -# store-file: /etc/aerospike-proximus/tls/$root_certificate_name.truststore.jks -# store-password-file: /etc/aerospike-proximus/tls/storepass +# store-file: /etc/aerospike-vector-search/tls/$root_certificate_name.truststore.jks +# store-password-file: /etc/aerospike-vector-search/tls/storepass # key-store: -# store-file: /etc/aerospike-proximus/tls/$server_name.keystore.jks -# store-password-file: /etc/aerospike-proximus/tls/storepass -# key-password-file: /etc/aerospike-proximus/tls/keypass +# store-file: /etc/aerospike-vector-search/tls/$server_name.keystore.jks +# store-password-file: /etc/aerospike-vector-search/tls/storepass +# key-password-file: /etc/aerospike-vector-search/tls/keypass # mutual-auth: true # # Client certificate subject names that are allowed # allowed-peer-names: @@ -95,8 +95,8 @@ interconnect: #security: # auth-token: -# private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem -# public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem +# private-key: /etc/aerospike-vector-search/tls/jwt/private_key.pem +# public-key: /etc/aerospike-vector-search/tls/jwt/public_key.pem # token-expiry: 300_000 # Target Aerospike cluster @@ -116,7 +116,7 @@ aerospike: # The logging properties. #logging: -# #file: /var/log/aerospike-proximus/aerospike-proximus.log +# #file: /var/log/aerospike-vector-search/aerospike-vector-search.log # enable-console-logging: true # levels: # root: debug diff --git a/tests/aerospike.conf b/tests/aerospike.conf index a7c979df..4e25d373 100755 --- a/tests/aerospike.conf +++ b/tests/aerospike.conf @@ -9,7 +9,7 @@ # This stanza must come first. service { feature-key-file /etc/aerospike/features.conf - cluster-name proximus + cluster-name vector-search } logging { @@ -54,7 +54,7 @@ network { } -namespace proximus-meta { +namespace avs-meta { replication-factor 2 storage-engine memory { data-size 2G diff --git a/tests/assets/aerospike-proximus.yml b/tests/assets/aerospike-proximus.yml index 0b6fe595..545f5ebe 100755 --- a/tests/assets/aerospike-proximus.yml +++ b/tests/assets/aerospike-proximus.yml @@ -3,7 +3,7 @@ cluster: # Unique identifier for this cluster. - cluster-name: aerospike-proximus + cluster-name: aerospike-vector-search # Custom node-id as 8 byte long in Hexadecimal format. # It will be auto-generated if not specified. @@ -15,12 +15,12 @@ cluster: #tls: # service-tls: # trust-store: -# store-file: /etc/aerospike-proximus/tls/$root_certificate_name.truststore.jks -# store-password-file: /etc/aerospike-proximus/tls/storepass +# store-file: /etc/aerospike-vector-search/tls/$root_certificate_name.truststore.jks +# store-password-file: /etc/aerospike-vector-search/tls/storepass # key-store: -# store-file: /etc/aerospike-proximus/tls/$server_name.keystore.jks -# store-password-file: /etc/aerospike-proximus/tls/storepass -# key-password-file: /etc/aerospike-proximus/tls/keypass +# store-file: /etc/aerospike-vector-search/tls/$server_name.keystore.jks +# store-password-file: /etc/aerospike-vector-search/tls/storepass +# key-password-file: /etc/aerospike-vector-search/tls/keypass # mutual-auth: true # # Client certificate subject names that are allowed # allowed-peer-names: @@ -95,8 +95,8 @@ interconnect: #security: # auth-token: -# private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem -# public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem +# private-key: /etc/aerospike-vector-search/tls/jwt/private_key.pem +# public-key: /etc/aerospike-vector-search/tls/jwt/public_key.pem # token-expiry: 300_000 # Target Aerospike cluster @@ -116,7 +116,7 @@ aerospike: # The logging properties. #logging: -# #file: /var/log/aerospike-proximus/aerospike-proximus.log +# #file: /var/log/aerospike-vector-search/aerospike-vector-search.log # enable-console-logging: true # levels: # root: debug diff --git a/tests/assets/aerospike-vector-search.yml b/tests/assets/aerospike-vector-search.yml new file mode 100755 index 00000000..545f5ebe --- /dev/null +++ b/tests/assets/aerospike-vector-search.yml @@ -0,0 +1,122 @@ +# Change the configuration for your use case. +# See: https://aerospike.com/docs/vector + +cluster: + # Unique identifier for this cluster. + cluster-name: aerospike-vector-search + + # Custom node-id as 8 byte long in Hexadecimal format. + # It will be auto-generated if not specified. + # node-id: a1 + +# If TLS is desired, TLS configuration ids used +# and associated TLS configurations. +# +#tls: +# service-tls: +# trust-store: +# store-file: /etc/aerospike-vector-search/tls/$root_certificate_name.truststore.jks +# store-password-file: /etc/aerospike-vector-search/tls/storepass +# key-store: +# store-file: /etc/aerospike-vector-search/tls/$server_name.keystore.jks +# store-password-file: /etc/aerospike-vector-search/tls/storepass +# key-password-file: /etc/aerospike-vector-search/tls/keypass +# mutual-auth: true +# # Client certificate subject names that are allowed +# allowed-peer-names: +# - $client_name +# interconnect-tls: +# trust-store: +# store-file: tls/ca.aerospike.com.truststore.jks +# store-password-file: tls/storepass +# key-store: +# store-file: tls/proximus.aerospike.com.keystore.jks +# store-password-file: tls/storepass +# key-password-file: tls/keypass +# override-tls-hostname: proximus.aerospike.com +# +# aerospike-tls: +# trust-store: +# store-file: tls/ca.aerospike.com.truststore.jks +# store-password-file: tls/storepass +# key-store: +# store-file: tls/proximus.aerospike.com.keystore.jks +# store-password-file: tls/storepass +# key-password-file: tls/keypass +# override-tls-hostname: asd.aerospike.com + + +# The Proximus service listening ports, TLS and network interface. +service: + ports: + 5000: + addresses: + localhost + # If TLS needs to be enabled, tls configuration id. + #tls-id: service-tls + + # Required when running behind NAT + #advertised-listeners: + # default: + # # List of externally accessible addresses and + # # ports for this Proximus instance. + # - address: $server_name + # port: 5000 + +# Management API listening ports, TLS and network interface. +manage: + ports: + 5040: + addresses: + localhost + # If TLS needs to be enabled, tls configuration id. + #tls-id: service-tls + + +# Intra cluster interconnect listening ports, TLS and network interface. +interconnect: + # Interconnect client side TLS configuration + # when TLS is enabled for interconnect + # client-tls-id: interconnect-tls + ports: + 5001: + addresses: + localhost + # If interconnect TLS needs to be enabled. + #tls-id: interconnect-tls + +#heartbeat: +# # Seed nodes to discover and form a cluster. +# seeds: +# - address: localhost +# port: 6001 + +# To enable client authentication + +#security: +# auth-token: +# private-key: /etc/aerospike-vector-search/tls/jwt/private_key.pem +# public-key: /etc/aerospike-vector-search/tls/jwt/public_key.pem +# token-expiry: 300_000 + +# Target Aerospike cluster +aerospike: + seeds: + - localhost: + port: 3000 + + client-policy: + max-conns-per-node: 1000 + #tls-id: aerospike-tls + # + # Aerospike credentials if required. + #credentials: + # username: admin + # password-file: aerospike-password.txt + +# The logging properties. +#logging: +# #file: /var/log/aerospike-vector-search/aerospike-vector-search.log +# enable-console-logging: true +# levels: +# root: debug diff --git a/tests/assets/aerospike.conf b/tests/assets/aerospike.conf index a7c979df..4e25d373 100755 --- a/tests/assets/aerospike.conf +++ b/tests/assets/aerospike.conf @@ -9,7 +9,7 @@ # This stanza must come first. service { feature-key-file /etc/aerospike/features.conf - cluster-name proximus + cluster-name vector-search } logging { @@ -54,7 +54,7 @@ network { } -namespace proximus-meta { +namespace avs-meta { replication-factor 2 storage-engine memory { data-size 2G diff --git a/tests/assets/call_gen.sh b/tests/assets/call_gen.sh index da5596ea..6d661eee 100755 --- a/tests/assets/call_gen.sh +++ b/tests/assets/call_gen.sh @@ -12,4 +12,7 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 0.0.0.0 + --host 0.0.0.0 \ + --for_testing y + + diff --git a/tests/assets/call_gen_normal.sh b/tests/assets/call_gen_normal.sh index c7e16289..9f55ec36 100755 --- a/tests/assets/call_gen_normal.sh +++ b/tests/assets/call_gen_normal.sh @@ -12,4 +12,5 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 127.0.0.1 + --host 127.0.0.1 \ + --for_testing y diff --git a/tests/assets/security_stanza.txt b/tests/assets/security_stanza.txt index 0d394039..8de2e796 100755 --- a/tests/assets/security_stanza.txt +++ b/tests/assets/security_stanza.txt @@ -1,5 +1,5 @@ security: auth-token: - private-key: /etc/aerospike-proximus/tls/jwt/private_key.pem - public-key: /etc/aerospike-proximus/tls/jwt/public_key.pem + private-key: /etc/aerospike-vector-search/tls/jwt/private_key.pem + public-key: /etc/aerospike-vector-search/tls/jwt/public_key.pem token-expiry: 300_000 diff --git a/tests/assets/tls_stanza.txt b/tests/assets/tls_stanza.txt index adfb24cb..15eb69e1 100755 --- a/tests/assets/tls_stanza.txt +++ b/tests/assets/tls_stanza.txt @@ -1,12 +1,12 @@ tls: service-tls: trust-store: - store-file: /etc/aerospike-proximus/tls/root.truststore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass + store-file: /etc/aerospike-vector-search/tls/root.truststore.jks + store-password-file: /etc/aerospike-vector-search/tls/storepass key-store: - store-file: /etc/aerospike-proximus/tls/brawn.keystore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass - key-password-file: /etc/aerospike-proximus/tls/keypass + store-file: /etc/aerospike-vector-search/tls/brawn.keystore.jks + store-password-file: /etc/aerospike-vector-search/tls/storepass + key-password-file: /etc/aerospike-vector-search/tls/keypass mutual-auth: true # Client certificate subject names that are allowed allowed-peer-names: diff --git a/tests/gen.sh b/tests/gen.sh index 85da9451..4c38ba5b 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -133,27 +133,27 @@ while [[ $# -gt 0 ]]; do esac done -if [[ "$for_testing" == "y" ]]; then - mv_command="mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|siftsmall|service_configs) tls/" - file_count=$(find . -type f | wc -l) - dir_count=$(find . -type d | wc -l) - total_count=$((file_count + dir_count)) - - echo "Number of files: $file_count" - echo "Number of directories: $dir_count" - echo "Total count: $total_count" - - if test -f "features.yml"; then - if [ "$total_count" -ne 100 ]; then - echo "Total count matches 100." - fi - else - if [ "$total_count" -ne 99 ]; then - echo "File number has changed, update the following command in the script below to reflect changes $mv_command" - fi - fi - -fi +#if [[ "$for_testing" == "y" ]]; then +# mv_command="mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|siftsmall|service_configs) tls/" +# file_count=$(find . -type f | wc -l) +# dir_count=$(find . -type d | wc -l) +# total_count=$((file_count + dir_count)) +# +# echo "Number of files: $file_count" +# echo "Number of directories: $dir_count" +# echo "Total count: $total_count" +# +# if test -f "features.yml"; then +# if [ "$total_count" -ne 100 ]; then +# echo "File number has changed, update the following command in the script below to reflect changes $mv_command" +# fi +# else +# if [ "$total_count" -ne 99 ]; then +# echo "File number has changed, update the following command in the script below to reflect changes $mv_command" +# fi +# fi +# +#fi @@ -180,7 +180,7 @@ echo "host: $host" rm -rf tls mkdir -p tls mkdir -p tls/jwt -cp assets/aerospike-proximus.yml aerospike-proximus.yml +cp assets/aerospike-vector-search.yml aerospike-vector-search.yml cp assets/aerospike.conf aerospike.conf cp assets/features.conf features.conf @@ -251,7 +251,7 @@ if [[ "$tls_maybe" == "y" ]]; then city=${city:-Spearfish} organization=${organization:-Aerospike} unit=${unit:-$Client SDK Team} - common_name=${common_name:-aerospike-proximus} + common_name=${common_name:-aerospike-vector-search} email=${email:-dpelini@aerospike.com} subj="/C=$country/ST=$state/L=$city/O=$organization/OU=$unit/CN=$common_name/emailAddress=$email" @@ -349,18 +349,18 @@ if [[ "$tls_maybe" == "y" ]]; then security_stanza=$(cat < "assets/security_stanza.txt" - sed -i '95r assets/security_stanza.txt' aerospike-proximus.yml + sed -i '95r assets/security_stanza.txt' aerospike-vector-search.yml fi fi @@ -383,12 +383,12 @@ EOF tls: service-tls: trust-store: - store-file: /etc/aerospike-proximus/tls/$root_certificate_name.truststore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass + store-file: /etc/aerospike-vector-search/tls/$root_certificate_name.truststore.jks + store-password-file: /etc/aerospike-vector-search/tls/storepass key-store: - store-file: /etc/aerospike-proximus/tls/$server_name.keystore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass - key-password-file: /etc/aerospike-proximus/tls/keypass + store-file: /etc/aerospike-vector-search/tls/$server_name.keystore.jks + store-password-file: /etc/aerospike-vector-search/tls/storepass + key-password-file: /etc/aerospike-vector-search/tls/keypass mutual-auth: true # Client certificate subject names that are allowed allowed-peer-names: @@ -396,11 +396,11 @@ tls: EOF ) - sed -i '15,27d' "aerospike-proximus.yml" + sed -i '15,27d' "aerospike-vector-search.yml" echo "$tls_stanza" | envsubst > "assets/tls_stanza.txt" - sed -i '14r assets/tls_stanza.txt' aerospike-proximus.yml + sed -i '14r assets/tls_stanza.txt' aerospike-vector-search.yml if [[ "$port" == "" ]]; then read -p "Specify a port address:" port @@ -421,11 +421,11 @@ EOF EOF ) - sed -i '56,65d' "aerospike-proximus.yml" + sed -i '56,65d' "aerospike-vector-search.yml" echo "$service_stanza" | envsubst > "assets/service_stanza.txt" - sed -i '55r assets/service_stanza.txt' aerospike-proximus.yml + sed -i '55r assets/service_stanza.txt' aerospike-vector-search.yml if [[ "$host" == "" ]]; then read -p "Specify a host address:" host @@ -441,23 +441,23 @@ EOF tls: service-tls: trust-store: - store-file: /etc/aerospike-proximus/tls/$root_certificate_name.truststore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass + store-file: /etc/aerospike-vector-search/tls/$root_certificate_name.truststore.jks + store-password-file: /etc/aerospike-vector-search/tls/storepass key-store: - store-file: /etc/aerospike-proximus/tls/child.keystore.jks - store-password-file: /etc/aerospike-proximus/tls/storepass - key-password-file: /etc/aerospike-proximus/tls/keypass + store-file: /etc/aerospike-vector-search/tls/child.keystore.jks + store-password-file: /etc/aerospike-vector-search/tls/storepass + key-password-file: /etc/aerospike-vector-search/tls/keypass #mutual-auth: true # Client certificate subject names that are allowed #allowed-peer-names: # - child EOF ) - sed -i '15,27d' "aerospike-proximus.yml" + sed -i '15,27d' "aerospike-vector-search.yml" echo "$tls_stanza" | envsubst > "assets/tls_stanza.txt" - sed -i '14r assets/tls_stanza.txt' aerospike-proximus.yml + sed -i '14r assets/tls_stanza.txt' aerospike-vector-search.yml if [[ "$port" == "" ]]; then read -p "Specify a port address:" port @@ -480,10 +480,10 @@ EOF EOF ) - sed -i '56,65d' "aerospike-proximus.yml" + sed -i '56,65d' "aerospike-vector-search.yml" echo "$service_stanza" | envsubst > "assets/service_stanza.txt" - sed -i '55r assets/service_stanza.txt' aerospike-proximus.yml + sed -i '55r assets/service_stanza.txt' aerospike-vector-search.yml @@ -503,7 +503,7 @@ mv !(tls|assets|rbac|standard|requirements.txt|setup.py|utils.py|__init__.py|sif mv tls/gen.sh gen.sh -mv tls/aerospike-proximus.yml aerospike-proximus.yml +mv tls/aerospike-vector-search.yml aerospike-vector-search.yml mv tls/aerospike.conf aerospike.conf diff --git a/tests/service_configs/backoff_multiplier.json b/tests/service_configs/backoff_multiplier.json index b23d7dff..4712024e 100644 --- a/tests/service_configs/backoff_multiplier.json +++ b/tests/service_configs/backoff_multiplier.json @@ -10,7 +10,7 @@ "maxBackoff": "5s", "backoffMultiplier": 3, "retryableStatusCodes": [ - "ALREADY_EXISTS" + "ALREADY_EXISTS", "UNAVAILABLE" ] } } diff --git a/tests/service_configs/initial_backoff.json b/tests/service_configs/initial_backoff.json index e5e4ca11..6e63db4f 100644 --- a/tests/service_configs/initial_backoff.json +++ b/tests/service_configs/initial_backoff.json @@ -10,7 +10,7 @@ "maxBackoff": "1s", "backoffMultiplier": 1, "retryableStatusCodes": [ - "ALREADY_EXISTS" + "ALREADY_EXISTS", "UNAVAILABLE" ] } } diff --git a/tests/service_configs/max_backoff.json b/tests/service_configs/max_backoff.json index e78512d6..90c7e9ed 100644 --- a/tests/service_configs/max_backoff.json +++ b/tests/service_configs/max_backoff.json @@ -10,7 +10,7 @@ "maxBackoff": "1s", "backoffMultiplier": 2, "retryableStatusCodes": [ - "ALREADY_EXISTS" + "ALREADY_EXISTS", "UNAVAILABLE" ] } } diff --git a/tests/service_configs/max_backoff_lower_than_initial.json b/tests/service_configs/max_backoff_lower_than_initial.json index 8b0a56ec..e31e33dd 100644 --- a/tests/service_configs/max_backoff_lower_than_initial.json +++ b/tests/service_configs/max_backoff_lower_than_initial.json @@ -10,7 +10,7 @@ "maxBackoff": "1s", "backoffMultiplier": 2, "retryableStatusCodes": [ - "ALREADY_EXISTS" + "ALREADY_EXISTS", "UNAVAILABLE" ] } } diff --git a/tests/service_configs/retries.json b/tests/service_configs/retries.json index cdc9d078..2487b8ad 100644 --- a/tests/service_configs/retries.json +++ b/tests/service_configs/retries.json @@ -13,7 +13,7 @@ "maxBackoff": "1s", "backoffMultiplier": 1, "retryableStatusCodes": [ - "ALREADY_EXISTS" + "ALREADY_EXISTS", "UNAVAILABLE" ] } } diff --git a/tests/service_configs/retryable_status_codes.json b/tests/service_configs/retryable_status_codes.json index ddcb3ceb..c9b13153 100644 --- a/tests/service_configs/retryable_status_codes.json +++ b/tests/service_configs/retryable_status_codes.json @@ -10,7 +10,7 @@ "maxBackoff": "1s", "backoffMultiplier": 1, "retryableStatusCodes": [ - "NOT_FOUND" + "NOT_FOUND", "UNAVAILABLE" ] } } diff --git a/tests/standard/aio/conftest.py b/tests/standard/aio/conftest.py index d55d9d6e..94e43f5a 100644 --- a/tests/standard/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -4,34 +4,6 @@ from aerospike_vector_search.aio.admin import Client as AdminClient from aerospike_vector_search import types -@pytest.fixture(scope="module", autouse=True) -def private_key(request): - return request.config.getoption("--private_key") - -@pytest.fixture(scope="module", autouse=True) -def certificate_chain(request): - return request.config.getoption("--certificate_chain") - -@pytest.fixture(scope="module", autouse=True) -def root_certificate(request): - return request.config.getoption("--root_certificate") - -@pytest.fixture(scope="module", autouse=True) -def username(request): - return request.config.getoption("--username") - -@pytest.fixture(scope="module", autouse=True) -def password(request): - return request.config.getoption("--password") - -@pytest.fixture(scope="module", autouse=True) -def host(request): - return request.config.getoption("--host") - -@pytest.fixture(scope="module", autouse=True) -def port(request): - return request.config.getoption("--port") - @pytest.fixture(scope="module", autouse=True) async def drop_all_indexes(host, port, username, password, root_certificate, certificate_chain, private_key): async with AdminClient( diff --git a/tests/standard/aio/test_admin_client_index_create.py b/tests/standard/aio/test_admin_client_index_create.py index ab2c621a..64723b13 100644 --- a/tests/standard/aio/test_admin_client_index_create.py +++ b/tests/standard/aio/test_admin_client_index_create.py @@ -80,7 +80,6 @@ async def test_index_create(session_admin_client, test_case, random_name): assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -147,7 +146,6 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -238,7 +236,6 @@ async def test_index_create_with_vector_distance_metric( assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -302,7 +299,6 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -353,7 +349,7 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na sets=None, index_params=types.HnswParams( batching_params=types.HnswBatchingParams( - max_records=500, interval=500, disabled=True + max_records=500, interval=500 ) ), index_meta_data=None, @@ -388,7 +384,6 @@ async def test_index_create_with_index_params(session_admin_client, test_case, r assert result['hnsw_params']['ef'] == test_case.index_params.ef assert result['hnsw_params']['batching_params']['max_records'] == test_case.index_params.batching_params.max_records assert result['hnsw_params']['batching_params']['interval'] == test_case.index_params.batching_params.interval - assert result['hnsw_params']['batching_params']['disabled'] == test_case.index_params.batching_params.disabled assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -442,7 +437,6 @@ async def test_index_create_index_meta_data(session_admin_client, test_case, ran assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -492,7 +486,6 @@ async def test_index_create_index_storage(session_admin_client, test_case, rando assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.index_storage.namespace assert result['storage']['set'] == test_case.index_storage.set_name assert found == True @@ -512,12 +505,15 @@ async def test_index_create_index_storage(session_admin_client, test_case, rando index_params=None, index_meta_data=None, index_storage=None, - timeout=0, + timeout=0.0001, ), ], ) -async def test_index_create_timeout(session_admin_client, test_case, random_name): +async def test_index_create_timeout(session_admin_client, test_case, random_name, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + with pytest.raises(AVSServerError) as e_info: for i in range(10): diff --git a/tests/standard/aio/test_admin_client_index_drop.py b/tests/standard/aio/test_admin_client_index_drop.py index bb257f00..97f25295 100644 --- a/tests/standard/aio/test_admin_client_index_drop.py +++ b/tests/standard/aio/test_admin_client_index_drop.py @@ -30,7 +30,9 @@ async def test_index_drop(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None, None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -async def test_index_drop_timeout(session_admin_client, empty_test_case, random_name): +async def test_index_drop_timeout(session_admin_client, empty_test_case, random_name, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") await session_admin_client.index_create( namespace="test", name=random_name, @@ -40,6 +42,6 @@ async def test_index_drop_timeout(session_admin_client, empty_test_case, random_ with pytest.raises(AVSServerError) as e_info: for i in range(10): - await session_admin_client.index_drop(namespace="test", name=random_name, timeout=0) + await session_admin_client.index_drop(namespace="test", name=random_name, timeout=0.0001) assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file diff --git a/tests/standard/aio/test_admin_client_index_get.py b/tests/standard/aio/test_admin_client_index_get.py index bf566be4..3083fd4e 100644 --- a/tests/standard/aio/test_admin_client_index_get.py +++ b/tests/standard/aio/test_admin_client_index_get.py @@ -30,7 +30,6 @@ async def test_index_get(session_admin_client, empty_test_case, random_name): assert result["hnsw_params"]["ef"] == 100 assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 assert result["hnsw_params"]["batching_params"]["interval"] == 30000 - assert not result["hnsw_params"]["batching_params"]["disabled"] assert result["storage"]["namespace"] == "test" assert result["storage"]["set"] == random_name @@ -39,16 +38,18 @@ async def test_index_get(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None, None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -async def test_index_get_timeout(session_admin_client, empty_test_case, random_name): +async def test_index_get_timeout(session_admin_client, empty_test_case, random_name, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") for i in range(10): try: result = await session_admin_client.index_get( - namespace="test", name=random_name, timeout=0 + namespace="test", name=random_name, timeout=0.0001 ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/aio/test_admin_client_index_get_status.py b/tests/standard/aio/test_admin_client_index_get_status.py index 5de335d1..52f34632 100644 --- a/tests/standard/aio/test_admin_client_index_get_status.py +++ b/tests/standard/aio/test_admin_client_index_get_status.py @@ -27,7 +27,9 @@ async def test_index_get_status(session_admin_client, empty_test_case, random_na @pytest.mark.parametrize("empty_test_case",[None, None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -async def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name): +async def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") try: await session_admin_client.index_create( namespace="test", @@ -41,11 +43,11 @@ async def test_index_get_status_timeout(session_admin_client, empty_test_case, r for i in range(10): try: result = await session_admin_client.index_get_status( - namespace="test", name=random_name, timeout=0 + namespace="test", name=random_name, timeout=0.0001 ) except AVSServerError as se: print(se.rpc_error.code()) if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/aio/test_admin_client_index_list.py b/tests/standard/aio/test_admin_client_index_list.py index 530d8f62..ac6e7073 100644 --- a/tests/standard/aio/test_admin_client_index_list.py +++ b/tests/standard/aio/test_admin_client_index_list.py @@ -31,15 +31,16 @@ async def test_index_list(session_admin_client, empty_test_case, random_name): assert isinstance(index['hnsw_params']['ef'], int) assert isinstance(index['hnsw_params']['batching_params']['max_records'], int) assert isinstance(index['hnsw_params']['batching_params']['interval'], int) - assert isinstance(index['hnsw_params']['batching_params']['disabled'], bool) assert isinstance(index['storage']['namespace'], str) assert isinstance(index['storage']['set'], str) await drop_specified_index(session_admin_client, "test", random_name) -async def test_index_list_timeout(session_admin_client): +async def test_index_list_timeout(session_admin_client, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") for i in range(10): try: - result = await session_admin_client.index_list(timeout=0) + result = await session_admin_client.index_list(timeout=0.0001) except AVSServerError as se: @@ -47,4 +48,4 @@ async def test_index_list_timeout(session_admin_client): assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/aio/test_service_config.py b/tests/standard/aio/test_service_config.py index 3289216d..296a6162 100644 --- a/tests/standard/aio/test_service_config.py +++ b/tests/standard/aio/test_service_config.py @@ -70,7 +70,7 @@ def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, m for attempt in range(max_attempts-1): expected_time += current_backkoff current_backkoff *= backoff_multiplier - current_backkoff = min(current_backkoff, max_backoff) + current_backkoff = min(current_backkoff, max_backoff ) return expected_time @@ -87,20 +87,27 @@ def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, m ) ], ) -async def test_admin_client_service_config_retries(host, port, test_case): +async def test_admin_client_service_config_retries(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path - ) - - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, ) + try: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() @@ -131,20 +138,27 @@ async def test_admin_client_service_config_retries(host, port, test_case): ) ], ) -async def test_admin_client_service_config_initial_backoff(host, port, test_case): +async def test_admin_client_service_config_initial_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path ) - - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) + try: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() @@ -183,21 +197,27 @@ async def test_admin_client_service_config_initial_backoff(host, port, test_case ) ], ) -async def test_admin_client_service_config_max_backoff(host, port, test_case): +async def test_admin_client_service_config_max_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path ) - - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - + try: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() @@ -228,20 +248,28 @@ async def test_admin_client_service_config_max_backoff(host, port, test_case): ) ], ) -async def test_admin_client_service_config_backoff_multiplier(host, port, test_case): +async def test_admin_client_service_config_backoff_multiplier(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path ) - - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) + try: + + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() @@ -273,9 +301,14 @@ async def test_admin_client_service_config_backoff_multiplier(host, port, test_c ) ], ) -async def test_admin_client_service_config_retryable_status_codes(host, port, test_case): +async def test_admin_client_service_config_retryable_status_codes(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path ) diff --git a/tests/standard/aio/test_vector_client_delete.py b/tests/standard/aio/test_vector_client_delete.py index 3bdc198e..a31de83e 100644 --- a/tests/standard/aio/test_vector_client_delete.py +++ b/tests/standard/aio/test_vector_client_delete.py @@ -85,11 +85,13 @@ async def test_vector_delete_without_record(session_vector_client, test_case, ra namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=0 + timeout=0.0001 ), ], ) -async def test_vector_delete_timeout(session_vector_client, test_case, random_key): +async def test_vector_delete_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): diff --git a/tests/standard/aio/test_vector_client_exists.py b/tests/standard/aio/test_vector_client_exists.py index f46c4885..0c52dc3d 100644 --- a/tests/standard/aio/test_vector_client_exists.py +++ b/tests/standard/aio/test_vector_client_exists.py @@ -65,11 +65,13 @@ async def test_vector_exists(session_vector_client, test_case, random_key): namespace="test", set_name=None, record_data=None, - timeout=0 + timeout=0.0001 ), ], ) -async def test_vector_exists_timeout(session_vector_client, test_case, random_key): +async def test_vector_exists_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): result = await session_vector_client.exists( diff --git a/tests/standard/aio/test_vector_client_get.py b/tests/standard/aio/test_vector_client_get.py index 368292f5..d19e1928 100644 --- a/tests/standard/aio/test_vector_client_get.py +++ b/tests/standard/aio/test_vector_client_get.py @@ -81,10 +81,12 @@ async def test_vector_get(session_vector_client, test_case, random_key): set_name=None, record_data=None, expected_fields=None, - timeout=0 + timeout=0.0001 ), ], ) -async def test_vector_get_timeout(session_vector_client, test_case, random_key): +async def test_vector_get_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): result = await session_vector_client.get( diff --git a/tests/standard/aio/test_vector_client_insert.py b/tests/standard/aio/test_vector_client_insert.py index 881207a1..ba2a7f63 100644 --- a/tests/standard/aio/test_vector_client_insert.py +++ b/tests/standard/aio/test_vector_client_insert.py @@ -108,11 +108,13 @@ async def test_vector_insert_with_existing_record(session_vector_client, test_ca namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0 + timeout=0.0001 ) ], ) -async def test_vector_insert_timeout(session_vector_client, test_case, random_key): +async def test_vector_insert_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): await session_vector_client.insert( diff --git a/tests/standard/aio/test_vector_client_update.py b/tests/standard/aio/test_vector_client_update.py index 95f2fa10..566dd4c4 100644 --- a/tests/standard/aio/test_vector_client_update.py +++ b/tests/standard/aio/test_vector_client_update.py @@ -80,7 +80,7 @@ async def test_vector_update_with_existing_record(session_vector_client, test_ca ], ) async def test_vector_update_without_existing_record(session_vector_client, test_case, random_key): - session_vector_client.delete( + await session_vector_client.delete( namespace=test_case.namespace, key=random_key, ) @@ -101,11 +101,13 @@ async def test_vector_update_without_existing_record(session_vector_client, test namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0 + timeout=0.0001 ) ], ) -async def test_vector_update_timeout(session_vector_client, test_case, random_key): +async def test_vector_update_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): await session_vector_client.update( diff --git a/tests/standard/aio/test_vector_client_upsert.py b/tests/standard/aio/test_vector_client_upsert.py index 9ee33dcb..10900b24 100644 --- a/tests/standard/aio/test_vector_client_upsert.py +++ b/tests/standard/aio/test_vector_client_upsert.py @@ -93,11 +93,13 @@ async def test_vector_upsert_with_existing_record(session_vector_client, test_ca namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0 + timeout=0.0001 ) ], ) -async def test_vector_upsert_timeout(session_vector_client, test_case, random_key): +async def test_vector_upsert_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): await session_vector_client.upsert( diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index 7eb73114..9169a9a3 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -67,15 +67,14 @@ def query_numpy(): return truth_numpy - async def put_vector(client, vector, j): await client.upsert( - namespace="test", key="aio/" + str(j), record_data={"unit_test": vector} + namespace="test", key=str(j), record_data={"unit_test": vector} ) async def get_vector(client, j): - result = await client.get(namespace="test", key="aio/" + str(j)) + result = await client.get(namespace="test", key=str(j)) async def vector_search(client, vector): @@ -114,6 +113,7 @@ async def test_vector_search( vector_field="unit_test", dimensions=128, ) + # Put base vectors for search tasks = [] @@ -167,26 +167,37 @@ async def test_vector_search( assert recall > 0.9 -async def test_vector_is_indexed(session_vector_client, session_admin_client): +async def test_vector_is_indexed(session_vector_client, session_admin_client, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") result = await session_vector_client.is_indexed( namespace="test", - key="aio/" + str(random.randrange(10_000)), + key=str(random.randrange(10_000)), index_name="demo", ) assert result is True -async def test_vector_is_indexed_timeout(session_vector_client, session_admin_client): - with pytest.raises(AVSServerError) as e_info: - for i in range(10): +async def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + for i in range(10): + try: result = await session_vector_client.is_indexed( namespace="test", - key="aio/" + str(random.randrange(10_000)), + key=str(random.randrange(10_000)), index_name="demo", - timeout=0 + timeout=0.0001 ) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert "In several attempts, the timeout did not happen" == "TEST FAIL" -async def test_vector_vector_search_timeout(session_vector_client, session_admin_client): +async def test_vector_vector_search_timeout(session_vector_client, session_admin_client, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + for i in range(10): try: result = await session_vector_client.vector_search( @@ -195,10 +206,10 @@ async def test_vector_vector_search_timeout(session_vector_client, session_admin query=[0, 1, 2], limit=100, field_names=["unit_test"], - timeout=0 + timeout=0.0001 ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/conftest.py b/tests/standard/conftest.py index 00379be9..e24f50ce 100644 --- a/tests/standard/conftest.py +++ b/tests/standard/conftest.py @@ -9,6 +9,7 @@ def pytest_addoption(parser): parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") parser.addoption("--certificate_chain", action="store", default=None, help="Path to certificate chain") parser.addoption("--private_key", action="store", default=None, help="Path to private key") + parser.addoption("--local_latency", action="store_true", help="Skip the test if latency is too low to effectively trigger timeout") @pytest.fixture(scope="module", autouse=True) @@ -39,3 +40,6 @@ def host(request): def port(request): return request.config.getoption("--port") +@pytest.fixture(scope="module", autouse=True) +def local_latency(request): + return request.config.getoption("--local_latency") diff --git a/tests/standard/sync/test_admin_client_index_create.py b/tests/standard/sync/test_admin_client_index_create.py index b1f8f30c..1644c8a5 100644 --- a/tests/standard/sync/test_admin_client_index_create.py +++ b/tests/standard/sync/test_admin_client_index_create.py @@ -52,8 +52,13 @@ def __init__( ], ) def test_index_create(session_admin_client, test_case, random_name): - if test_case == None: - return + try: + session_admin_client.index_drop(namespace="test", name=random_name) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: + pass + + session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -66,6 +71,8 @@ def test_index_create(session_admin_client, test_case, random_name): index_storage=test_case.index_storage, timeout=test_case.timeout ) + + results = session_admin_client.index_list() found = False for result in results: @@ -79,7 +86,6 @@ def test_index_create(session_admin_client, test_case, random_name): assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -116,6 +122,14 @@ def test_index_create(session_admin_client, test_case, random_name): ], ) def test_index_create_with_dimnesions(session_admin_client, test_case, random_name): + + try: + session_admin_client.index_drop(namespace="test", name=random_name) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: + pass + + session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -145,7 +159,6 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -209,6 +222,11 @@ def test_index_create_with_vector_distance_metric( session_admin_client, test_case, random_name ): + try: + session_admin_client.index_drop(namespace="test", name=random_name) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: + pass session_admin_client.index_create( namespace=test_case.namespace, @@ -235,7 +253,6 @@ def test_index_create_with_vector_distance_metric( assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -273,6 +290,12 @@ def test_index_create_with_vector_distance_metric( ) def test_index_create_with_sets(session_admin_client, test_case, random_name): + try: + session_admin_client.index_drop(namespace="test", name=random_name) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: + pass + session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -298,7 +321,6 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -306,7 +328,7 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -335,6 +357,7 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): m=8, ef_construction=50, ef=25, + max_mem_queue_size=16384 ), index_meta_data=None, index_storage=None, @@ -348,16 +371,45 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): sets=None, index_params=types.HnswParams( batching_params=types.HnswBatchingParams( - max_records=500, interval=500, disabled=True - ) + max_records=500, interval=500 + ), + ), index_meta_data=None, index_storage=None, timeout=None, ), + index_create_test_case( + namespace="test", + vector_field="example_13", + dimensions=1024, + vector_distance_metric=None, + sets=None, + index_params=types.HnswParams( + caching_params=types.HnswCachingParams(max_entries=10, expiry=3000), + healer_params=types.HnswHealerParams( + max_scan_rate_per_node=80, + max_scan_page_size=40, + re_index_percent=50, + schedule_delay=5, + parallelism=4, + ), + merge_params=types.HnswIndexMergeParams( + parallelism=10 + ) + ), + index_meta_data=None, + index_storage=None, + timeout=None, + ) ], ) def test_index_create_with_index_params(session_admin_client, test_case, random_name): + try: + session_admin_client.index_drop(namespace="test", name=random_name) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: + pass session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -370,6 +422,9 @@ def test_index_create_with_index_params(session_admin_client, test_case, random_ index_storage=test_case.index_storage, timeout=test_case.timeout ) + + + results = session_admin_client.index_list() found = False for result in results: @@ -381,9 +436,26 @@ def test_index_create_with_index_params(session_admin_client, test_case, random_ assert result['hnsw_params']['m'] == test_case.index_params.m assert result['hnsw_params']['ef_construction'] == test_case.index_params.ef_construction assert result['hnsw_params']['ef'] == test_case.index_params.ef + if 'max_mem_queue_size' in result.get('hnsw_params', {}): + assert result['hnsw_params']['max_mem_queue_size'] == test_case.index_params.max_mem_queue_size + assert result['hnsw_params']['batching_params']['max_records'] == test_case.index_params.batching_params.max_records assert result['hnsw_params']['batching_params']['interval'] == test_case.index_params.batching_params.interval - assert result['hnsw_params']['batching_params']['disabled'] == test_case.index_params.batching_params.disabled + if 'caching_params' in result.get('hnsw_params', {}): + + assert int(result['hnsw_params']['caching_params']['max_entries']) == test_case.index_params.caching_params.max_entries + assert int(result['hnsw_params']['caching_params']['expiry']) == test_case.index_params.caching_params.expiry + + if 'merge_params' in result.get('hnsw_params', {}): + assert result['hnsw_params']['merge_params']['parallelism'] == test_case.index_params.merge_params.parallelism + + if 'healer_params' in result.get('hnsw_params', {}): + assert int(result['hnsw_params']['healer_params']['max_scan_rate_per_node']) == test_case.index_params.healer_params.max_scan_rate_per_node + assert int(result['hnsw_params']['healer_params']['max_scan_page_size']) == test_case.index_params.healer_params.max_scan_page_size + assert int(result['hnsw_params']['healer_params']['re_index_percent']) == test_case.index_params.healer_params.re_index_percent + assert int(result['hnsw_params']['healer_params']['schedule_delay']) == test_case.index_params.healer_params.schedule_delay + assert result['hnsw_params']['healer_params']['parallelism'] == test_case.index_params.healer_params.parallelism + assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -397,7 +469,7 @@ def test_index_create_with_index_params(session_admin_client, test_case, random_ [ index_create_test_case( namespace="test", - vector_field="example_13", + vector_field="example_16", dimensions=1024, vector_distance_metric=None, sets=None, @@ -409,8 +481,11 @@ def test_index_create_with_index_params(session_admin_client, test_case, random_ ], ) def test_index_create_index_meta_data(session_admin_client, test_case, random_name): - if test_case == None: - return + try: + session_admin_client.index_drop(namespace="test", name=random_name) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: + pass session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -423,6 +498,8 @@ def test_index_create_index_meta_data(session_admin_client, test_case, random_na index_storage=test_case.index_storage, timeout=test_case.timeout ) + + results = session_admin_client.index_list() found = False for result in results: @@ -431,12 +508,13 @@ def test_index_create_index_meta_data(session_admin_client, test_case, random_na assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions assert result['field'] == test_case.vector_field + assert isinstance(result['field'], str) + assert result['hnsw_params']['m'] == 16 assert result['hnsw_params']['ef_construction'] == 100 assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.namespace assert result['storage']['set'] == random_name assert found == True @@ -449,7 +527,7 @@ def test_index_create_index_meta_data(session_admin_client, test_case, random_na [ index_create_test_case( namespace="test", - vector_field="example_14", + vector_field="example_17", dimensions=1024, vector_distance_metric=None, sets=None, @@ -461,24 +539,23 @@ def test_index_create_index_meta_data(session_admin_client, test_case, random_na ], ) def test_index_create_index_storage(session_admin_client, test_case, random_name): - - - try: - session_admin_client.index_create( - namespace=test_case.namespace, - name=random_name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - vector_distance_metric=test_case.vector_distance_metric, - sets=test_case.sets, - index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, - index_storage=test_case.index_storage, - timeout=test_case.timeout - ) + try: + session_admin_client.index_drop(namespace="test", name=random_name) except AVSServerError as se: - if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: - raise se + if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: + pass + session_admin_client.index_create( + namespace=test_case.namespace, + name=random_name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + vector_distance_metric=test_case.vector_distance_metric, + sets=test_case.sets, + index_params=test_case.index_params, + index_meta_data=test_case.index_meta_data, + index_storage=test_case.index_storage, + timeout=test_case.timeout + ) results = session_admin_client.index_list() @@ -488,13 +565,12 @@ def test_index_create_index_storage(session_admin_client, test_case, random_name found = True assert result['id']['namespace'] == test_case.namespace assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field + assert isinstance(result['field'], str) assert result['hnsw_params']['m'] == 16 assert result['hnsw_params']['ef_construction'] == 100 assert result['hnsw_params']['ef'] == 100 assert result['hnsw_params']['batching_params']['max_records'] == 100000 assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['hnsw_params']['batching_params']['disabled'] == False assert result['storage']['namespace'] == test_case.index_storage.namespace assert result['storage']['set'] == test_case.index_storage.set_name assert found == True @@ -506,23 +582,26 @@ def test_index_create_index_storage(session_admin_client, test_case, random_name [ index_create_test_case( namespace="test", - vector_field="example_15", + vector_field="example_18", dimensions=1024, vector_distance_metric=None, sets=None, index_params=None, index_meta_data=None, index_storage=None, - timeout=0, + timeout=0.0001, ), ], ) -def test_index_create_timeout(session_admin_client, test_case, random_name): +def test_index_create_timeout(session_admin_client, test_case, random_name, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") try: session_admin_client.index_drop(namespace="test", name=random_name) - except: - pass + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: + pass for i in range(10): @@ -543,4 +622,4 @@ def test_index_create_timeout(session_admin_client, test_case, random_name): if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_drop.py b/tests/standard/sync/test_admin_client_index_drop.py index 5aaafb07..db645179 100644 --- a/tests/standard/sync/test_admin_client_index_drop.py +++ b/tests/standard/sync/test_admin_client_index_drop.py @@ -37,7 +37,10 @@ def test_index_drop(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_drop_timeout(session_admin_client, empty_test_case, random_name): +def test_index_drop_timeout(session_admin_client, empty_test_case, random_name, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + try: session_admin_client.index_create( namespace="test", @@ -51,9 +54,9 @@ def test_index_drop_timeout(session_admin_client, empty_test_case, random_name): for i in range(10): try: - session_admin_client.index_drop(namespace="test", name=random_name, timeout=0) + session_admin_client.index_drop(namespace="test", name=random_name, timeout=0.0001) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_get.py b/tests/standard/sync/test_admin_client_index_get.py index aafd0f35..b475bb26 100644 --- a/tests/standard/sync/test_admin_client_index_get.py +++ b/tests/standard/sync/test_admin_client_index_get.py @@ -38,7 +38,6 @@ def test_index_get(session_admin_client, empty_test_case, random_name): assert result["hnsw_params"]["ef"] == 100 assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 assert result["hnsw_params"]["batching_params"]["interval"] == 30000 - assert not result["hnsw_params"]["batching_params"]["disabled"] assert result["storage"]["namespace"] == "test" assert result["storage"]["set"] == random_name @@ -47,8 +46,9 @@ def test_index_get(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_get_timeout(session_admin_client, empty_test_case, random_name): - +def test_index_get_timeout(session_admin_client, empty_test_case, random_name, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") try: session_admin_client.index_create( namespace="test", @@ -65,11 +65,11 @@ def test_index_get_timeout(session_admin_client, empty_test_case, random_name): for i in range(10): try: result = session_admin_client.index_get( - namespace="test", name=random_name, timeout=0 + namespace="test", name=random_name, timeout=0.0001 ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_get_status.py b/tests/standard/sync/test_admin_client_index_get_status.py index 9db11746..a2048260 100644 --- a/tests/standard/sync/test_admin_client_index_get_status.py +++ b/tests/standard/sync/test_admin_client_index_get_status.py @@ -29,17 +29,18 @@ def test_index_get_status(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name): - +def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") for i in range(10): try: result = session_admin_client.index_get_status( - namespace="test", name=random_name, timeout=0 + namespace="test", name=random_name, timeout=0.0001 ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_admin_client_index_list.py b/tests/standard/sync/test_admin_client_index_list.py index 9b6f9a06..eaac05eb 100644 --- a/tests/standard/sync/test_admin_client_index_list.py +++ b/tests/standard/sync/test_admin_client_index_list.py @@ -29,7 +29,6 @@ def test_index_list(session_admin_client, empty_test_case, random_name): assert isinstance(index['hnsw_params']['ef'], int) assert isinstance(index['hnsw_params']['batching_params']['max_records'], int) assert isinstance(index['hnsw_params']['batching_params']['interval'], int) - assert isinstance(index['hnsw_params']['batching_params']['disabled'], bool) assert isinstance(index['storage']['namespace'], str) assert isinstance(index['storage']['set'], str) drop_specified_index(session_admin_client, "test", random_name) @@ -38,9 +37,10 @@ def test_index_list(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_list_timeout(session_admin_client, empty_test_case, random_name): - +def test_index_list_timeout(session_admin_client, empty_test_case, random_name, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") try: session_admin_client.index_create( namespace="test", @@ -52,7 +52,13 @@ def test_index_list_timeout(session_admin_client, empty_test_case, random_name): if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: raise se - with pytest.raises(AVSServerError) as e_info: - for i in range(10): - result = session_admin_client.index_list(timeout=0) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + for i in range(10): + + try: + result = session_admin_client.index_list(timeout=0.0001) + + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_service_config.py b/tests/standard/sync/test_service_config.py index 53a10a0d..93e6141f 100644 --- a/tests/standard/sync/test_service_config.py +++ b/tests/standard/sync/test_service_config.py @@ -87,20 +87,21 @@ def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, m ) ], ) -def test_admin_client_service_config_retries(host, port, test_case): +def test_admin_client_service_config_retries(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), service_config_path=test_case.service_config_path ) - - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - + try: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() @@ -131,21 +132,27 @@ def test_admin_client_service_config_retries(host, port, test_case): ) ], ) -def test_admin_client_service_config_initial_backoff(host, port, test_case): +def test_admin_client_service_config_initial_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path ) - - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - + try: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() @@ -183,21 +190,27 @@ def test_admin_client_service_config_initial_backoff(host, port, test_case): ) ], ) -def test_admin_client_service_config_max_backoff(host, port, test_case): +def test_admin_client_service_config_max_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path ) - - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - + try: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() @@ -228,21 +241,27 @@ def test_admin_client_service_config_max_backoff(host, port, test_case): ) ], ) -def test_admin_client_service_config_backoff_multiplier(host, port, test_case): +def test_admin_client_service_config_backoff_multiplier(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path ) - - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - + try: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() @@ -273,9 +292,14 @@ def test_admin_client_service_config_backoff_multiplier(host, port, test_case): ) ], ) -def test_admin_client_service_config_retryable_status_codes(host, port, test_case): +def test_admin_client_service_config_retryable_status_codes(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path ) diff --git a/tests/standard/sync/test_vector_client_delete.py b/tests/standard/sync/test_vector_client_delete.py index 75abd5ea..44e32781 100644 --- a/tests/standard/sync/test_vector_client_delete.py +++ b/tests/standard/sync/test_vector_client_delete.py @@ -87,11 +87,14 @@ def test_vector_delete_without_record(session_vector_client, test_case, random_k namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=0 + timeout=0.0001 ), ], ) -def test_vector_delete_timeout(session_vector_client, test_case, random_key): +def test_vector_delete_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + for i in range(10): try: session_vector_client.delete( @@ -103,4 +106,4 @@ def test_vector_delete_timeout(session_vector_client, test_case, random_key): if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_exists.py b/tests/standard/sync/test_vector_client_exists.py index a0ea6b92..19971a1b 100644 --- a/tests/standard/sync/test_vector_client_exists.py +++ b/tests/standard/sync/test_vector_client_exists.py @@ -67,11 +67,14 @@ def test_vector_exists(session_vector_client, test_case, random_key): namespace="test", set_name=None, record_data=None, - timeout=0 + timeout=0.0001 ), ], ) -def test_vector_exists_timeout(session_vector_client, test_case, random_key): +def test_vector_exists_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + for i in range(10): try: result = session_vector_client.exists( @@ -84,4 +87,4 @@ def test_vector_exists_timeout(session_vector_client, test_case, random_key): assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_get.py b/tests/standard/sync/test_vector_client_get.py index 55f48fba..e2bd0654 100644 --- a/tests/standard/sync/test_vector_client_get.py +++ b/tests/standard/sync/test_vector_client_get.py @@ -82,11 +82,14 @@ def test_vector_get(session_vector_client, test_case, random_key): set_name=None, record_data=None, expected_fields=None, - timeout=0 + timeout=0.0001 ), ], ) -def test_vector_get_timeout(session_vector_client, test_case, random_key): +def test_vector_get_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + for i in range(10): try: result = session_vector_client.get( @@ -96,4 +99,4 @@ def test_vector_get_timeout(session_vector_client, test_case, random_key): if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_insert.py b/tests/standard/sync/test_vector_client_insert.py index 1570f23a..68360094 100644 --- a/tests/standard/sync/test_vector_client_insert.py +++ b/tests/standard/sync/test_vector_client_insert.py @@ -14,11 +14,13 @@ def __init__( namespace, record_data, set_name, - timeout, + ignore_mem_queue_full, + timeout ): self.namespace = namespace self.record_data = record_data self.set_name = set_name + self.ignore_mem_queue_full = ignore_mem_queue_full self.timeout = timeout @given(random_key=key_strategy()) @@ -30,18 +32,21 @@ def __init__( namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, + ignore_mem_queue_full=None, timeout=None ), insert_test_case( namespace="test", record_data={"homeSkills": [float(i) for i in range(1024)]}, set_name=None, + ignore_mem_queue_full=None, timeout=None ), insert_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None, + ignore_mem_queue_full=None, timeout=None ) ], @@ -73,12 +78,13 @@ def test_vector_insert_without_existing_record(session_vector_client, test_case, namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, + ignore_mem_queue_full=None, timeout=None ) ], ) def test_vector_insert_with_existing_record(session_vector_client, test_case, random_key): - session_vector_client.insert( + session_vector_client.upsert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, @@ -96,6 +102,40 @@ def test_vector_insert_with_existing_record(session_vector_client, test_case, ra key=random_key, ) +@given(random_key=key_strategy()) +@settings(max_examples=5, deadline=1000) +@pytest.mark.parametrize( + "test_case", + [ + insert_test_case( + namespace="test", + record_data={"english": [bool(i) for i in range(1024)]}, + set_name=None, + ignore_mem_queue_full=True, + timeout=None + ) + ], +) +def test_vector_insert_without_existing_record_ignore_mem_queue_full(session_vector_client, test_case, random_key): + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) + + session_vector_client.insert( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name, + ignore_mem_queue_full=test_case.ignore_mem_queue_full + ) + + session_vector_client.delete( + namespace=test_case.namespace, + key=random_key, + ) + + @given(random_key=key_strategy()) @settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( @@ -105,11 +145,15 @@ def test_vector_insert_with_existing_record(session_vector_client, test_case, ra namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0 + ignore_mem_queue_full=None, + timeout=0.0001 ) ], ) -def test_vector_insert_timeout(session_vector_client, test_case, random_key): +def test_vector_insert_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + for i in range(10): try: session_vector_client.insert( @@ -123,4 +167,4 @@ def test_vector_insert_timeout(session_vector_client, test_case, random_key): if e.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert e.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_vector_client_update.py b/tests/standard/sync/test_vector_client_update.py index 3923a32c..fd30c410 100644 --- a/tests/standard/sync/test_vector_client_update.py +++ b/tests/standard/sync/test_vector_client_update.py @@ -45,17 +45,14 @@ def __init__( ], ) def test_vector_update_with_existing_record(session_vector_client, test_case, random_key): - try: - session_vector_client.insert( - namespace=test_case.namespace, - key=random_key, - record_data=test_case.record_data, - set_name=test_case.set_name, - timeout=None - ) - except AVSServerError as se: - if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: - raise se + session_vector_client.upsert( + namespace=test_case.namespace, + key=random_key, + record_data=test_case.record_data, + set_name=test_case.set_name, + timeout=None + ) + session_vector_client.update( namespace=test_case.namespace, @@ -101,11 +98,14 @@ def test_vector_update_without_existing_record(session_vector_client, test_case, namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0 + timeout=0.0001 ) ], ) -def test_vector_update_timeout(session_vector_client, test_case, random_key): +def test_vector_update_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + for i in range(10): try: session_vector_client.update( @@ -119,6 +119,6 @@ def test_vector_update_timeout(session_vector_client, test_case, random_key): if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_vector_client_upsert.py b/tests/standard/sync/test_vector_client_upsert.py index ab3af916..857a1e1f 100644 --- a/tests/standard/sync/test_vector_client_upsert.py +++ b/tests/standard/sync/test_vector_client_upsert.py @@ -93,11 +93,14 @@ def test_vector_upsert_with_existing_record(session_vector_client, test_case, ra namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0 + timeout=0.0001 ) ], ) -def test_vector_upsert_timeout(session_vector_client, test_case, random_key): +def test_vector_upsert_timeout(session_vector_client, test_case, random_key, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + for i in range(10): try: session_vector_client.upsert( @@ -111,4 +114,4 @@ def test_vector_upsert_timeout(session_vector_client, test_case, random_key): if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index 953c540c..c63f5743 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -121,8 +121,6 @@ def test_vector_search( session_vector_client.wait_for_index_completion(namespace='test', name='demo') - for j, vector in enumerate(base_numpy): - get_vector(session_vector_client, j) # Vector search all query vectors @@ -174,18 +172,28 @@ def test_vector_is_indexed(session_vector_client, session_admin_client): ) assert result is True -def test_vector_is_indexed_timeout(session_vector_client, session_admin_client): - with pytest.raises(AVSServerError) as e_info: - for i in range(10): +def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") + + for i in range(10): + try: result = session_vector_client.is_indexed( namespace="test", key="" + str(random.randrange(10_000)), index_name="demo", - timeout=0 + timeout=0.0001 ) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + except AVSServerError as se: + if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED + return + assert "In several attempts, the timeout did not happen" == "TEST FAIL" + +def test_vector_vector_search_timeout(session_vector_client, session_admin_client, local_latency): + if local_latency: + pytest.skip("Server latency too low to test timeout") -def test_vector_vector_search_timeout(session_vector_client, session_admin_client): for i in range(10): try: result = session_vector_client.vector_search( @@ -194,10 +202,10 @@ def test_vector_vector_search_timeout(session_vector_client, session_admin_clien query=[0, 1, 2], limit=100, field_names=["unit_test"], - timeout=0 + timeout=0.0001 ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert 1 == 2 \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file diff --git a/tests/utils.py b/tests/utils.py index fc8e0b7e..22ce60a9 100755 --- a/tests/utils.py +++ b/tests/utils.py @@ -10,7 +10,7 @@ def random_int(): list(string.ascii_lowercase) + # a-z list(string.ascii_uppercase) + # A-Z list(string.digits) + # 0-9 - ['_', '-', '$'] # _, -, $ + ['_', '-'] # _, -, $ ) def key_strategy(): From c533281aff1f55d2d4e869cb03d2c472dad7dc9e Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Wed, 17 Jul 2024 14:11:24 -0600 Subject: [PATCH 129/215] Quick Patch --- pyproject.toml | 2 +- src/aerospike_vector_search/types.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0f97d113..55c71c02 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Topic :: Database" ] -version = "1.0.0.dev1" +version = "1.0.0.dev2" requires-python = ">3.8" dependencies = [ "grpcio", diff --git a/src/aerospike_vector_search/types.py b/src/aerospike_vector_search/types.py index 1b29d6a0..07cae68c 100644 --- a/src/aerospike_vector_search/types.py +++ b/src/aerospike_vector_search/types.py @@ -321,8 +321,11 @@ def __init__(self, *, namespace: Optional[str] = None, set_name: Optional[str] = def _to_pb2(self): index_storage = types_pb2.IndexStorage() - index_storage.namespace = self.namespace - index_storage.set = self.set_name + if self.namespace: + + index_storage.namespace = self.namespace + if self.set_name: + index_storage.set = self.set_name return index_storage From ab265ae8584ee90e0c74ab7dabb6bc0466794e08 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 18 Jul 2024 11:52:05 -0600 Subject: [PATCH 130/215] Locked dependencies --- pyproject.toml | 9 ++++++--- requirements.txt | 4 ---- .../aio/internal/channel_provider.py | 8 ++++++++ .../shared/base_channel_provider.py | 10 +++++++++- .../max_backoff_lower_than_initial.json | 2 +- .../sync/test_admin_client_index_get_status.py | 1 + 6 files changed, 25 insertions(+), 9 deletions(-) delete mode 100644 requirements.txt diff --git a/pyproject.toml b/pyproject.toml index 55c71c02..b1688340 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,11 +22,14 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Topic :: Database" ] -version = "1.0.0.dev2" +version = "1.0.0.dev3" requires-python = ">3.8" dependencies = [ - "grpcio", - "protobuf" + "grpcio == 1.65.1", + "protobuf == 5.27.2", + "pyjwt == 2.8.0", + "numpy", + "sphinx_rtd_theme" ] [project.urls] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index a10a9a08..00000000 --- a/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -grpcio -protobuf -sphinx_rtd_theme -pyjwt \ No newline at end of file diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 8726a56a..30db5b53 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -152,8 +152,16 @@ async def _tend(self): await asyncio.gather(*tasks) + #if not self.current_server_version: self._tend_initalized.set() + #stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) + #about_request = vector_db_pb2.AboutRequest() + + #self.current_server_version = await stub.Get(about_request, credentials=self._token) + + #self.client_server_compatible = self.verify_compatibile_server() + # TODO: check tend interval. await asyncio.sleep(1) self._task = asyncio.create_task(self._tend()) diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index acb455bf..88f682d1 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -73,6 +73,8 @@ def __init__( ] self._closed: bool = False self._cluster_id: int = 0 + self.current_server_version = "" + self.minimum_required_version = "0.9.0" def get_channel(self) -> Union[grpc.aio.Channel, grpc.Channel]: if not self._is_loadbalancer: @@ -193,4 +195,10 @@ def _respond_authenticate(self, token): self._ttl = self._get_ttl(payload) self._ttl_start = payload['exp'] - self._token = grpc.access_token_call_credentials(token) \ No newline at end of file + self._token = grpc.access_token_call_credentials(token) + + def verify_compatibile_server() -> bool: + def parse_version(v: str): + return tuple(map(int, v.split('.'))) + + return parse_version(self.server_current_version) >= parse_version(self.minimum_required_version) \ No newline at end of file diff --git a/tests/service_configs/max_backoff_lower_than_initial.json b/tests/service_configs/max_backoff_lower_than_initial.json index e31e33dd..8b0a56ec 100644 --- a/tests/service_configs/max_backoff_lower_than_initial.json +++ b/tests/service_configs/max_backoff_lower_than_initial.json @@ -10,7 +10,7 @@ "maxBackoff": "1s", "backoffMultiplier": 2, "retryableStatusCodes": [ - "ALREADY_EXISTS", "UNAVAILABLE" + "ALREADY_EXISTS" ] } } diff --git a/tests/standard/sync/test_admin_client_index_get_status.py b/tests/standard/sync/test_admin_client_index_get_status.py index a2048260..52a31da5 100644 --- a/tests/standard/sync/test_admin_client_index_get_status.py +++ b/tests/standard/sync/test_admin_client_index_get_status.py @@ -12,6 +12,7 @@ @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) def test_index_get_status(session_admin_client, empty_test_case, random_name): + session_admin_client.index_create( namespace="test", name=random_name, From e5a5662a88b30fc2dcf594e896fc81d6e13deeb0 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 18 Jul 2024 12:36:08 -0600 Subject: [PATCH 131/215] CLIENT-3036 CLIENT-3037 CLIENT-3041 Reverted grpcio to 1.64.1 --- pyproject.toml | 2 +- src/aerospike_vector_search/admin.py | 4 ++-- src/aerospike_vector_search/aio/admin.py | 4 ++-- src/aerospike_vector_search/aio/client.py | 8 +++----- src/aerospike_vector_search/client.py | 8 +++----- 5 files changed, 11 insertions(+), 15 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b1688340..1d6e7b5c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ version = "1.0.0.dev3" requires-python = ">3.8" dependencies = [ - "grpcio == 1.65.1", + "grpcio == 1.64.1", "protobuf == 5.27.2", "pyjwt == 2.8.0", "numpy", diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index 2ed80b22..2d7074a9 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -441,7 +441,7 @@ def _wait_for_index_creation( # Index has been created return except grpc.RpcError as e: - if e.code() in (grpc.StatusCode.UNAVAILABLE, grpc.StatusCode.NOT_FOUND): + if e.code() == grpc.StatusCode.NOT_FOUND: # Wait for some more time. time.sleep(wait_interval) @@ -475,7 +475,7 @@ def _wait_for_index_deletion( # Wait for some more time. time.sleep(wait_interval) except grpc.RpcError as e: - if e.code() in (grpc.StatusCode.UNAVAILABLE, grpc.StatusCode.NOT_FOUND): + if e.code() == grpc.StatusCode.NOT_FOUND: logger.debug("Index deleted succesfully") # Index has been created return diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index fb1ca302..e2cad14a 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -427,7 +427,7 @@ async def _wait_for_index_creation( # Index has been created return except grpc.RpcError as e: - if e.code() in (grpc.StatusCode.UNAVAILABLE, grpc.StatusCode.NOT_FOUND): + if e.code() == grpc.StatusCode.NOT_FOUND: # Wait for some more time. await asyncio.sleep(wait_interval) @@ -461,7 +461,7 @@ async def _wait_for_index_deletion( # Wait for some more time. await asyncio.sleep(wait_interval) except grpc.RpcError as e: - if e.code() in (grpc.StatusCode.UNAVAILABLE, grpc.StatusCode.NOT_FOUND): + if e.code() == grpc.StatusCode.NOT_FOUND: logger.debug("Index deleted succesfully") # Index has been created return diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index 06e60207..d58b6a95 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -437,11 +437,9 @@ async def wait_for_index_completion( index_status = await index_stub.GetStatus(index_completion_request, credentials=self._channel_provider._token) except grpc.RpcError as e: - if e.code() == grpc.StatusCode.UNAVAILABLE: - continue - else: - logger.error("Failed with error: %s", e) - raise types.AVSServerError(rpc_error=e) + + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) if self._check_completion_condition( start_time, timeout, index_status, unmerged_record_initialized ): diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index f888ec73..ac9a03f9 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -434,11 +434,9 @@ def wait_for_index_completion( try: index_status = index_stub.GetStatus(index_completion_request, credentials=self._channel_provider._token) except grpc.RpcError as e: - if e.code() == grpc.StatusCode.UNAVAILABLE: - continue - else: - logger.error("Failed with error: %s", e) - raise types.AVSServerError(rpc_error=e) + + logger.error("Failed with error: %s", e) + raise types.AVSServerError(rpc_error=e) if self._check_completion_condition( start_time, timeout, index_status, unmerged_record_initialized ): From c03965a91de40254a8314516fa2c62d72c110367 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 18 Jul 2024 12:42:16 -0600 Subject: [PATCH 132/215] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1d6e7b5c..3354f56b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Topic :: Database" ] -version = "1.0.0.dev3" +version = "1.0.0.dev4" requires-python = ">3.8" dependencies = [ "grpcio == 1.64.1", From 419f43f3a48b7ca276a0b69227821bbefdaa319e Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Thu, 18 Jul 2024 23:51:03 -0600 Subject: [PATCH 133/215] Fixed tending logic and added version check --- src/aerospike_vector_search/aio/admin.py | 46 ++++++++++++------ src/aerospike_vector_search/aio/client.py | 27 ++++++---- .../aio/internal/channel_provider.py | 36 +++++++------- .../internal/channel_provider.py | 9 ++++ .../shared/base_channel_provider.py | 9 ++-- src/aerospike_vector_search/types.py | 4 ++ tests/standard/sync/test_vector_search.py | 2 +- tests/standard/sync/test_vector_search.zip | Bin 0 -> 1837 bytes 8 files changed, 87 insertions(+), 46 deletions(-) create mode 100644 tests/standard/sync/test_vector_search.zip diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index e2cad14a..e8b3b322 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -91,7 +91,9 @@ async def index_create( It waits for up to 100,000 seconds for the index creation to complete. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() + (index_stub, index_create_request) = self._prepare_index_create( namespace, @@ -140,7 +142,8 @@ async def index_drop(self, *, namespace: str, name: str, timeout: Optional[int] This method drops an index with the specified parameters and waits for the index deletion to complete. It waits for up to 100,000 seconds for the index deletion to complete. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (index_stub, index_drop_request) = self._prepare_index_drop( namespace, name, timeout, logger @@ -174,7 +177,8 @@ async def index_list(self, timeout: Optional[int] = None) -> list[dict]: grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (index_stub, index_list_request) = self._prepare_index_list(timeout, logger) @@ -207,7 +211,8 @@ async def index_get( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (index_stub, index_get_request) = self._prepare_index_get( namespace, name, timeout, logger @@ -245,7 +250,8 @@ async def index_get_status(self, *, namespace: str, name: str, timeout: Optional Warning: This API is subject to change. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (index_stub, index_get_status_request) = self._prepare_index_get_status( namespace, name, timeout, logger @@ -264,7 +270,8 @@ async def index_get_status(self, *, namespace: str, name: str, timeout: Optional return self._respond_index_get_status(response) async def add_user(self, *, username: str, password: str, roles: list[str], timeout: Optional[int] = None) -> int: - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (user_admin_stub, add_user_request) = self._prepare_add_user( username, password, roles, timeout, logger @@ -281,7 +288,8 @@ async def add_user(self, *, username: str, password: str, roles: list[str], time raise types.AVSServerError(rpc_error=e) async def update_credentials(self, *, username: str, password: str, timeout: Optional[int] = None) -> int: - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (user_admin_stub, update_credentials_request) = self._prepare_update_credentials( username, password, timeout, logger @@ -298,7 +306,8 @@ async def update_credentials(self, *, username: str, password: str, timeout: Opt raise types.AVSServerError(rpc_error=e) async def drop_user(self, *, username: str, timeout: Optional[int] = None) -> int: - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (user_admin_stub, drop_user_request) = self._prepare_drop_user( username, timeout, logger @@ -315,7 +324,8 @@ async def drop_user(self, *, username: str, timeout: Optional[int] = None) -> in raise types.AVSServerError(rpc_error=e) async def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (user_admin_stub, get_user_request) = self._prepare_get_user( username, timeout, logger @@ -334,7 +344,8 @@ async def get_user(self, *, username: str, timeout: Optional[int] = None) -> int return self._respond_get_user(response) async def list_users(self, timeout: Optional[int] = None) -> int: - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (user_admin_stub, list_users_request) = self._prepare_list_users( timeout, logger @@ -352,7 +363,8 @@ async def list_users(self, timeout: Optional[int] = None) -> int: return self._respond_list_users(response) async def grant_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (user_admin_stub, grant_roles_request) = self._prepare_grant_roles( username, roles, timeout, logger @@ -369,7 +381,8 @@ async def grant_roles(self, *, username: str, roles: list[str], timeout: Optiona raise types.AVSServerError(rpc_error=e) async def revoke_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (user_admin_stub, revoke_roles_request) = self._prepare_revoke_roles( username, roles, timeout, logger @@ -386,7 +399,8 @@ async def revoke_roles(self, *, username: str, roles: list[str], timeout: Option raise types.AVSServerError(rpc_error=e) async def list_roles(self, timeout: Optional[int] = None) -> int: - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (user_admin_stub, list_roles_request) = self._prepare_list_roles( timeout, logger @@ -414,7 +428,8 @@ async def _wait_for_index_creation( """ Wait for the index to be created. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (index_stub, wait_interval, start_time, _, _, index_creation_request) = ( self._prepare_wait_for_index_waiting(namespace, name, wait_interval) @@ -446,7 +461,8 @@ async def _wait_for_index_deletion( """ Wait for the index to be deleted. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() # Wait interval between polling (index_stub, wait_interval, start_time, _, _, index_deletion_request) = ( diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index d58b6a95..a7167600 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -81,7 +81,8 @@ async def insert( """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (transact_stub, insert_request) = self._prepare_insert( namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger @@ -125,7 +126,8 @@ async def update( """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (transact_stub, update_request) = self._prepare_update( namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger @@ -169,7 +171,8 @@ async def upsert( """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (transact_stub, upsert_request) = self._prepare_upsert( namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger @@ -212,7 +215,8 @@ async def get( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (transact_stub, key, get_request) = self._prepare_get( namespace, key, field_names, set_name, timeout, logger @@ -249,7 +253,8 @@ async def exists( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (transact_stub, exists_request) = self._prepare_exists( namespace, key, set_name, timeout, logger @@ -283,7 +288,8 @@ async def delete( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (transact_stub, delete_request) = self._prepare_delete( namespace, key, set_name, timeout, logger @@ -328,7 +334,8 @@ async def is_indexed( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (transact_stub, is_indexed_request) = self._prepare_is_indexed( namespace, key, index_name, index_namespace, set_name, timeout, logger @@ -376,7 +383,8 @@ async def vector_search( grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() (transact_stub, vector_search_request) = self._prepare_vector_search( namespace, index_name, query, limit, search_params, field_names, timeout, logger @@ -421,7 +429,8 @@ async def wait_for_index_completion( The function polls the index status with a wait interval of 10 seconds until either the timeout is reached or the index has no pending index update operations. """ - await self._channel_provider._is_ready() + if not self._channel_provider.client_server_compatible: + await self._channel_provider._is_ready() # Wait interval between polling ( diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 30db5b53..aafd5aa0 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -61,6 +61,9 @@ async def close(self): async def _is_ready(self): await self._tend_initalized.wait() + if not self.client_server_compatible: + raise types.AVSClientError(message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + self.minimum_required_version) + async def _tend(self): try: (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() @@ -77,7 +80,7 @@ async def _tend(self): stubs = [] tasks = [] - + update_endpoints_stubs = [] for channel in channels: stub = vector_db_pb2_grpc.ClusterInfoServiceStub(channel) @@ -98,13 +101,13 @@ async def _tend(self): for index, value in enumerate(new_cluster_ids): if self.check_cluster_id(value.id): - update_endpoints_stub = stubs[index] - break + update_endpoints_stubs.append(stubs[index]) + - if update_endpoints_stub: + for stub in update_endpoints_stubs: try: - response = await update_endpoints_stub.GetClusterEndpoints( + response = await stub.GetClusterEndpoints( vector_db_pb2.ClusterNodeEndpointsRequest( listenerName=self.listener_name ), @@ -118,8 +121,8 @@ async def _tend(self): ) tasks = [] - add_new_channel_info = [] + if update_endpoints_stubs: for node, newEndpoints in temp_endpoints.items(): (channel_endpoints, add_new_channel) = self.check_for_new_endpoints( node, newEndpoints @@ -133,13 +136,10 @@ async def _tend(self): logger.debug( "While tending, failed to close GRPC channel:" + str(e) ) - add_new_channel_info.append((node, newEndpoints)) - - for node, newEndpoints in add_new_channel_info: - self.add_new_channel_to_node_channels(node, newEndpoints) + self.add_new_channel_to_node_channels(node, newEndpoints) for node, channel_endpoints in list(self._node_channels.items()): - if not self._node_channels.get(node): + if not temp_endpoints.get(node): try: # TODO: Wait for all calls to drain tasks.append(channel_endpoints.channel.close()) @@ -152,20 +152,22 @@ async def _tend(self): await asyncio.gather(*tasks) - #if not self.current_server_version: - self._tend_initalized.set() + if not self.client_server_compatible: + + stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) + about_request = vector_db_pb2.AboutRequest() - #stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) - #about_request = vector_db_pb2.AboutRequest() + self.current_server_version = (await stub.Get(about_request, credentials=self._token)).version + self.client_server_compatible = self.verify_compatibile_server() - #self.current_server_version = await stub.Get(about_request, credentials=self._token) - #self.client_server_compatible = self.verify_compatibile_server() + self._tend_initalized.set() # TODO: check tend interval. await asyncio.sleep(1) self._task = asyncio.create_task(self._tend()) except Exception as e: + print(e) diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index 9ad749b7..b5b1c02a 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -119,6 +119,15 @@ def _tend(self): "While tending, failed to close GRPC channel:" + str(e) ) + if not self.client_server_compatible: + + stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) + about_request = vector_db_pb2.AboutRequest() + + self.current_server_version = stub.Get(about_request, credentials=self._token).version + self.client_server_compatible = self.verify_compatibile_server() + if not self.client_server_compatible: + raise types.AVSClientError(message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + self.minimum_required_version) self._timer = threading.Timer(1, self._tend).start() diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index 88f682d1..9cd01eae 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -75,6 +75,7 @@ def __init__( self._cluster_id: int = 0 self.current_server_version = "" self.minimum_required_version = "0.9.0" + self.client_server_compatible = False def get_channel(self) -> Union[grpc.aio.Channel, grpc.Channel]: if not self._is_loadbalancer: @@ -160,8 +161,6 @@ def check_for_new_endpoints(self, node, newEndpoints): if channel_endpoints.endpoints == newEndpoints: # Nothing to be done for this node add_new_channel = False - else: - add_new_channel = True return (channel_endpoints, add_new_channel) @@ -197,8 +196,10 @@ def _respond_authenticate(self, token): self._token = grpc.access_token_call_credentials(token) - def verify_compatibile_server() -> bool: + def verify_compatibile_server(self) -> bool: def parse_version(v: str): return tuple(map(int, v.split('.'))) - return parse_version(self.server_current_version) >= parse_version(self.minimum_required_version) \ No newline at end of file + return parse_version(self.current_server_version) >= parse_version(self.minimum_required_version) + + \ No newline at end of file diff --git a/src/aerospike_vector_search/types.py b/src/aerospike_vector_search/types.py index 07cae68c..5e54106c 100644 --- a/src/aerospike_vector_search/types.py +++ b/src/aerospike_vector_search/types.py @@ -353,3 +353,7 @@ class AVSServerError(AVSError): def __init__(self, *, rpc_error) -> None: self.rpc_error = rpc_error + +class AVSClientError(AVSError): + def __init__(self, *, message) -> None: + self.message = message \ No newline at end of file diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index c63f5743..3c9bca5b 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -96,7 +96,7 @@ def vector_search_ef_80(client, vector): query=vector, limit=100, field_names=["unit_test"], - search_params=types.HnswSearchParams(ef=80) + search_params=types.HnswSearchParams(ef=80), ) return result diff --git a/tests/standard/sync/test_vector_search.zip b/tests/standard/sync/test_vector_search.zip new file mode 100644 index 0000000000000000000000000000000000000000..399d132025ce2e0ab13959222c2e544e2742996a GIT binary patch literal 1837 zcmbW2XE@u79>@QQO;A0F#%g1=u_EQDS*v0MHAA9^*~BaoB~A}D>e{n4LaEW(o7O5q zX;JIgHA;`3W3~<{ZBe&9&ppq*ukZK!{MPe*@q78PG-Y9h0-WEiRIrB!{v$0o0KfnQ zK=q_hiMKu7skefN6i?S6cQPt~hO^}bIM4&RH~*>NP#yrpy1@bff43d{4WG3u(D1`L zODF91KqzTap%j#j%A4QmwH9oYzvqgkH)vVCyCJPUU&QP_Tz9*%HNPW)c=sQad{Ep(3w; z5qFu3MYp7*Tt22|)t|ihqj$ga)`XFvoaNW7M}EWb$kPixw=Jr~hLAR-182jaDHnDL zwGoW$rfp=l+rX|i(zxZPX9DBd0&jqrjVB|NUKfm;fHRF#n>PeZep%}KLVJDmUM#9Y zH3Xr^gsR8Y60*F7)dYbM=G8D*F@=fETvNFQoxo~%8$mQB&BF%@nnx+uS$7}x^sFvq z`oH4)EL9?T@|59E$I47uWyt19Gwa@3-@z?Dq#CRC(W-=_!pwS} z0ayoL)6;kVr{?2E>EyczuH$Dpf>PItXZ&rQ^&QTDM@kD5pI%+WBr~!%LoXb0H|y;}g4(6j#y1|j&+Xus>~f2fH=r@7JOV^zUIyV% zSrGfqU?O4Mj5o;_11*=mdJ)kwmBX+d4n|L#zC`0}CqWxZIT)MF6AJka;LwoD7@@;JUc1dGNxg@VvYOQD z!u0p&bN}VGeimogHP#zuA%SGR;rOGf@R#g5;#(iqY~lb`Cl zx`$F!y1iDu27ahblvSS*xEqJ|>IW)RmIP$RCp50Y6Ykkl^0ds;MKEj zCLAH?RXti7NNQw-4{Q587zyAX(d}qeo*LpO%-Q=moh@P;zC&njs)mV1SD=yJdmqR9 z$-hndx-aUM41!ffNiIdJ==Jod%t>`RH~>tn`JnEotdX|NKtNzl#U&zXd_WXP$&;#j zFnm*XNj!vVFQ#jQ#+3WBl?eq#zZhy77qT*bGnLN`r-rq{6dhlcOK9GyXJb?jcvMtl zL8h|_<4Ze+7-Z69tA6El3f5AuZQOxhM5ELEA@yg~w7yQU_AYo%@Q3lz2D>4dz*T$( zH_1MY;V0Ga;pm2|eW1~qf>F4~QFP6MB4@$@b9!Pk*U>#De#LjQ&oZC+8+o-ev0glk zPwKfY1K&I>EgA^#e+zUiZu7hmar9jP2jHHOmb1!7aj&#iilrA*NNu^s87|g65YuD8 ze?g#y^o;{0IDC%NaOe`j4RxvZ8*_{-aLRNq#Ih^W?iIYd9NJfZnVFCnGRGz}t8(9i zBJEb`n#>WmA?x>-c2U{j#K<9IEGT^Pqgump36Y!GVGKVnrma7A*_nhgDn#TIG-^M% zg-P=vM(f8U2=|yj-mmhrXCS8YJ*$p3s(8A~%vZMTr99$R=)}GTBid57!K-qX5WdeB z-(Gh{W)mEjnzW$c9G$_G--oK$i<58Hj(DVMm;rUkKNJX{9KDr-P z%A~VK`D_f*WGd0=j$}RgiwHicF1xNyr}NY=7ZnlFdD1=3@SekNhb_nmyS+N7a4>DPr og1}Ig|5EFJvmey@N6nExw*QM^mZogqp8){qyWPLf=D)9h1NYfKCjbBd literal 0 HcmV?d00001 From b4a451b16782cbd7bcfebbb27ccf5fba4e85caee Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 00:01:31 -0600 Subject: [PATCH 134/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 79ebad37..cfa4b01a 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -52,7 +52,7 @@ jobs: - name: create config run: | #assets/call_gen_normal.sh - cat aerospike-proximus.yml + cat aerospike-vector-search.yml cat aerospike.conf cat /etc/hosts @@ -60,7 +60,7 @@ jobs: - name: Run unit tests run: | - docker run -d --network=host -p 5000:5000 --name aerospike-proximus -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --network=host -p 5000:5000 --name aerospike-vector-search -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf aerospike/aerospike-vector-search:0.9.0 docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest @@ -124,7 +124,7 @@ jobs: - name: create config run: | assets/call_gen_tls.sh - cat aerospike-proximus.yml + cat aerospike-vector-search.yml cat aerospike.conf cat /etc/hosts working-directory: tests @@ -136,7 +136,7 @@ jobs: - name: Run unit tests run: | - docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf -v ./tls:/etc/aerospike-vector-search/tls aerospike/aerospike-vector-search:0.9.0 docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 5 @@ -212,7 +212,7 @@ jobs: - name: Run unit tests run: | - docker run -d --name aerospike-proximus --network=host -p 5000:5000 -v ./aerospike-proximus.yml:/etc/aerospike-proximus/aerospike-proximus.yml -v ./features.conf:/etc/aerospike-proximus/features.conf -v ./tls:/etc/aerospike-proximus/tls aerospike.jfrog.io/docker/aerospike/aerospike-proximus-private:0.5.0-SNAPSHOT + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf -v ./tls:/etc/aerospike-vector-search/tls aerospike/aerospike-vector-search:0.9.0 docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 5 @@ -222,7 +222,7 @@ jobs: " - cat aerospike-proximus.yml + cat aerospike-vector-search.yml cat aerospike.conf cat tls/root.crt cat tls/brawn.key.pem @@ -231,6 +231,6 @@ jobs: python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs docker ps - docker logs aerospike-proximus + docker logs aerospike-vector-search working-directory: tests \ No newline at end of file From 3613ad76b5e492328b72e6f54d799915357f642d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 00:10:54 -0600 Subject: [PATCH 135/215] Tweaked configurations --- .github/workflows/integration_test.yml | 10 +++++----- tests/assets/call_gen_normal.sh | 2 +- tests/assets/call_gen_tls.sh | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index cfa4b01a..9a3029ff 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -68,7 +68,7 @@ jobs: sleep 5 docker ps - python -m pytest standard -s --host 0.0.0.0 --port 5000 + python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency working-directory: tests test-tls: @@ -136,7 +136,7 @@ jobs: - name: Run unit tests run: | - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf -v ./tls:/etc/aerospike-vector-search/tls aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 5 @@ -145,7 +145,7 @@ jobs: docker ps - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs working-directory: tests @@ -212,7 +212,7 @@ jobs: - name: Run unit tests run: | - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf -v ./tls:/etc/aerospike-vector-search/tls aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest sleep 5 @@ -228,7 +228,7 @@ jobs: cat tls/brawn.key.pem cat tls/brawn.crt - python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs docker ps docker logs aerospike-vector-search diff --git a/tests/assets/call_gen_normal.sh b/tests/assets/call_gen_normal.sh index 9f55ec36..c56529c9 100755 --- a/tests/assets/call_gen_normal.sh +++ b/tests/assets/call_gen_normal.sh @@ -12,5 +12,5 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 127.0.0.1 \ + --host 0.0.0.0 \ --for_testing y diff --git a/tests/assets/call_gen_tls.sh b/tests/assets/call_gen_tls.sh index 5dfbcb35..4e23af31 100755 --- a/tests/assets/call_gen_tls.sh +++ b/tests/assets/call_gen_tls.sh @@ -12,5 +12,5 @@ --client_name brawn \ --server_name brawn \ --port 5000 \ - --host 127.0.0.1 \ + --host 0.0.0.0 \ --for_testing y From 2de0a067732c1d346cac75eb9ae7ef80e299db6e Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 00:15:18 -0600 Subject: [PATCH 136/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 9a3029ff..17c470a7 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -141,12 +141,13 @@ jobs: sleep 5 - ls /home/runner/work/avs-client-python/avs-client-python/tests/ docker ps python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + docker logs aerospike-vector-search + docker logs aerospike working-directory: tests @@ -228,7 +229,7 @@ jobs: cat tls/brawn.key.pem cat tls/brawn.crt - python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs + python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs docker ps docker logs aerospike-vector-search From df62a54a75a70ce9c35696a2d0295a134e4f0443 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 00:17:25 -0600 Subject: [PATCH 137/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 17c470a7..64f41e6d 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -144,7 +144,7 @@ jobs: docker ps - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs docker logs aerospike-vector-search docker logs aerospike From 7001003ca79531c1ac3d5ec719afc290f52b6fe1 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 00:36:48 -0600 Subject: [PATCH 138/215] Shortened files, made tests more consistent --- .github/workflows/integration_test.yml | 124 ++--------- .github/workflows/reusable-steps.yml | 237 +++++++++++++++++++++ tests/service_configs/master.json | 6 +- tests/standard/sync/test_service_config.py | 2 +- 4 files changed, 262 insertions(+), 107 deletions(-) create mode 100644 .github/workflows/reusable-steps.yml diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 64f41e6d..c7460365 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -6,48 +6,32 @@ on: - dev jobs: - test-normal: + + setup: runs-on: ubuntu-24.04 continue-on-error: true - - strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - - name: Checkout code - uses: actions/checkout@v3 + - name: Call reusable setup steps + uses: ./.github/workflows/reusable-steps.yml + with: + python-version: ${{ matrix.python-version }} - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} + test-normal: + runs-on: ubuntu-24.04 + needs: setup-normal - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - - working-directory: tests - + continue-on-error: true + - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} + steps: - name: create config run: | @@ -73,6 +57,8 @@ jobs: test-tls: runs-on: ubuntu-24.04 + needs: setup-normal + continue-on-error: true @@ -83,37 +69,6 @@ jobs: steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - name: Set up RANDFILE environment variable run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV @@ -153,6 +108,9 @@ jobs: test-tls-auth: runs-on: ubuntu-24.04 + + needs: setup-normal + continue-on-error: true @@ -162,36 +120,6 @@ jobs: steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - name: Set up RANDFILE environment variable @@ -218,16 +146,6 @@ jobs: sleep 5 - docker ps - echo " - - " - - cat aerospike-vector-search.yml - cat aerospike.conf - cat tls/root.crt - cat tls/brawn.key.pem - cat tls/brawn.crt python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs diff --git a/.github/workflows/reusable-steps.yml b/.github/workflows/reusable-steps.yml new file mode 100644 index 00000000..2f4e89fe --- /dev/null +++ b/.github/workflows/reusable-steps.yml @@ -0,0 +1,237 @@ +name: Run Unit Tests + +on: + pull_request: + branches: + - dev + +jobs: + test-normal: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + - name: create config + run: | + #assets/call_gen_normal.sh + cat aerospike-vector-search.yml + cat aerospike.conf + cat /etc/hosts + + working-directory: tests + + - name: Run unit tests + run: | + docker run -d --network=host -p 5000:5000 --name aerospike-vector-search -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf aerospike/aerospike-vector-search:0.9.0 + + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + + sleep 5 + + docker ps + python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency + working-directory: tests + + test-tls: + runs-on: ubuntu-24.04 + continue-on-error: true + + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: create config + run: | + assets/call_gen_tls.sh + cat aerospike-vector-search.yml + cat aerospike.conf + cat /etc/hosts + working-directory: tests + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + + + docker ps + python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + + docker logs aerospike-vector-search + docker logs aerospike + working-directory: tests + + + test-tls-auth: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + + - name: create config + run: | + assets/call_gen.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + docker ps + echo " + + " + + cat aerospike-vector-search.yml + cat aerospike.conf + cat tls/root.crt + cat tls/brawn.key.pem + cat tls/brawn.crt + + python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + + docker ps + docker logs aerospike-vector-search + + working-directory: tests \ No newline at end of file diff --git a/tests/service_configs/master.json b/tests/service_configs/master.json index 40489578..e65e571e 100644 --- a/tests/service_configs/master.json +++ b/tests/service_configs/master.json @@ -3,7 +3,7 @@ { "name": [{}], - "timeout": "1s" + "timeout": "11s" }, { "name": [ @@ -11,7 +11,7 @@ "service": "Transact" } ], - "timeout": "2s" + "timeout": "12s" }, { "name": [ @@ -20,7 +20,7 @@ "method": "Create" } ], - "timeout": "3s" + "timeout": "13s" } ] diff --git a/tests/standard/sync/test_service_config.py b/tests/standard/sync/test_service_config.py index 93e6141f..2169a963 100644 --- a/tests/standard/sync/test_service_config.py +++ b/tests/standard/sync/test_service_config.py @@ -23,7 +23,7 @@ def __init__( ), ], ) -def test_admin_client_service_config_parse(host, port, test_case): +def test_admin_client_service_config_parse(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), service_config_path=test_case.service_config_path, From 16ea71cc8e7a0296d5db02ba1da9f79bb3e50976 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 00:49:43 -0600 Subject: [PATCH 139/215] updating tests --- .github/workflows/integration_test.yml | 13 +++++++------ tests/standard/sync/test_service_config.py | 12 +++++++++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c7460365..3d1d1ac8 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -12,7 +12,7 @@ jobs: continue-on-error: true strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - name: Call reusable setup steps uses: ./.github/workflows/reusable-steps.yml @@ -29,16 +29,13 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - name: create config run: | #assets/call_gen_normal.sh - cat aerospike-vector-search.yml - cat aerospike.conf - cat /etc/hosts working-directory: tests @@ -55,6 +52,11 @@ jobs: python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency working-directory: tests + - name : NEXT STEP + run: | + docker ps + working-directory: tests + test-tls: runs-on: ubuntu-24.04 needs: setup-normal @@ -135,7 +137,6 @@ jobs: - name: create config run: | assets/call_gen.sh - cat /etc/hosts working-directory: tests - name: Run unit tests diff --git a/tests/standard/sync/test_service_config.py b/tests/standard/sync/test_service_config.py index 2169a963..864a45f5 100644 --- a/tests/standard/sync/test_service_config.py +++ b/tests/standard/sync/test_service_config.py @@ -26,7 +26,12 @@ def __init__( def test_admin_client_service_config_parse(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), - service_config_path=test_case.service_config_path, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, + service_config_path=test_case.service_config_path ) client.close() @@ -90,6 +95,11 @@ def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, m def test_admin_client_service_config_retries(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): client = AdminClient( seeds=types.HostPort(host=host, port=port), + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, service_config_path=test_case.service_config_path ) From 2a6cfacdc10b681e7ce1994edc472044073a905a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 00:51:55 -0600 Subject: [PATCH 140/215] Update reusable-steps.yml --- .github/workflows/reusable-steps.yml | 211 +-------------------------- 1 file changed, 5 insertions(+), 206 deletions(-) diff --git a/.github/workflows/reusable-steps.yml b/.github/workflows/reusable-steps.yml index 2f4e89fe..aec485ab 100644 --- a/.github/workflows/reusable-steps.yml +++ b/.github/workflows/reusable-steps.yml @@ -1,166 +1,10 @@ -name: Run Unit Tests +name: Reusable Steps -on: - pull_request: - branches: - - dev +on: workflow_call jobs: - test-normal: + setup: runs-on: ubuntu-24.04 - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - name: create config - run: | - #assets/call_gen_normal.sh - cat aerospike-vector-search.yml - cat aerospike.conf - cat /etc/hosts - - working-directory: tests - - - name: Run unit tests - run: | - docker run -d --network=host -p 5000:5000 --name aerospike-vector-search -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf aerospike/aerospike-vector-search:0.9.0 - - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - - sleep 5 - - docker ps - python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency - working-directory: tests - - test-tls: - runs-on: ubuntu-24.04 - continue-on-error: true - - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - - name: Set up RANDFILE environment variable - run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV - - - name: Create .rnd file if it doesn't exist - run: touch $HOME/.rnd - - - name: create config - run: | - assets/call_gen_tls.sh - cat aerospike-vector-search.yml - cat aerospike.conf - cat /etc/hosts - working-directory: tests - - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts - - - name: Run unit tests - run: | - - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - sleep 5 - - - - docker ps - python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs - - docker logs aerospike-vector-search - docker logs aerospike - working-directory: tests - - - test-tls-auth: - runs-on: ubuntu-24.04 - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - steps: - name: Checkout code uses: actions/checkout@v3 @@ -168,8 +12,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: ${{ matrix.python-version }} - + python-version: ${{ inputs.python-version }} - name: Install dependencies run: | @@ -178,7 +21,6 @@ jobs: pip install -r requirements.txt working-directory: tests - - name: Retrieve the secret and decode it to a file env: FEATURE_FILE: ${{ secrets.FEATURE_FILE }} @@ -191,47 +33,4 @@ jobs: with: registry: aerospike.jfrog.io username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - - name: Set up RANDFILE environment variable - run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV - - - name: Create .rnd file if it doesn't exist - run: touch $HOME/.rnd - - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - - - name: create config - run: | - assets/call_gen.sh - cat /etc/hosts - working-directory: tests - - - name: Run unit tests - run: | - - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - sleep 5 - - docker ps - echo " - - " - - cat aerospike-vector-search.yml - cat aerospike.conf - cat tls/root.crt - cat tls/brawn.key.pem - cat tls/brawn.crt - - python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs - - docker ps - docker logs aerospike-vector-search - - working-directory: tests \ No newline at end of file + password: ${{ secrets.JFROG_PASSWORD }} \ No newline at end of file From 30602bba471805aff34e411be61b6568b803d16a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 00:53:04 -0600 Subject: [PATCH 141/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 3d1d1ac8..521aceac 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -22,7 +22,7 @@ jobs: test-normal: runs-on: ubuntu-24.04 - needs: setup-normal + needs: setup continue-on-error: true @@ -59,7 +59,7 @@ jobs: test-tls: runs-on: ubuntu-24.04 - needs: setup-normal + needs: setup continue-on-error: true @@ -111,7 +111,7 @@ jobs: test-tls-auth: runs-on: ubuntu-24.04 - needs: setup-normal + needs: setup continue-on-error: true From 5fdf58a28f4f8c3aef8175dd1ecb6051218b7c82 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 00:56:11 -0600 Subject: [PATCH 142/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 521aceac..9cd9b9b8 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -14,6 +14,10 @@ jobs: matrix: python-version: ["3.9", "3.10", "3.11", "3.12"] steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Call reusable setup steps uses: ./.github/workflows/reusable-steps.yml with: From 563de51da0ab3e580e83cb6a94f392874431ff5c Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:01:38 -0600 Subject: [PATCH 143/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 9cd9b9b8..41c73d8e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -17,7 +17,9 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - + - name: list actions + - run: ls .github/workflows + - name: Call reusable setup steps uses: ./.github/workflows/reusable-steps.yml with: From 04a1e5759cbb7b13e175eb55663ce3f5e13f00e0 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:02:47 -0600 Subject: [PATCH 144/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 41c73d8e..6d5e2ddd 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v3 - name: list actions - - run: ls .github/workflows + - runs: ls .github/workflows - name: Call reusable setup steps uses: ./.github/workflows/reusable-steps.yml From 11834bb2bdc3418a6732c088356bb1a702e250f1 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:03:37 -0600 Subject: [PATCH 145/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 6d5e2ddd..41c73d8e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v3 - name: list actions - - runs: ls .github/workflows + - run: ls .github/workflows - name: Call reusable setup steps uses: ./.github/workflows/reusable-steps.yml From ad3a8c95c503fc6065e9e1009c9467db8bf02c2a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:04:47 -0600 Subject: [PATCH 146/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 41c73d8e..0e1cec12 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -17,9 +17,6 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - - name: list actions - - run: ls .github/workflows - - name: Call reusable setup steps uses: ./.github/workflows/reusable-steps.yml with: From be6def808baea35d4560c37f0bd579f4fd301111 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:06:52 -0600 Subject: [PATCH 147/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 0e1cec12..03742367 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -17,6 +17,9 @@ jobs: - name: Checkout code uses: actions/checkout@v3 + - name: list + run: | + ls ./.github/workflows/reusable-steps.yml - name: Call reusable setup steps uses: ./.github/workflows/reusable-steps.yml with: From ac0a96c720fbb61621c3701870c6f591914bf797 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:10:00 -0600 Subject: [PATCH 148/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 41 +++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 03742367..7f21aeb8 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -10,20 +10,41 @@ jobs: setup: runs-on: ubuntu-24.04 continue-on-error: true + + strategy: matrix: python-version: ["3.9", "3.10", "3.11", "3.12"] + steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: list - run: | - ls ./.github/workflows/reusable-steps.yml - - name: Call reusable setup steps - uses: ./.github/workflows/reusable-steps.yml - with: - python-version: ${{ matrix.python-version }} + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} test-normal: From 2a04b6af5b83420f917bcb1718fc64cb6d4cdaa3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:11:55 -0600 Subject: [PATCH 149/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 7f21aeb8..b77ff807 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: python-version: ["3.9", "3.10", "3.11", "3.12"] - + steps: - name: Checkout code uses: actions/checkout@v3 @@ -60,6 +60,9 @@ jobs: steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: create config run: | #assets/call_gen_normal.sh From c2ed1ff4299c2d51e51b9e8ad8a2adbc763849b8 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:18:58 -0600 Subject: [PATCH 150/215] Reverted away from reusable-steps.yml --- .github/workflows/integration_test.yml | 114 ++++++++++++++++++------- .github/workflows/reusable-steps.yml | 36 -------- 2 files changed, 83 insertions(+), 67 deletions(-) delete mode 100644 .github/workflows/reusable-steps.yml diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index b77ff807..242ffe75 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -1,3 +1,4 @@ + name: Run Unit Tests on: @@ -6,16 +7,16 @@ on: - dev jobs: - - setup: + test-normal: runs-on: ubuntu-24.04 continue-on-error: true - + strategy: matrix: python-version: ["3.9", "3.10", "3.11", "3.12"] + steps: - name: Checkout code uses: actions/checkout@v3 @@ -25,13 +26,16 @@ jobs: with: python-version: ${{ matrix.python-version }} + - name: Install dependencies run: | python -m pip install --upgrade pip python setup.py pip install -r requirements.txt + working-directory: tests + - name: Retrieve the secret and decode it to a file env: FEATURE_FILE: ${{ secrets.FEATURE_FILE }} @@ -46,26 +50,12 @@ jobs: username: ${{ secrets.JFROG_USERNAME }} password: ${{ secrets.JFROG_PASSWORD }} - - test-normal: - runs-on: ubuntu-24.04 - needs: setup - - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - steps: - - - name: Checkout code - uses: actions/checkout@v3 - - name: create config run: | #assets/call_gen_normal.sh + cat aerospike-vector-search.yml + cat aerospike.conf + cat /etc/hosts working-directory: tests @@ -82,15 +72,8 @@ jobs: python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency working-directory: tests - - name : NEXT STEP - run: | - docker ps - working-directory: tests - test-tls: runs-on: ubuntu-24.04 - needs: setup - continue-on-error: true @@ -101,6 +84,37 @@ jobs: steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + - name: Set up RANDFILE environment variable run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV @@ -140,9 +154,6 @@ jobs: test-tls-auth: runs-on: ubuntu-24.04 - - needs: setup - continue-on-error: true @@ -152,6 +163,36 @@ jobs: steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} - name: Set up RANDFILE environment variable @@ -167,6 +208,7 @@ jobs: - name: create config run: | assets/call_gen.sh + cat /etc/hosts working-directory: tests - name: Run unit tests @@ -177,10 +219,20 @@ jobs: sleep 5 + docker ps + echo " + + " + + cat aerospike-vector-search.yml + cat aerospike.conf + cat tls/root.crt + cat tls/brawn.key.pem + cat tls/brawn.crt python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs docker ps docker logs aerospike-vector-search - working-directory: tests \ No newline at end of file + working-directory: tests diff --git a/.github/workflows/reusable-steps.yml b/.github/workflows/reusable-steps.yml deleted file mode 100644 index aec485ab..00000000 --- a/.github/workflows/reusable-steps.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Reusable Steps - -on: workflow_call - -jobs: - setup: - runs-on: ubuntu-24.04 - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ inputs.python-version }} - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} \ No newline at end of file From 9887bd2fd857ae3309ef2e3231fb989d42104e6a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:51:34 -0600 Subject: [PATCH 151/215] CI/CD improvments --- .github/workflows/integration_test.yml | 317 +++++++++++++++++- tests/assets/call_gen.sh | 6 +- .../{call_gen_normal.sh => call_gen_mtls.sh} | 4 +- tests/assets/call_gen_mtls_auth.sh | 18 + tests/assets/call_gen_tls_auth.sh | 16 + tests/standard/aio/test_service_config.py | 253 +++++++------- tests/standard/sync/test_service_config.py | 249 +++++++------- 7 files changed, 586 insertions(+), 277 deletions(-) rename tests/assets/{call_gen_normal.sh => call_gen_mtls.sh} (94%) mode change 100755 => 100644 create mode 100755 tests/assets/call_gen_mtls_auth.sh create mode 100644 tests/assets/call_gen_tls_auth.sh diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 242ffe75..fc867996 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -52,7 +52,7 @@ jobs: - name: create config run: | - #assets/call_gen_normal.sh + #assets/call_gen.sh cat aerospike-vector-search.yml cat aerospike.conf cat /etc/hosts @@ -145,18 +145,170 @@ jobs: docker ps - python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs docker logs aerospike-vector-search docker logs aerospike working-directory: tests - test-tls-auth: runs-on: ubuntu-24.04 continue-on-error: true + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: create config + run: | + assets/call_gen_tls_auth.sh + working-directory: tests + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + + + working-directory: tests + + + test-tls-auth-rbac: + runs-on: ubuntu-24.04 + continue-on-error: true + + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: create config + run: | + assets/call_gen_tls_auth.sh + cat aerospike-vector-search.yml + cat aerospike.conf + cat /etc/hosts + working-directory: tests + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + + + docker ps + python -m pytest rbac -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + + docker logs aerospike-vector-search + docker logs aerospike + working-directory: tests + + + test-mtls: + runs-on: ubuntu-24.04 + continue-on-error: true + + strategy: matrix: python-version: ["3.9", "3.10", "3.11", "3.12"] @@ -207,7 +359,7 @@ jobs: - name: create config run: | - assets/call_gen.sh + assets/call_gen_mtls.sh cat /etc/hosts working-directory: tests @@ -219,20 +371,155 @@ jobs: sleep 5 - docker ps - echo " + python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs - " - cat aerospike-vector-search.yml - cat aerospike.conf - cat tls/root.crt - cat tls/brawn.key.pem - cat tls/brawn.crt - python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + working-directory: tests + + + test-mtls-auth: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + + - name: create config + run: | + assets/call_gen_mtls_auth.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs + - docker ps - docker logs aerospike-vector-search working-directory: tests + + + test-mtls-auth-rbac: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + + - name: create config + run: | + assets/call_gen_mtls_auth.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + + + working-directory: tests \ No newline at end of file diff --git a/tests/assets/call_gen.sh b/tests/assets/call_gen.sh index 6d661eee..c56529c9 100755 --- a/tests/assets/call_gen.sh +++ b/tests/assets/call_gen.sh @@ -1,6 +1,6 @@ ./gen.sh \ - --tls_maybe y \ - --rbac_maybe y \ + --tls_maybe n \ + --rbac_maybe n \ --root_certificate_maybe y \ --root_certificate_name root \ --specify_details_maybe n \ @@ -14,5 +14,3 @@ --port 5000 \ --host 0.0.0.0 \ --for_testing y - - diff --git a/tests/assets/call_gen_normal.sh b/tests/assets/call_gen_mtls.sh old mode 100755 new mode 100644 similarity index 94% rename from tests/assets/call_gen_normal.sh rename to tests/assets/call_gen_mtls.sh index c56529c9..bc923ff9 --- a/tests/assets/call_gen_normal.sh +++ b/tests/assets/call_gen_mtls.sh @@ -1,5 +1,5 @@ ./gen.sh \ - --tls_maybe n \ + --tls_maybe y \ --rbac_maybe n \ --root_certificate_maybe y \ --root_certificate_name root \ @@ -14,3 +14,5 @@ --port 5000 \ --host 0.0.0.0 \ --for_testing y + + diff --git a/tests/assets/call_gen_mtls_auth.sh b/tests/assets/call_gen_mtls_auth.sh new file mode 100755 index 00000000..6d661eee --- /dev/null +++ b/tests/assets/call_gen_mtls_auth.sh @@ -0,0 +1,18 @@ +./gen.sh \ + --tls_maybe y \ + --rbac_maybe y \ + --root_certificate_maybe y \ + --root_certificate_name root \ + --specify_details_maybe n \ + --openssl_cnf_maybe n \ + --password citrusstore \ + --key_pair_maybe y \ + --key_password citrusstore \ + --mutual_auth_maybe y \ + --client_name brawn \ + --server_name brawn \ + --port 5000 \ + --host 0.0.0.0 \ + --for_testing y + + diff --git a/tests/assets/call_gen_tls_auth.sh b/tests/assets/call_gen_tls_auth.sh new file mode 100644 index 00000000..c1dfde82 --- /dev/null +++ b/tests/assets/call_gen_tls_auth.sh @@ -0,0 +1,16 @@ +./gen.sh \ + --tls_maybe y \ + --rbac_maybe y \ + --root_certificate_maybe y \ + --root_certificate_name root \ + --specify_details_maybe n \ + --openssl_cnf_maybe n \ + --password citrusstore \ + --key_pair_maybe y \ + --key_password citrusstore \ + --mutual_auth_maybe n \ + --client_name brawn \ + --server_name brawn \ + --port 5000 \ + --host 0.0.0.0 \ + --for_testing y diff --git a/tests/standard/aio/test_service_config.py b/tests/standard/aio/test_service_config.py index 296a6162..f6e1ef87 100644 --- a/tests/standard/aio/test_service_config.py +++ b/tests/standard/aio/test_service_config.py @@ -24,11 +24,15 @@ def __init__( ], ) async def test_admin_client_service_config_parse(host, port, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), - service_config_path=test_case.service_config_path, - ) - await client.close() + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, + service_config_path=test_case.service_config_path + ) as client: class service_config_test_case: def __init__( @@ -88,7 +92,7 @@ def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, m ], ) async def test_admin_client_service_config_retries(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -96,34 +100,31 @@ async def test_admin_client_service_config_retries(host, port, username, passwo certificate_chain=certificate_chain, private_key=private_key, service_config_path=test_case.service_config_path - - ) - - try: - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - except: - pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - - end_time = time.time() - elapsed_time = end_time - start_time - - assert abs(elapsed_time - expected_time) < 1.2 - await client.close() + ) as client: + try: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + + assert abs(elapsed_time - expected_time) < 1.2 @pytest.mark.parametrize( "test_case", @@ -139,7 +140,7 @@ async def test_admin_client_service_config_retries(host, port, username, passwo ], ) async def test_admin_client_service_config_initial_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -147,35 +148,33 @@ async def test_admin_client_service_config_initial_backoff(host, port, username, certificate_chain=certificate_chain, private_key=private_key, service_config_path=test_case.service_config_path - - ) - - try: - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - except: - pass - - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - - end_time = time.time() - elapsed_time = end_time - start_time + ) as client: + + try: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass + + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time assert abs(elapsed_time - expected_time) < 1.2 - await client.close() @pytest.mark.parametrize( "test_case", @@ -198,7 +197,7 @@ async def test_admin_client_service_config_initial_backoff(host, port, username, ], ) async def test_admin_client_service_config_max_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -206,34 +205,32 @@ async def test_admin_client_service_config_max_backoff(host, port, username, pas certificate_chain=certificate_chain, private_key=private_key, service_config_path=test_case.service_config_path + ) as client: + + try: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 - ) - - try: - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - except: - pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - - end_time = time.time() - elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 - - await client.close() @pytest.mark.parametrize( "test_case", @@ -249,7 +246,7 @@ async def test_admin_client_service_config_max_backoff(host, port, username, pas ], ) async def test_admin_client_service_config_backoff_multiplier(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -257,36 +254,34 @@ async def test_admin_client_service_config_backoff_multiplier(host, port, userna certificate_chain=certificate_chain, private_key=private_key, service_config_path=test_case.service_config_path + ) as client: - ) + try: - try: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - except: - pass - - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - await client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() - end_time = time.time() - elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + with pytest.raises(AVSServerError) as e_info: + await client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 - await client.close() @pytest.mark.parametrize( "test_case", @@ -302,7 +297,7 @@ async def test_admin_client_service_config_backoff_multiplier(host, port, userna ], ) async def test_admin_client_service_config_retryable_status_codes(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -310,21 +305,19 @@ async def test_admin_client_service_config_retryable_status_codes(host, port, us certificate_chain=certificate_chain, private_key=private_key, service_config_path=test_case.service_config_path + ) as client: - ) + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + await client.index_get_status( + namespace=test_case.namespace, + name=test_case.name, + ) - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - await client.index_get_status( - namespace=test_case.namespace, - name=test_case.name, - ) - - end_time = time.time() - elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 - await client.close() \ No newline at end of file diff --git a/tests/standard/sync/test_service_config.py b/tests/standard/sync/test_service_config.py index 864a45f5..03d39cd5 100644 --- a/tests/standard/sync/test_service_config.py +++ b/tests/standard/sync/test_service_config.py @@ -24,7 +24,7 @@ def __init__( ], ) def test_admin_client_service_config_parse(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -32,8 +32,8 @@ def test_admin_client_service_config_parse(host, port, username, password, root certificate_chain=certificate_chain, private_key=private_key, service_config_path=test_case.service_config_path - ) - client.close() + ) as client: + pass class service_config_test_case: def __init__( @@ -93,7 +93,7 @@ def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, m ], ) def test_admin_client_service_config_retries(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -101,33 +101,32 @@ def test_admin_client_service_config_retries(host, port, username, password, ro certificate_chain=certificate_chain, private_key=private_key, service_config_path=test_case.service_config_path - ) - - try: - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - except: - pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - - end_time = time.time() - elapsed_time = end_time - start_time - - assert abs(elapsed_time - expected_time) < 1.2 - client.close() + ) as client: + + try: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + + assert abs(elapsed_time - expected_time) < 1.2 @pytest.mark.parametrize( "test_case", @@ -143,7 +142,7 @@ def test_admin_client_service_config_retries(host, port, username, password, ro ], ) def test_admin_client_service_config_initial_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -152,33 +151,32 @@ def test_admin_client_service_config_initial_backoff(host, port, username, pass private_key=private_key, service_config_path=test_case.service_config_path - ) - - try: - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - except: - pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - - end_time = time.time() - elapsed_time = end_time - start_time - - assert abs(elapsed_time - expected_time) < 1.2 - client.close() + ) as client: + + try: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + + assert abs(elapsed_time - expected_time) < 1.2 @pytest.mark.parametrize( "test_case", @@ -201,7 +199,7 @@ def test_admin_client_service_config_initial_backoff(host, port, username, pass ], ) def test_admin_client_service_config_max_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -210,33 +208,32 @@ def test_admin_client_service_config_max_backoff(host, port, username, password private_key=private_key, service_config_path=test_case.service_config_path - ) + ) as client: + + try: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 - try: - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - except: - pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - - end_time = time.time() - elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 - - client.close() @pytest.mark.parametrize( "test_case", @@ -252,7 +249,7 @@ def test_admin_client_service_config_max_backoff(host, port, username, password ], ) def test_admin_client_service_config_backoff_multiplier(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -261,33 +258,32 @@ def test_admin_client_service_config_backoff_multiplier(host, port, username, p private_key=private_key, service_config_path=test_case.service_config_path - ) + ) as client: + + try: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + except: + pass + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_create( + namespace=test_case.namespace, + name=test_case.name, + vector_field=test_case.vector_field, + dimensions=test_case.dimensions, + ) + + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 - try: - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - except: - pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - client.index_create( - namespace=test_case.namespace, - name=test_case.name, - vector_field=test_case.vector_field, - dimensions=test_case.dimensions, - ) - - end_time = time.time() - elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 - - client.close() @pytest.mark.parametrize( "test_case", @@ -303,7 +299,7 @@ def test_admin_client_service_config_backoff_multiplier(host, port, username, p ], ) def test_admin_client_service_config_retryable_status_codes(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - client = AdminClient( + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -312,20 +308,19 @@ def test_admin_client_service_config_retryable_status_codes(host, port, usernam private_key=private_key, service_config_path=test_case.service_config_path - ) + ) as client: - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) - start_time = time.time() - - with pytest.raises(AVSServerError) as e_info: - client.index_get_status( - namespace=test_case.namespace, - name=test_case.name, - ) + expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + start_time = time.time() + + with pytest.raises(AVSServerError) as e_info: + client.index_get_status( + namespace=test_case.namespace, + name=test_case.name, + ) - end_time = time.time() - elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + end_time = time.time() + elapsed_time = end_time - start_time + assert abs(elapsed_time - expected_time) < 1.2 - client.close() \ No newline at end of file From f95c31bdd596045317967ddb504924a0852470a5 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:55:49 -0600 Subject: [PATCH 152/215] Fixed testing bug --- .github/workflows/integration_test.yml | 66 +++++++++++++++++++++++ tests/standard/aio/test_service_config.py | 2 +- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index fc867996..0858599b 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -522,4 +522,70 @@ jobs: python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + working-directory: tests + + + test-timeout-on-sandbox: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + - name: create config + run: | + #assets/call_gen.sh + cat aerospike-vector-search.yml + cat aerospike.conf + cat /etc/hosts + + working-directory: tests + + - name: Run unit tests + run: | + docker run -d --network=host -p 5000:5000 --name aerospike-vector-search -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf aerospike/aerospike-vector-search:0.9.0 + + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + + sleep 5 + + docker ps + python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency working-directory: tests \ No newline at end of file diff --git a/tests/standard/aio/test_service_config.py b/tests/standard/aio/test_service_config.py index f6e1ef87..8b16c817 100644 --- a/tests/standard/aio/test_service_config.py +++ b/tests/standard/aio/test_service_config.py @@ -33,7 +33,7 @@ async def test_admin_client_service_config_parse(host, port, test_case): private_key=private_key, service_config_path=test_case.service_config_path ) as client: - + pass class service_config_test_case: def __init__( self, From d664dd5313814172e12b5d1827756fa906820626 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 01:58:52 -0600 Subject: [PATCH 153/215] Change config gen permissions --- tests/assets/call_gen_mtls.sh | 0 tests/assets/call_gen_tls_auth.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tests/assets/call_gen_mtls.sh mode change 100644 => 100755 tests/assets/call_gen_tls_auth.sh diff --git a/tests/assets/call_gen_mtls.sh b/tests/assets/call_gen_mtls.sh old mode 100644 new mode 100755 diff --git a/tests/assets/call_gen_tls_auth.sh b/tests/assets/call_gen_tls_auth.sh old mode 100644 new mode 100755 From 1a0bdb41fc69b1615d4cdfff42551e14a88b3f4d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 02:03:59 -0600 Subject: [PATCH 154/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 0858599b..58c28c3e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -69,7 +69,7 @@ jobs: sleep 5 docker ps - python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --local_latency working-directory: tests test-tls: @@ -145,7 +145,7 @@ jobs: docker ps - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs docker logs aerospike-vector-search docker logs aerospike @@ -218,7 +218,7 @@ jobs: sleep 5 - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs working-directory: tests @@ -371,7 +371,7 @@ jobs: sleep 5 - python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs + python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs @@ -445,7 +445,7 @@ jobs: sleep 5 - python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs + python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs @@ -579,13 +579,8 @@ jobs: - name: Run unit tests run: | - docker run -d --network=host -p 5000:5000 --name aerospike-vector-search -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf aerospike/aerospike-vector-search:0.9.0 - - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - sleep 5 - docker ps - python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --local_latency working-directory: tests \ No newline at end of file From ef56e5d2dfeb4287dd262358e23729a0917ecead Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 08:06:44 -0600 Subject: [PATCH 155/215] Fixed testing bug --- .github/workflows/integration_test.yml | 2 +- tests/standard/aio/test_service_config.py | 24 +++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 58c28c3e..f82df1f6 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -297,7 +297,7 @@ jobs: docker ps - python -m pytest rbac -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest rbac -s --host child --port 5000 --root_certificate tls/root.crt -vs docker logs aerospike-vector-search docker logs aerospike diff --git a/tests/standard/aio/test_service_config.py b/tests/standard/aio/test_service_config.py index 8b16c817..7b8ed6b6 100644 --- a/tests/standard/aio/test_service_config.py +++ b/tests/standard/aio/test_service_config.py @@ -23,8 +23,8 @@ def __init__( ), ], ) -async def test_admin_client_service_config_parse(host, port, test_case): - with AdminClient( +async def test_admin_client_service_config_parse(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -92,7 +92,7 @@ def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, m ], ) async def test_admin_client_service_config_retries(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - with AdminClient( + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -113,7 +113,7 @@ async def test_admin_client_service_config_retries(host, port, username, passwo expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - with pytest.raises(AVSServerError) as e_info: + async with pytest.raises(AVSServerError) as e_info: await client.index_create( namespace=test_case.namespace, name=test_case.name, @@ -140,7 +140,7 @@ async def test_admin_client_service_config_retries(host, port, username, passwo ], ) async def test_admin_client_service_config_initial_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - with AdminClient( + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -163,7 +163,7 @@ async def test_admin_client_service_config_initial_backoff(host, port, username, expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - with pytest.raises(AVSServerError) as e_info: + async with pytest.raises(AVSServerError) as e_info: await client.index_create( namespace=test_case.namespace, name=test_case.name, @@ -197,7 +197,7 @@ async def test_admin_client_service_config_initial_backoff(host, port, username, ], ) async def test_admin_client_service_config_max_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - with AdminClient( + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -219,7 +219,7 @@ async def test_admin_client_service_config_max_backoff(host, port, username, pas expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - with pytest.raises(AVSServerError) as e_info: + async with pytest.raises(AVSServerError) as e_info: await client.index_create( namespace=test_case.namespace, name=test_case.name, @@ -246,7 +246,7 @@ async def test_admin_client_service_config_max_backoff(host, port, username, pas ], ) async def test_admin_client_service_config_backoff_multiplier(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - with AdminClient( + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -270,7 +270,7 @@ async def test_admin_client_service_config_backoff_multiplier(host, port, userna expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - with pytest.raises(AVSServerError) as e_info: + async with pytest.raises(AVSServerError) as e_info: await client.index_create( namespace=test_case.namespace, name=test_case.name, @@ -297,7 +297,7 @@ async def test_admin_client_service_config_backoff_multiplier(host, port, userna ], ) async def test_admin_client_service_config_retryable_status_codes(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): - with AdminClient( + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, @@ -310,7 +310,7 @@ async def test_admin_client_service_config_retryable_status_codes(host, port, us expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - with pytest.raises(AVSServerError) as e_info: + async with pytest.raises(AVSServerError) as e_info: await client.index_get_status( namespace=test_case.namespace, name=test_case.name, From 103988fb140c7b2e697746b4d43d553ebde3cac3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 08:15:01 -0600 Subject: [PATCH 156/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index f82df1f6..84ff6b94 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -218,7 +218,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs working-directory: tests @@ -371,7 +371,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs + python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs @@ -582,5 +582,5 @@ jobs: docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --local_latency + python -m pytest standard/sync -s --host 34.42.225.207 --port 5000 --local_latency working-directory: tests \ No newline at end of file From 30d87a6e79d55edf634e3e783e0df8422c263614 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 08:21:50 -0600 Subject: [PATCH 157/215] Test debugging --- .github/workflows/integration_test.yml | 2 +- src/aerospike_vector_search/aio/internal/channel_provider.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 84ff6b94..c0ee567b 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -582,5 +582,5 @@ jobs: docker ps - python -m pytest standard/sync -s --host 34.42.225.207 --port 5000 --local_latency + python -m pytest standard/sync -s --host 34.122.59.14 --port 5000 --local_latency working-directory: tests \ No newline at end of file diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index aafd5aa0..562e5cbf 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -160,8 +160,9 @@ async def _tend(self): self.current_server_version = (await stub.Get(about_request, credentials=self._token)).version self.client_server_compatible = self.verify_compatibile_server() - + print("EXECUTED HERE") self._tend_initalized.set() + print(self.client_server_compatible) # TODO: check tend interval. await asyncio.sleep(1) From e052a71943705e2abbe05516e88749cc2fb5b317 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 08:30:20 -0600 Subject: [PATCH 158/215] Fixing flaky tests --- .../retryable_status_codes.json | 5 ++++- .../sync/test_admin_client_index_get_status.py | 18 ++++++++++-------- tests/standard/sync/test_service_config.py | 2 ++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/service_configs/retryable_status_codes.json b/tests/service_configs/retryable_status_codes.json index c9b13153..523b9e32 100644 --- a/tests/service_configs/retryable_status_codes.json +++ b/tests/service_configs/retryable_status_codes.json @@ -2,7 +2,10 @@ "methodConfig": [ { "name": [ - {} + { + "service": "aerospike.vector.IndexService", + "method": "GetStatus" + } ], "retryPolicy": { "maxAttempts": 2, diff --git a/tests/standard/sync/test_admin_client_index_get_status.py b/tests/standard/sync/test_admin_client_index_get_status.py index 52a31da5..c185bdc3 100644 --- a/tests/standard/sync/test_admin_client_index_get_status.py +++ b/tests/standard/sync/test_admin_client_index_get_status.py @@ -12,14 +12,16 @@ @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) def test_index_get_status(session_admin_client, empty_test_case, random_name): - - session_admin_client.index_create( - namespace="test", - name=random_name, - vector_field="science", - dimensions=1024, - ) - + try: + session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="science", + dimensions=1024, + ) + except AVSServerError as se: + if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: + raise se result = session_admin_client.index_get_status( namespace="test", name=random_name ) diff --git a/tests/standard/sync/test_service_config.py b/tests/standard/sync/test_service_config.py index 03d39cd5..ecd24756 100644 --- a/tests/standard/sync/test_service_config.py +++ b/tests/standard/sync/test_service_config.py @@ -318,6 +318,8 @@ def test_admin_client_service_config_retryable_status_codes(host, port, usernam namespace=test_case.namespace, name=test_case.name, ) + + print(e_info.value.rpc_error.code()) end_time = time.time() elapsed_time = end_time - start_time From 84f37ff7b0367f2743ebec4005b852db99e66487 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 08:32:01 -0600 Subject: [PATCH 159/215] Update admin.py --- src/aerospike_vector_search/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index 2d7074a9..bfdb224a 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -260,7 +260,7 @@ def index_get_status(self, *, namespace: str, name: str, timeout: Optional[int] kwargs['timeout'] = timeout try: - response = index_stub.GetStatus(index_get_status_request, **kwargs) + response = index_stub.GetStatus(index_get_status_request, credentials=self._channel_provider._token, **kwargs) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) From 1578d8000b4d1477e25dd749dc30be7be0022f06 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 09:37:00 -0600 Subject: [PATCH 160/215] Update test_vector_search.py --- tests/standard/sync/test_vector_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index 3c9bca5b..c63f5743 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -96,7 +96,7 @@ def vector_search_ef_80(client, vector): query=vector, limit=100, field_names=["unit_test"], - search_params=types.HnswSearchParams(ef=80), + search_params=types.HnswSearchParams(ef=80) ) return result From 93396a14e60e5a9da4140e2a05b9c67c95ff0462 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 09:39:51 -0600 Subject: [PATCH 161/215] Debugging hanging tests --- .github/workflows/integration_test.yml | 6 +++--- .../aio/internal/channel_provider.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c0ee567b..1a319bc9 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -371,7 +371,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs + python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs @@ -445,7 +445,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs + python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs @@ -582,5 +582,5 @@ jobs: docker ps - python -m pytest standard/sync -s --host 34.122.59.14 --port 5000 --local_latency + python -m pytest standard -s --host 34.122.59.14 --port 5000 --local_latency working-directory: tests \ No newline at end of file diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 562e5cbf..0285b4e0 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -67,7 +67,7 @@ async def _is_ready(self): async def _tend(self): try: (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() - + print("\n\n\n TEND HERE \n\n\n") if self._token: if self._check_if_token_refresh_needed(): await self._update_token_and_ttl() From a6d033e06bef01a5c25f25a00a23ded5a3bb290e Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 09:42:38 -0600 Subject: [PATCH 162/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 1a319bc9..b372038d 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -69,7 +69,7 @@ jobs: sleep 5 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --local_latency + python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency working-directory: tests test-tls: @@ -145,7 +145,7 @@ jobs: docker ps - python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs docker logs aerospike-vector-search docker logs aerospike @@ -218,7 +218,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs working-directory: tests @@ -582,5 +582,5 @@ jobs: docker ps - python -m pytest standard -s --host 34.122.59.14 --port 5000 --local_latency + python -m pytest standard -s --host 34.42.225.207 --port 5000 --local_latency working-directory: tests \ No newline at end of file From 5719f478b9997472e61494d6cb5f1554c2dcde1d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 09:46:05 -0600 Subject: [PATCH 163/215] Update channel_provider.py --- src/aerospike_vector_search/aio/internal/channel_provider.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 0285b4e0..5805df69 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -38,6 +38,7 @@ def __init__( super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path) + print("\n\n\n BEFORE TEND \n\n\n") self._tend_initalized: asyncio.Event = asyncio.Event() self._tend_ended: asyncio.Event = asyncio.Event() self._task: Optional[asyncio.Task] = None From 4a25454dc2eb5de2499f4efca1d9b32454d411f8 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 09:48:06 -0600 Subject: [PATCH 164/215] Update channel_provider.py --- src/aerospike_vector_search/aio/internal/channel_provider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 5805df69..e93266c1 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -35,10 +35,10 @@ def __init__( service_config_path: Optional[str] = None, ) -> None: + print("\n\n\n BEFORE TEND \n\n\n") super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path) - print("\n\n\n BEFORE TEND \n\n\n") self._tend_initalized: asyncio.Event = asyncio.Event() self._tend_ended: asyncio.Event = asyncio.Event() self._task: Optional[asyncio.Task] = None From ca4925ce9b56ca05a83abaa71554d9b47d0d7919 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 09:51:11 -0600 Subject: [PATCH 165/215] Update conftest.py --- tests/standard/aio/conftest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/standard/aio/conftest.py b/tests/standard/aio/conftest.py index 94e43f5a..4c941132 100644 --- a/tests/standard/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -6,10 +6,13 @@ @pytest.fixture(scope="module", autouse=True) async def drop_all_indexes(host, port, username, password, root_certificate, certificate_chain, private_key): + print("\n\n\n BEFORE EXE \n\n\n") + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: + print("\n\n\n YOOOOOOOO") index_list = await client.index_list() tasks = [] From 16ac2fdf544b97cb4069e1a7a312d9fbfe5e0ce3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 09:53:20 -0600 Subject: [PATCH 166/215] Update conftest.py --- tests/standard/aio/conftest.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/standard/aio/conftest.py b/tests/standard/aio/conftest.py index 4c941132..58cced6f 100644 --- a/tests/standard/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -25,6 +25,8 @@ async def drop_all_indexes(host, port, username, password, root_certificate, cer @pytest.fixture(scope="module") async def session_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key): + print("\n\n\n BEFORE EXE \n\n\n") + client = AdminClient( seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password ) @@ -33,6 +35,8 @@ async def session_admin_client(host, port, username, password, root_certificate, @pytest.fixture(scope="module") async def session_vector_client(host, port, username, password, root_certificate, certificate_chain, private_key): + print("\n\n\n BEFORE EXE \n\n\n") + client = Client( seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password ) @@ -41,6 +45,8 @@ async def session_vector_client(host, port, username, password, root_certificate @pytest.fixture async def function_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key): + print("\n\n\n BEFORE EXE \n\n\n") + client = AdminClient( seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password ) From 6f0cfcd2063f0365e3e60706c03fff038bff5b2c Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Fri, 19 Jul 2024 10:01:11 -0600 Subject: [PATCH 167/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index b372038d..0cf32917 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -145,7 +145,7 @@ jobs: docker ps - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest standard/aio -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs docker logs aerospike-vector-search docker logs aerospike @@ -218,7 +218,7 @@ jobs: sleep 5 - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs + python -m pytest standard/aio -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs working-directory: tests @@ -371,7 +371,7 @@ jobs: sleep 5 - python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs + python -m pytest standard/aio -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs From 463b28e9201897153fa94234aa30c18c2987e94b Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 21:09:20 -0600 Subject: [PATCH 168/215] Fixing flaky tests --- .github/workflows/integration_test.yml | 6 +++--- pyproject.toml | 2 +- .../aio/internal/channel_provider.py | 4 ---- .../shared/client_helpers.py | 6 ++---- tests/standard/aio/conftest.py | 5 ----- .../aio/test_admin_client_index_get_status.py | 1 - tests/standard/aio/test_service_config.py | 10 +++++----- tests/standard/sync/test_service_config.py | 2 -- tests/standard/sync/test_vector_search.py | 20 +++++++++++++++---- 9 files changed, 27 insertions(+), 29 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 0cf32917..b372038d 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -145,7 +145,7 @@ jobs: docker ps - python -m pytest standard/aio -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs docker logs aerospike-vector-search docker logs aerospike @@ -218,7 +218,7 @@ jobs: sleep 5 - python -m pytest standard/aio -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs working-directory: tests @@ -371,7 +371,7 @@ jobs: sleep 5 - python -m pytest standard/aio -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs + python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs diff --git a/pyproject.toml b/pyproject.toml index 3354f56b..afad321e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Topic :: Database" ] -version = "1.0.0.dev4" +version = "1.0.0.dev5" requires-python = ">3.8" dependencies = [ "grpcio == 1.64.1", diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index e93266c1..8af94ad0 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -35,7 +35,6 @@ def __init__( service_config_path: Optional[str] = None, ) -> None: - print("\n\n\n BEFORE TEND \n\n\n") super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path) @@ -68,7 +67,6 @@ async def _is_ready(self): async def _tend(self): try: (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() - print("\n\n\n TEND HERE \n\n\n") if self._token: if self._check_if_token_refresh_needed(): await self._update_token_and_ttl() @@ -161,9 +159,7 @@ async def _tend(self): self.current_server_version = (await stub.Get(about_request, credentials=self._token)).version self.client_server_compatible = self.verify_compatibile_server() - print("EXECUTED HERE") self._tend_initalized.set() - print(self.client_server_compatible) # TODO: check tend interval. await asyncio.sleep(1) diff --git a/src/aerospike_vector_search/shared/client_helpers.py b/src/aerospike_vector_search/shared/client_helpers.py index 9dc56be0..bda5707a 100644 --- a/src/aerospike_vector_search/shared/client_helpers.py +++ b/src/aerospike_vector_search/shared/client_helpers.py @@ -252,15 +252,13 @@ def _get_key( self, namespace: str, set: str, key: Union[int, str, bytes, bytearray] ): if isinstance(key, str): - key = types_pb2.Key(namespace=namespace, set=None, stringValue=key) - - + key = types_pb2.Key(namespace=namespace, set=set, stringValue=key) elif isinstance(key, int): key = types_pb2.Key(namespace=namespace, set=set, longValue=key) elif isinstance(key, (bytes, bytearray)): key = types_pb2.Key(namespace=namespace, set=set, bytesValue=key) else: - raise Exception("Invalid key type" + type(key)) + raise Exception("Invalid key type" + str(type(key))) return key def _prepare_wait_for_index_waiting(self, namespace, name, wait_interval): diff --git a/tests/standard/aio/conftest.py b/tests/standard/aio/conftest.py index 58cced6f..01732b5e 100644 --- a/tests/standard/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -6,13 +6,11 @@ @pytest.fixture(scope="module", autouse=True) async def drop_all_indexes(host, port, username, password, root_certificate, certificate_chain, private_key): - print("\n\n\n BEFORE EXE \n\n\n") async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: - print("\n\n\n YOOOOOOOO") index_list = await client.index_list() tasks = [] @@ -25,7 +23,6 @@ async def drop_all_indexes(host, port, username, password, root_certificate, cer @pytest.fixture(scope="module") async def session_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key): - print("\n\n\n BEFORE EXE \n\n\n") client = AdminClient( seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password @@ -35,7 +32,6 @@ async def session_admin_client(host, port, username, password, root_certificate, @pytest.fixture(scope="module") async def session_vector_client(host, port, username, password, root_certificate, certificate_chain, private_key): - print("\n\n\n BEFORE EXE \n\n\n") client = Client( seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password @@ -45,7 +41,6 @@ async def session_vector_client(host, port, username, password, root_certificate @pytest.fixture async def function_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key): - print("\n\n\n BEFORE EXE \n\n\n") client = AdminClient( seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password diff --git a/tests/standard/aio/test_admin_client_index_get_status.py b/tests/standard/aio/test_admin_client_index_get_status.py index 52f34632..c0a750eb 100644 --- a/tests/standard/aio/test_admin_client_index_get_status.py +++ b/tests/standard/aio/test_admin_client_index_get_status.py @@ -46,7 +46,6 @@ async def test_index_get_status_timeout(session_admin_client, empty_test_case, r namespace="test", name=random_name, timeout=0.0001 ) except AVSServerError as se: - print(se.rpc_error.code()) if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return diff --git a/tests/standard/aio/test_service_config.py b/tests/standard/aio/test_service_config.py index 7b8ed6b6..f30eeee9 100644 --- a/tests/standard/aio/test_service_config.py +++ b/tests/standard/aio/test_service_config.py @@ -113,7 +113,7 @@ async def test_admin_client_service_config_retries(host, port, username, passwo expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - async with pytest.raises(AVSServerError) as e_info: + with pytest.raises(AVSServerError) as e_info: await client.index_create( namespace=test_case.namespace, name=test_case.name, @@ -163,7 +163,7 @@ async def test_admin_client_service_config_initial_backoff(host, port, username, expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - async with pytest.raises(AVSServerError) as e_info: + with pytest.raises(AVSServerError) as e_info: await client.index_create( namespace=test_case.namespace, name=test_case.name, @@ -219,7 +219,7 @@ async def test_admin_client_service_config_max_backoff(host, port, username, pas expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - async with pytest.raises(AVSServerError) as e_info: + with pytest.raises(AVSServerError) as e_info: await client.index_create( namespace=test_case.namespace, name=test_case.name, @@ -270,7 +270,7 @@ async def test_admin_client_service_config_backoff_multiplier(host, port, userna expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - async with pytest.raises(AVSServerError) as e_info: + with pytest.raises(AVSServerError) as e_info: await client.index_create( namespace=test_case.namespace, name=test_case.name, @@ -310,7 +310,7 @@ async def test_admin_client_service_config_retryable_status_codes(host, port, us expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) start_time = time.time() - async with pytest.raises(AVSServerError) as e_info: + with pytest.raises(AVSServerError) as e_info: await client.index_get_status( namespace=test_case.namespace, name=test_case.name, diff --git a/tests/standard/sync/test_service_config.py b/tests/standard/sync/test_service_config.py index ecd24756..990578b1 100644 --- a/tests/standard/sync/test_service_config.py +++ b/tests/standard/sync/test_service_config.py @@ -319,8 +319,6 @@ def test_admin_client_service_config_retryable_status_codes(host, port, usernam name=test_case.name, ) - print(e_info.value.rpc_error.code()) - end_time = time.time() elapsed_time = end_time - start_time assert abs(elapsed_time - expected_time) < 1.2 diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index c63f5743..568ca1dd 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -70,12 +70,12 @@ def query_numpy(): def put_vector(client, vector, j): client.upsert( - namespace="test", key=str(j), record_data={"unit_test": vector} + namespace="test", key=str(j), record_data={"unit_test": vector}, set_name="demo" ) def get_vector(client, j): - result = client.get(namespace="test", key=str(j)) + result = client.get(namespace="test", key=str(j), set_name="demo") def vector_search(client, vector): @@ -113,12 +113,18 @@ def test_vector_search( name="demo", vector_field="unit_test", dimensions=128, + sets="demo" ) # Put base vectors for search for j, vector in enumerate(base_numpy): put_vector(session_vector_client, vector, j) + + # Put base vectors for search + for j, vector in enumerate(base_numpy): + get_vector(session_vector_client, j) + session_vector_client.wait_for_index_completion(namespace='test', name='demo') @@ -165,11 +171,17 @@ def test_vector_search( def test_vector_is_indexed(session_vector_client, session_admin_client): + val = random.randrange(10_000) + + result = session_vector_client.is_indexed( namespace="test", - key="" + str(random.randrange(10_000)), + key=str(val), index_name="demo", + set_name="demo" ) + + assert result is True def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, local_latency): @@ -180,7 +192,7 @@ def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, try: result = session_vector_client.is_indexed( namespace="test", - key="" + str(random.randrange(10_000)), + key=500, index_name="demo", timeout=0.0001 ) From 0f164a72dc2e80053679d34b900f91adde5b5d04 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 21:40:50 -0600 Subject: [PATCH 169/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 850 ++++++++++++------------- 1 file changed, 425 insertions(+), 425 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index b372038d..12cb896c 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -7,149 +7,149 @@ on: - dev jobs: - test-normal: - runs-on: ubuntu-24.04 - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - name: create config - run: | - #assets/call_gen.sh - cat aerospike-vector-search.yml - cat aerospike.conf - cat /etc/hosts - - working-directory: tests - - - name: Run unit tests - run: | - docker run -d --network=host -p 5000:5000 --name aerospike-vector-search -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf aerospike/aerospike-vector-search:0.9.0 - - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - - sleep 5 - - docker ps - python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency - working-directory: tests - - test-tls: - runs-on: ubuntu-24.04 - continue-on-error: true - - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - - name: Set up RANDFILE environment variable - run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV - - - name: Create .rnd file if it doesn't exist - run: touch $HOME/.rnd - - - name: create config - run: | - assets/call_gen_tls.sh - cat aerospike-vector-search.yml - cat aerospike.conf - cat /etc/hosts - working-directory: tests - - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts - - - name: Run unit tests - run: | - - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - sleep 5 - - - - docker ps - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs - - docker logs aerospike-vector-search - docker logs aerospike - working-directory: tests +# test-normal: +# runs-on: ubuntu-24.04 +# continue-on-error: true +# +# +# strategy: +# matrix: +# python-version: ["3.9", "3.10", "3.11", "3.12"] +# +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v3 +# +# - name: Set up Python +# uses: actions/setup-python@v2 +# with: +# python-version: ${{ matrix.python-version }} +# +# +# - name: Install dependencies +# run: | +# python -m pip install --upgrade pip +# python setup.py +# pip install -r requirements.txt +# +# working-directory: tests +# +# +# - name: Retrieve the secret and decode it to a file +# env: +# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} +# run: | +# echo $FEATURE_FILE | base64 --decode > features.conf +# working-directory: tests +# +# - name: Docker Login +# uses: docker/login-action@v2 +# with: +# registry: aerospike.jfrog.io +# username: ${{ secrets.JFROG_USERNAME }} +# password: ${{ secrets.JFROG_PASSWORD }} +# +# - name: create config +# run: | +# #assets/call_gen.sh +# cat aerospike-vector-search.yml +# cat aerospike.conf +# cat /etc/hosts +# +# working-directory: tests +# +# - name: Run unit tests +# run: | +# docker run -d --network=host -p 5000:5000 --name aerospike-vector-search -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf aerospike/aerospike-vector-search:0.9.0 +# +# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest +# +# +# sleep 5 +# +# docker ps +# python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency +# working-directory: tests +# +# test-tls: +# runs-on: ubuntu-24.04 +# continue-on-error: true +# +# +# +# strategy: +# matrix: +# python-version: ["3.9", "3.10", "3.11", "3.12"] +# +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v3 +# +# - name: Set up Python +# uses: actions/setup-python@v2 +# with: +# python-version: ${{ matrix.python-version }} +# +# +# - name: Install dependencies +# run: | +# python -m pip install --upgrade pip +# python setup.py +# pip install -r requirements.txt +# working-directory: tests +# +# +# - name: Retrieve the secret and decode it to a file +# env: +# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} +# run: | +# echo $FEATURE_FILE | base64 --decode > features.conf +# working-directory: tests +# +# - name: Docker Login +# uses: docker/login-action@v2 +# with: +# registry: aerospike.jfrog.io +# username: ${{ secrets.JFROG_USERNAME }} +# password: ${{ secrets.JFROG_PASSWORD }} +# +# +# - name: Set up RANDFILE environment variable +# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV +# +# - name: Create .rnd file if it doesn't exist +# run: touch $HOME/.rnd +# +# - name: create config +# run: | +# assets/call_gen_tls.sh +# cat aerospike-vector-search.yml +# cat aerospike.conf +# cat /etc/hosts +# working-directory: tests +# +# - name: Add hosts to /etc/hosts +# run: | +# sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts +# +# - name: Run unit tests +# run: | +# +# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 +# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest +# +# sleep 5 +# +# +# +# docker ps +# python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs +# +# docker logs aerospike-vector-search +# docker logs aerospike +# working-directory: tests test-tls-auth: runs-on: ubuntu-24.04 @@ -218,7 +218,7 @@ jobs: sleep 5 - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs + python -m pytest standard/aio -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs working-directory: tests @@ -297,290 +297,290 @@ jobs: docker ps - python -m pytest rbac -s --host child --port 5000 --root_certificate tls/root.crt -vs + python -m pytest rbac/aio -s --host child --port 5000 --root_certificate tls/root.crt -vs docker logs aerospike-vector-search docker logs aerospike working-directory: tests - test-mtls: - runs-on: ubuntu-24.04 - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - - name: Set up RANDFILE environment variable - run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV - - - name: Create .rnd file if it doesn't exist - run: touch $HOME/.rnd - - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - - - name: create config - run: | - assets/call_gen_mtls.sh - cat /etc/hosts - working-directory: tests - - - name: Run unit tests - run: | - - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - sleep 5 - - python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs - - - - working-directory: tests - - - test-mtls-auth: - runs-on: ubuntu-24.04 - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - - name: Set up RANDFILE environment variable - run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV - - - name: Create .rnd file if it doesn't exist - run: touch $HOME/.rnd - - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - - - name: create config - run: | - assets/call_gen_mtls_auth.sh - cat /etc/hosts - working-directory: tests - - - name: Run unit tests - run: | - - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - sleep 5 - - python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs - - - - working-directory: tests - - - test-mtls-auth-rbac: - runs-on: ubuntu-24.04 - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - - name: Set up RANDFILE environment variable - run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV - - - name: Create .rnd file if it doesn't exist - run: touch $HOME/.rnd - - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - - - name: create config - run: | - assets/call_gen_mtls_auth.sh - cat /etc/hosts - working-directory: tests - - - name: Run unit tests - run: | - - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - sleep 5 - - python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs - - - working-directory: tests - - - test-timeout-on-sandbox: - runs-on: ubuntu-24.04 - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - name: create config - run: | - #assets/call_gen.sh - cat aerospike-vector-search.yml - cat aerospike.conf - cat /etc/hosts - - working-directory: tests - - - name: Run unit tests - run: | - - - docker ps - python -m pytest standard -s --host 34.42.225.207 --port 5000 --local_latency - working-directory: tests \ No newline at end of file +# test-mtls: +# runs-on: ubuntu-24.04 +# continue-on-error: true +# +# +# strategy: +# matrix: +# python-version: ["3.9", "3.10", "3.11", "3.12"] +# +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v3 +# +# - name: Set up Python +# uses: actions/setup-python@v2 +# with: +# python-version: ${{ matrix.python-version }} +# +# +# - name: Install dependencies +# run: | +# python -m pip install --upgrade pip +# python setup.py +# pip install -r requirements.txt +# working-directory: tests +# +# +# - name: Retrieve the secret and decode it to a file +# env: +# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} +# run: | +# echo $FEATURE_FILE | base64 --decode > features.conf +# working-directory: tests +# +# - name: Docker Login +# uses: docker/login-action@v2 +# with: +# registry: aerospike.jfrog.io +# username: ${{ secrets.JFROG_USERNAME }} +# password: ${{ secrets.JFROG_PASSWORD }} +# +# +# - name: Set up RANDFILE environment variable +# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV +# +# - name: Create .rnd file if it doesn't exist +# run: touch $HOME/.rnd +# +# - name: Add hosts to /etc/hosts +# run: | +# sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts +# +# - name: create config +# run: | +# assets/call_gen_mtls.sh +# cat /etc/hosts +# working-directory: tests +# +# - name: Run unit tests +# run: | +# +# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 +# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest +# +# sleep 5 +# +# python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs +# +# +# +# working-directory: tests +# +# +# test-mtls-auth: +# runs-on: ubuntu-24.04 +# continue-on-error: true +# +# +# strategy: +# matrix: +# python-version: ["3.9", "3.10", "3.11", "3.12"] +# +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v3 +# +# - name: Set up Python +# uses: actions/setup-python@v2 +# with: +# python-version: ${{ matrix.python-version }} +# +# +# - name: Install dependencies +# run: | +# python -m pip install --upgrade pip +# python setup.py +# pip install -r requirements.txt +# working-directory: tests +# +# +# - name: Retrieve the secret and decode it to a file +# env: +# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} +# run: | +# echo $FEATURE_FILE | base64 --decode > features.conf +# working-directory: tests +# +# - name: Docker Login +# uses: docker/login-action@v2 +# with: +# registry: aerospike.jfrog.io +# username: ${{ secrets.JFROG_USERNAME }} +# password: ${{ secrets.JFROG_PASSWORD }} +# +# +# - name: Set up RANDFILE environment variable +# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV +# +# - name: Create .rnd file if it doesn't exist +# run: touch $HOME/.rnd +# +# - name: Add hosts to /etc/hosts +# run: | +# sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts +# +# - name: create config +# run: | +# assets/call_gen_mtls_auth.sh +# cat /etc/hosts +# working-directory: tests +# +# - name: Run unit tests +# run: | +# +# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 +# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest +# +# sleep 5 +# +# python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs +# +# +# +# working-directory: tests +# +# +# test-mtls-auth-rbac: +# runs-on: ubuntu-24.04 +# continue-on-error: true +# +# +# strategy: +# matrix: +# python-version: ["3.9", "3.10", "3.11", "3.12"] +# +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v3 +# +# - name: Set up Python +# uses: actions/setup-python@v2 +# with: +# python-version: ${{ matrix.python-version }} +# +# +# - name: Install dependencies +# run: | +# python -m pip install --upgrade pip +# python setup.py +# pip install -r requirements.txt +# working-directory: tests +# +# +# - name: Retrieve the secret and decode it to a file +# env: +# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} +# run: | +# echo $FEATURE_FILE | base64 --decode > features.conf +# working-directory: tests +# +# - name: Docker Login +# uses: docker/login-action@v2 +# with: +# registry: aerospike.jfrog.io +# username: ${{ secrets.JFROG_USERNAME }} +# password: ${{ secrets.JFROG_PASSWORD }} +# +# +# - name: Set up RANDFILE environment variable +# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV +# +# - name: Create .rnd file if it doesn't exist +# run: touch $HOME/.rnd +# +# - name: Add hosts to /etc/hosts +# run: | +# sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts +# +# - name: create config +# run: | +# assets/call_gen_mtls_auth.sh +# cat /etc/hosts +# working-directory: tests +# +# - name: Run unit tests +# run: | +# +# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 +# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest +# +# sleep 5 +# +# python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs +# +# +# working-directory: tests +# +# +# test-timeout-on-sandbox: +# runs-on: ubuntu-24.04 +# continue-on-error: true +# +# +# strategy: +# matrix: +# python-version: ["3.9", "3.10", "3.11", "3.12"] +# +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v3 +# +# - name: Set up Python +# uses: actions/setup-python@v2 +# with: +# python-version: ${{ matrix.python-version }} +# +# +# - name: Install dependencies +# run: | +# python -m pip install --upgrade pip +# python setup.py +# pip install -r requirements.txt +# +# working-directory: tests +# +# +# - name: Retrieve the secret and decode it to a file +# env: +# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} +# run: | +# echo $FEATURE_FILE | base64 --decode > features.conf +# working-directory: tests +# +# - name: Docker Login +# uses: docker/login-action@v2 +# with: +# registry: aerospike.jfrog.io +# username: ${{ secrets.JFROG_USERNAME }} +# password: ${{ secrets.JFROG_PASSWORD }} +# +# - name: create config +# run: | +# #assets/call_gen.sh +# cat aerospike-vector-search.yml +# cat aerospike.conf +# cat /etc/hosts +# +# working-directory: tests +# +# - name: Run unit tests +# run: | +# +# +# docker ps +# python -m pytest standard -s --host 34.42.225.207 --port 5000 --local_latency +# working-directory: tests \ No newline at end of file From 7efbba4997e90fc37d56fce0abe723f012424b6b Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 21:42:46 -0600 Subject: [PATCH 170/215] Update admin.py --- src/aerospike_vector_search/aio/admin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index e8b3b322..99765387 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -43,6 +43,7 @@ def __init__( Exception: Raised when no seed host is provided. """ + print("\n\n\n\n THIS IS RUNNING AT ALL\n\n\n") seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( From f551ac9a006b7d6b7c67801b35ec93cccbbed006 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 21:49:22 -0600 Subject: [PATCH 171/215] Update client.py --- src/aerospike_vector_search/aio/client.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index a7167600..1e156570 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -48,6 +48,8 @@ def __init__( Raises: Exception: Raised when no seed host is provided. """ + print("\n\n\n\n THIS IS RUNNING AT ALL\n\n\n") + seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path From 737d4a63e065cf8638bf693e618b526c87a3495b Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 21:55:49 -0600 Subject: [PATCH 172/215] Update conftest.py --- tests/rbac/aio/conftest.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/rbac/aio/conftest.py b/tests/rbac/aio/conftest.py index dad08115..a41921df 100644 --- a/tests/rbac/aio/conftest.py +++ b/tests/rbac/aio/conftest.py @@ -27,6 +27,7 @@ def certificate_chain(request): @pytest.fixture(scope="module", autouse=True) async def drop_all_indexes(username, password, host, port, root_certificate, certificate_chain, private_key): + print("\n\n\n\n MADE IT TO FUNCTION") async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: @@ -40,6 +41,7 @@ async def drop_all_indexes(username, password, host, port, root_certificate, cer @pytest.fixture(scope="module") async def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): + print("\n\n\n\n MADE IT TO FUNCTION") client = AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) From cda50f955385c347bdc61ed2605e0537fcb9dbbe Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:04:44 -0600 Subject: [PATCH 173/215] Flaky tests --- .github/workflows/integration_test.yml | 4 ++-- tests/requirements.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 12cb896c..ae7c834e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -218,7 +218,7 @@ jobs: sleep 5 - python -m pytest standard/aio -s --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency -vs + python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency working-directory: tests @@ -297,7 +297,7 @@ jobs: docker ps - python -m pytest rbac/aio -s --host child --port 5000 --root_certificate tls/root.crt -vs + python -m pytest rbac/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt docker logs aerospike-vector-search docker logs aerospike diff --git a/tests/requirements.txt b/tests/requirements.txt index c8defcde..32083971 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,6 +1,7 @@ numpy==1.26.4 pytest==7.4.0 pytest-aio==1.5.0 +pytest-timeout pyjwt hypothesis .. \ No newline at end of file From 75e0eb7f23ad8184ac817f1b5b205d8e9051e8f8 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:08:45 -0600 Subject: [PATCH 174/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index ae7c834e..db9c345e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -218,7 +218,7 @@ jobs: sleep 5 - python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency + python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency --timeout=30 working-directory: tests @@ -297,7 +297,7 @@ jobs: docker ps - python -m pytest rbac/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt + python -m pytest rbac/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --timeout=30 docker logs aerospike-vector-search docker logs aerospike From e694370a440c96199ff08f3ff94158f12e5981a4 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:14:31 -0600 Subject: [PATCH 175/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 148 ++++++++++++------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index db9c345e..f913b30a 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -150,79 +150,79 @@ jobs: # docker logs aerospike-vector-search # docker logs aerospike # working-directory: tests - - test-tls-auth: - runs-on: ubuntu-24.04 - continue-on-error: true - - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - - name: Set up RANDFILE environment variable - run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV - - - name: Create .rnd file if it doesn't exist - run: touch $HOME/.rnd - - - name: create config - run: | - assets/call_gen_tls_auth.sh - working-directory: tests - - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts - - - name: Run unit tests - run: | - - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - sleep 5 - - python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency --timeout=30 - - - working-directory: tests - +# +# test-tls-auth: +# runs-on: ubuntu-24.04 +# continue-on-error: true +# +# +# +# strategy: +# matrix: +# python-version: ["3.9", "3.10", "3.11", "3.12"] +# +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v3 +# +# - name: Set up Python +# uses: actions/setup-python@v2 +# with: +# python-version: ${{ matrix.python-version }} +# +# +# - name: Install dependencies +# run: | +# python -m pip install --upgrade pip +# python setup.py +# pip install -r requirements.txt +# working-directory: tests +# +# +# - name: Retrieve the secret and decode it to a file +# env: +# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} +# run: | +# echo $FEATURE_FILE | base64 --decode > features.conf +# working-directory: tests +# +# - name: Docker Login +# uses: docker/login-action@v2 +# with: +# registry: aerospike.jfrog.io +# username: ${{ secrets.JFROG_USERNAME }} +# password: ${{ secrets.JFROG_PASSWORD }} +# +# +# - name: Set up RANDFILE environment variable +# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV +# +# - name: Create .rnd file if it doesn't exist +# run: touch $HOME/.rnd +# +# - name: create config +# run: | +# assets/call_gen_tls_auth.sh +# working-directory: tests +# +# - name: Add hosts to /etc/hosts +# run: | +# sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts +# +# - name: Run unit tests +# run: | +# +# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 +# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest +# +# sleep 5 +# +# python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency --timeout=30 +# +# +# working-directory: tests +# test-tls-auth-rbac: runs-on: ubuntu-24.04 @@ -297,7 +297,7 @@ jobs: docker ps - python -m pytest rbac/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --timeout=30 + python -m pytest rbac/aio/test_admin_client_add_user.py -s -vv --host child --port 5000 --root_certificate tls/root.crt --timeout=30 docker logs aerospike-vector-search docker logs aerospike From 68b55d9a109ab1d7cf0cfb87fc2295ad66df0205 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:17:38 -0600 Subject: [PATCH 176/215] Flaky tests --- .github/workflows/integration_test.yml | 2 +- tests/rbac/aio/debug.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 tests/rbac/aio/debug.py diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index f913b30a..5eeb7378 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -297,7 +297,7 @@ jobs: docker ps - python -m pytest rbac/aio/test_admin_client_add_user.py -s -vv --host child --port 5000 --root_certificate tls/root.crt --timeout=30 + python -m pytest rbac/aio/debug.py -s -vv --host child --port 5000 --root_certificate tls/root.crt --timeout=30 docker logs aerospike-vector-search docker logs aerospike diff --git a/tests/rbac/aio/debug.py b/tests/rbac/aio/debug.py new file mode 100644 index 00000000..042f5c37 --- /dev/null +++ b/tests/rbac/aio/debug.py @@ -0,0 +1,5 @@ +import pytest + +@pytest.mark.parametrize("test_case", []) +async def test_add_user(session_rbac_admin_client, test_case): + pass \ No newline at end of file From 231ad93ea8a3b37f759f95abb55ccc8692020ef3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:23:13 -0600 Subject: [PATCH 177/215] Update debug.py --- tests/rbac/aio/debug.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rbac/aio/debug.py b/tests/rbac/aio/debug.py index 042f5c37..a6da1fe0 100644 --- a/tests/rbac/aio/debug.py +++ b/tests/rbac/aio/debug.py @@ -2,4 +2,4 @@ @pytest.mark.parametrize("test_case", []) async def test_add_user(session_rbac_admin_client, test_case): - pass \ No newline at end of file + print("YO") \ No newline at end of file From f4c81dfe4326422cb0a9224f34f09d7bfd14b4b6 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:27:35 -0600 Subject: [PATCH 178/215] Everything right --- tests/rbac/aio/debug.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/rbac/aio/debug.py b/tests/rbac/aio/debug.py index a6da1fe0..00125653 100644 --- a/tests/rbac/aio/debug.py +++ b/tests/rbac/aio/debug.py @@ -1,5 +1,13 @@ import pytest +import pytest +from ...utils import random_int @pytest.mark.parametrize("test_case", []) async def test_add_user(session_rbac_admin_client, test_case): - print("YO") \ No newline at end of file + await session_rbac_admin_client.add_user( + username="admin", + password="admin", + roles=None + + ) + assert 1 == 1 \ No newline at end of file From 5a2e50725fdd24c883612ff3792aac2771feca73 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:29:05 -0600 Subject: [PATCH 179/215] Update debug.py --- tests/rbac/aio/debug.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rbac/aio/debug.py b/tests/rbac/aio/debug.py index 00125653..eec3f9ca 100644 --- a/tests/rbac/aio/debug.py +++ b/tests/rbac/aio/debug.py @@ -3,7 +3,7 @@ from ...utils import random_int @pytest.mark.parametrize("test_case", []) -async def test_add_user(session_rbac_admin_client, test_case): +async def test_add_user(session_rbac_admin_client): await session_rbac_admin_client.add_user( username="admin", password="admin", From 0179920a64917452259a4177ca2de35a28308638 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:31:51 -0600 Subject: [PATCH 180/215] Update debug.py --- tests/rbac/aio/debug.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/rbac/aio/debug.py b/tests/rbac/aio/debug.py index eec3f9ca..20bfc382 100644 --- a/tests/rbac/aio/debug.py +++ b/tests/rbac/aio/debug.py @@ -2,7 +2,6 @@ import pytest from ...utils import random_int -@pytest.mark.parametrize("test_case", []) async def test_add_user(session_rbac_admin_client): await session_rbac_admin_client.add_user( username="admin", From 80322a61213425579615d4b277f8d696f02d6c6d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:33:40 -0600 Subject: [PATCH 181/215] Update debug.py --- tests/rbac/aio/debug.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rbac/aio/debug.py b/tests/rbac/aio/debug.py index 20bfc382..f0ca9965 100644 --- a/tests/rbac/aio/debug.py +++ b/tests/rbac/aio/debug.py @@ -1,8 +1,8 @@ import pytest -import pytest from ...utils import random_int async def test_add_user(session_rbac_admin_client): + print("WE ARE IN THIS") await session_rbac_admin_client.add_user( username="admin", password="admin", From 45cf74c81ad4e544823ff009b522d9acab2ef7b6 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:36:50 -0600 Subject: [PATCH 182/215] Update conftest.py --- tests/rbac/aio/conftest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/rbac/aio/conftest.py b/tests/rbac/aio/conftest.py index a41921df..1ca59d6d 100644 --- a/tests/rbac/aio/conftest.py +++ b/tests/rbac/aio/conftest.py @@ -24,7 +24,7 @@ def private_key(request): def certificate_chain(request): return request.config.getoption("--certificate_chain") - +""" @pytest.fixture(scope="module", autouse=True) async def drop_all_indexes(username, password, host, port, root_certificate, certificate_chain, private_key): print("\n\n\n\n MADE IT TO FUNCTION") @@ -38,6 +38,7 @@ async def drop_all_indexes(username, password, host, port, root_certificate, cer tasks.append(client.index_drop(namespace="test", name=item['id']['name'])) await asyncio.gather(*tasks) +""" @pytest.fixture(scope="module") async def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): From e3e2cfc1c485bb907f086acc9164c7df407d0bfe Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 22:40:57 -0600 Subject: [PATCH 183/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 5eeb7378..f7043270 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -285,6 +285,7 @@ jobs: - name: Add hosts to /etc/hosts run: | sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts + cat /etc/hosts - name: Run unit tests run: | @@ -297,7 +298,7 @@ jobs: docker ps - python -m pytest rbac/aio/debug.py -s -vv --host child --port 5000 --root_certificate tls/root.crt --timeout=30 + python -m pytest rbac/aio/debug.py -s -vv --host child --port 5000 --root_certificate tls/child.crt --timeout=30 docker logs aerospike-vector-search docker logs aerospike From 9b5f0219a2f2df7079ae032e94f805d800528998 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 23:00:01 -0600 Subject: [PATCH 184/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index f7043270..0d656ec6 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -284,7 +284,7 @@ jobs: - name: Add hosts to /etc/hosts run: | - sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts + #sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts cat /etc/hosts - name: Run unit tests @@ -298,7 +298,7 @@ jobs: docker ps - python -m pytest rbac/aio/debug.py -s -vv --host child --port 5000 --root_certificate tls/child.crt --timeout=30 + python -m pytest rbac/aio/debug.py -s -vv --host child --port 5000 --root_certificate tls/root.crt --timeout=30 docker logs aerospike-vector-search docker logs aerospike From 3815f89a1ae46edd52bfa91ce954425c37830cb4 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Sun, 21 Jul 2024 23:05:34 -0600 Subject: [PATCH 185/215] flaky tests --- .github/workflows/integration_test.yml | 4 +- tests/aerospike-vector-search.yml | 51 ++++++++++++------------- tests/assets/service_stanza.txt | 2 +- tests/assets/tls_stanza.txt | 8 ++-- tests/tls/child.crt | 23 +++++++++++ tests/tls/child.csr | 17 +++++++++ tests/tls/child.key | 28 ++++++++++++++ tests/tls/child.key.encrypted.pem | 30 +++++++++++++++ tests/tls/child.key.pem | 28 ++++++++++++++ tests/tls/child.keystore.jks | Bin 0 -> 2798 bytes tests/tls/child.p12 | Bin 0 -> 2739 bytes tests/tls/jwt/private_key.pem | 28 ++++++++++++++ tests/tls/jwt/public_key.pem | 9 +++++ tests/tls/keypass | 1 + tests/tls/root.cert.pem | 25 ++++++++++++ tests/tls/root.crt | 25 ++++++++++++ tests/tls/root.key | 28 ++++++++++++++ tests/tls/root.key.pem | 28 ++++++++++++++ tests/tls/root.srl | 1 + tests/tls/root.truststore.jks | Bin 0 -> 1430 bytes tests/tls/storepass | 1 + 21 files changed, 304 insertions(+), 33 deletions(-) create mode 100644 tests/tls/child.crt create mode 100644 tests/tls/child.csr create mode 100644 tests/tls/child.key create mode 100644 tests/tls/child.key.encrypted.pem create mode 100644 tests/tls/child.key.pem create mode 100644 tests/tls/child.keystore.jks create mode 100755 tests/tls/child.p12 create mode 100755 tests/tls/jwt/private_key.pem create mode 100755 tests/tls/jwt/public_key.pem create mode 100755 tests/tls/keypass create mode 100644 tests/tls/root.cert.pem create mode 100644 tests/tls/root.crt create mode 100644 tests/tls/root.key create mode 100644 tests/tls/root.key.pem create mode 100644 tests/tls/root.srl create mode 100644 tests/tls/root.truststore.jks create mode 100755 tests/tls/storepass diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 0d656ec6..606effd3 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -284,7 +284,7 @@ jobs: - name: Add hosts to /etc/hosts run: | - #sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts + sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts cat /etc/hosts - name: Run unit tests @@ -298,7 +298,7 @@ jobs: docker ps - python -m pytest rbac/aio/debug.py -s -vv --host child --port 5000 --root_certificate tls/root.crt --timeout=30 + python -m pytest rbac/aio/debug.py -s -vv --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --timeout=30 docker logs aerospike-vector-search docker logs aerospike diff --git a/tests/aerospike-vector-search.yml b/tests/aerospike-vector-search.yml index 545f5ebe..91492163 100755 --- a/tests/aerospike-vector-search.yml +++ b/tests/aerospike-vector-search.yml @@ -12,19 +12,19 @@ cluster: # If TLS is desired, TLS configuration ids used # and associated TLS configurations. # -#tls: -# service-tls: -# trust-store: -# store-file: /etc/aerospike-vector-search/tls/$root_certificate_name.truststore.jks -# store-password-file: /etc/aerospike-vector-search/tls/storepass -# key-store: -# store-file: /etc/aerospike-vector-search/tls/$server_name.keystore.jks -# store-password-file: /etc/aerospike-vector-search/tls/storepass -# key-password-file: /etc/aerospike-vector-search/tls/keypass -# mutual-auth: true -# # Client certificate subject names that are allowed -# allowed-peer-names: -# - $client_name +tls: + service-tls: + trust-store: + store-file: /etc/aerospike-vector-search/tls/root.truststore.jks + store-password-file: /etc/aerospike-vector-search/tls/storepass + key-store: + store-file: /etc/aerospike-vector-search/tls/child.keystore.jks + store-password-file: /etc/aerospike-vector-search/tls/storepass + key-password-file: /etc/aerospike-vector-search/tls/keypass + #mutual-auth: true + # Client certificate subject names that are allowed + #allowed-peer-names: + # - child # interconnect-tls: # trust-store: # store-file: tls/ca.aerospike.com.truststore.jks @@ -53,16 +53,15 @@ service: addresses: localhost # If TLS needs to be enabled, tls configuration id. - #tls-id: service-tls + tls-id: service-tls # Required when running behind NAT - #advertised-listeners: - # default: - # # List of externally accessible addresses and - # # ports for this Proximus instance. - # - address: $server_name - # port: 5000 - + advertised-listeners: + default: + # List of externally accessible addresses and + # ports for this Proximus instance. + - address: 0.0.0.0 + port: 5000 # Management API listening ports, TLS and network interface. manage: ports: @@ -93,11 +92,11 @@ interconnect: # To enable client authentication -#security: -# auth-token: -# private-key: /etc/aerospike-vector-search/tls/jwt/private_key.pem -# public-key: /etc/aerospike-vector-search/tls/jwt/public_key.pem -# token-expiry: 300_000 +security: + auth-token: + private-key: /etc/aerospike-vector-search/tls/jwt/private_key.pem + public-key: /etc/aerospike-vector-search/tls/jwt/public_key.pem + token-expiry: 300_000 # Target Aerospike cluster aerospike: diff --git a/tests/assets/service_stanza.txt b/tests/assets/service_stanza.txt index 810fc65b..0fae663c 100755 --- a/tests/assets/service_stanza.txt +++ b/tests/assets/service_stanza.txt @@ -5,5 +5,5 @@ default: # List of externally accessible addresses and # ports for this Proximus instance. - - address: brawn + - address: 0.0.0.0 port: 5000 diff --git a/tests/assets/tls_stanza.txt b/tests/assets/tls_stanza.txt index 15eb69e1..f940f5e0 100755 --- a/tests/assets/tls_stanza.txt +++ b/tests/assets/tls_stanza.txt @@ -4,10 +4,10 @@ tls: store-file: /etc/aerospike-vector-search/tls/root.truststore.jks store-password-file: /etc/aerospike-vector-search/tls/storepass key-store: - store-file: /etc/aerospike-vector-search/tls/brawn.keystore.jks + store-file: /etc/aerospike-vector-search/tls/child.keystore.jks store-password-file: /etc/aerospike-vector-search/tls/storepass key-password-file: /etc/aerospike-vector-search/tls/keypass - mutual-auth: true + #mutual-auth: true # Client certificate subject names that are allowed - allowed-peer-names: - - brawn + #allowed-peer-names: + # - child diff --git a/tests/tls/child.crt b/tests/tls/child.crt new file mode 100644 index 00000000..061b1b6b --- /dev/null +++ b/tests/tls/child.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDzjCCAragAwIBAgIUH61Up2ngTX6qZHywBEHz4a4zQn4wDQYJKoZIhvcNAQEL +BQAwgZ4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm +aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEgMB4G +A1UEAwwXYWVyb3NwaWtlLXZlY3Rvci1zZWFyY2gxJDAiBgkqhkiG9w0BCQEWFWRw +ZWxpbmlAYWVyb3NwaWtlLmNvbTAeFw0yNDA3MjIwNTA0MjNaFw0zNDA3MjAwNTA0 +MjNaMEQxCzAJBgNVBAYTAklOMQswCQYDVQQIDAJLQTEYMBYGA1UECgwPQWVyb3Nw +aWtlLCBJbmMuMQ4wDAYDVQQDDAVjaGlsZDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANmqvUIVV97SpPgp6mhCsLYsqEL9iQT9PG2ge7Uc4gu4Ke6cpfEe +gg1y1Oukmi4eyeGAriJwOI1eejsvMtxi7a+foyBqkVpmMxC51AGypAYjO8xC4BiP +eZiZ0LL1cTbaTItjNrqtHtuyetmnw+TirrOKtmibgSStTEJavLHk1TlzuyR/Vrfs +uB2urXUkyKZoIoKgQk/BR0uQVsftk5Ll150mcD19z5D/t29jme6gogLjbrLy4YVo +Py12Wzeemdb3ZDO0apWceo0g+vIU4xjTzGcmg5cl1C7PmcKHQm2odPQZNfKjvx/j +5BtYWF5NQLWUqrcGeFXUgBLvfI+uFLwm9FkCAwEAAaNdMFswGQYDVR0RBBIwEIIF +Y2hpbGSCByouY2hpbGQwHQYDVR0OBBYEFJLBLt+iYdiLY+WbAXH66IJfLBhmMB8G +A1UdIwQYMBaAFIsRKxjSCFjsitTnrCmPjFbbVe/pMA0GCSqGSIb3DQEBCwUAA4IB +AQAgXY4wEvoMqy5sPAiuwyKAAByIRM7Zcv+3QbNrWByTlMch7/ViuZEJMfqPZAWk +KfnVaiiedV+sbuiSJUDSMKbI1RLQe4NeG/rN73jNpycqFEfzu96k5SyS4ST7J/7u +6UHNEduHTXeIa6RJkYE27cPXsU87/cTaMZCEjaTzLuZYefLhcGaVpqKega9PvKXV +UiNpYwl+oDiJ4IQbyW1MgFdRoZrwRIAICmf5GyFRp0Oj+VQkTuxAGYyM++e4gsr8 +r7G/bVc+yIgzb6QuzinNIKokyjQuWJiTYBO2bHetbRX+GxytDhR0Sea+RrsDdAj1 +IBjx5XC3RZQalC42r8yJFiPU +-----END CERTIFICATE----- diff --git a/tests/tls/child.csr b/tests/tls/child.csr new file mode 100644 index 00000000..97360b2e --- /dev/null +++ b/tests/tls/child.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICtTCCAZ0CAQAwRDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMRgwFgYDVQQK +DA9BZXJvc3Bpa2UsIEluYy4xDjAMBgNVBAMMBWNoaWxkMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA2aq9QhVX3tKk+CnqaEKwtiyoQv2JBP08baB7tRzi +C7gp7pyl8R6CDXLU66SaLh7J4YCuInA4jV56Oy8y3GLtr5+jIGqRWmYzELnUAbKk +BiM7zELgGI95mJnQsvVxNtpMi2M2uq0e27J62afD5OKus4q2aJuBJK1MQlq8seTV +OXO7JH9Wt+y4Ha6tdSTIpmgigqBCT8FHS5BWx+2TkuXXnSZwPX3PkP+3b2OZ7qCi +AuNusvLhhWg/LXZbN56Z1vdkM7RqlZx6jSD68hTjGNPMZyaDlyXULs+ZwodCbah0 +9Bk18qO/H+PkG1hYXk1AtZSqtwZ4VdSAEu98j64UvCb0WQIDAQABoCwwKgYJKoZI +hvcNAQkOMR0wGzAZBgNVHREEEjAQggVjaGlsZIIHKi5jaGlsZDANBgkqhkiG9w0B +AQsFAAOCAQEAZbZCNqkHjv+WBA0jssz4xIrD24Rt2hnD7nOZ31wNJarcq1kDADU1 +327t6ECMUi2ExVRotlLR3adsa39lGPZsYLoF2HfOVURKsDovNIct7hiBAQCYPD60 +dMaWlbpE1Allban4GwuI/BdS0M/tTNaE7B9MnPw3fKC8Fe74D+7u/jTcBHcXpQM4 +PnKS5Y4Rhd6gKVXg6SDl5F5jUeQeowFKF1uLDPcpJGU83Xq1Rm2ijXx0V/0CT3dB +1PaOD+6KZjmOjo2itvDzU8mTB3JSqanVe9NAb50l4Z75aRPURjan42g+gfka9PQG +iX6eHsFJaMQPoR4XAUHKH9Rl+JR8QVOczA== +-----END CERTIFICATE REQUEST----- diff --git a/tests/tls/child.key b/tests/tls/child.key new file mode 100644 index 00000000..24e02749 --- /dev/null +++ b/tests/tls/child.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDZqr1CFVfe0qT4 +KepoQrC2LKhC/YkE/TxtoHu1HOILuCnunKXxHoINctTrpJouHsnhgK4icDiNXno7 +LzLcYu2vn6MgapFaZjMQudQBsqQGIzvMQuAYj3mYmdCy9XE22kyLYza6rR7bsnrZ +p8Pk4q6zirZom4EkrUxCWryx5NU5c7skf1a37Lgdrq11JMimaCKCoEJPwUdLkFbH +7ZOS5dedJnA9fc+Q/7dvY5nuoKIC426y8uGFaD8tdls3npnW92QztGqVnHqNIPry +FOMY08xnJoOXJdQuz5nCh0JtqHT0GTXyo78f4+QbWFheTUC1lKq3BnhV1IAS73yP +rhS8JvRZAgMBAAECggEAFNYIxuYnIq/UVeMhSrizlMTCmKMPdjhNjAr0PJqWstt+ +vBYntmSeu23WHvaDQc31sk3wnWBTsYitN7QlcL5RlWG5KlW5M0ecNMotFrqEhAfk +ZgGy1PcLA0YaGb9wBnmwIRmuuADxdsNniiVKlcLzSUGKg4n7O0kRhzqLXJYUqSqT +MlIatf3n6LpeV4BEbzZqWtiU0gBTYW1sJ6nJqyikn1k+h1b3/hwmUpTrNd3fOQkE +pEBeWLdOZDvIX/qtx5VeNoqkv7XnMvb89ROof1rgdouO1OjBUBAVC06yY36Zz26C +M2VuxgciJmqjWHCHp1YhhuePK5Iwgj1uD2p4SO5ITwKBgQD1Ff+PBNT0BUVzBKy4 +aaPngPJ+IUxpLCHS6cYy0jI+d5zvUzV4IH5Sj03Kon4GnUnjIbbIUWWCaeByLt12 +tk8I7vr7w4mtsjfAZG2hfb95piZcZ/gKe4UG9u5NCYaCs3ICU/JY6rCbh6+ffFZZ +uKo8OkpYFTv6tWPgBOcd6kzhNwKBgQDjXCmDggSm9DmFxgkx0m5EyhpTTqBkh38Z +gIFNVLwtMXVEvhGbPIMXG+XUaC+zyFeDUDq/chd2c+IctHyXjvOnJuaNmD6MbUwG +TEGQMt1SzEMpl91UJOFzir77dqjCPgdLsxx4AEcrYK4Oom8IdG0zqcLqz5E71bkj +rekR+wXe7wKBgEQgFkaB+FPQN0rObNhh/P532G/4/41oiAphkwdDaFX217eqsH0w +wwxd6yi9XDyocgZhs7Yg8g97MLlsj4DVEkkQbNGYu+d9V4PyJosyMgw1hApBmDAJ +v6N89iaR1EL2cGV3QjE3I1pIMCgr3rDX5PIS3eF4HZEF5Lo7gqbNHwunAoGAdIlw +3e9u4wSb123CmL77tlbBV6IdpGmvRCsSG8krCx8mtK2X6LIDn3y1OUKN8ODnum8N +LcQVMqoDZCM/GZA0Y6EU288FgIUlSrUbhgYMW7xHULJ+x/p/dPHRIqOXrLiOlMah ++QBrelh73xRzRSooLyr8tc7e6oSJ+TfTF1xLjhECgYEAhgHs58Vb3eRlMrtFtB2t +5TXFxmzXyeMLygHp2DGOliXEGSNoYLlhJJpFLexhbfPlVVyNNuWkliQ+e4rKcNmG +fDJq/9BOZ19xjGWYFHjXL/IXjeATQhFI/mMUhzfHoa535LK00TOocmWc1BQpvDKr +rccshL800qIwRkVID7nTRM0= +-----END PRIVATE KEY----- diff --git a/tests/tls/child.key.encrypted.pem b/tests/tls/child.key.encrypted.pem new file mode 100644 index 00000000..46799aa4 --- /dev/null +++ b/tests/tls/child.key.encrypted.pem @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQDMQpak/3CdXwl7mf +DNZrEwICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEL7jJg5Nyv7ywyds +5zjF0roEggTQw4Qi3uVDpAKTNCOXO8ndTMlczkPp8jDsE/0xWcGsV5kAD1Dywk3Y +mKnnU+08yKyIlZrEVu9k5CLn7kCzEZC3SSSYqG/LZNa+M4EO+zVNjbIwD1K3p26o +1s6gxDe7H8HChPDye63VDZJ2ojOwPJBKC1tuPz45W9X7o45NSBwflyIIhNkudAHf +yY0foNlDTBXFWRDvuK1ME5e1jt78GWzyzvJjkR8xZDMVb4TJb/mZ9OrA+1a8slyz +s6HNJGAZWQnJNhoWBO5BrgtPC/xPnkCNY/TVm9hKCp4aQ2QItbnsXOD88BUI8kKk +79dZbkyH5qalmSM8zvim8thDHr5X5T96hm+YSUK1ijD7NmCCCwlt2adCVxqKH2Ie +kwS8M4OJYlKzNyih53tugKYp2P7xXchBKvPf1wh7tfGJLRZtOHDpnjrzUzvUb5EU +C+ZBZM+UfhJcHb+l5012L2iOox5pH0tsprp1zD5FcfylFXFNBZG41FaEbajfk4UW +CJiURJH1VyFnrLTiHk7SVb8VzUVyFrrX1Npk2NEqRzfg7/d1+QyYHaZAC/9MnbP0 +SsNFjpu8r/8ujjId2lbemQ26Jj7UEVkL7QiOnRtf3gYqPWOfmWNgtNA9PEImr8Fa +hPGRh5Tp5URNYmmFaOZb4/QdKVAYArPa7xXOHbwv0CEKGYsp2houL6OEyC27cbJS +K2W2jS6SvxJJavzbGWrnNL+Wx+9BeE09DtXDxGxr6VFy/EZ0FTDBTXBxi15/8LxC +WP7ZmVqYU6LJNML6oKRmS9UZAh42O3KHWW/lbEtey8Bz+HKGEMdHi8aRk2C0/BU/ +a8orBZa2TQIl0i7gVEEtQJ9BkLK1G+KTsmHRudbzw+y169zVqjFK7StxofbUsPkk +srEZNwE6MVn0n19Tc/kQNIa79bSGqlpMtFGhbXBzdBqQfZx9ySf/wsE2+JEYbnx5 +i06eQWCTy0eE17tSaJ2BkJc24oPvDoEh9375et22a9S6zRgXPIBpF5D6PlvZKkYa +ZEv03VrpJzDBdoM6i3HIHCq/aHkf0IumilBjqvLgwr90sQkn/YvQZlPuyVb6H7ay +A+1YcSNBVAbRhYipyUvBvXZCSbpSP/hty/cjya46fNsZEQnrelNNUCoPtxvG98Yo +FJ7TYtAdi5m+qvYtsEA/etaPeRh8S7m0JuXAEckjMNxDhTx+nWdcwc/OdLAMX4yx +S7vYP6qfvxbaUjfHwRgVIB4f9XEKOjuV7gzdr1o1pE+cgEk1MnPm27ibb6nm1NDB +UlMPVSHcCuJ74Q8TPjTVoLY5MhulRUlEAg/4kgYuM8ReMb1Usr6bguk5E2Derau9 +cEv8SWkHrpIyqHWHNV9EXRtbSLW08SwIirESJ/x+V7SoiknlE3mTyNZzmKm/tG7I ++Qwo4vu3uKc9efvyI8v6HQwVZaKAr1lCbS++Yo43EsBBOM3WiKOf2ROkIGEoBASG +5pfPjVhesioVkyl7n5fXn0ULewPFxoyqKNSP+WaTkk74AVHdn60VHOsigfmSpiin +vv+zGIGdkmhY/RuBFQrWnTBwkk5A2CrOAmhfloiCNud6/ei5UaLLrRrUAUYmDxrn +H2TcUZ3RzZvb8M9HOZIBJ0VZPhmyvOQUTP/KReqSmV36Mgo+oPwSboE= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/tls/child.key.pem b/tests/tls/child.key.pem new file mode 100644 index 00000000..24e02749 --- /dev/null +++ b/tests/tls/child.key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDZqr1CFVfe0qT4 +KepoQrC2LKhC/YkE/TxtoHu1HOILuCnunKXxHoINctTrpJouHsnhgK4icDiNXno7 +LzLcYu2vn6MgapFaZjMQudQBsqQGIzvMQuAYj3mYmdCy9XE22kyLYza6rR7bsnrZ +p8Pk4q6zirZom4EkrUxCWryx5NU5c7skf1a37Lgdrq11JMimaCKCoEJPwUdLkFbH +7ZOS5dedJnA9fc+Q/7dvY5nuoKIC426y8uGFaD8tdls3npnW92QztGqVnHqNIPry +FOMY08xnJoOXJdQuz5nCh0JtqHT0GTXyo78f4+QbWFheTUC1lKq3BnhV1IAS73yP +rhS8JvRZAgMBAAECggEAFNYIxuYnIq/UVeMhSrizlMTCmKMPdjhNjAr0PJqWstt+ +vBYntmSeu23WHvaDQc31sk3wnWBTsYitN7QlcL5RlWG5KlW5M0ecNMotFrqEhAfk +ZgGy1PcLA0YaGb9wBnmwIRmuuADxdsNniiVKlcLzSUGKg4n7O0kRhzqLXJYUqSqT +MlIatf3n6LpeV4BEbzZqWtiU0gBTYW1sJ6nJqyikn1k+h1b3/hwmUpTrNd3fOQkE +pEBeWLdOZDvIX/qtx5VeNoqkv7XnMvb89ROof1rgdouO1OjBUBAVC06yY36Zz26C +M2VuxgciJmqjWHCHp1YhhuePK5Iwgj1uD2p4SO5ITwKBgQD1Ff+PBNT0BUVzBKy4 +aaPngPJ+IUxpLCHS6cYy0jI+d5zvUzV4IH5Sj03Kon4GnUnjIbbIUWWCaeByLt12 +tk8I7vr7w4mtsjfAZG2hfb95piZcZ/gKe4UG9u5NCYaCs3ICU/JY6rCbh6+ffFZZ +uKo8OkpYFTv6tWPgBOcd6kzhNwKBgQDjXCmDggSm9DmFxgkx0m5EyhpTTqBkh38Z +gIFNVLwtMXVEvhGbPIMXG+XUaC+zyFeDUDq/chd2c+IctHyXjvOnJuaNmD6MbUwG +TEGQMt1SzEMpl91UJOFzir77dqjCPgdLsxx4AEcrYK4Oom8IdG0zqcLqz5E71bkj +rekR+wXe7wKBgEQgFkaB+FPQN0rObNhh/P532G/4/41oiAphkwdDaFX217eqsH0w +wwxd6yi9XDyocgZhs7Yg8g97MLlsj4DVEkkQbNGYu+d9V4PyJosyMgw1hApBmDAJ +v6N89iaR1EL2cGV3QjE3I1pIMCgr3rDX5PIS3eF4HZEF5Lo7gqbNHwunAoGAdIlw +3e9u4wSb123CmL77tlbBV6IdpGmvRCsSG8krCx8mtK2X6LIDn3y1OUKN8ODnum8N +LcQVMqoDZCM/GZA0Y6EU288FgIUlSrUbhgYMW7xHULJ+x/p/dPHRIqOXrLiOlMah ++QBrelh73xRzRSooLyr8tc7e6oSJ+TfTF1xLjhECgYEAhgHs58Vb3eRlMrtFtB2t +5TXFxmzXyeMLygHp2DGOliXEGSNoYLlhJJpFLexhbfPlVVyNNuWkliQ+e4rKcNmG +fDJq/9BOZ19xjGWYFHjXL/IXjeATQhFI/mMUhzfHoa535LK00TOocmWc1BQpvDKr +rccshL800qIwRkVID7nTRM0= +-----END PRIVATE KEY----- diff --git a/tests/tls/child.keystore.jks b/tests/tls/child.keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..1e048814369a0abe022d0f8882a218cec1e76751 GIT binary patch literal 2798 zcma);dpHx08pmyBY_2i)%yJz{n`^mKZdnLR(lL}mA?Y_^sJZ2m%TgkVF(H%du-uB= z=FZ66ql6|!$^CSmbDn74GmCN|2Vk#Q7)(x ze~)}9H4w}}=FTe(R8_V_(3gJz?Fa|UX*@hYpt2AUfI#tqdH#J72;t&D$$%m5u~q;t zP7pv9B(!Jo;jy&gzLdC+X}{~pBn?Ca4S3>=OMI5svYAsCUYjidB_%_UFzYXIrRBF& zCl$<@r>p3-qa70wG5a%wb}-yumP$eN796_W=n%4HL z*tRtXcGh|<-*&e%u-bkR)wLSiQjpx`p^@RW`aJ|v6?vcMbpmVtvHY`LnbUMwmCHa^ zY!}#v@~%Ezp-dZSK5hH+ebhHK5r5{HhF+0*MNp&MQL(N~>398g43&Mk;(_R%D@we* zG6h3i57uAnEd|nyBq35ayB@1Ku*ebLGQ_X=iYm;V3EJUb=fg0O_eMp``qzY&FbC+$$%> zhV{B?TDEwy>~TM$uf5N zp;4fumN6;Sodied;iOos0{sL>Z}=HkD8AK)!N4-z2(D zAyfqTg~W1$QmCb00sL0|37y>L@%HW-?V-X%+SwusBO8msy*02X)9f?rS4&U%nm>7$ z>bT9KTA4QbU5?c}DjscVuEsx&04HPcP6|0<=H^B~!G;wn?+jMZ%T2P$LH1I-!XZ14 z#frKEK7q}>kzEW{FHyo)cw|Pq2}_kP`VxObw*Ev_I!rz9+Oima-yjJ$X%oWFkrS8K z{i5xLt%%q$4}&aQ#j8~#)pnj3wYzuf_}VQ!r9fGC%<3Pc=L~;(zz|Z`9d>oaYO1OE zb1ttQ=D`$?9E?#v^XVLJYq@T-jP%POkGrp*Hhl4|+VgIcMxf~(mp^Y1pt_m1y{;-DrDLu|{X%%n8)J zo=~fOBX;Tj{pZg0Hlxy4ui`QW8k;qLoLkc!xzCbJF2}o!8L5|tcRI#}LL4h6Q}v)o zXWQe(%|uA@^XPK0yfjB0T+Tm!XE2nPCO_QFuF<9og0boHM4w z>u>kuO)`}b_1nTQy;m*493P4;@y7)x@>_)jkz2vHdn)Bt;29-5X$*bKzjkd}bJq$D zlA*A;4jHr#>d>FKguu`sIFJL4I`TIXMZ-YCPCkBK2(+#ST1P`mM@LgbR~JPD4gOi; z2Imq%Z-1jEAb{g{tNmL6{I76sJ=u$W65_0PD~a*giKML*k`ejf{|RRUc;Y7B=M!X& z-Dj03o)C4H2r}V8;XbBrQ8SZtdpuE@0#zy z6-tKP;K^H0k+R)1oxjG!k1Ax(-*+zS8$1wTRlFbmcCYxV*v@As4wAR1+Gq-;KHitughwYE$xuxVMJWdZ?!?V$qIC zHl#LmsedW@f?Eb|t0uXzh~9MY*W87r`lXFvm7wxqZe_8!j^jKhEoh=I-$zM&C@Jlp zz_vYQ(-o6~O0_7VgORn2@V)#_cn;6d;2{hm>2e)cKy(-WV-ov=?BY1ZQ*h;KjQ}yqCqY#h8^hHq&_*eDOe7!m3QoC zwy!hxB$L`I1^U+Iqz3ZM+RT>n;>lLADyqDxy0OY?Sov5IRKingg+f<(tGyU6xO6#xRjh;!&-+0X&%8T_E)I>tmrZ}Vcs zdYXFVMnuL39_xC*=x!&dNfKi=yXQi@Y58;&3%(p6j$Y(zMo@YTWzPDGvWpS*rvJ1xPp2NUxo!n9&^mv-0D-&TKNv~FG z*v#42N23*Q!x@!Raf-l#e`qlaB~l;NQ-Gh%7pg$KEl~8SQhAL`;nNt&qB!Nek}1NC zOvq!q)|&}hsq@M1Z1R}iwL28p{wg!gjV)@txH7G}jPvb9L&q)_JdA)L!Xf8Uf=r0y5)=ql byh`3VQt6AE@O1W=+YKxsoLfWuE5iN>Z|4%f literal 0 HcmV?d00001 diff --git a/tests/tls/child.p12 b/tests/tls/child.p12 new file mode 100755 index 0000000000000000000000000000000000000000..3c008b723c03d21386cb1b4055cd638691b87e03 GIT binary patch literal 2739 zcmai$c{~%0AIFW^m~&$zIpaZyN!jG4G)H6z9qyx8kupib%+?YmO)QyQ6LKGAMC6{R zu(C?1?G8;~6GMMAFC|Rw*7k4{GPS7^q$3o;z177&l zgz{yaB`g$%6~^#nG;#gjPV5YtKVJ8Kt5tk?r!Q?y0%yD3flf<=O4q5>2?vYk8-rjy{euLp^3r7f* zdQtd$pF)JM2faQ+1az;^>zEiu_E}RwCx1jRq)zEERwb@FWkKS>ro;~;zRk9-5%_tm zC3C;S2u_4z+>>L+}!3TSpja7`;vEc3~Z4Q50MVyIN=&<`X+86ax(g}SVnH=vI zc<@f__|g9B!g?zbhYV^zBvXwZi~E~dmWE+{2{Coz2bLb@_74|9Tloj#Vc4jk#a#h^ zgNLDqRO|EZ>sFt64JcBA96gB{maO~^ymvhYthBzptaZ_ty>(UYJDH2t*gDu9XzLzT z62S~ur?hrPovb?^c3m2Lv7T&wc(VP(r{4>-s;x*vkPIE}K(EW=tB`idf4cf=fH;<( zW(%({pY2)B0;)eUjSre$AepA3E2@*JU<^4z+-8l6L67ptsi<-3XTq)!dCW6;G9 z+)LF8l=p3{8o)5c6D@H3)>&HT#`CQ7bn!+%)@*bg&%kD~d6d19#tk(Ps45v1(n9(v z^^VymLgo4G`^L3-!NQ#!597anJt!s6j-*s5OLJy`+nN%slMte6s>#xv8we9N$|hXo zMhTCaXVU{m@4?Z?O(DYD8K#N%%!eI$h7f1WU_)&HCN!fodKcA|vo>iu`wqsQL03nN z-G0vipCjk?z^;o+EqH@{J0StRQAyi^{>BiAS>MyPO;Hwp;g-KV*b>5TusymL2 zMw;u5x8HY_y-0QDnY9@%Ia)j0Pyq_)v_UPPjcS8CKQ1lzMf9FhARa8@-yBLeG>cFQSRf3WecvXJjt>=o3v6uoS>kXwuZx+)8Dt&9dxXm(Nf2`u8n zopn@H#n-J#X~rq4g?&9na|FYedjtDN5e{vBpmH##oI7<)=tmq!*m-=8%(KGwb?<4j zJkHXJ#=Q);&_BXb*<4`5U7&5!3b3t-ys(FdJ}uZZloZ}!VP7RKXgYDPt=l~a8)B&} zj=EmZX`wJc-MdxM?`)p{$D7JL|JqpWgaWKB(gu+P-g|#M^pDthBY_0o@I4&5H&;Od z|974s1i-yl>g~a!|0Oa}pOe4zi@%0^73C^eJ!OCRKSg$Qm?W^Kx~g~T3x2XtBnb{A z0DGm{r>0wL&&k|#&{3@Zur!Z?{3dCGhV|(-3o`35)XuGPYi8zylajSxE6b$HB^i=+ zn^Mr)w+LM$BWU9#X|LDUN*8%EsKgz&Lif!umjpxo!&}VT z4=gX(7T--QF#EARqavt{(+`kn>DSR?Lz>%zYfC(C>BDwYKALL?k%kdJ)&$(@Y!7%y zkU4^5^gzoHHT?p0m>ASr1#5gyfN_{4{zJN3F0qD~;waz48W-Z22vm7pGdwY=;~IiC z7(u#>%f{i(sf5hllpU$uq(9l77}@oFpIfcg8SK6oa%Vq$fbdq&jO*78x7sgcyGv@V zjSr{xfA`Ux@y>)?=YK_xyW}yCr!>tZ0l6wJ%k8N8W9l?%((0_zgQN8S&Uf z6sL5#`hud#6Il+Il(0;NJWXtuZ2vipzo)%^&8%&-Q^^>7(T;AES$<|hJg-Y0r_D55 zqMQ@FX25(D?}zBw_n=Y8UXCuc-12SED<43CULNTBq!k|S_E(P)k z#BSiMEY4&V$6{DJ6N;oA^P1oBxGwn~%x%h>HmlvRqBV_n9YY?ko$yBO$ZFVtg?P*{ zU~(pF>|rukT?=EX@WH3Jg);S4d9L5lg`N}TfuhpfYFDhg4~xJZvxCgnj%db(=S=y1 zsrIqYe((00;sJX44Y#U;zIu6wjeiHW7Z|IFOy_Gqk$kiG%EC29>gXF2i~!Qw(?fCHp@5@zn&C6iD=`2@I`18`lrMOJ_g<{5 z?-3%?n=Y#qJguZ!)}v4)3>#JT4ExC#iHR}Ajh}8E(9HWbbm^vgk7bQ9U2KR&IRDjo zNv`U)k2Kf#(10*Eb6~*67EKg;Wl#2}9#BRLQbw5eEkR(0thtDzUz9nsCTAx-?XXEn zDig)d7vGpqk`#8Ym6>&(3?A;g9X#hmdpZmrb+gdvzc{>xFs}G!f>X(j&~mk(d&z|O zAF_shb|Jt=hK+h(1krrW^TlJT%JgtPG(Jk?9c-@rH&(`e1w^bjGW2p z^Nf{85?aMxoX(_urUoW-hgP~0k56tSUpyry{CxaE$&Yf2iU$sPk ai1_+z;xS^K&H(ZW5*2ijQ;8}6sP=CwpaaSP literal 0 HcmV?d00001 diff --git a/tests/tls/jwt/private_key.pem b/tests/tls/jwt/private_key.pem new file mode 100755 index 00000000..c5fca243 --- /dev/null +++ b/tests/tls/jwt/private_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDvfofGU9m+9NXd +0GLhWMgO9cn8rGRG7xV33lJ/biL9uuoj1oCqA5pLcnfQx3f0pF/ZFFDvvD+aeGK+ +y/jFRoTcOAdA0WGBaXc3bHQzC7FQdXgEzX6sMnWvAYgSJlP6sY3qm4tDR1W7bnZv +S4Q+AmxNNkHJtWlbRKthGqxWPwag50iQK8a2Z5AQ63yP57ljmsql3bR3xGXVyNRy +Q9ONhaZUs7/j2ktKt9XFfREnzrdJPgUbw//xydgWHMNRlEeXrI8ZDjAQctu95Tb4 +SkCtM5m/AmB03ttDERzDuA0UtF0nvJ0pN8MKNCkLqroHOEUs3WUFs4ntxdyBF6j7 +RYwm25RRAgMBAAECggEAC0kC5zFipHu6ANfwc4jw8w+EQz/xAQyuuMrE8r9DA9dv +xVzhYYww6ZbibCKcwEOR8VM36yFg5+D+BNqXWt29+03ikvHVg+PEhoaO79bVtfe1 +vkLb/LZAqGH3Qk+vC7RGfoRyKqtCWsYo64lQmRwZHrGh+6TCQFbl3SSvc+hIDNiH +J5r+cn310vUEBgTXE5kLFr/QDMDqWm/kBrcET3BiHNKrxE7x0xCI5qw7aoeoAuxW +XCg9uhRoq6j/kFmTaLhSVtpJmaz4VTivxraPx+qDbVLgikQquTsSI87D9ee0k9hJ +DEV90qtMvuxt+Ozju3Xo2iVRK5x6v61R0IH82tHq3wKBgQD8fCI3viD3LDJBajsh +tt2SvkhI9BB6c9eDso4D5MDh8WgZOJzHGLMDMihVr9AHTsbKrl2SXHs7Si/H8r2t +vZzwTh+gQav9A1QaoyPEA+nIQkdaxtYxkk1IOR34CNxmBxq/XEJbAEHbKnXliiZM +iJGORNb4XAnmR43rEo8XP//biwKBgQDy1Bj5FEnxMxMX1IPzgJKbjN/ygcHypfeT +wyyrb9f+t20l2TsLzOjuN+Jsdbyg+zJb1deQhn+qtCllM3/JSS3i+ZQf+4ybQybn +6JUZi70gmS40hML2CIrZZqVuQcu9TXad6O7gmW5hbMbVkH5N/yrVb61xbMqJIg8G ++DB+F3f7EwKBgFvy7Rc105WQb+Doyg4WJY06ZOLEl3ew1kys6xE57pCaNNnyhw3u +zcqdKplCBNWUd8r6QzN5IJvQAaSknzU1t4DAQr4/DF6BJtDolq7c6fe3Q3sorHqz +GBf0TRi2SWWSssf71mKDrngdd4AXlqkKl0+jfFJIWoaVinaQdLH36brPAoGBALkt +2eWI/WJ9KqBPpli5whPxeI79OSSMQKNkgdozLqrGwuvMH2U+XJvd7kP7/V9ecObr +yroid5V8Ut0kStz7e4zN+5HwSSfWLANKsPmMQSxs5HmUjQEHPqvPxXSxpGe2fTCr +BBAvsaeGRpNy338niki+I6yN5F5zpLYR6xkdWJgVAoGAXKJfrrvxMY2BsTDaghuo +CgL2TwL1T0TwVm05jfo0TwyuQibK64BvuPsYmBa7PYvdyPEYaMndlyW4Ny1NPGyM +M8fbSXiC/oRbAlW3G0qy3J90ZJ1eupS8iJo40Cg3tGIGfMKvKojCyS2T8rouk4BZ +kQxVnAczJr96Pwdu76+ITg4= +-----END PRIVATE KEY----- diff --git a/tests/tls/jwt/public_key.pem b/tests/tls/jwt/public_key.pem new file mode 100755 index 00000000..ea05d18b --- /dev/null +++ b/tests/tls/jwt/public_key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA736HxlPZvvTV3dBi4VjI +DvXJ/KxkRu8Vd95Sf24i/brqI9aAqgOaS3J30Md39KRf2RRQ77w/mnhivsv4xUaE +3DgHQNFhgWl3N2x0MwuxUHV4BM1+rDJ1rwGIEiZT+rGN6puLQ0dVu252b0uEPgJs +TTZBybVpW0SrYRqsVj8GoOdIkCvGtmeQEOt8j+e5Y5rKpd20d8Rl1cjUckPTjYWm +VLO/49pLSrfVxX0RJ863ST4FG8P/8cnYFhzDUZRHl6yPGQ4wEHLbveU2+EpArTOZ +vwJgdN7bQxEcw7gNFLRdJ7ydKTfDCjQpC6q6BzhFLN1lBbOJ7cXcgReo+0WMJtuU +UQIDAQAB +-----END PUBLIC KEY----- diff --git a/tests/tls/keypass b/tests/tls/keypass new file mode 100755 index 00000000..b1f833ed --- /dev/null +++ b/tests/tls/keypass @@ -0,0 +1 @@ +citrusstore diff --git a/tests/tls/root.cert.pem b/tests/tls/root.cert.pem new file mode 100644 index 00000000..ffa31ea3 --- /dev/null +++ b/tests/tls/root.cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIELzCCAxegAwIBAgIUArMsUI4jnSv02dxf2IiJTc/YNvYwDQYJKoZIhvcNAQEL +BQAwgZ4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm +aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEgMB4G +A1UEAwwXYWVyb3NwaWtlLXZlY3Rvci1zZWFyY2gxJDAiBgkqhkiG9w0BCQEWFWRw +ZWxpbmlAYWVyb3NwaWtlLmNvbTAeFw0yNDA3MjIwNTA0MjJaFw00NDA3MTcwNTA0 +MjJaMIGeMQswCQYDVQQGEwJVUzELMAkGA1UECAwCU0QxEjAQBgNVBAcMCVNwZWFy +ZmlzaDESMBAGA1UECgwJQWVyb3NwaWtlMRIwEAYDVQQLDAkgU0RLIFRlYW0xIDAe +BgNVBAMMF2Flcm9zcGlrZS12ZWN0b3Itc2VhcmNoMSQwIgYJKoZIhvcNAQkBFhVk +cGVsaW5pQGFlcm9zcGlrZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDGhYnRfMjTOxWlvQNtCuVWYr3GyYvkm/HrdAHUNt3hEmJ3KlGkLUnYnJXu +xs6hc8ZRHgTQ0RTQkTuhyTNZKWmYsr9phWEbkGMsOGX+zoNpOrV2XqshvjBIJ+8M +MIrF5kFLL8oqSKmej7wWIfRIxCo9pppeyY3Oml+fja3YDM5mMbmqxtiyzQGV0sOE +NGXnAJNYxxt4SWTDy/QXMg8bNV3W8edu5oFKMymodR35qw69Wywpr7uKDMiw0V2p +vYXFotjvxhFdDzdM19jh2OhmgywzTQw1jeqFkC9Ej/+8PW1nFkkIXNg+82QugODD +4zRWBFZSoMNgPqIc7peU0+SWVYiFAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8w +DgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSLESsY0ghY7IrU56wpj4xW21Xv6TAf +BgNVHSMEGDAWgBSLESsY0ghY7IrU56wpj4xW21Xv6TANBgkqhkiG9w0BAQsFAAOC +AQEAtbNyIzTGzZGZ1ddz8VJpdJZ9ZvqvC9Fa90XPxS5VxHtczOa7krSHJJtWtei9 +pvbnI1ta5pVWJq8mM4bYILi7Oi5xzQGqC+JClSAzsUuBTIC7JdX6MLSDdS8MHZUi +d/GACOlAf8vgzAGI6TyBFaz7p0NHgBWA140jcSeLbxQebIUlxOPVPuUqXLF1jTvZ +OpOJEhDJtei1kLOoMA8Mq42se6byO+u0CmRd/dgP6HOPG3A+xaflQi6NJH6iJXb7 +9Wain46nYsewVnfkUPjqj3B34ESYh1EO1OszClGcqokaO1R7u1zywfrtsLtpvFqx +U/UVbQdWwsdoPY27E2uwecQEoQ== +-----END CERTIFICATE----- diff --git a/tests/tls/root.crt b/tests/tls/root.crt new file mode 100644 index 00000000..556b27cc --- /dev/null +++ b/tests/tls/root.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEHzCCAwegAwIBAgIUcQXE4qjG87hWgyTobtiM6v8jOHYwDQYJKoZIhvcNAQEL +BQAwgZ4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm +aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEgMB4G +A1UEAwwXYWVyb3NwaWtlLXZlY3Rvci1zZWFyY2gxJDAiBgkqhkiG9w0BCQEWFWRw +ZWxpbmlAYWVyb3NwaWtlLmNvbTAeFw0yNDA3MjIwNTA0MjJaFw0zNDA3MjAwNTA0 +MjJaMIGeMQswCQYDVQQGEwJVUzELMAkGA1UECAwCU0QxEjAQBgNVBAcMCVNwZWFy +ZmlzaDESMBAGA1UECgwJQWVyb3NwaWtlMRIwEAYDVQQLDAkgU0RLIFRlYW0xIDAe +BgNVBAMMF2Flcm9zcGlrZS12ZWN0b3Itc2VhcmNoMSQwIgYJKoZIhvcNAQkBFhVk +cGVsaW5pQGFlcm9zcGlrZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDGhYnRfMjTOxWlvQNtCuVWYr3GyYvkm/HrdAHUNt3hEmJ3KlGkLUnYnJXu +xs6hc8ZRHgTQ0RTQkTuhyTNZKWmYsr9phWEbkGMsOGX+zoNpOrV2XqshvjBIJ+8M +MIrF5kFLL8oqSKmej7wWIfRIxCo9pppeyY3Oml+fja3YDM5mMbmqxtiyzQGV0sOE +NGXnAJNYxxt4SWTDy/QXMg8bNV3W8edu5oFKMymodR35qw69Wywpr7uKDMiw0V2p +vYXFotjvxhFdDzdM19jh2OhmgywzTQw1jeqFkC9Ej/+8PW1nFkkIXNg+82QugODD +4zRWBFZSoMNgPqIc7peU0+SWVYiFAgMBAAGjUzBRMB0GA1UdDgQWBBSLESsY0ghY +7IrU56wpj4xW21Xv6TAfBgNVHSMEGDAWgBSLESsY0ghY7IrU56wpj4xW21Xv6TAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBAU8NE0den3/XwtNR/ +5Kf0Qt5SRaNHO0r6dnbs4njfQjHXGG+B1ULGVjLsG9gdUur1y4Yldro3ca+o95yi +KOT1TrCzDEjMvtbjttifi0AIevn+XItED2RE8oK5WoQablXsO0elzNM6B3BX3Vd3 +FR3wfVnCGNzqQaBObYbNJ7zi6XSHJOp4CAuAe5F/yARjzZyx0vPysb9Hva54NOCd +50AlyZTbanZVMqXeDt2VdUh8VmmQs1EOFA8holyU4t390vc9BWGDcMHQET39tcPs +nm4uhyN1ynLNWGnYUWKQUOBbUOuxEu+L8fhwOG6aY8V/lINQI7pG3F0PVM40UD5x +Je/6 +-----END CERTIFICATE----- diff --git a/tests/tls/root.key b/tests/tls/root.key new file mode 100644 index 00000000..5164d6d2 --- /dev/null +++ b/tests/tls/root.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDGhYnRfMjTOxWl +vQNtCuVWYr3GyYvkm/HrdAHUNt3hEmJ3KlGkLUnYnJXuxs6hc8ZRHgTQ0RTQkTuh +yTNZKWmYsr9phWEbkGMsOGX+zoNpOrV2XqshvjBIJ+8MMIrF5kFLL8oqSKmej7wW +IfRIxCo9pppeyY3Oml+fja3YDM5mMbmqxtiyzQGV0sOENGXnAJNYxxt4SWTDy/QX +Mg8bNV3W8edu5oFKMymodR35qw69Wywpr7uKDMiw0V2pvYXFotjvxhFdDzdM19jh +2OhmgywzTQw1jeqFkC9Ej/+8PW1nFkkIXNg+82QugODD4zRWBFZSoMNgPqIc7peU +0+SWVYiFAgMBAAECggEAJxaUFFNll3HCyWd2DTpf/apjg4ibqt+pupqU4ZwMBA0C +pkQG3zSrnaL3QpSSiueo3L/0YslIN+jgvPJI0f19dTt8xOImRK8hV8ujCZDP/yA4 +Kp5pQ7OW/h4ey1+jc2Pq50r5m2nDPB1BA3qcBtfZGVp8er1k1pE+0sOqvyeGXEiE +6PeCS7HX0T0hgfhlSv9yopiUn3RYQ6vFOCjihq5QghO5fv7MFKB36vhJFUl6ZKcP +0xLJgd6AwcdfD5Y8f6Q95knpiqRIsc0/SoUGQBaZKWqlKadUsgpSbMZh5zsDxKQ2 +Fr8fivkIv1LTc7lskbMpNG71V7lipnylqCMmsEFBAQKBgQD6gmv7fOVKGvp9msJ3 +5GdmfCPy5m82GoMnCmVM0IxCZ2vqT3uXFdHZZlQeqtbQiDC/dAnSL69HhJQxrjwq +7s9tzo6Qv60s4UW26BKnjFlTZVCft9iwNBQuwqeyBiqsyz2lGbXWhkKMjOjWmaGf +Hq5OarXFA2RhSID4ixrrJYul+QKBgQDK32tOJhxWw5hCHuSIht5rgw+SvxDIxNHo +vxG+pmDo9Tt7j57AjfYYAbA7geIOobHf5Bk0A2RG66QogvBfAfr8dVZLrIDsTZ2J +xubGEUxrxS5yHo0bV7GOut5UvelE+uoLWlA53QYnnTzihCX2IFQRmGaYBUUErloE +hIxmaDgp7QKBgCdwjSuk+Dx4juNjkCZsEVNzS/2cBfpQpkFpQ5WaZ9q0iar0JJMe +3lEJ6UiCwRtHtdUOodUzqLbryqEfu11PB91T3eIwK0Wbmew4EWfLkuysUMs0mKr1 +KBBMmTZP/jwCK4xoxdYmgSe7r5TJz0ZMAElcR43jANTII3X+AJjw6lGRAoGBAJa5 +pWy7beScj1vYvewdX9S62/AoGl0/tcDZbGKcFHYf9OCZVNY04rj1UCz2E7DRO2lf +e8YkGvWCD0W1+sZrn0DAIKw6btKh28DIUR6pLYEIT7ijsCy3W4jyl0qYil4gmZBz +uhUzfGYkMV8N1XJmlG86LkcV6zBOJT0kCXfwSIIFAoGANTf2L9kiFfOKnAd6DIa4 +7MlBB22erE2EGFfJgYXSpMk3sO2Y8zZqPDnxvsRXxrmSbGeu0WXKYvgwerlsmQc0 +ehkIzgwdWv1mAaNXTOvKmVQXoVL8v4Q0IjJgCeftawv+VU2v63VjHsYb7rZn4phV +2Hg4wJS9HzRyw3UExij1dpc= +-----END PRIVATE KEY----- diff --git a/tests/tls/root.key.pem b/tests/tls/root.key.pem new file mode 100644 index 00000000..5164d6d2 --- /dev/null +++ b/tests/tls/root.key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDGhYnRfMjTOxWl +vQNtCuVWYr3GyYvkm/HrdAHUNt3hEmJ3KlGkLUnYnJXuxs6hc8ZRHgTQ0RTQkTuh +yTNZKWmYsr9phWEbkGMsOGX+zoNpOrV2XqshvjBIJ+8MMIrF5kFLL8oqSKmej7wW +IfRIxCo9pppeyY3Oml+fja3YDM5mMbmqxtiyzQGV0sOENGXnAJNYxxt4SWTDy/QX +Mg8bNV3W8edu5oFKMymodR35qw69Wywpr7uKDMiw0V2pvYXFotjvxhFdDzdM19jh +2OhmgywzTQw1jeqFkC9Ej/+8PW1nFkkIXNg+82QugODD4zRWBFZSoMNgPqIc7peU +0+SWVYiFAgMBAAECggEAJxaUFFNll3HCyWd2DTpf/apjg4ibqt+pupqU4ZwMBA0C +pkQG3zSrnaL3QpSSiueo3L/0YslIN+jgvPJI0f19dTt8xOImRK8hV8ujCZDP/yA4 +Kp5pQ7OW/h4ey1+jc2Pq50r5m2nDPB1BA3qcBtfZGVp8er1k1pE+0sOqvyeGXEiE +6PeCS7HX0T0hgfhlSv9yopiUn3RYQ6vFOCjihq5QghO5fv7MFKB36vhJFUl6ZKcP +0xLJgd6AwcdfD5Y8f6Q95knpiqRIsc0/SoUGQBaZKWqlKadUsgpSbMZh5zsDxKQ2 +Fr8fivkIv1LTc7lskbMpNG71V7lipnylqCMmsEFBAQKBgQD6gmv7fOVKGvp9msJ3 +5GdmfCPy5m82GoMnCmVM0IxCZ2vqT3uXFdHZZlQeqtbQiDC/dAnSL69HhJQxrjwq +7s9tzo6Qv60s4UW26BKnjFlTZVCft9iwNBQuwqeyBiqsyz2lGbXWhkKMjOjWmaGf +Hq5OarXFA2RhSID4ixrrJYul+QKBgQDK32tOJhxWw5hCHuSIht5rgw+SvxDIxNHo +vxG+pmDo9Tt7j57AjfYYAbA7geIOobHf5Bk0A2RG66QogvBfAfr8dVZLrIDsTZ2J +xubGEUxrxS5yHo0bV7GOut5UvelE+uoLWlA53QYnnTzihCX2IFQRmGaYBUUErloE +hIxmaDgp7QKBgCdwjSuk+Dx4juNjkCZsEVNzS/2cBfpQpkFpQ5WaZ9q0iar0JJMe +3lEJ6UiCwRtHtdUOodUzqLbryqEfu11PB91T3eIwK0Wbmew4EWfLkuysUMs0mKr1 +KBBMmTZP/jwCK4xoxdYmgSe7r5TJz0ZMAElcR43jANTII3X+AJjw6lGRAoGBAJa5 +pWy7beScj1vYvewdX9S62/AoGl0/tcDZbGKcFHYf9OCZVNY04rj1UCz2E7DRO2lf +e8YkGvWCD0W1+sZrn0DAIKw6btKh28DIUR6pLYEIT7ijsCy3W4jyl0qYil4gmZBz +uhUzfGYkMV8N1XJmlG86LkcV6zBOJT0kCXfwSIIFAoGANTf2L9kiFfOKnAd6DIa4 +7MlBB22erE2EGFfJgYXSpMk3sO2Y8zZqPDnxvsRXxrmSbGeu0WXKYvgwerlsmQc0 +ehkIzgwdWv1mAaNXTOvKmVQXoVL8v4Q0IjJgCeftawv+VU2v63VjHsYb7rZn4phV +2Hg4wJS9HzRyw3UExij1dpc= +-----END PRIVATE KEY----- diff --git a/tests/tls/root.srl b/tests/tls/root.srl new file mode 100644 index 00000000..0d93d97e --- /dev/null +++ b/tests/tls/root.srl @@ -0,0 +1 @@ +1FAD54A769E04D7EAA647CB00441F3E1AE33427E diff --git a/tests/tls/root.truststore.jks b/tests/tls/root.truststore.jks new file mode 100644 index 0000000000000000000000000000000000000000..2c2c20c3df9a64241913e4d1b34212d92358300d GIT binary patch literal 1430 zcmV;H1!?*)f(4QS0Ru3C1v~}`Duzgg_YDCD0ic2fEd+uEDKLTsB`|^oAqEL5hDe6@ z4FLxRpn?SwFoFdR0s#Opf&~W#2`Yw2hW8Bt2LUi<1_>&LNQU+thDZTr0|Wso1Q5RxgW!w|ph;XBju8<4Y0iLx1ds(v(f|F?wpfjHNi}~!!cBL& z8ZTXYBx8Xn9P^H~RymZhx;I**b0_HZuO~J)4cd9RbgshFGemH)1cVl^(ZkUUkKf1X z;^?j_Xw^j@$|cFPy7-!qs`ySjVoWP+-B z%X^aCBoCkmr@+A8(_8G^>I>=doa;bEtI&P$puC(Naz_!0SZ}TBlKG=xB_&SLel1x~ zo{yX0RylmvpKiBbDrT!u?u@02ra&8#L~fmnLF`6l9(@XDC096W9^yeu znGWyN43lgbF*F|bPZ?(yY5T?P&cjsgNY|TIjw@TIYrw zPxQMnb1Wuk(jju;-fp`eDr@rGy7(0Bwscnh`BGdaI+oZBtx7%ID>}nfEGY~s2`6%F z7lkW2qsMw-*C48qZh|xvf$h**Go;rk+YD=FGYGMkn~KDnd=-uhU`w>BTj&aGb}`q& zJ6n7h_*oT!C#0haQ!36!B(X*-W?VjhlWQ^IP|Jd}sA|_QRb0%}!lfG>Yn2I`cwIki%&-p*O*1FNJUl=c9R3j?qaZ1b`DmDHP z7NqhIwLt`}&>bo4olq6z!Xv3`G~ImIE5hXaW&!8Spue2`K{EEwLK}NYpSIB%_lv?L zvd&&&r3Py_d470bEn6T&-O8Oj*i_g)(lN=q84Z4z@#24}DT8)K{*}esKE9^&@pizr zdPkGc3~9MzblgLlpN{5CO?XeWq$XP<&tRKnkyJRwe-VLG6L{D-M8J+Bm+O~r9H=0gs`@j_EQ~Te-eegj-u6QjdKrf zM&%hJnflKn)29`w@hv4+NrhBZ8mPvs-%|K=Fvu%|!r!rH@iH{sr3xaY+u~QP#c1DJ zJBb?6<7kyC8`Lr&>8gD9l;$r#AX$NEn5VOc9kXX5kHczR~XWdzFflL<1_@w>NC9O71OfpC00baq;|F4YM6H!s4!or*pwJ}9z@zLzrz|8O kBtpN8qQmY46a$2F Date: Sun, 21 Jul 2024 23:12:52 -0600 Subject: [PATCH 186/215] Flaky tests --- tests/aerospike-vector-search.yml | 4 +-- tests/tls/child.crt | 34 +++++++++--------- tests/tls/child.csr | 24 ++++++------- tests/tls/child.key | 52 +++++++++++++-------------- tests/tls/child.key.encrypted.pem | 56 +++++++++++++++--------------- tests/tls/child.key.pem | 52 +++++++++++++-------------- tests/tls/child.keystore.jks | Bin 2798 -> 2798 bytes tests/tls/child.p12 | Bin 2739 -> 2739 bytes tests/tls/jwt/private_key.pem | 52 +++++++++++++-------------- tests/tls/jwt/public_key.pem | 14 ++++---- tests/tls/root.cert.pem | 34 +++++++++--------- tests/tls/root.crt | 34 +++++++++--------- tests/tls/root.key | 52 +++++++++++++-------------- tests/tls/root.key.pem | 52 +++++++++++++-------------- tests/tls/root.srl | 2 +- tests/tls/root.truststore.jks | Bin 1430 -> 1430 bytes 16 files changed, 231 insertions(+), 231 deletions(-) diff --git a/tests/aerospike-vector-search.yml b/tests/aerospike-vector-search.yml index 91492163..ef24c617 100755 --- a/tests/aerospike-vector-search.yml +++ b/tests/aerospike-vector-search.yml @@ -23,8 +23,8 @@ tls: key-password-file: /etc/aerospike-vector-search/tls/keypass #mutual-auth: true # Client certificate subject names that are allowed - #allowed-peer-names: - # - child + allowed-peer-names: + - child # interconnect-tls: # trust-store: # store-file: tls/ca.aerospike.com.truststore.jks diff --git a/tests/tls/child.crt b/tests/tls/child.crt index 061b1b6b..4ff7135f 100644 --- a/tests/tls/child.crt +++ b/tests/tls/child.crt @@ -1,23 +1,23 @@ -----BEGIN CERTIFICATE----- -MIIDzjCCAragAwIBAgIUH61Up2ngTX6qZHywBEHz4a4zQn4wDQYJKoZIhvcNAQEL +MIIDzjCCAragAwIBAgIUFZfW9uLW++TLlAV9eLlu5dmZ+1UwDQYJKoZIhvcNAQEL BQAwgZ4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEgMB4G A1UEAwwXYWVyb3NwaWtlLXZlY3Rvci1zZWFyY2gxJDAiBgkqhkiG9w0BCQEWFWRw -ZWxpbmlAYWVyb3NwaWtlLmNvbTAeFw0yNDA3MjIwNTA0MjNaFw0zNDA3MjAwNTA0 -MjNaMEQxCzAJBgNVBAYTAklOMQswCQYDVQQIDAJLQTEYMBYGA1UECgwPQWVyb3Nw +ZWxpbmlAYWVyb3NwaWtlLmNvbTAeFw0yNDA3MjIwNTA5NTFaFw0zNDA3MjAwNTA5 +NTFaMEQxCzAJBgNVBAYTAklOMQswCQYDVQQIDAJLQTEYMBYGA1UECgwPQWVyb3Nw aWtlLCBJbmMuMQ4wDAYDVQQDDAVjaGlsZDCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBANmqvUIVV97SpPgp6mhCsLYsqEL9iQT9PG2ge7Uc4gu4Ke6cpfEe -gg1y1Oukmi4eyeGAriJwOI1eejsvMtxi7a+foyBqkVpmMxC51AGypAYjO8xC4BiP -eZiZ0LL1cTbaTItjNrqtHtuyetmnw+TirrOKtmibgSStTEJavLHk1TlzuyR/Vrfs -uB2urXUkyKZoIoKgQk/BR0uQVsftk5Ll150mcD19z5D/t29jme6gogLjbrLy4YVo -Py12Wzeemdb3ZDO0apWceo0g+vIU4xjTzGcmg5cl1C7PmcKHQm2odPQZNfKjvx/j -5BtYWF5NQLWUqrcGeFXUgBLvfI+uFLwm9FkCAwEAAaNdMFswGQYDVR0RBBIwEIIF -Y2hpbGSCByouY2hpbGQwHQYDVR0OBBYEFJLBLt+iYdiLY+WbAXH66IJfLBhmMB8G -A1UdIwQYMBaAFIsRKxjSCFjsitTnrCmPjFbbVe/pMA0GCSqGSIb3DQEBCwUAA4IB -AQAgXY4wEvoMqy5sPAiuwyKAAByIRM7Zcv+3QbNrWByTlMch7/ViuZEJMfqPZAWk -KfnVaiiedV+sbuiSJUDSMKbI1RLQe4NeG/rN73jNpycqFEfzu96k5SyS4ST7J/7u -6UHNEduHTXeIa6RJkYE27cPXsU87/cTaMZCEjaTzLuZYefLhcGaVpqKega9PvKXV -UiNpYwl+oDiJ4IQbyW1MgFdRoZrwRIAICmf5GyFRp0Oj+VQkTuxAGYyM++e4gsr8 -r7G/bVc+yIgzb6QuzinNIKokyjQuWJiTYBO2bHetbRX+GxytDhR0Sea+RrsDdAj1 -IBjx5XC3RZQalC42r8yJFiPU +ADCCAQoCggEBALSJqUNjAEGkSYNTsahmK59dHntD35u+WlnsklRuYQxUKCVxbZfn +hogbvBxKZIFCVoGohRUPCA4h0vk/siCFtYsBrJsGykoMqQdG7niZ/YH8U++/Lko+ +z3PFCE/i6l2hBLoS1zZ1GCA2OCrCtQGi6r72jN8Yx1l0G8zrnavD0Z/+luviZ+qH +asYAbaByOi2/MViKSzSJ+JaUQz6b+xWlXwXUi195fn1lmHncBYcbv9P3r66R1U2Z +R8JHeSo/zkgBrbMkx2NxYmTBqpwOBQwY/QCpO5PGJwuZxOj/bPn3h7p4kMSNQtvL +bQ6VWyCjpu2rAa9eZ8GTsRc3TOXMUvw2I+MCAwEAAaNdMFswGQYDVR0RBBIwEIIF +Y2hpbGSCByouY2hpbGQwHQYDVR0OBBYEFBNlLE3PFWDxZGrQOcbG5m+mLpNeMB8G +A1UdIwQYMBaAFHno7QKg/K/UvsrdzutNX+OVM1P6MA0GCSqGSIb3DQEBCwUAA4IB +AQBDMVqi9ch3kaiRtQ6yK9XtdV3MASJsa5yoiBpJXBi08OH1juGOIKMUKKHzukRm +mV8kQDvYjrtiBmR3PHQe9LwqG9x88nW81pEDTozUERLu7ohm4v7rMv0I1QvBmp59 +2PN8ZvBs4DY03qugh4gcwxPZQUze8FO2t8cBQU1g0wO68NM/74KqAveFtzofIFCF +JFVo+gmEYXd1WXFxUOelUUz6b8nLJxfO2nTEnr8rl84JmPOET5kIzZsift1fMTkv +/4jnqo8OflX4IO6w75WQKnScchER1Wl6p8ceoIDUn7UoDYYB99L8WHQPflz1dDzd +Ck+wCO4rmoZS/gJRE4u9uMTy -----END CERTIFICATE----- diff --git a/tests/tls/child.csr b/tests/tls/child.csr index 97360b2e..b46b6c43 100644 --- a/tests/tls/child.csr +++ b/tests/tls/child.csr @@ -1,17 +1,17 @@ -----BEGIN CERTIFICATE REQUEST----- MIICtTCCAZ0CAQAwRDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMRgwFgYDVQQK DA9BZXJvc3Bpa2UsIEluYy4xDjAMBgNVBAMMBWNoaWxkMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA2aq9QhVX3tKk+CnqaEKwtiyoQv2JBP08baB7tRzi -C7gp7pyl8R6CDXLU66SaLh7J4YCuInA4jV56Oy8y3GLtr5+jIGqRWmYzELnUAbKk -BiM7zELgGI95mJnQsvVxNtpMi2M2uq0e27J62afD5OKus4q2aJuBJK1MQlq8seTV -OXO7JH9Wt+y4Ha6tdSTIpmgigqBCT8FHS5BWx+2TkuXXnSZwPX3PkP+3b2OZ7qCi -AuNusvLhhWg/LXZbN56Z1vdkM7RqlZx6jSD68hTjGNPMZyaDlyXULs+ZwodCbah0 -9Bk18qO/H+PkG1hYXk1AtZSqtwZ4VdSAEu98j64UvCb0WQIDAQABoCwwKgYJKoZI +AQEFAAOCAQ8AMIIBCgKCAQEAtImpQ2MAQaRJg1OxqGYrn10ee0Pfm75aWeySVG5h +DFQoJXFtl+eGiBu8HEpkgUJWgaiFFQ8IDiHS+T+yIIW1iwGsmwbKSgypB0bueJn9 +gfxT778uSj7Pc8UIT+LqXaEEuhLXNnUYIDY4KsK1AaLqvvaM3xjHWXQbzOudq8PR +n/6W6+Jn6odqxgBtoHI6Lb8xWIpLNIn4lpRDPpv7FaVfBdSLX3l+fWWYedwFhxu/ +0/evrpHVTZlHwkd5Kj/OSAGtsyTHY3FiZMGqnA4FDBj9AKk7k8YnC5nE6P9s+feH +uniQxI1C28ttDpVbIKOm7asBr15nwZOxFzdM5cxS/DYj4wIDAQABoCwwKgYJKoZI hvcNAQkOMR0wGzAZBgNVHREEEjAQggVjaGlsZIIHKi5jaGlsZDANBgkqhkiG9w0B -AQsFAAOCAQEAZbZCNqkHjv+WBA0jssz4xIrD24Rt2hnD7nOZ31wNJarcq1kDADU1 -327t6ECMUi2ExVRotlLR3adsa39lGPZsYLoF2HfOVURKsDovNIct7hiBAQCYPD60 -dMaWlbpE1Allban4GwuI/BdS0M/tTNaE7B9MnPw3fKC8Fe74D+7u/jTcBHcXpQM4 -PnKS5Y4Rhd6gKVXg6SDl5F5jUeQeowFKF1uLDPcpJGU83Xq1Rm2ijXx0V/0CT3dB -1PaOD+6KZjmOjo2itvDzU8mTB3JSqanVe9NAb50l4Z75aRPURjan42g+gfka9PQG -iX6eHsFJaMQPoR4XAUHKH9Rl+JR8QVOczA== +AQsFAAOCAQEAsBfOm8whD3jimtE4kLDkiizgNVUT5FgXtgqGutzVcCDn1+BQ5FOY +tyZK5lrJuOwdoyzoQ/CtMOlSr/QjqF5t0SZ8NF4wJe4Hdi5oFxdZMvfqQOaGuyoB +OXctsgR+RiccXEfwPs5h5Y1YtXvckseAX/K3t7P3Xk+rFGZi3xtf4bzTa/7xVrPU +ZdlSn5/Ds0u3Hx0DRNxNhAlaY6e8TacKl+DBN7f5jyoViJVxh+hrTnw6f8kZaIWU +Omo0UU1UAraS2r6KWHqSVkKt7MnsjmvcJyXijz/W9mS/as90IK+V1rcAJoImlJZD +PXsJ5sQGdmzbcvFdS19prveArSMl7N6NBg== -----END CERTIFICATE REQUEST----- diff --git a/tests/tls/child.key b/tests/tls/child.key index 24e02749..9f0590bb 100644 --- a/tests/tls/child.key +++ b/tests/tls/child.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDZqr1CFVfe0qT4 -KepoQrC2LKhC/YkE/TxtoHu1HOILuCnunKXxHoINctTrpJouHsnhgK4icDiNXno7 -LzLcYu2vn6MgapFaZjMQudQBsqQGIzvMQuAYj3mYmdCy9XE22kyLYza6rR7bsnrZ -p8Pk4q6zirZom4EkrUxCWryx5NU5c7skf1a37Lgdrq11JMimaCKCoEJPwUdLkFbH -7ZOS5dedJnA9fc+Q/7dvY5nuoKIC426y8uGFaD8tdls3npnW92QztGqVnHqNIPry -FOMY08xnJoOXJdQuz5nCh0JtqHT0GTXyo78f4+QbWFheTUC1lKq3BnhV1IAS73yP -rhS8JvRZAgMBAAECggEAFNYIxuYnIq/UVeMhSrizlMTCmKMPdjhNjAr0PJqWstt+ -vBYntmSeu23WHvaDQc31sk3wnWBTsYitN7QlcL5RlWG5KlW5M0ecNMotFrqEhAfk -ZgGy1PcLA0YaGb9wBnmwIRmuuADxdsNniiVKlcLzSUGKg4n7O0kRhzqLXJYUqSqT -MlIatf3n6LpeV4BEbzZqWtiU0gBTYW1sJ6nJqyikn1k+h1b3/hwmUpTrNd3fOQkE -pEBeWLdOZDvIX/qtx5VeNoqkv7XnMvb89ROof1rgdouO1OjBUBAVC06yY36Zz26C -M2VuxgciJmqjWHCHp1YhhuePK5Iwgj1uD2p4SO5ITwKBgQD1Ff+PBNT0BUVzBKy4 -aaPngPJ+IUxpLCHS6cYy0jI+d5zvUzV4IH5Sj03Kon4GnUnjIbbIUWWCaeByLt12 -tk8I7vr7w4mtsjfAZG2hfb95piZcZ/gKe4UG9u5NCYaCs3ICU/JY6rCbh6+ffFZZ -uKo8OkpYFTv6tWPgBOcd6kzhNwKBgQDjXCmDggSm9DmFxgkx0m5EyhpTTqBkh38Z -gIFNVLwtMXVEvhGbPIMXG+XUaC+zyFeDUDq/chd2c+IctHyXjvOnJuaNmD6MbUwG -TEGQMt1SzEMpl91UJOFzir77dqjCPgdLsxx4AEcrYK4Oom8IdG0zqcLqz5E71bkj -rekR+wXe7wKBgEQgFkaB+FPQN0rObNhh/P532G/4/41oiAphkwdDaFX217eqsH0w -wwxd6yi9XDyocgZhs7Yg8g97MLlsj4DVEkkQbNGYu+d9V4PyJosyMgw1hApBmDAJ -v6N89iaR1EL2cGV3QjE3I1pIMCgr3rDX5PIS3eF4HZEF5Lo7gqbNHwunAoGAdIlw -3e9u4wSb123CmL77tlbBV6IdpGmvRCsSG8krCx8mtK2X6LIDn3y1OUKN8ODnum8N -LcQVMqoDZCM/GZA0Y6EU288FgIUlSrUbhgYMW7xHULJ+x/p/dPHRIqOXrLiOlMah -+QBrelh73xRzRSooLyr8tc7e6oSJ+TfTF1xLjhECgYEAhgHs58Vb3eRlMrtFtB2t -5TXFxmzXyeMLygHp2DGOliXEGSNoYLlhJJpFLexhbfPlVVyNNuWkliQ+e4rKcNmG -fDJq/9BOZ19xjGWYFHjXL/IXjeATQhFI/mMUhzfHoa535LK00TOocmWc1BQpvDKr -rccshL800qIwRkVID7nTRM0= +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0ialDYwBBpEmD +U7GoZiufXR57Q9+bvlpZ7JJUbmEMVCglcW2X54aIG7wcSmSBQlaBqIUVDwgOIdL5 +P7IghbWLAaybBspKDKkHRu54mf2B/FPvvy5KPs9zxQhP4updoQS6Etc2dRggNjgq +wrUBouq+9ozfGMdZdBvM652rw9Gf/pbr4mfqh2rGAG2gcjotvzFYiks0ifiWlEM+ +m/sVpV8F1ItfeX59ZZh53AWHG7/T96+ukdVNmUfCR3kqP85IAa2zJMdjcWJkwaqc +DgUMGP0AqTuTxicLmcTo/2z594e6eJDEjULby20OlVsgo6btqwGvXmfBk7EXN0zl +zFL8NiPjAgMBAAECggEABaLek+n9Ug9M9Dqiqz01U25Wy0ZdLsGMlI4cK2KeyQG/ +lxupbjqeKpWjE8cGyDpH9RhLv1KOz9IiggGJEBbcihBtURGvMwyeIkoGm+FC1tIH +1M5FJbA8TcLy9XuCEZY7TYvVCDAzpp3KtxsJB5oMdhXAZB6j6pkDXSxl6bzdSH9e +w/S6TqG2s1G81UY1DMRV9UyxxWr6pClNbqcbv0BlPd+RQaDjWgmY+rYhVkyRZgi2 +cxTX4So11CVIzVEMahiw7GS6ZObXCaXqKa2tTOXV6CUz5Nzwd415OybLfGjeGb13 +Tv62Sd5fIGzeM/kNcJu5ZcXwCNMEx4nztuMU4k62IQKBgQDodQwvqup9vW+8uFpM +ykOf8yjDq5HqVkp9GX9clnkkrAYXJLH5EfEL9+gN2TUSQNA8qkgFW+57sVTDbpP7 +yJdt/FTi04i9xRvVl9LIUZu+BWFRsq7fcTXQ/JJw4nZRFdYeb/oaZw69HMZNlC0e +tHpTg8hy+GsF7azh31vIX6UOmwKBgQDG0n1ZnHN4CkMYoaUGSoj9jBZSeBvVTY7k +bh2R8IQAgr7MKn7T4XOrv9/xHoXfDEIqOK2KH/N+cidklCa51JwrjxEbqYeOSnIO +H4cwZQOGzdkM575GynHeUwXN5WlgW54PrSikwTqvmDjT4yQGY5YHUfTSqD69XD+w +POSu+TUwWQKBgHYB5ZvVUpFet/jARecxzz7F/G3JDZw/DjWP2h4wrXM2eSkKkeb1 +er8urPlKySxpBs2lTEacMudMUNGdszZg0K8fKCC2bnaYN9co6fKTq1K9/HezFB+O +o1livxzbemETis2M3xTEOLE8iFcd4AH0cR0wi3QCNKKf0+Iet8Ny+qH9AoGBAKZM +754ht4+DfeW/ZwohE/6HyzAF2LoMmmXFGSS1uaO3uKGLNfRB0n+pCUZkUnNjjIBG +UhmDaiaskviU1uN+y3W/v/6USZch+86GXoyDIXUC/vbFbClIMgBVDzjOF9sKJuZT +3vgXy9+OApJwnfReHeJXkeEV6wx2easO8/TK68tZAoGBAKrASjB/OAEwFNE8DSLd +zeLKSMJc7OK2bZAmiDmVCJzoUogQzVydv4xo2vq5bXFCOGo2qDE1ehcj19fuxLv1 +73k8wpkxjB6FgIEpMEoXLjhrSpTdXaNHXqxgyalhsmpEOb1aozqrisqBUGrjLk2y +hr/7Fexl+bOk9n22BEhlTcLz -----END PRIVATE KEY----- diff --git a/tests/tls/child.key.encrypted.pem b/tests/tls/child.key.encrypted.pem index 46799aa4..db8b121a 100644 --- a/tests/tls/child.key.encrypted.pem +++ b/tests/tls/child.key.encrypted.pem @@ -1,30 +1,30 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQDMQpak/3CdXwl7mf -DNZrEwICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEL7jJg5Nyv7ywyds -5zjF0roEggTQw4Qi3uVDpAKTNCOXO8ndTMlczkPp8jDsE/0xWcGsV5kAD1Dywk3Y -mKnnU+08yKyIlZrEVu9k5CLn7kCzEZC3SSSYqG/LZNa+M4EO+zVNjbIwD1K3p26o -1s6gxDe7H8HChPDye63VDZJ2ojOwPJBKC1tuPz45W9X7o45NSBwflyIIhNkudAHf -yY0foNlDTBXFWRDvuK1ME5e1jt78GWzyzvJjkR8xZDMVb4TJb/mZ9OrA+1a8slyz -s6HNJGAZWQnJNhoWBO5BrgtPC/xPnkCNY/TVm9hKCp4aQ2QItbnsXOD88BUI8kKk -79dZbkyH5qalmSM8zvim8thDHr5X5T96hm+YSUK1ijD7NmCCCwlt2adCVxqKH2Ie -kwS8M4OJYlKzNyih53tugKYp2P7xXchBKvPf1wh7tfGJLRZtOHDpnjrzUzvUb5EU -C+ZBZM+UfhJcHb+l5012L2iOox5pH0tsprp1zD5FcfylFXFNBZG41FaEbajfk4UW -CJiURJH1VyFnrLTiHk7SVb8VzUVyFrrX1Npk2NEqRzfg7/d1+QyYHaZAC/9MnbP0 -SsNFjpu8r/8ujjId2lbemQ26Jj7UEVkL7QiOnRtf3gYqPWOfmWNgtNA9PEImr8Fa -hPGRh5Tp5URNYmmFaOZb4/QdKVAYArPa7xXOHbwv0CEKGYsp2houL6OEyC27cbJS -K2W2jS6SvxJJavzbGWrnNL+Wx+9BeE09DtXDxGxr6VFy/EZ0FTDBTXBxi15/8LxC -WP7ZmVqYU6LJNML6oKRmS9UZAh42O3KHWW/lbEtey8Bz+HKGEMdHi8aRk2C0/BU/ -a8orBZa2TQIl0i7gVEEtQJ9BkLK1G+KTsmHRudbzw+y169zVqjFK7StxofbUsPkk -srEZNwE6MVn0n19Tc/kQNIa79bSGqlpMtFGhbXBzdBqQfZx9ySf/wsE2+JEYbnx5 -i06eQWCTy0eE17tSaJ2BkJc24oPvDoEh9375et22a9S6zRgXPIBpF5D6PlvZKkYa -ZEv03VrpJzDBdoM6i3HIHCq/aHkf0IumilBjqvLgwr90sQkn/YvQZlPuyVb6H7ay -A+1YcSNBVAbRhYipyUvBvXZCSbpSP/hty/cjya46fNsZEQnrelNNUCoPtxvG98Yo -FJ7TYtAdi5m+qvYtsEA/etaPeRh8S7m0JuXAEckjMNxDhTx+nWdcwc/OdLAMX4yx -S7vYP6qfvxbaUjfHwRgVIB4f9XEKOjuV7gzdr1o1pE+cgEk1MnPm27ibb6nm1NDB -UlMPVSHcCuJ74Q8TPjTVoLY5MhulRUlEAg/4kgYuM8ReMb1Usr6bguk5E2Derau9 -cEv8SWkHrpIyqHWHNV9EXRtbSLW08SwIirESJ/x+V7SoiknlE3mTyNZzmKm/tG7I -+Qwo4vu3uKc9efvyI8v6HQwVZaKAr1lCbS++Yo43EsBBOM3WiKOf2ROkIGEoBASG -5pfPjVhesioVkyl7n5fXn0ULewPFxoyqKNSP+WaTkk74AVHdn60VHOsigfmSpiin -vv+zGIGdkmhY/RuBFQrWnTBwkk5A2CrOAmhfloiCNud6/ei5UaLLrRrUAUYmDxrn -H2TcUZ3RzZvb8M9HOZIBJ0VZPhmyvOQUTP/KReqSmV36Mgo+oPwSboE= +MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQ3tXdXhu4tmny32VY +lDdelAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEGdra8qMj1KOgd1Z +eIbh/u4EggTQghhyWEkZvuYi3WkyHIlsWAUDJdRjNKWAAkuhhuaiwzZIoqIM/yX6 +2KGpU/+KC01JOHEnz3Ur+bQVc8/pjPu9YCgRkW6O9GdoMVnLwU0AzX6FdtyZOlFM +4gBPS2w1ushSbi4yiQDgGdTYl1Y2pYBmPX3phjI+mrAVP4dJD8QBrkPdo/SNeeWi +CEbtWM0S1ljw3yIxy23K8I7qCZaU80JHEuyoWXDZGsOtR8BGXJ8Ps8fXulxyyCJ0 +hrZW3ywTEa8BxJO3sBzxex0n9MBtQzznktEF00uMP3RLf9D6qZw268a5SexxIUFN +01mOOczRIoEOlibOrL3sLvcbAMLjYVeCQEEqfRCkFJf6UOXROMmWTcIrXPq4/fym ++7e+0NWqB5HQ8slcJyzPt4ouH//TW3CFX1P4odtC0heRvRZ/6NYZTKNzKEi/rl6X +MHcu686zdfAH1dEyyvD6lD6pQP8B0BsymUFg12rirYg83Y3Gz2eJAtomD0VAG2fx +Xv81pcsCuMXVzh+u8Qys6GqVnK6MbSoGjyaYx0oZWv4H1K7lzZcrORRtXGzkJZhz +e3xO1eO61Q18UdMEv+AspmXJygN4L1vrKXpCd67qrQ6MfpMkgcGLxJPkHkD8tMB9 +TNaZm8ncpQ+J5KEa548FKlBKSrOLnutEM2dF3WBqkt/56arnwTLy4dZabl4sPyQK +A6eUn7/3zllWbB3GXIzQD6Cabl0CSDisT44ND/xSy50l4ffOP0UmrUhOFp7/EPFa +nfW44emjn4AtAQeW6WqGiGgupJeVERjy1TNiOKnmDR0mboY3QoQ3zFmOO9GX3n37 +tLQuWP00CZzwASVdGYUWCEpG5zqUvIVY0NjE8PinI1WDKfDbQekiCk3HuqGdC2zM +hkPcjeGGE2FweNBZotW4DKfXX8T4QC9oofD3O8usBdJ2Z0c6kT8Jy0T7TXEsEjjO +Eol/hHfdXQH6LM4z/Eb2bKQtieabKG9JIfKwH+luAto7rTlEQCPQpwQ6x2VPxaJO +UOzr36XTqFWM4UEMDAos3XNjF6FERZM/789Gr/4Jl9jMm84qHBKAcOXdQsBs7K/i +k/htHaVVEIoQ38ffzVLjTTkRjbufNDlknzhyU5ZG958xGF/ktPSK0qNTkHAyzPQs +9ZVODIkMNXbhLrKFy3nx+wHDzdIAxSSgWtXnieNkp4DB+1A56+3oZX3ThZYlXttx +3CkAATbzEZ+OlkiyZ8PglCx/Cz+YgCJIY4IRJJN7mb83idR4l97J63oc+5NwEAkM +4iiU9vKEnA8K/qRzKgk0t++/zv//ynbJivTcaNbQAXOmT06Nfc1MPRbl1KVD3HI7 +Uc+AqM7pvwU+zxdqKfmTjaFWXQH9ZpFuq2F/WlsVGMxU/6QMYz8A+yiQlJI8ZOO4 +PDIFzlNlgx+R+lMRd7h7U1I7wxA4XPti0IGHLmO3bV5v9x/meOO3yMEmGZtEbpW5 +e9LBpEppIMWSfhxPe7XPH76JTuAdseH7x7ABTWrE42qfsS8rKbzSW2LdBpK8+5vV +xD0+i883CmUbMjTbAPyKjM/CnAiOMncX04QHEokJhh5Ayo5b6R9zr2kbwHqeB4ad +VLKFqSTJMRBD1elJN+AN2EozhN4/BZPA7/0s0WIC8jbcHHZBH+Qojyc= -----END ENCRYPTED PRIVATE KEY----- diff --git a/tests/tls/child.key.pem b/tests/tls/child.key.pem index 24e02749..9f0590bb 100644 --- a/tests/tls/child.key.pem +++ b/tests/tls/child.key.pem @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDZqr1CFVfe0qT4 -KepoQrC2LKhC/YkE/TxtoHu1HOILuCnunKXxHoINctTrpJouHsnhgK4icDiNXno7 -LzLcYu2vn6MgapFaZjMQudQBsqQGIzvMQuAYj3mYmdCy9XE22kyLYza6rR7bsnrZ -p8Pk4q6zirZom4EkrUxCWryx5NU5c7skf1a37Lgdrq11JMimaCKCoEJPwUdLkFbH -7ZOS5dedJnA9fc+Q/7dvY5nuoKIC426y8uGFaD8tdls3npnW92QztGqVnHqNIPry -FOMY08xnJoOXJdQuz5nCh0JtqHT0GTXyo78f4+QbWFheTUC1lKq3BnhV1IAS73yP -rhS8JvRZAgMBAAECggEAFNYIxuYnIq/UVeMhSrizlMTCmKMPdjhNjAr0PJqWstt+ -vBYntmSeu23WHvaDQc31sk3wnWBTsYitN7QlcL5RlWG5KlW5M0ecNMotFrqEhAfk -ZgGy1PcLA0YaGb9wBnmwIRmuuADxdsNniiVKlcLzSUGKg4n7O0kRhzqLXJYUqSqT -MlIatf3n6LpeV4BEbzZqWtiU0gBTYW1sJ6nJqyikn1k+h1b3/hwmUpTrNd3fOQkE -pEBeWLdOZDvIX/qtx5VeNoqkv7XnMvb89ROof1rgdouO1OjBUBAVC06yY36Zz26C -M2VuxgciJmqjWHCHp1YhhuePK5Iwgj1uD2p4SO5ITwKBgQD1Ff+PBNT0BUVzBKy4 -aaPngPJ+IUxpLCHS6cYy0jI+d5zvUzV4IH5Sj03Kon4GnUnjIbbIUWWCaeByLt12 -tk8I7vr7w4mtsjfAZG2hfb95piZcZ/gKe4UG9u5NCYaCs3ICU/JY6rCbh6+ffFZZ -uKo8OkpYFTv6tWPgBOcd6kzhNwKBgQDjXCmDggSm9DmFxgkx0m5EyhpTTqBkh38Z -gIFNVLwtMXVEvhGbPIMXG+XUaC+zyFeDUDq/chd2c+IctHyXjvOnJuaNmD6MbUwG -TEGQMt1SzEMpl91UJOFzir77dqjCPgdLsxx4AEcrYK4Oom8IdG0zqcLqz5E71bkj -rekR+wXe7wKBgEQgFkaB+FPQN0rObNhh/P532G/4/41oiAphkwdDaFX217eqsH0w -wwxd6yi9XDyocgZhs7Yg8g97MLlsj4DVEkkQbNGYu+d9V4PyJosyMgw1hApBmDAJ -v6N89iaR1EL2cGV3QjE3I1pIMCgr3rDX5PIS3eF4HZEF5Lo7gqbNHwunAoGAdIlw -3e9u4wSb123CmL77tlbBV6IdpGmvRCsSG8krCx8mtK2X6LIDn3y1OUKN8ODnum8N -LcQVMqoDZCM/GZA0Y6EU288FgIUlSrUbhgYMW7xHULJ+x/p/dPHRIqOXrLiOlMah -+QBrelh73xRzRSooLyr8tc7e6oSJ+TfTF1xLjhECgYEAhgHs58Vb3eRlMrtFtB2t -5TXFxmzXyeMLygHp2DGOliXEGSNoYLlhJJpFLexhbfPlVVyNNuWkliQ+e4rKcNmG -fDJq/9BOZ19xjGWYFHjXL/IXjeATQhFI/mMUhzfHoa535LK00TOocmWc1BQpvDKr -rccshL800qIwRkVID7nTRM0= +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0ialDYwBBpEmD +U7GoZiufXR57Q9+bvlpZ7JJUbmEMVCglcW2X54aIG7wcSmSBQlaBqIUVDwgOIdL5 +P7IghbWLAaybBspKDKkHRu54mf2B/FPvvy5KPs9zxQhP4updoQS6Etc2dRggNjgq +wrUBouq+9ozfGMdZdBvM652rw9Gf/pbr4mfqh2rGAG2gcjotvzFYiks0ifiWlEM+ +m/sVpV8F1ItfeX59ZZh53AWHG7/T96+ukdVNmUfCR3kqP85IAa2zJMdjcWJkwaqc +DgUMGP0AqTuTxicLmcTo/2z594e6eJDEjULby20OlVsgo6btqwGvXmfBk7EXN0zl +zFL8NiPjAgMBAAECggEABaLek+n9Ug9M9Dqiqz01U25Wy0ZdLsGMlI4cK2KeyQG/ +lxupbjqeKpWjE8cGyDpH9RhLv1KOz9IiggGJEBbcihBtURGvMwyeIkoGm+FC1tIH +1M5FJbA8TcLy9XuCEZY7TYvVCDAzpp3KtxsJB5oMdhXAZB6j6pkDXSxl6bzdSH9e +w/S6TqG2s1G81UY1DMRV9UyxxWr6pClNbqcbv0BlPd+RQaDjWgmY+rYhVkyRZgi2 +cxTX4So11CVIzVEMahiw7GS6ZObXCaXqKa2tTOXV6CUz5Nzwd415OybLfGjeGb13 +Tv62Sd5fIGzeM/kNcJu5ZcXwCNMEx4nztuMU4k62IQKBgQDodQwvqup9vW+8uFpM +ykOf8yjDq5HqVkp9GX9clnkkrAYXJLH5EfEL9+gN2TUSQNA8qkgFW+57sVTDbpP7 +yJdt/FTi04i9xRvVl9LIUZu+BWFRsq7fcTXQ/JJw4nZRFdYeb/oaZw69HMZNlC0e +tHpTg8hy+GsF7azh31vIX6UOmwKBgQDG0n1ZnHN4CkMYoaUGSoj9jBZSeBvVTY7k +bh2R8IQAgr7MKn7T4XOrv9/xHoXfDEIqOK2KH/N+cidklCa51JwrjxEbqYeOSnIO +H4cwZQOGzdkM575GynHeUwXN5WlgW54PrSikwTqvmDjT4yQGY5YHUfTSqD69XD+w +POSu+TUwWQKBgHYB5ZvVUpFet/jARecxzz7F/G3JDZw/DjWP2h4wrXM2eSkKkeb1 +er8urPlKySxpBs2lTEacMudMUNGdszZg0K8fKCC2bnaYN9co6fKTq1K9/HezFB+O +o1livxzbemETis2M3xTEOLE8iFcd4AH0cR0wi3QCNKKf0+Iet8Ny+qH9AoGBAKZM +754ht4+DfeW/ZwohE/6HyzAF2LoMmmXFGSS1uaO3uKGLNfRB0n+pCUZkUnNjjIBG +UhmDaiaskviU1uN+y3W/v/6USZch+86GXoyDIXUC/vbFbClIMgBVDzjOF9sKJuZT +3vgXy9+OApJwnfReHeJXkeEV6wx2easO8/TK68tZAoGBAKrASjB/OAEwFNE8DSLd +zeLKSMJc7OK2bZAmiDmVCJzoUogQzVydv4xo2vq5bXFCOGo2qDE1ehcj19fuxLv1 +73k8wpkxjB6FgIEpMEoXLjhrSpTdXaNHXqxgyalhsmpEOb1aozqrisqBUGrjLk2y +hr/7Fexl+bOk9n22BEhlTcLz -----END PRIVATE KEY----- diff --git a/tests/tls/child.keystore.jks b/tests/tls/child.keystore.jks index 1e048814369a0abe022d0f8882a218cec1e76751..a178ec055faf86cbdbf4af002df082763ffefb1a 100644 GIT binary patch delta 2529 zcmV<72_E+D748*~b`%b;PNGFywkTO=98-looKVkYZh)K<@*t0xq{pn#ae zKSFDYVP@{WR53A+&bnVzeWifEbtisQ?OHmyNe2VkQI|_L|18rm?*QnhW)o{@{W0c* zhKlsxxmwnWwtu1nB;zqZQ663u(KQTgEpZ;G>pcm=nbY$E;idBuWcY5LRaG!V4*v>r zXWZ}-|3tNGlBX6RFHJVRxBT@{75S6R-cNftmY49t`{tjKPG$W8C|{8<9_p#)Bo;f+ zmWD+*Z|ha;AaFc0JwHAYkk(M30Dy@b2wBXOkU$|6vwt-ZQ>CHpAdL^T!vNDG@$-4Y z5!L)dih@e`&g56IM;f=OJPLnTGH-#20T#7qCdk2_>CnF*)V|lC!F(O;SE)ipYEO;) zvkOP^sDyEEs1Y=ZpH$CZ!xU-F0OFS;dE)K(kiD!l3%w`xVaxbdb7mzomEfI@fiTtF z6v7SBK7YL!P82)qygB#&Aav$rb_1ry{}qhZhMuxnGga#5=4^B;zXKQFtL1ujd%K-L zYjy#OZi~g3F31`jNYm)(GfPQF_}?bz4peHSse0r2B`qsDQ88$ZtI;5&6 zJorFL{;nzy2_)94B-%9yp_f{Kcf*_2?$8{v%0-4!T)kIg+{6R@D9rYarr*^$MxYtT zt$(ua17kZ9MLgsn5qJ)6@CVj$zZf-znE$Ib5lfq|YRlCcnAecCqT@l)_S<+Z-Tn?7 zN3>M^Qjpuv4|GCl7%TIk>UAJR-!>o!Wa|odXvkKEjJk|9Y=OUtO$jEjZ7|@4Bt1C1 zD`;;z5UlnFWR;8o91U^Yeua|yQ0_9xc7MFe6|&EE3f71zqc8IO!Za|T;A_z~m`}7( z&sSZVRm*BwOU8igl(1nYyw@d-+ed{96w~Ikzp*eW_U>x2GS6U`_f0W2Q-z{VFHWeF zA)#bJ1uJsQWXqeF$?9}pef%;>1CfyF#vSDVv%A1c*lYeX{iiIwPQ=y(kPrSiC4X`E zyHtLU$`^1VRjmQxRNQ5G=Mjz--of0;YLKd4nCY)u#4*HHz%uA@G@?Fgm)Ba`OOcf& z1Ot)NbSA53TJG84`1!zqW_K*j&uCazaEh1FM7Wq_%#ZUXZsZVkQYNa6_WpQy zaFpuj6TZr2RSwuY*)VZ4$ZTJMB!9p?geMDJfKSA=FPG}6qxTEJb%LfsRK~f zDzS`|lI^32dnEa1HnEJ0aY0#*bdq&L@|_iVJb&^BrjY20%#)Y!G;X>QJ9G|ICV3U{ zAbz8aLs_VH;_iba{n8nwFX0+RYHUBHO>AHyG5L^IUiG0$^nUWZ$uGlLLQUK8B-7F{ zHZTze2`Yw2hW8Bt2^28|9+RX6AO<-(F*q|glgb526mjN%s6O<)g0mn+fov7y!KAK= z&5?>Ee|i}K)?i;GBUo|D5q;XUhk$|vK+n#4`#(K%dT5P$%O$-N-QG9&M@`|pq*3o&{3qoEt;P{9$EznihzqRKsvBl0K;8iwf`D( zO2Hv{O!pRS&t-cF-rS1sYCCf_Y6xFPw$DC{pM=Z)MPo~~JS77_V|tfc*Nw-My~iK1 ze_qqE7<0KYY#7Ji2eBh38zUN>FOJdm8bQ60WJEDcprwRbbR9xKiLvrHqoHkYp*o=` z{N$Js?kFa4jf+->wHB{v2hOsXYwMddFegJHAEiN2K}ac(zN-c-NsVgvYf8C@E zHP2SV`vsuZ@YpKui?`}foj3Q0$C=47m5wFnsO5+5THs)PL%V7=NicOzEgQ1P!)Xm_ zbWL>hO~ve%C<3U{_?%Ghoa_LuG}U%we>n!H^k(OucAdjdmLMFYe4^_q03eYP**)jm zAtR#XCr02()b;6h2HDLQq3?0re`8QM*>mC)LN0(>Zub;{oKY+kG$o(&A6PUSyvjSo zb1lcdPs%g!RxIGaR_Qk|m8w{pp&=)})H45TC~KiFPNV8eL*rRDY$)>r<)jw9 z&AnA-8Z0haI`}B~%gzR`rfjcrLj^$Ot?Km;iMIo$aBt?W6uDmVJG*wYe`nTlC2|8N zFol%59$|_bb^6xHO~$Q!bC`Z zKtx9cNwnb5JJ>tYQ22nqFso{LMd_D1??lG%0f1w1xbHvQ6&Uw4nZ+`CtXpl;zL)em>p^bmX*z|Fv+eE;f^2ndmiB!B%z;+7jd{u&o)LC;&% z+_nUQ1khq%KdNc!@SN4%Si3^x0vQ>3C=^NThpe!2D%>PR)kL$px7Nqoeue(ue8vVI zZXd0JkM=bq%E=}sb~*RvJc`W8Ch0&;q=$SHs2jG#ovBX4o)k?<*P~AS$Z@n#=P=3c zhQOqb$zd{=Wqlc!u z;clM1J^(3FLHs8RcOsu4BN6C#;TdsM!L%48Ma?@OqoXDYt;Vgd-B!^KY2ETMNp_=> z%kmWpm48(EVK9VirspmpoekZ@9$uN~>0hmBEBhnhiO&D8_)x&xC?W0B9nPZIhcb75 zRblVm;N+>HiIpl6(&2*}+QN!+Uz=8H9w>>81ssbuDI?Y1IVm&owC@7J3~OWM1$-XE#lu9nZ*v82;Y zf{^@N-uUHED4GJ`#pnt0HM+DD+sGiiXW0hrw=Y=`l1GN>lRj}7G(VD%V3HmnI$s*v z+JB@wic@GFN?Rw91Es!vmr% z4M@+5$OlD&< z7lcPeD-GTt298X2R3x4jMMXXW54`IdXn&X5bF25FK>wWSi6jwEVdt^9{|pZI{nY$S zRXU3pP7>7LHNI7?BdF|&Y#+Hevy>Drp=atAcK$q!U))Q14FH~pp~|PkY)%svEnz&G zP990*LQ)PMii zt>_Fk9K^tDOX?_Xm!jEV^F%$T@w8%qzA|w^cv;R@)KYD?wj8P|CdpI3O4_j>MG1UU zZ^jc+5`|gZ?T+9Fwh&4Cy6Tx>%DBwlYC2UI*CK0&czjTo;n#(n50eTspRH);%UXWA zX9l&p8s7zWlD+M{zFzwF>oG<^%f<3{;KKl11wKn8RI52_CdPx30?X3QY zpI5m{)*EJKUzgCmzcckw@Hfa%U)oAWV1_0uzM|Lj{+oQt}4=DL}bj-3M>mHY?`;p5#M|J#5!=Uh{JdO$!hsPZ; zHZTze2`Yw2hW8Bt2^28|9+RX6AO@(G_jYOK3GnUCNQ)PWgMfkrKnO8kqn^gg5V9csM%6&(oF#3d&3d~-AC6jcPVqQcLygH zhsQ4nIYzb>tJs4W;;O95+f~Gy?Ybq5bF4I_deMKk%YFT$$R3^u($Nu2AdF+U1#g6V z1G@U|(wR`m20L2Tx%;%XQl}-QPzGD|e|**OHL!$iknp)#rP7cy;I?giWfI!L$;cSI z%xV714uIMcFbqqZp7yy1?j7MJO)) zD71&J{#1YF5Pco|zd1N;xCRf1hro9zQ2mdIm!2NgC9>P)guxAxGgU1VuoHA`e?N^F z6?0j@J;yQNjLstMK?WioG@&i_oN8B9In}Mh8U*plR4W8(n)jRky2B=tpvR&Z0+1dZEJr}l^myMp6D`V@RdJb4OofO+hd{gOND+k54bukN+&)!@4fTr}0D7?72@r2^ z=j+}i^hSwp(Mfj6U=)W!{wedv`Na4%wVJQ#Z*ne)v;Kci3;de>T{ rlYSH+eF;&Ib3lTksxSl;sqUitA+l;;+hSK?;rwx`d{OWq0ssNnHCkPBOto{B_JwR{&I9wyQ(6m6x0waf05?R&moN%@~`PIxEW{&{rD;#2HmmX{M2{(fE1)>2DC)JcL{x zYC`Mf41c;y$60R=_is&xIJaV)REqVsDzt7&)?iCqv?hC47n9e&Ocq%o3l;av?#MOU z`yqmYy*q@qTBLxMSD^sHrBkR1F0xY_sSG`h5VS9 zSXHofh;wohQgN8^0IJ?sgDQT}GuW%kUVG+tQfEzce)~ zmC6s7^c{@Z!!fFinLpPP3@!6XWJ9=o>6W^5(mWGYAM~>dRw3$!{YFK@I=pyeNmX17 zzJKp?jzGS9+wV!2M=%Mc?YWSD^On}I`ZrDAw?GFVlCQQPhqfb&^s9isg>Od8q>q1O z&%-D+obO)WK4YB_q|k*Pfq^KXG>_m;EUd{KatsP|q0z9N|Av8`1ab+7`021m_a2sl z0c`&p&X7YDjopD}BE}MTPW@2ChWUPS=pOUBoqv^ybAc`qpy$~dDnpOoxG-6ZMcPSTCldR4n2=8` ziM%%tR*+I!M&CkP0Qu-bndv;Qb=&W`-`ZP$9z}*gf-;V8@#8lYC|8czb-~R+d$&=3B9DP&q+5!k)n;~~ zD^#dE9s1&CxWxNX&g5p<7&&vW0RU=t^4zf&|cgQAGZ21M3d_ym`PS63dn( zcrHkl+hlx?iLi^7?vrr5!f1*wRLO^vT=X=sYo_(5gW|%#d)3qGN{qEuWs%oWHBg8# zmI*QyPUZXKQKwE2YF5;caqQx+;~BS0$@xhCcZ3gps4AZf?dKuxdT1yS?BzGQ|jA*o1R<5ivwLFz)TMC4;!_ zNUIsUmb@%>_J@B;?UAnUcQ_w(7{&G2WH9|`iV$BxP~fVaSSZ8lMja+rS?+h9l>bJYd6H3)`iD?+1M+&6Ob{ICDQ@dsUn2A@ilk^@bHcStI1 z-ISe{Tz3=8KP93Du;$8-#%=Rr0q6d}6*yM-%`<}yHr{{IA9z?aZ!%JukNl2&G&6VO z=ypLL+L^SSoytKOJX0`-Q$KRj6_ zN&Fg=*%n_wvNJT+aOhKkvYIPyVO^hAWf}F7uKMesV8XQ>_vG1D|HR)XH9GWYk4TL# zv53~7b#Z_Ay&Z31#hE{KUIh*`rLEnhy{jbi;j}M?j7Q=R7`shoO7r^?3~N5q&zmgH zAXL`eRGhzGO+vnGh(?~77VniYIP3}4k5o8tB47Cc9qtjNgKj@t(49%8JdZ5wW7M^) zs*6QGe~Hs z8kB!+O)Yl{5DJ%*SBS$)Zu20RUiEJ*0gW*2+NR{Oxut)Y z#{|O6!^HxoWIj8V2;(;+P3@lh41s2i6D0Sh)m&>vNHxss(3ouUv;vEDznGm584{oM z5;Orgq1FS=@!r0(?`LBxLF&DuH|QbYuZ}IcQu%Sox$mGCrL{aGqZmL zTlyp>7HR{;tFx+cAdNSa+V@IpW<~Awmj{v@Rmh+LjnH}eweNmY4|`Gb%OjXRInk8P zJv2M5Yl35!dbrIUIsja5%?dsZi*PdN#QjRIFWVYM>|vvgC&^B!7&6AX{as}F!+}9LnX(M)FoY|mu}Q2C4M$8W z6@DQnq9!29;ff0cLX$GN>YfjToQ5GE=^DkKhuw=q4|j&LNQU+&*a2E;2}Y0*qGZL3f6` S0|W?!OlqGVePW#g0tf&K2+P9& delta 2504 zcmV;(2{-n$6|)tPYY@pn78PqyF4mPf_dKPr3J{TdA%82ChXm*b2W9>Xy%lyhE6;#} z1TglHoImA zv=a2pvgev9vGZW*oTNMuEAxgS2LH*Zu}t%rlLzx+>ln5n2!(!u9}G^5WJV8&zjh8y z;U;ZtNq-V`5>gIG1D?VF|N4%~Z|Ow5(fP&{@BGx6^%rbE{18cl7+Ja)0|E9Fij6-a z82OmYn=1MW9~Q@1$U~&}k&mk#Z#Rd=Ks}lf+uyy$ERP@(Jckc&=1g}Jn;im}_rjmq z_6OiCQk?M{2g!&)Ib`^)tmsv9KfAUTr&;@@3xAB`g!TPXF98D0+{P0H(AJfxzdiEB z^9?tcXb$kyA$w(DpS_+B28^p>Iul49p~9-l343q~yd;-WCxy0_>KBms7xX>|_{YoK z692okuXQX_l(MgqyO!+D*xgyw)D$xrUx)PMUJRXBby zlYfh5Ybl6>-!;~B4mt4`Ej+r?la)S~6lX$7uy;~rf`PmgBJGl;*4nHQ#tGMp5>kI} z>;4O8Jd$-SD7~hSHnvv20jwknHAhI=7_{&NjC6qqB=-96FK9p8`EeichX9(u#@Nkk zPG5hod%J4(iN?x*N4!LLbQ}k0y@yLOXq>g>|3lLBES*jy|0O_>)6_Q6wyQDh39% zlQ(k3hWi@MyVMVr1OH{gS;Oi^Ux$kl33POCmTOOjB&!~pSEmQZ!j4Ok77!{ZlN|GS z7C_rKOnDD@uLCM!!jM#B*xh~j4S#~f=DR>+=FM}}L93B* zhrDCsJ1G2Az&O(BFS ztO@wpoIOK}L8K#tA4~a4akPDum9czPfIHa0iY5(ZT2gK|?v^>DUUGb=YM&^~3UjfV z0U^U!A^QZZ2y9wZBPe#f^%^dPBPw_7I+|1m74Oh%*4-9U$7Tky2S~C4nBEQah4T(q z-{^+}@!Mrz&&Nqb%rAg!xJ-FQJ2cEE`0CpgSP{n@ArkrFrgxGp)#^;Yud9g6Qn`-m zE>!~c_D_&^*~};F-C12T#fhf|&HlB3&Q6;I-@>tBCHL#f5dlj^nb?!y1XK_ZWJmow zuIzH`5CE$3O;IwDdm(={+J+1DDDpW?;&$V!50MoFf&|bS$mHe5x?3HLQ!^vB((UOt z3jc;N2HHEHOzIu>ftAYnvP-+5kVhE0?6k2OvKXfry!aXsy2KVXK0Xn^X&hp{bFk|L zo|T0BUaMdD*k>!dWN~AF$1{~9wc4g%o;GB;v8G-kQrSw_Vo85Uo;Eqxw3>#aFJGey z)rCm1ho@l#XT5}jMEvX29xSTBdbc?EnZw{*3k%A_BVw?PtPl~Jca(jeD=U?1ub-wn z1rvS9ILW^x!()bW6$Xv@qJ(J+KT^LZ61Wob?F@BidBsD>BJb)>u8NMTLiGCPCk!!c zJ8Boj)-yTV3d4WMaJsKxd^-~UmeWHl4Tjnl^z{o~yiOuu7l-o<-k)npawkSh7|N1%^!}pgqBnw&&=Nq^FRx=Vskx3<1<-uI6T}iSl=FnY+EOC=XxI8 zwD_N!`r+LEVbP_wD#~zQ>vD)271x5qIYI#acwV~VhfjZLD#pN)2{j3RO%IhQ8e)^-`U9RvtxaV$K}=;^h9`1N*xq~>o@bT@3vhdK${-(02&S* zvmlxi{)bWEnF-Ixz4b!J-O40C2WU^9KA^Hz;S{FJAZ#(aLhXrL40AlYl#6B-&l!-w z4N)JT8t;F_?$~0e0f`Z9*UQx}i-Utbdxm=DtEC#rgj&v)3X}%hzw`0y=Ay2HNX-1< zBZmA#xBrW5%OKB4eu=@yO8$4O^(@FUJp*F=dB8D!wi4Gy6oEPflc3Drl9LB3FGxWl z(qyj1iR8p4=+;zNpQL|aHY4 z#w>rp0q#^B!dm5hM?o!x&2<4ah{F};fboF=rn}HVo>)*DM4*dr|*A_ zJ0<>377<#J%ZBR`F8RG}N?}S45rD;u$96WBb>K_etHiaIs@TELe}^H)NoTWF5*VAW zV?Rp@yth-Cgq@Y}f{SX$STO6shjwTA^E`?jLCp!qo$@K#a^d>vRM+qSRr7ATWZ) z6Rl97n&6ddjm>qmS%gI6_mgN%6Ar20UBG(!!Y-{tYmM_;n?hYd$!|CjaMVlPnHkK3 zvAbQg%#s)SiP+t@3Td;;w9woWIHUcJ>H!$&LNQUB!8$SvG9wT1!@%!OZCXq ziX(u61dua0ttEkCiVk+Ki6zX|>`}pK#a4Xy`!*^Ij_FS zg8PjKEhF6u0e=)56pA0l5*=RcR|tlCNaq^z>x*I6N(y}Fcgjt!gLI!R!BCLqlv_(k z$ENCq&GU!v*|Qs4R3x4g^dboHrR9$Uz+IRXqnZWbT1k3NZ2aC@udLcq+4hts{s&otJX3XfOcw^r z2N=bq%75;^VJ)97TGQj^Ot(X1XU4x~aO1wMnXvD7XXyo|8QLm_!oO$FQmI4#FBYvo znl^|XD82=g(xm!+TgXR6>xa}-Bo_j-xA??dbX=%}`|$Icj1E&BMvfXh3l4J$JYy+i z6dr`>XV4Y)ozNhKmyAT(riKREb3v%su1x1}JbybkN|_GLJdItMtC};BYkbQ#y8doI zxjg~?KwSfnuu&I!c9#+TPkWt+vo_uoxg0J$SQ7H47cRj0gq{?8b-|_L$^HJ!la9Tj zz($G`)emATWBCH%qU_|rxpB~e-j$1}dm<~Qez)TH*M8gs9}I5{TlzOA8KVn`w3`Rv z!GFjPINg#?3-Oyfn!g`FhIu}g_1PAjh@aSWfa}FlPC@;!INEk6U((6kLlJ~UgaNFD zj#Is+V(Ab7k*lf7D!*W|&GRNGmlcE}Ea0%#8+HCX20i_7L|AvchIIa`j=y+bm%n)K zh;Xc{nmWjZ06c2Q-F`1*I%W>ihCb1N!hfkmpnCE)M4Rx}Sa#3V$u!QYt1VNeTM9;` zFAe?$KcENxuxuYB#|E1ucBj!wD_YGu8PUKYh82a}`B(Z+w}0fT!@gZweo1F_Cv zMa)sWgbGUX1dhidII>S3F#xWoU_Gw*H_~4P#npPeJ~snl#CCP6!zCE*;te{0Wq(D9 zE<-P|PDh0%&{M^3h<>^xO%SfTe-`p8R9CE+8t7jZEi~y63B_cCSA_Y7=+tCX$KQiz z{=&%q9`L>&i-&%Y4g_<>5KB>&E|Cc@#eP{ZBp$Fh7cI8h`pLVMmnn5RJ_-T>n(>jso?1DGdB>5vtm~JVgsfF<=-S%B zkz)9RH*{1nbJ1$KXQEW!9D^(hE))y$Cwtj!<&QkgKmuB7M@0oC!; R=7SThddCPl}+$0a62dBWm-qTy`-0BPI@to^GMXS(# z@Swb$9dbtzidb*0>XP}RU?n9^(S9viPo9sP;8r<&*Pm{;Un*v+QSOYTi>5#ul0*cA zRn=<9ArYkl8z}FFoogmgQ#P0>h(~-0%Gj;6bTP@6-hUDM2hUW;6h=7Tt0w$Xzggy4 zn|ttBT6qpg!<|tfr0}PW&9_!RB7 zbXNZPQd}lFme>rfNS{gDGVwJCvt2Tg)2Iv$9iGcAgYmWf;1F??a*2?q}M6i z3~OdH2(gx%io~0I6^;vFOSGz6=n8ChG1tO7TYr2Q_*oT!C#0haQ!36!B(X*-W?Vjh zlWQ^IP|Jd}sA|_QRb0%}!lfG>Yn2I`cwIki%&-p*O z)_=OuuU{B1VpJn4{K85jCk?btd2ve29V#{c5Ei8J54AxAt>%%H!V{XsJJ&q5n}NuRdS8TX6AB(lz4Vx+djUg^MCPnz_xlvlh6!lxnp$PLzN@h}QUav`G7b|4E2i)o5ENO+W!dGCQn8gD9l;$r# zAX$NEn5VOc9kXX5kHczR~XWf! Date: Sun, 21 Jul 2024 23:45:32 -0600 Subject: [PATCH 187/215] Flaky tests --- .github/workflows/integration_test.yml | 992 ++++++++++++------------- tests/aerospike-vector-search.yml | 51 +- tests/assets/service_stanza.txt | 2 +- tests/gen.sh | 2 +- tests/tls/child.crt | 23 - tests/tls/child.csr | 17 - tests/tls/child.key | 28 - tests/tls/child.key.encrypted.pem | 30 - tests/tls/child.key.pem | 28 - tests/tls/child.keystore.jks | Bin 2798 -> 0 bytes tests/tls/child.p12 | Bin 2739 -> 0 bytes tests/tls/jwt/private_key.pem | 28 - tests/tls/jwt/public_key.pem | 9 - tests/tls/keypass | 1 - tests/tls/root.cert.pem | 25 - tests/tls/root.crt | 25 - tests/tls/root.key | 28 - tests/tls/root.key.pem | 28 - tests/tls/root.srl | 1 - tests/tls/root.truststore.jks | Bin 1430 -> 0 bytes tests/tls/storepass | 1 - 21 files changed, 524 insertions(+), 795 deletions(-) delete mode 100644 tests/tls/child.crt delete mode 100644 tests/tls/child.csr delete mode 100644 tests/tls/child.key delete mode 100644 tests/tls/child.key.encrypted.pem delete mode 100644 tests/tls/child.key.pem delete mode 100644 tests/tls/child.keystore.jks delete mode 100755 tests/tls/child.p12 delete mode 100755 tests/tls/jwt/private_key.pem delete mode 100755 tests/tls/jwt/public_key.pem delete mode 100755 tests/tls/keypass delete mode 100644 tests/tls/root.cert.pem delete mode 100644 tests/tls/root.crt delete mode 100644 tests/tls/root.key delete mode 100644 tests/tls/root.key.pem delete mode 100644 tests/tls/root.srl delete mode 100644 tests/tls/root.truststore.jks delete mode 100755 tests/tls/storepass diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 606effd3..c42cc7b4 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -7,222 +7,222 @@ on: - dev jobs: -# test-normal: -# runs-on: ubuntu-24.04 -# continue-on-error: true -# -# -# strategy: -# matrix: -# python-version: ["3.9", "3.10", "3.11", "3.12"] -# -# -# steps: -# - name: Checkout code -# uses: actions/checkout@v3 -# -# - name: Set up Python -# uses: actions/setup-python@v2 -# with: -# python-version: ${{ matrix.python-version }} -# -# -# - name: Install dependencies -# run: | -# python -m pip install --upgrade pip -# python setup.py -# pip install -r requirements.txt -# -# working-directory: tests -# -# -# - name: Retrieve the secret and decode it to a file -# env: -# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} -# run: | -# echo $FEATURE_FILE | base64 --decode > features.conf -# working-directory: tests -# -# - name: Docker Login -# uses: docker/login-action@v2 -# with: -# registry: aerospike.jfrog.io -# username: ${{ secrets.JFROG_USERNAME }} -# password: ${{ secrets.JFROG_PASSWORD }} -# -# - name: create config -# run: | -# #assets/call_gen.sh -# cat aerospike-vector-search.yml -# cat aerospike.conf -# cat /etc/hosts -# -# working-directory: tests -# -# - name: Run unit tests -# run: | -# docker run -d --network=host -p 5000:5000 --name aerospike-vector-search -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf aerospike/aerospike-vector-search:0.9.0 -# -# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest -# -# -# sleep 5 -# -# docker ps -# python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency -# working-directory: tests -# -# test-tls: -# runs-on: ubuntu-24.04 -# continue-on-error: true -# -# -# -# strategy: -# matrix: -# python-version: ["3.9", "3.10", "3.11", "3.12"] -# -# -# steps: -# - name: Checkout code -# uses: actions/checkout@v3 -# -# - name: Set up Python -# uses: actions/setup-python@v2 -# with: -# python-version: ${{ matrix.python-version }} -# -# -# - name: Install dependencies -# run: | -# python -m pip install --upgrade pip -# python setup.py -# pip install -r requirements.txt -# working-directory: tests -# -# -# - name: Retrieve the secret and decode it to a file -# env: -# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} -# run: | -# echo $FEATURE_FILE | base64 --decode > features.conf -# working-directory: tests -# -# - name: Docker Login -# uses: docker/login-action@v2 -# with: -# registry: aerospike.jfrog.io -# username: ${{ secrets.JFROG_USERNAME }} -# password: ${{ secrets.JFROG_PASSWORD }} -# -# -# - name: Set up RANDFILE environment variable -# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV -# -# - name: Create .rnd file if it doesn't exist -# run: touch $HOME/.rnd -# -# - name: create config -# run: | -# assets/call_gen_tls.sh -# cat aerospike-vector-search.yml -# cat aerospike.conf -# cat /etc/hosts -# working-directory: tests -# -# - name: Add hosts to /etc/hosts -# run: | -# sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts -# -# - name: Run unit tests -# run: | -# -# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 -# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest -# -# sleep 5 -# -# -# -# docker ps -# python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs -# -# docker logs aerospike-vector-search -# docker logs aerospike -# working-directory: tests -# -# test-tls-auth: -# runs-on: ubuntu-24.04 -# continue-on-error: true -# -# -# -# strategy: -# matrix: -# python-version: ["3.9", "3.10", "3.11", "3.12"] -# -# -# steps: -# - name: Checkout code -# uses: actions/checkout@v3 -# -# - name: Set up Python -# uses: actions/setup-python@v2 -# with: -# python-version: ${{ matrix.python-version }} -# -# -# - name: Install dependencies -# run: | -# python -m pip install --upgrade pip -# python setup.py -# pip install -r requirements.txt -# working-directory: tests -# -# -# - name: Retrieve the secret and decode it to a file -# env: -# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} -# run: | -# echo $FEATURE_FILE | base64 --decode > features.conf -# working-directory: tests -# -# - name: Docker Login -# uses: docker/login-action@v2 -# with: -# registry: aerospike.jfrog.io -# username: ${{ secrets.JFROG_USERNAME }} -# password: ${{ secrets.JFROG_PASSWORD }} -# -# -# - name: Set up RANDFILE environment variable -# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV -# -# - name: Create .rnd file if it doesn't exist -# run: touch $HOME/.rnd -# -# - name: create config -# run: | -# assets/call_gen_tls_auth.sh -# working-directory: tests -# -# - name: Add hosts to /etc/hosts -# run: | -# sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts -# -# - name: Run unit tests -# run: | -# -# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 -# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest -# -# sleep 5 -# -# python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency --timeout=30 -# -# -# working-directory: tests -# + test-normal: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + - name: create config + run: | + assets/call_gen.sh + cat aerospike-vector-search.yml + cat aerospike.conf + cat /etc/hosts + + working-directory: tests + + - name: Run unit tests + run: | + docker run -d --network=host -p 5000:5000 --name aerospike-vector-search -v ./aerospike-vector-search.yml:/etc/aerospike-vector-search/aerospike-vector-search.yml -v ./features.conf:/etc/aerospike-vector-search/features.conf aerospike/aerospike-vector-search:0.9.0 + + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + + sleep 5 + + docker ps + python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency + working-directory: tests + + test-tls: + runs-on: ubuntu-24.04 + continue-on-error: true + + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: create config + run: | + assets/call_gen_tls.sh + cat aerospike-vector-search.yml + cat aerospike.conf + cat /etc/hosts + working-directory: tests + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + + + docker ps + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + + docker logs aerospike-vector-search + docker logs aerospike + working-directory: tests + + test-tls-auth: + runs-on: ubuntu-24.04 + continue-on-error: true + + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: create config + run: | + assets/call_gen_tls_auth.sh + working-directory: tests + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 child" | sudo tee -a /etc/hosts + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency --timeout=30 + + + working-directory: tests + test-tls-auth-rbac: runs-on: ubuntu-24.04 @@ -305,283 +305,283 @@ jobs: working-directory: tests -# test-mtls: -# runs-on: ubuntu-24.04 -# continue-on-error: true -# -# -# strategy: -# matrix: -# python-version: ["3.9", "3.10", "3.11", "3.12"] -# -# -# steps: -# - name: Checkout code -# uses: actions/checkout@v3 -# -# - name: Set up Python -# uses: actions/setup-python@v2 -# with: -# python-version: ${{ matrix.python-version }} -# -# -# - name: Install dependencies -# run: | -# python -m pip install --upgrade pip -# python setup.py -# pip install -r requirements.txt -# working-directory: tests -# -# -# - name: Retrieve the secret and decode it to a file -# env: -# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} -# run: | -# echo $FEATURE_FILE | base64 --decode > features.conf -# working-directory: tests -# -# - name: Docker Login -# uses: docker/login-action@v2 -# with: -# registry: aerospike.jfrog.io -# username: ${{ secrets.JFROG_USERNAME }} -# password: ${{ secrets.JFROG_PASSWORD }} -# -# -# - name: Set up RANDFILE environment variable -# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV -# -# - name: Create .rnd file if it doesn't exist -# run: touch $HOME/.rnd -# -# - name: Add hosts to /etc/hosts -# run: | -# sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts -# -# - name: create config -# run: | -# assets/call_gen_mtls.sh -# cat /etc/hosts -# working-directory: tests -# -# - name: Run unit tests -# run: | -# -# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 -# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest -# -# sleep 5 -# -# python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs -# -# -# -# working-directory: tests -# -# -# test-mtls-auth: -# runs-on: ubuntu-24.04 -# continue-on-error: true -# -# -# strategy: -# matrix: -# python-version: ["3.9", "3.10", "3.11", "3.12"] -# -# -# steps: -# - name: Checkout code -# uses: actions/checkout@v3 -# -# - name: Set up Python -# uses: actions/setup-python@v2 -# with: -# python-version: ${{ matrix.python-version }} -# -# -# - name: Install dependencies -# run: | -# python -m pip install --upgrade pip -# python setup.py -# pip install -r requirements.txt -# working-directory: tests -# -# -# - name: Retrieve the secret and decode it to a file -# env: -# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} -# run: | -# echo $FEATURE_FILE | base64 --decode > features.conf -# working-directory: tests -# -# - name: Docker Login -# uses: docker/login-action@v2 -# with: -# registry: aerospike.jfrog.io -# username: ${{ secrets.JFROG_USERNAME }} -# password: ${{ secrets.JFROG_PASSWORD }} -# -# -# - name: Set up RANDFILE environment variable -# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV -# -# - name: Create .rnd file if it doesn't exist -# run: touch $HOME/.rnd -# -# - name: Add hosts to /etc/hosts -# run: | -# sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts -# -# - name: create config -# run: | -# assets/call_gen_mtls_auth.sh -# cat /etc/hosts -# working-directory: tests -# -# - name: Run unit tests -# run: | -# -# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 -# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest -# -# sleep 5 -# -# python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs -# -# -# -# working-directory: tests -# -# -# test-mtls-auth-rbac: -# runs-on: ubuntu-24.04 -# continue-on-error: true -# -# -# strategy: -# matrix: -# python-version: ["3.9", "3.10", "3.11", "3.12"] -# -# -# steps: -# - name: Checkout code -# uses: actions/checkout@v3 -# -# - name: Set up Python -# uses: actions/setup-python@v2 -# with: -# python-version: ${{ matrix.python-version }} -# -# -# - name: Install dependencies -# run: | -# python -m pip install --upgrade pip -# python setup.py -# pip install -r requirements.txt -# working-directory: tests -# -# -# - name: Retrieve the secret and decode it to a file -# env: -# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} -# run: | -# echo $FEATURE_FILE | base64 --decode > features.conf -# working-directory: tests -# -# - name: Docker Login -# uses: docker/login-action@v2 -# with: -# registry: aerospike.jfrog.io -# username: ${{ secrets.JFROG_USERNAME }} -# password: ${{ secrets.JFROG_PASSWORD }} -# -# -# - name: Set up RANDFILE environment variable -# run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV -# -# - name: Create .rnd file if it doesn't exist -# run: touch $HOME/.rnd -# -# - name: Add hosts to /etc/hosts -# run: | -# sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts -# -# - name: create config -# run: | -# assets/call_gen_mtls_auth.sh -# cat /etc/hosts -# working-directory: tests -# -# - name: Run unit tests -# run: | -# -# docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 -# docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest -# -# sleep 5 -# -# python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs -# -# -# working-directory: tests -# -# -# test-timeout-on-sandbox: -# runs-on: ubuntu-24.04 -# continue-on-error: true -# -# -# strategy: -# matrix: -# python-version: ["3.9", "3.10", "3.11", "3.12"] -# -# -# steps: -# - name: Checkout code -# uses: actions/checkout@v3 -# -# - name: Set up Python -# uses: actions/setup-python@v2 -# with: -# python-version: ${{ matrix.python-version }} -# -# -# - name: Install dependencies -# run: | -# python -m pip install --upgrade pip -# python setup.py -# pip install -r requirements.txt -# -# working-directory: tests -# -# -# - name: Retrieve the secret and decode it to a file -# env: -# FEATURE_FILE: ${{ secrets.FEATURE_FILE }} -# run: | -# echo $FEATURE_FILE | base64 --decode > features.conf -# working-directory: tests -# -# - name: Docker Login -# uses: docker/login-action@v2 -# with: -# registry: aerospike.jfrog.io -# username: ${{ secrets.JFROG_USERNAME }} -# password: ${{ secrets.JFROG_PASSWORD }} -# -# - name: create config -# run: | -# #assets/call_gen.sh -# cat aerospike-vector-search.yml -# cat aerospike.conf -# cat /etc/hosts -# -# working-directory: tests -# -# - name: Run unit tests -# run: | -# -# -# docker ps -# python -m pytest standard -s --host 34.42.225.207 --port 5000 --local_latency -# working-directory: tests \ No newline at end of file + test-mtls: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + + - name: create config + run: | + assets/call_gen_mtls.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs + + + + working-directory: tests + + + test-mtls-auth: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + + - name: create config + run: | + assets/call_gen_mtls_auth.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs + + + + working-directory: tests + + + test-mtls-auth-rbac: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + + - name: create config + run: | + assets/call_gen_mtls_auth.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + + + working-directory: tests + + + test-timeout-on-sandbox: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + - name: create config + run: | + assets/call_gen.sh + cat aerospike-vector-search.yml + cat aerospike.conf + cat /etc/hosts + + working-directory: tests + + - name: Run unit tests + run: | + + + docker ps + python -m pytest standard -s --host 34.42.225.207 --port 5000 --local_latency + working-directory: tests \ No newline at end of file diff --git a/tests/aerospike-vector-search.yml b/tests/aerospike-vector-search.yml index ef24c617..545f5ebe 100755 --- a/tests/aerospike-vector-search.yml +++ b/tests/aerospike-vector-search.yml @@ -12,19 +12,19 @@ cluster: # If TLS is desired, TLS configuration ids used # and associated TLS configurations. # -tls: - service-tls: - trust-store: - store-file: /etc/aerospike-vector-search/tls/root.truststore.jks - store-password-file: /etc/aerospike-vector-search/tls/storepass - key-store: - store-file: /etc/aerospike-vector-search/tls/child.keystore.jks - store-password-file: /etc/aerospike-vector-search/tls/storepass - key-password-file: /etc/aerospike-vector-search/tls/keypass - #mutual-auth: true - # Client certificate subject names that are allowed - allowed-peer-names: - - child +#tls: +# service-tls: +# trust-store: +# store-file: /etc/aerospike-vector-search/tls/$root_certificate_name.truststore.jks +# store-password-file: /etc/aerospike-vector-search/tls/storepass +# key-store: +# store-file: /etc/aerospike-vector-search/tls/$server_name.keystore.jks +# store-password-file: /etc/aerospike-vector-search/tls/storepass +# key-password-file: /etc/aerospike-vector-search/tls/keypass +# mutual-auth: true +# # Client certificate subject names that are allowed +# allowed-peer-names: +# - $client_name # interconnect-tls: # trust-store: # store-file: tls/ca.aerospike.com.truststore.jks @@ -53,15 +53,16 @@ service: addresses: localhost # If TLS needs to be enabled, tls configuration id. - tls-id: service-tls + #tls-id: service-tls # Required when running behind NAT - advertised-listeners: - default: - # List of externally accessible addresses and - # ports for this Proximus instance. - - address: 0.0.0.0 - port: 5000 + #advertised-listeners: + # default: + # # List of externally accessible addresses and + # # ports for this Proximus instance. + # - address: $server_name + # port: 5000 + # Management API listening ports, TLS and network interface. manage: ports: @@ -92,11 +93,11 @@ interconnect: # To enable client authentication -security: - auth-token: - private-key: /etc/aerospike-vector-search/tls/jwt/private_key.pem - public-key: /etc/aerospike-vector-search/tls/jwt/public_key.pem - token-expiry: 300_000 +#security: +# auth-token: +# private-key: /etc/aerospike-vector-search/tls/jwt/private_key.pem +# public-key: /etc/aerospike-vector-search/tls/jwt/public_key.pem +# token-expiry: 300_000 # Target Aerospike cluster aerospike: diff --git a/tests/assets/service_stanza.txt b/tests/assets/service_stanza.txt index 0fae663c..8164bf0c 100755 --- a/tests/assets/service_stanza.txt +++ b/tests/assets/service_stanza.txt @@ -5,5 +5,5 @@ default: # List of externally accessible addresses and # ports for this Proximus instance. - - address: 0.0.0.0 + - address: 127.0.0.1 port: 5000 diff --git a/tests/gen.sh b/tests/gen.sh index 4c38ba5b..e4deabbd 100755 --- a/tests/gen.sh +++ b/tests/gen.sh @@ -475,7 +475,7 @@ EOF default: # List of externally accessible addresses and # ports for this Proximus instance. - - address: $host + - address: child port: $port EOF ) diff --git a/tests/tls/child.crt b/tests/tls/child.crt deleted file mode 100644 index 4ff7135f..00000000 --- a/tests/tls/child.crt +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDzjCCAragAwIBAgIUFZfW9uLW++TLlAV9eLlu5dmZ+1UwDQYJKoZIhvcNAQEL -BQAwgZ4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm -aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEgMB4G -A1UEAwwXYWVyb3NwaWtlLXZlY3Rvci1zZWFyY2gxJDAiBgkqhkiG9w0BCQEWFWRw -ZWxpbmlAYWVyb3NwaWtlLmNvbTAeFw0yNDA3MjIwNTA5NTFaFw0zNDA3MjAwNTA5 -NTFaMEQxCzAJBgNVBAYTAklOMQswCQYDVQQIDAJLQTEYMBYGA1UECgwPQWVyb3Nw -aWtlLCBJbmMuMQ4wDAYDVQQDDAVjaGlsZDCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBALSJqUNjAEGkSYNTsahmK59dHntD35u+WlnsklRuYQxUKCVxbZfn -hogbvBxKZIFCVoGohRUPCA4h0vk/siCFtYsBrJsGykoMqQdG7niZ/YH8U++/Lko+ -z3PFCE/i6l2hBLoS1zZ1GCA2OCrCtQGi6r72jN8Yx1l0G8zrnavD0Z/+luviZ+qH -asYAbaByOi2/MViKSzSJ+JaUQz6b+xWlXwXUi195fn1lmHncBYcbv9P3r66R1U2Z -R8JHeSo/zkgBrbMkx2NxYmTBqpwOBQwY/QCpO5PGJwuZxOj/bPn3h7p4kMSNQtvL -bQ6VWyCjpu2rAa9eZ8GTsRc3TOXMUvw2I+MCAwEAAaNdMFswGQYDVR0RBBIwEIIF -Y2hpbGSCByouY2hpbGQwHQYDVR0OBBYEFBNlLE3PFWDxZGrQOcbG5m+mLpNeMB8G -A1UdIwQYMBaAFHno7QKg/K/UvsrdzutNX+OVM1P6MA0GCSqGSIb3DQEBCwUAA4IB -AQBDMVqi9ch3kaiRtQ6yK9XtdV3MASJsa5yoiBpJXBi08OH1juGOIKMUKKHzukRm -mV8kQDvYjrtiBmR3PHQe9LwqG9x88nW81pEDTozUERLu7ohm4v7rMv0I1QvBmp59 -2PN8ZvBs4DY03qugh4gcwxPZQUze8FO2t8cBQU1g0wO68NM/74KqAveFtzofIFCF -JFVo+gmEYXd1WXFxUOelUUz6b8nLJxfO2nTEnr8rl84JmPOET5kIzZsift1fMTkv -/4jnqo8OflX4IO6w75WQKnScchER1Wl6p8ceoIDUn7UoDYYB99L8WHQPflz1dDzd -Ck+wCO4rmoZS/gJRE4u9uMTy ------END CERTIFICATE----- diff --git a/tests/tls/child.csr b/tests/tls/child.csr deleted file mode 100644 index b46b6c43..00000000 --- a/tests/tls/child.csr +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICtTCCAZ0CAQAwRDELMAkGA1UEBhMCSU4xCzAJBgNVBAgMAktBMRgwFgYDVQQK -DA9BZXJvc3Bpa2UsIEluYy4xDjAMBgNVBAMMBWNoaWxkMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAtImpQ2MAQaRJg1OxqGYrn10ee0Pfm75aWeySVG5h -DFQoJXFtl+eGiBu8HEpkgUJWgaiFFQ8IDiHS+T+yIIW1iwGsmwbKSgypB0bueJn9 -gfxT778uSj7Pc8UIT+LqXaEEuhLXNnUYIDY4KsK1AaLqvvaM3xjHWXQbzOudq8PR -n/6W6+Jn6odqxgBtoHI6Lb8xWIpLNIn4lpRDPpv7FaVfBdSLX3l+fWWYedwFhxu/ -0/evrpHVTZlHwkd5Kj/OSAGtsyTHY3FiZMGqnA4FDBj9AKk7k8YnC5nE6P9s+feH -uniQxI1C28ttDpVbIKOm7asBr15nwZOxFzdM5cxS/DYj4wIDAQABoCwwKgYJKoZI -hvcNAQkOMR0wGzAZBgNVHREEEjAQggVjaGlsZIIHKi5jaGlsZDANBgkqhkiG9w0B -AQsFAAOCAQEAsBfOm8whD3jimtE4kLDkiizgNVUT5FgXtgqGutzVcCDn1+BQ5FOY -tyZK5lrJuOwdoyzoQ/CtMOlSr/QjqF5t0SZ8NF4wJe4Hdi5oFxdZMvfqQOaGuyoB -OXctsgR+RiccXEfwPs5h5Y1YtXvckseAX/K3t7P3Xk+rFGZi3xtf4bzTa/7xVrPU -ZdlSn5/Ds0u3Hx0DRNxNhAlaY6e8TacKl+DBN7f5jyoViJVxh+hrTnw6f8kZaIWU -Omo0UU1UAraS2r6KWHqSVkKt7MnsjmvcJyXijz/W9mS/as90IK+V1rcAJoImlJZD -PXsJ5sQGdmzbcvFdS19prveArSMl7N6NBg== ------END CERTIFICATE REQUEST----- diff --git a/tests/tls/child.key b/tests/tls/child.key deleted file mode 100644 index 9f0590bb..00000000 --- a/tests/tls/child.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0ialDYwBBpEmD -U7GoZiufXR57Q9+bvlpZ7JJUbmEMVCglcW2X54aIG7wcSmSBQlaBqIUVDwgOIdL5 -P7IghbWLAaybBspKDKkHRu54mf2B/FPvvy5KPs9zxQhP4updoQS6Etc2dRggNjgq -wrUBouq+9ozfGMdZdBvM652rw9Gf/pbr4mfqh2rGAG2gcjotvzFYiks0ifiWlEM+ -m/sVpV8F1ItfeX59ZZh53AWHG7/T96+ukdVNmUfCR3kqP85IAa2zJMdjcWJkwaqc -DgUMGP0AqTuTxicLmcTo/2z594e6eJDEjULby20OlVsgo6btqwGvXmfBk7EXN0zl -zFL8NiPjAgMBAAECggEABaLek+n9Ug9M9Dqiqz01U25Wy0ZdLsGMlI4cK2KeyQG/ -lxupbjqeKpWjE8cGyDpH9RhLv1KOz9IiggGJEBbcihBtURGvMwyeIkoGm+FC1tIH -1M5FJbA8TcLy9XuCEZY7TYvVCDAzpp3KtxsJB5oMdhXAZB6j6pkDXSxl6bzdSH9e -w/S6TqG2s1G81UY1DMRV9UyxxWr6pClNbqcbv0BlPd+RQaDjWgmY+rYhVkyRZgi2 -cxTX4So11CVIzVEMahiw7GS6ZObXCaXqKa2tTOXV6CUz5Nzwd415OybLfGjeGb13 -Tv62Sd5fIGzeM/kNcJu5ZcXwCNMEx4nztuMU4k62IQKBgQDodQwvqup9vW+8uFpM -ykOf8yjDq5HqVkp9GX9clnkkrAYXJLH5EfEL9+gN2TUSQNA8qkgFW+57sVTDbpP7 -yJdt/FTi04i9xRvVl9LIUZu+BWFRsq7fcTXQ/JJw4nZRFdYeb/oaZw69HMZNlC0e -tHpTg8hy+GsF7azh31vIX6UOmwKBgQDG0n1ZnHN4CkMYoaUGSoj9jBZSeBvVTY7k -bh2R8IQAgr7MKn7T4XOrv9/xHoXfDEIqOK2KH/N+cidklCa51JwrjxEbqYeOSnIO -H4cwZQOGzdkM575GynHeUwXN5WlgW54PrSikwTqvmDjT4yQGY5YHUfTSqD69XD+w -POSu+TUwWQKBgHYB5ZvVUpFet/jARecxzz7F/G3JDZw/DjWP2h4wrXM2eSkKkeb1 -er8urPlKySxpBs2lTEacMudMUNGdszZg0K8fKCC2bnaYN9co6fKTq1K9/HezFB+O -o1livxzbemETis2M3xTEOLE8iFcd4AH0cR0wi3QCNKKf0+Iet8Ny+qH9AoGBAKZM -754ht4+DfeW/ZwohE/6HyzAF2LoMmmXFGSS1uaO3uKGLNfRB0n+pCUZkUnNjjIBG -UhmDaiaskviU1uN+y3W/v/6USZch+86GXoyDIXUC/vbFbClIMgBVDzjOF9sKJuZT -3vgXy9+OApJwnfReHeJXkeEV6wx2easO8/TK68tZAoGBAKrASjB/OAEwFNE8DSLd -zeLKSMJc7OK2bZAmiDmVCJzoUogQzVydv4xo2vq5bXFCOGo2qDE1ehcj19fuxLv1 -73k8wpkxjB6FgIEpMEoXLjhrSpTdXaNHXqxgyalhsmpEOb1aozqrisqBUGrjLk2y -hr/7Fexl+bOk9n22BEhlTcLz ------END PRIVATE KEY----- diff --git a/tests/tls/child.key.encrypted.pem b/tests/tls/child.key.encrypted.pem deleted file mode 100644 index db8b121a..00000000 --- a/tests/tls/child.key.encrypted.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQ3tXdXhu4tmny32VY -lDdelAICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEGdra8qMj1KOgd1Z -eIbh/u4EggTQghhyWEkZvuYi3WkyHIlsWAUDJdRjNKWAAkuhhuaiwzZIoqIM/yX6 -2KGpU/+KC01JOHEnz3Ur+bQVc8/pjPu9YCgRkW6O9GdoMVnLwU0AzX6FdtyZOlFM -4gBPS2w1ushSbi4yiQDgGdTYl1Y2pYBmPX3phjI+mrAVP4dJD8QBrkPdo/SNeeWi -CEbtWM0S1ljw3yIxy23K8I7qCZaU80JHEuyoWXDZGsOtR8BGXJ8Ps8fXulxyyCJ0 -hrZW3ywTEa8BxJO3sBzxex0n9MBtQzznktEF00uMP3RLf9D6qZw268a5SexxIUFN -01mOOczRIoEOlibOrL3sLvcbAMLjYVeCQEEqfRCkFJf6UOXROMmWTcIrXPq4/fym -+7e+0NWqB5HQ8slcJyzPt4ouH//TW3CFX1P4odtC0heRvRZ/6NYZTKNzKEi/rl6X -MHcu686zdfAH1dEyyvD6lD6pQP8B0BsymUFg12rirYg83Y3Gz2eJAtomD0VAG2fx -Xv81pcsCuMXVzh+u8Qys6GqVnK6MbSoGjyaYx0oZWv4H1K7lzZcrORRtXGzkJZhz -e3xO1eO61Q18UdMEv+AspmXJygN4L1vrKXpCd67qrQ6MfpMkgcGLxJPkHkD8tMB9 -TNaZm8ncpQ+J5KEa548FKlBKSrOLnutEM2dF3WBqkt/56arnwTLy4dZabl4sPyQK -A6eUn7/3zllWbB3GXIzQD6Cabl0CSDisT44ND/xSy50l4ffOP0UmrUhOFp7/EPFa -nfW44emjn4AtAQeW6WqGiGgupJeVERjy1TNiOKnmDR0mboY3QoQ3zFmOO9GX3n37 -tLQuWP00CZzwASVdGYUWCEpG5zqUvIVY0NjE8PinI1WDKfDbQekiCk3HuqGdC2zM -hkPcjeGGE2FweNBZotW4DKfXX8T4QC9oofD3O8usBdJ2Z0c6kT8Jy0T7TXEsEjjO -Eol/hHfdXQH6LM4z/Eb2bKQtieabKG9JIfKwH+luAto7rTlEQCPQpwQ6x2VPxaJO -UOzr36XTqFWM4UEMDAos3XNjF6FERZM/789Gr/4Jl9jMm84qHBKAcOXdQsBs7K/i -k/htHaVVEIoQ38ffzVLjTTkRjbufNDlknzhyU5ZG958xGF/ktPSK0qNTkHAyzPQs -9ZVODIkMNXbhLrKFy3nx+wHDzdIAxSSgWtXnieNkp4DB+1A56+3oZX3ThZYlXttx -3CkAATbzEZ+OlkiyZ8PglCx/Cz+YgCJIY4IRJJN7mb83idR4l97J63oc+5NwEAkM -4iiU9vKEnA8K/qRzKgk0t++/zv//ynbJivTcaNbQAXOmT06Nfc1MPRbl1KVD3HI7 -Uc+AqM7pvwU+zxdqKfmTjaFWXQH9ZpFuq2F/WlsVGMxU/6QMYz8A+yiQlJI8ZOO4 -PDIFzlNlgx+R+lMRd7h7U1I7wxA4XPti0IGHLmO3bV5v9x/meOO3yMEmGZtEbpW5 -e9LBpEppIMWSfhxPe7XPH76JTuAdseH7x7ABTWrE42qfsS8rKbzSW2LdBpK8+5vV -xD0+i883CmUbMjTbAPyKjM/CnAiOMncX04QHEokJhh5Ayo5b6R9zr2kbwHqeB4ad -VLKFqSTJMRBD1elJN+AN2EozhN4/BZPA7/0s0WIC8jbcHHZBH+Qojyc= ------END ENCRYPTED PRIVATE KEY----- diff --git a/tests/tls/child.key.pem b/tests/tls/child.key.pem deleted file mode 100644 index 9f0590bb..00000000 --- a/tests/tls/child.key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0ialDYwBBpEmD -U7GoZiufXR57Q9+bvlpZ7JJUbmEMVCglcW2X54aIG7wcSmSBQlaBqIUVDwgOIdL5 -P7IghbWLAaybBspKDKkHRu54mf2B/FPvvy5KPs9zxQhP4updoQS6Etc2dRggNjgq -wrUBouq+9ozfGMdZdBvM652rw9Gf/pbr4mfqh2rGAG2gcjotvzFYiks0ifiWlEM+ -m/sVpV8F1ItfeX59ZZh53AWHG7/T96+ukdVNmUfCR3kqP85IAa2zJMdjcWJkwaqc -DgUMGP0AqTuTxicLmcTo/2z594e6eJDEjULby20OlVsgo6btqwGvXmfBk7EXN0zl -zFL8NiPjAgMBAAECggEABaLek+n9Ug9M9Dqiqz01U25Wy0ZdLsGMlI4cK2KeyQG/ -lxupbjqeKpWjE8cGyDpH9RhLv1KOz9IiggGJEBbcihBtURGvMwyeIkoGm+FC1tIH -1M5FJbA8TcLy9XuCEZY7TYvVCDAzpp3KtxsJB5oMdhXAZB6j6pkDXSxl6bzdSH9e -w/S6TqG2s1G81UY1DMRV9UyxxWr6pClNbqcbv0BlPd+RQaDjWgmY+rYhVkyRZgi2 -cxTX4So11CVIzVEMahiw7GS6ZObXCaXqKa2tTOXV6CUz5Nzwd415OybLfGjeGb13 -Tv62Sd5fIGzeM/kNcJu5ZcXwCNMEx4nztuMU4k62IQKBgQDodQwvqup9vW+8uFpM -ykOf8yjDq5HqVkp9GX9clnkkrAYXJLH5EfEL9+gN2TUSQNA8qkgFW+57sVTDbpP7 -yJdt/FTi04i9xRvVl9LIUZu+BWFRsq7fcTXQ/JJw4nZRFdYeb/oaZw69HMZNlC0e -tHpTg8hy+GsF7azh31vIX6UOmwKBgQDG0n1ZnHN4CkMYoaUGSoj9jBZSeBvVTY7k -bh2R8IQAgr7MKn7T4XOrv9/xHoXfDEIqOK2KH/N+cidklCa51JwrjxEbqYeOSnIO -H4cwZQOGzdkM575GynHeUwXN5WlgW54PrSikwTqvmDjT4yQGY5YHUfTSqD69XD+w -POSu+TUwWQKBgHYB5ZvVUpFet/jARecxzz7F/G3JDZw/DjWP2h4wrXM2eSkKkeb1 -er8urPlKySxpBs2lTEacMudMUNGdszZg0K8fKCC2bnaYN9co6fKTq1K9/HezFB+O -o1livxzbemETis2M3xTEOLE8iFcd4AH0cR0wi3QCNKKf0+Iet8Ny+qH9AoGBAKZM -754ht4+DfeW/ZwohE/6HyzAF2LoMmmXFGSS1uaO3uKGLNfRB0n+pCUZkUnNjjIBG -UhmDaiaskviU1uN+y3W/v/6USZch+86GXoyDIXUC/vbFbClIMgBVDzjOF9sKJuZT -3vgXy9+OApJwnfReHeJXkeEV6wx2easO8/TK68tZAoGBAKrASjB/OAEwFNE8DSLd -zeLKSMJc7OK2bZAmiDmVCJzoUogQzVydv4xo2vq5bXFCOGo2qDE1ehcj19fuxLv1 -73k8wpkxjB6FgIEpMEoXLjhrSpTdXaNHXqxgyalhsmpEOb1aozqrisqBUGrjLk2y -hr/7Fexl+bOk9n22BEhlTcLz ------END PRIVATE KEY----- diff --git a/tests/tls/child.keystore.jks b/tests/tls/child.keystore.jks deleted file mode 100644 index a178ec055faf86cbdbf4af002df082763ffefb1a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2798 zcma);X*d*&7RSwEtl1hu(%5%qEMptXgxA(sYHZV+B}-z$WDv4VD8tk!GLbBUls8+n z*thJAJxYv1LdcS-EN}O@_vwA^r+Yt~=RD{4KmYUb{~S1pdl?7-!Aaa15H96ptK{7y z01iMti8~2Q;!gO5W8ftAqW_ZEGr=VG^k10rt5P65|8enh1AzG?cGF)F1^4^yU_SzP zgX{e>^1@ZXP`=7Q{o`NAv+8xaV(3e)byMrlHGx0{0U!Vd=Y??o`y!Bwoeh2h!sVH4 z1@Hxd0m@(j>!np11T}-G5y{O!m|Nw5N#LP^m?`(6t%WbURkbO9u0JX_jn_Pv+I&t{ ztYfBRFyMmxir1JkBd<&W+MFLxYd1L+NcQquYr-NBw+HJyurbB)&0z|$*e^JPSJoV$ zw~kr1$V1gp_&VFtBfq18{`-i<#ANdJ>?_;^`FSBo_9Mc?QPN#_Scey{MvyFBG2&{w zKe`2+E8Y_FVFf*Oa)O)l9dci}IK3fsXkHt5=aC3Z1A}aQvA5$W{Qd60jD57;y{wJ4 zpNo0vcE0-nMUQm2@l zOh@2salscDg}=6)ZB*v#R%Dyt_?{V=WWySqcd4=zfAJW_9p|DMoR9(#sl6!Q-TLtJ zP%~_-=}ms?wG*o@k55?y*i-hN@mOw_CK7^61+~d}ScXSC^wI#^hb)=M4_{c+#=o?A z8WncD`dH4PesWrw%-mZE@bPJA+mT`8Mo~Mc;Yx%4?g5Or=o1bq={yupn@E0G?WX0l zyts%bsx*U+&6X`hg-6%tng)gg$U&*EY3kkL5>}&2OIo(pmaJL%B|dCG(MNjd#((Dm9igQ6!2D3+UW?>2e>S>! zPj`U!75l$YN@mCP|Hv2XdRn~(@-`H*K+VGhukrCO*_HO-#zhF;-nMmYDxO(nX< z=3bjNJf9gjjHKDuI5J$$XFK%;xY>5buVz$w$v3=_qr9_B;(?AX)-+eamAeG`q@`exJS^TF)}kBW6$28kA1`+<9Vw?OA<`?PTDA*8U^a zM!Sv)FqQv6PmZu#kBzkaOmZF;607?eIrlrOu8Tbp9CzPH5tMW_xi{9Ro_$TXg3~U($T~Z*R#5 z%?pH`k$*z@c5wA-NXGJ~qfNcOPJEMwQ*eS-H{K&bw#6t>;iS!6#f5VDGI;pH4OLq_ zeL*}VsPZ}lcbhjb?=CJ@G}iwFm$Ni)Hbdpd#kGz3i119cURMqVMT~>M*Ok-0N+=|^ z0)S2nP^l!v3t<-)b9njPDzGN6s^`0FxEq)iI;R#{cS>(Zd1-ejRfwbVZ9XgxRHLD^ zbqQ44;bV})gmP6{#+@(po6)l0FCwebQVD3cTf{qIW}CUfk*K&$juPq;x&Lm~hIUY$ zkRg!|D<3KR6&6cRGjl5q|FCvlc7H^ySYuAyA^>kvjKOHAmM_)BiQ6-m~^lJk+LDD)RKM2%g~^%{4Pk zUJoz~MFwzsSUzVMr{yK~9awnV)}rJAno_l?M=!V>TwqY3xHnG|TvOES)j~fh#%Ma0N4|lf`I9w3QOIsSKiOO$pP87JPq?a5UDpu90^c`^fPEqxwR0 z*lMqOs<^3ATPSPtOflBC-0M!)FfsIdIWe?kwIU&cGJ-zsBZbOtf}yRYrP@q5ibTX) znB?aC7ttr*7xav%$!0>wdMnA^`sEq3^bqO*TEhx`euL}%Su=m*7u>QqGOGH_*F{c$ zdWh9zk@C&)kwmpOzGgFjWyT}L-mOSmaA;&4GF{#m@#-*~+kdj>Pi#youcf|NcF5J; zz1elY2a$P8?o;W)jWrz8Gsdhw0BH>mvr{`>-Q9laNB|K-+{V0Ky{8B)9c4XmSbwm} zR<1oB?h~gEd9>~KDK9*?-Tod-qUc)TiV_p1d!g+;1m^NcOpTi+j1IG&1 z3De#VdQ+hvpr_R1aY4J#ga?kQP;I%qt&^_W#~XSLJ3`gEn(TYEHk?(NEzX~H;h9fd zvkRmYn#ME_0~G@cH0Ob)i(&KD8W}; zF=IEKf4aQGpYj4!5)!;v4t?dmX;>d#b8&(ocLk&XPs*s1^dcV*`!Ugj>3n)EY+#K| zxgKWuZ0cbq!eTLZex$+mJ*c=2;)a@(7cB9;CK~$M)ZCKYx`sJqIB7WIz>05%mjyhv z->y{uj*I5Mmm^RcOEkbx*9uSD_TI;jk{U!&BQ@Z_IG+%U&shfR=A9dWc<)!L!jvO% zUpp!j=mu93-2=ng2YP}Zvh3CI#pY?4x$8ZxyC9FMoTCo}`n?zl^uxpGRSAtVVJL4c zfl=iC2-PFvcEfbNOLBhDoa{J%#KgA1HL;eM>~nbKk;5zQ*0&tJ=E9Gym%k<^&b_(r zOzXG_Fkr3j^@;7%E3VwKvXUNW^S35(QZ9-PxRW#09TC{q&oQ2I2oXgw%Q!znMVM}6 zgTw)FNB{1?+kJnTxb2uVAyMQ@M#6>T26Fe4U^N*r*$*EuyCf+*Wy9>TMrdO@NA|v5 z-t)1%cOBsvI0Am;_YVjJu(N?-PRKoJg7i7(sZgN1%%%3;f&Qgz727dn%J|Od5GITU dhJr^0^V-eU%8z4Rf22+fB z-T&0{Q3Li`})2<@6R9K|K6`Jip*aJ0vxrX?^O^V7XT&B&3BoC19}|-0~NqRg8O`#E__6KGw4q> zsqV`%QDiWR_3Z)LW|kA*)qDwH=Sr(KYcL;bV_eSJl_PNtcxOqi4;KA} zCbeT+ByJci&qLbGUO4$fxBV?B8qJ=0c8MICLZhGQ*kv=9M!7J@qZ#8}=E6=V4kNai zUtX$B?Vli%JGEkH&ZSXVmx=-OGTTai(M$Nt@MCU9tYyfl_KD zVX*h4THc!5jLwyOq0*sP2@>gK5r+E7Qt`>Fw^dz)s6Ncl**D%B4oTK>4$7as<Jye+yEK8T-djd;rDc+=; zy~5oWC1^sG3@@)UDAvfhWk!@yAu?;1g;eioc%7V zzhMJQ&n$W|^CsRxuARy7(6YpM&hujqo{VB2Cc8S#wp9f`jFjBIJY~Qvh#D!)xbKvw z_?4DIt8BI)?j&o($TK zLKMS+ef=6o>!rj$(%BLlZTSxpf=J3oiWWW`Q!u2?w4j`lj3!Oow>4&T4yHlkrGA}J+exw|JONn#K}vkAA)<{=!Z31-;<(}2&MSMN26Eo6rZ-M)DqvD zz1q^BvL+lHgFtAHC^g)aB+ad#9m&lUykhodtE<0^@cB$p(~n-mN}6R<7)V)aKDlR` z&t*Eq3Rl(vCZ8$@wLO3qBh%CruFnngEEsTLpp2jpdPnDbRkP7Q1lI?WfX%b-CW}3y z7HUezn7)yGvFN&&-@JrQ%&WCZnGNR_`qzo5PGX=EHEt*}SMqNU{UbK62r!u|^cN2P zH38g*|K~giKM?e*)cgh2{-4MmJC3oM%A!;LDj{bmJ$p<4zaqPh8;B4u#=B%R#0E;R zP4Qqdcqqd9!q1zBmIc3egm%lqm{~F*%D4wpgm7v?eNxt!j9VRa@5D29ui`RXHZk=+ z<(!J>S$cQa=({D;`f}1Snl||6B2e_Nl?r8vOf~2I&oR^giZ2TWFK@ zc9O0_2S4WZYT91!2Vcho;IWf;JJrV>7{jsi#ym_@lP%w&=mmexywulek@YvuSGIS4 z(okXWx=+Leg&aX&&_sP%eI^^-vWlw~ZO`gZyt5T&x_ZBMji@1cTZF-xAfSGDCknai zU;I=>w{|o)MLIH`3OWTQeG>ha#WiD}eDkbzN?=ap(W%S0<3Xcb&1$?9@6!g4oTt?T zH@?>$(7*Dy#&Q>$W~Lvqh$i9`d_QL9XSopJOkLR$?)tx9Q~PgjcmfxGb|W+#cHXE) z3!MFHL^8w?u#rW^Y(h>y;@!H0@(k#=L#c6nXy76#9KpmLr!z{pl zNy(G33En!wbL>4w$~BiNb^KXhH>m6;3&ZQYdlU{R8j5S=xSjP&mS>S7eio?W1*^8O zODp!kX>C=Ucg4I1cc0mnLE^E@n-)q$ewa2WtPL_M7e7sfm&=PrFOJRZUW)HE^V>k? zxN-ayfhnlf$#T}y*0RW)7hw88F9TFg(9z1`ol}>#SS{Fxkgle{Wwy&lU3{=OwSncK z9N%w^prqigoP4M#tdIl405w?aR*ibH69YaK{o4u48G1U!oRDDyJx@KnU6j{wXthmH z6TsJMbp#Kco4{2A#8WlLJ*VAZH{i`>p31IVr*hl-d*h@d!tdgah+SA+B{`fIJ5syT z=XR16*0nJYrp=&6srroAq`^ag{E+nmsOB9JmHxILu7urQlD=kc17sN$ zbGq!Q$rGr6vAF``-U;~PVeg^HEl`XimL}<#J%QMp;>>g_8v{y|Y7bgZ9UScvZ9R#WMM?h_Egu3c4F01d zW9^&puHM_o#OGYmw&W+r>+cnz^igP(!0$H?1mpsMk!d_?DBq>4&l`d7EyXJ5rggmE eDXZW@LCFqmeIlj(5STZ{{6?WfglGOgs{Icl`1ex) diff --git a/tests/tls/jwt/private_key.pem b/tests/tls/jwt/private_key.pem deleted file mode 100755 index f93bd12d..00000000 --- a/tests/tls/jwt/private_key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5RujtOHg9/dv5 -9azVxNdXf3SxWeFjdUdhUmNFdJc6y59eTHB2Mt3CKGkBRI6a4RtynadJXGQPYRki -dpW2rgy52wdjKTYQjKPsq+KRGBQOsPQMkXvWujD9Cjj3PffzF4Fzi0sqmSXKJkKC -O+2LoRsMBrZXibzUR0zIj1t6lBlUPELSeZ0zh89vkM/COoK0VxWbwABbA7pyzL27 -avYtRT3ymqMUxRLw1j0oY98jewc5oMneu2yY1zgwMvYja4S2wCbK3+0nJ87pTEIz -UFnChur6onogKbTLYd1Dy0YnenWvbo/r+gMVS416BYYPHHz9sEjuW9FPxpRqP+Fu -A3a+MTxJAgMBAAECggEADhhDOgtfYl/rRIMYaJQhSbUW3IhuPrxk92tmxUQ5s62v -7GLmSfz+pSRL216AIW+ElgiWTwdp+Ug1ZaDIgkLlZvIvCAUnlBoO579VF3KnJqL2 -6J8yC5jTMed9g+7r66CwfBNvCXOTI2NxEH/x8fsJ7V/0A97PmwU9kHhkyNjMFdNK -n9duThvFlDtiYD7N5t6hr1k5zysc1WaB8X7z9ZcZ+xutq19rCRs8SyO2wtsY/9Pd -6pUuUzN4krCf2GRDN/yAX3KJ+QJ2NbecOMhCYak/n44ajHu0W9vGN5zkMeB71UgY -0XIjJT94m4itdAi8hX9tM8Y052k7MhMUr5msgJewfQKBgQDf/xM2HYvRifvdSbkM -K8TwA0XthxNKuFb67lLSNUuTocvyT35CyfIvtq7HPmSlFl4+zXjguFl9kVCYlqmX -EM41TSfDMuMvsJ8sMqaYJ/rEm9H0xrIyGveo04a6AuCQoMEV3MiXbzEHz/mH2fbi -5zVNu4ZdNFxJH/IbJvcY9rNBiwKBgQDTv6Dlj4CI8d9wFcF8RFH391HX7fWJbU1I -HYsm5ts9Cb5FVSE9fphUP/Oa51Y7gujV8VnqAs0xGsZe73Va/OPoN4ymt4CECEyX -MGiN1Su0izFJtIszowpneZK5kBq9YMSuPAV9AGRDnUfu1dqW4Am1JpM3DstB/3FI -69Hx770L+wKBgEt5JL39IplNxuF+76zcKpU8ZRltg+CPUC9okdtmPbrWr2NLyZ0z -cjkFcsqLiVneuY6rqOj+9JhMmD1xtl7CONjY0GcDBG2TM26u+lcWUXZhklLJiE09 -rOjjrOeMBKJ2p9h39dagjoK1XryZgohdoyY340QQWnABJZBkhqmQpkGVAoGAG2iL -iAtaJN/B/z0hrVcekQ03T87iYGaAgVwpneB18mGnekv5oH8ZcpZQjvVwyQU55C94 -Zvzz2G5RzQoL07o2OeGu2AmanfyBBXTjo7A7FwSJXbP77LQm7Zvj7RcFDwxOiQsF -3tdFIydhnz2ZLLxVJViX56GHl8Rbwoebxkg03S8CgYEAhggCxvidzGlGEhLtkb8e -m/NjJgXIly9IUDkBDBC7cOgZiQiZiDfCvn3GSzxOhK8AI7Y0Sfris51YLcd3E7qj -rDys63atL1NQ2jnDUVD/TxeS9DwmNNPz3jgWEoOOant4T6XLXlwOn4WkYqBw9jd0 -F0X4VEqxgiYI8qsR7ci1L6E= ------END PRIVATE KEY----- diff --git a/tests/tls/jwt/public_key.pem b/tests/tls/jwt/public_key.pem deleted file mode 100755 index 230b69ab..00000000 --- a/tests/tls/jwt/public_key.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuUbo7Th4Pf3b+fWs1cTX -V390sVnhY3VHYVJjRXSXOsufXkxwdjLdwihpAUSOmuEbcp2nSVxkD2EZInaVtq4M -udsHYyk2EIyj7KvikRgUDrD0DJF71row/Qo49z338xeBc4tLKpklyiZCgjvti6Eb -DAa2V4m81EdMyI9bepQZVDxC0nmdM4fPb5DPwjqCtFcVm8AAWwO6csy9u2r2LUU9 -8pqjFMUS8NY9KGPfI3sHOaDJ3rtsmNc4MDL2I2uEtsAmyt/tJyfO6UxCM1BZwobq -+qJ6ICm0y2HdQ8tGJ3p1r26P6/oDFUuNegWGDxx8/bBI7lvRT8aUaj/hbgN2vjE8 -SQIDAQAB ------END PUBLIC KEY----- diff --git a/tests/tls/keypass b/tests/tls/keypass deleted file mode 100755 index b1f833ed..00000000 --- a/tests/tls/keypass +++ /dev/null @@ -1 +0,0 @@ -citrusstore diff --git a/tests/tls/root.cert.pem b/tests/tls/root.cert.pem deleted file mode 100644 index 6449fc39..00000000 --- a/tests/tls/root.cert.pem +++ /dev/null @@ -1,25 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIELzCCAxegAwIBAgIUJM5sPDvOMOdHRDY20cVlnLD1VwIwDQYJKoZIhvcNAQEL -BQAwgZ4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm -aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEgMB4G -A1UEAwwXYWVyb3NwaWtlLXZlY3Rvci1zZWFyY2gxJDAiBgkqhkiG9w0BCQEWFWRw -ZWxpbmlAYWVyb3NwaWtlLmNvbTAeFw0yNDA3MjIwNTA5NTFaFw00NDA3MTcwNTA5 -NTFaMIGeMQswCQYDVQQGEwJVUzELMAkGA1UECAwCU0QxEjAQBgNVBAcMCVNwZWFy -ZmlzaDESMBAGA1UECgwJQWVyb3NwaWtlMRIwEAYDVQQLDAkgU0RLIFRlYW0xIDAe -BgNVBAMMF2Flcm9zcGlrZS12ZWN0b3Itc2VhcmNoMSQwIgYJKoZIhvcNAQkBFhVk -cGVsaW5pQGFlcm9zcGlrZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCgRcrbvo/mssvjSVvMxx5oG2+QRS9lJ2833q3q+Y65Yii+d+iDnB+CVfxJ -kWZmzikDyudEOzhCqCM+v8WhmaABmNTO7uSeQFCZBxcWpO44nrfxtpC3HvuXmrnN -Fspy8ItJfb51lnyb5T78m15MDA8Zo56DUpwBJTXiUN3LnzvR36n31YIuw7JOJey2 -5dlpRKVIr9/PnmpddJzCP8QymenS+h9C8E+IxuQwkcyK5ZiUKat+66tEJCDMDMvw -o07TH+UIiRPOywcX52zoscG4YHHp1080nW4nz40HheeSHqYJJgucMAi392Uk280p -+8VtLlMAp0Vyue/cNvs5uU5e/qQzAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8w -DgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBR56O0CoPyv1L7K3c7rTV/jlTNT+jAf -BgNVHSMEGDAWgBR56O0CoPyv1L7K3c7rTV/jlTNT+jANBgkqhkiG9w0BAQsFAAOC -AQEAJLcqWsPJNMFezCX7UUhbXOAxJVCn+8so29aefOgsEP7yw1M7jQxpMV4KGDy6 -hqQo78PsTaAJk6xEZqovPn2vlbal9OyixMorKrHlAwzqAlhUorJ6AXI1KSuV50Q+ -sYeNpjjOFxexI6pV4BJO9mJ0CmfSiupPvMnmv6ALeTzQf9FC01lz5kVxlN2d3p3m -awhT4sbfuRlVTtUvw7RrEaNLLSO605nWvIKKICMFzFcdlG4Iadv8G/dT0ulJTbv4 -hBbHd+WPH2pTFQRftBQhX3qcrYkaBOnZpr9/UslM158DdM+aM+cvZzhETvKDdw2a -W0ZB6ORAGnwbL4qGulN9oZ5jng== ------END CERTIFICATE----- diff --git a/tests/tls/root.crt b/tests/tls/root.crt deleted file mode 100644 index 03ee71da..00000000 --- a/tests/tls/root.crt +++ /dev/null @@ -1,25 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEHzCCAwegAwIBAgIULDOaowPZopwqIwY3JrUCYz2KitswDQYJKoZIhvcNAQEL -BQAwgZ4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTRDESMBAGA1UEBwwJU3BlYXJm -aXNoMRIwEAYDVQQKDAlBZXJvc3Bpa2UxEjAQBgNVBAsMCSBTREsgVGVhbTEgMB4G -A1UEAwwXYWVyb3NwaWtlLXZlY3Rvci1zZWFyY2gxJDAiBgkqhkiG9w0BCQEWFWRw -ZWxpbmlAYWVyb3NwaWtlLmNvbTAeFw0yNDA3MjIwNTA5NTFaFw0zNDA3MjAwNTA5 -NTFaMIGeMQswCQYDVQQGEwJVUzELMAkGA1UECAwCU0QxEjAQBgNVBAcMCVNwZWFy -ZmlzaDESMBAGA1UECgwJQWVyb3NwaWtlMRIwEAYDVQQLDAkgU0RLIFRlYW0xIDAe -BgNVBAMMF2Flcm9zcGlrZS12ZWN0b3Itc2VhcmNoMSQwIgYJKoZIhvcNAQkBFhVk -cGVsaW5pQGFlcm9zcGlrZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCgRcrbvo/mssvjSVvMxx5oG2+QRS9lJ2833q3q+Y65Yii+d+iDnB+CVfxJ -kWZmzikDyudEOzhCqCM+v8WhmaABmNTO7uSeQFCZBxcWpO44nrfxtpC3HvuXmrnN -Fspy8ItJfb51lnyb5T78m15MDA8Zo56DUpwBJTXiUN3LnzvR36n31YIuw7JOJey2 -5dlpRKVIr9/PnmpddJzCP8QymenS+h9C8E+IxuQwkcyK5ZiUKat+66tEJCDMDMvw -o07TH+UIiRPOywcX52zoscG4YHHp1080nW4nz40HheeSHqYJJgucMAi392Uk280p -+8VtLlMAp0Vyue/cNvs5uU5e/qQzAgMBAAGjUzBRMB0GA1UdDgQWBBR56O0CoPyv -1L7K3c7rTV/jlTNT+jAfBgNVHSMEGDAWgBR56O0CoPyv1L7K3c7rTV/jlTNT+jAP -BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAOhtG1JBnKdajV/dCb -OIJk4dOXAqSo1aS8JZFQXKVQBqIH54zzIFzPFDK04Dq0GSB47RPcGZM06T/HrLI0 -NwmLf1y3/Hg5d2IO3gjpa7kOGhq34soUPEGXZGjJJOxtZZoAdeLnZsVfqZGmbv9F -F82KdrqfYX9n61kEqRelx2Y7M/igOqLkgKpniIcVVULuCOLSyAYlQfUy4ba7FYzj -ZohUvTyDVa/BtLv/teJjVSLt5+yrWnNTXBw2ifDKv2GeqgqJFsg4GPAsXdaU8PdE -sIyL6iSkABbjK3ghqra4eEtIbK0DmAvWEhU28JbHydnVk3JWgI0DYbKuEb9uYCKk -K4sv ------END CERTIFICATE----- diff --git a/tests/tls/root.key b/tests/tls/root.key deleted file mode 100644 index 9e71685d..00000000 --- a/tests/tls/root.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCgRcrbvo/mssvj -SVvMxx5oG2+QRS9lJ2833q3q+Y65Yii+d+iDnB+CVfxJkWZmzikDyudEOzhCqCM+ -v8WhmaABmNTO7uSeQFCZBxcWpO44nrfxtpC3HvuXmrnNFspy8ItJfb51lnyb5T78 -m15MDA8Zo56DUpwBJTXiUN3LnzvR36n31YIuw7JOJey25dlpRKVIr9/PnmpddJzC -P8QymenS+h9C8E+IxuQwkcyK5ZiUKat+66tEJCDMDMvwo07TH+UIiRPOywcX52zo -scG4YHHp1080nW4nz40HheeSHqYJJgucMAi392Uk280p+8VtLlMAp0Vyue/cNvs5 -uU5e/qQzAgMBAAECggEAR0NBE7wDl/xgE8uGeeL/biLk1C0vCbcjCKCGjDgycdNn -cmk2hW5hxD4fU0bHVWbNbdZGRlxeg6TnJvt2EIiSUKN33Br0pDjMnX49kd/73EkW -WO9oIUQxchNmEf7UPY8fH6o9iWNEPL0N6Jvcrcue2zOZQ6Lzor682shCFkvS+VnZ -kzVFMlE928eQEsvp0fVAEY0U49eRFsWdpaUyff9JJsNP4gEpNt4O3XIHuguyhchM -d3HcgDcrnADYGpm7cV+JgDfHh3WGhEewkiJOvskRvGHR8aea/p0IXBT/lozDzcc8 -jENj0sD5nWh/TimJb6cLcsp5lZEMUtC6eXByP5XNIQKBgQDUD4sFvbx9NryJUAE5 -uqIvnD1xtCNPAN1tBV8fJ5vcLIwx1K6yf2+2iALKWa2f44SBm8/0IEWla+kW5OCJ -5F8BWLFRb3+Aft774E87sfbJmyMLgZXe+AgTZhM8SmOZyI9BxoHXFXo2v75qSdcX -9oBWPsmv97d0Ust6jlo0QJ3jrQKBgQDBezlwdlAfb5E0OO3cP5AiMJnfJZju413V -SskrZJXnXSgvYNLJWUHDL7yuYYrLB3z6YRE1c+MoPWqexYiX7N1l/aIRBhlB2MJC -EZoAwwy0qgnqw0k7SUqGGIcftI7s9GmTuO+XCC3djOkgMLan1KRC4cqjyEvN+mNW -sT/dXDCjXwKBgB9UFIPKnhgZiAz5JtUyf1dtS56KsFSxmgTLMFxX66zBYAzUkOKJ -9SUQPulKCl5+rErBjB1Szzc7E/pv4cQ9WtPGGJwhTsLa+3JWlx4Ikp8CLlE62btR -BVBoWhskGkbT3GYpP3FZGO8RsL3fHsnJfvg+2mkGvbGPscPvV+A0U58ZAoGAPBoR -H7RA82Lu0jAVA2PjXBuI0N6XAS4zybvvfcFDJ5myj/UdxVoqqX08uVanjKYI1qYs -eFRFbgyWADgQVFFJ/RKqs2sXkXLJ9UgOdMoiOkTPy9NZ/kaoFbuszdaCx2ytFyxN -kLcDuFy7VjqLotrVI8mL7xCbK6LqFNX+pr6qhTUCgYBmRGlAszsCDd/Uf0KJPJZ6 -wBnriDosdoKq3XJZ9yTckThhWOfzy3UbmhsQ8r3j7QX0qeDqmj1wg8H3XDhIfvo8 -cCyECyV7Z9f2tAQjubApvAqqDwpa9TT29VK8KJ0CB/a9ouBIl5gv1mLzsNdQSHNv -rIk4eBNfIK/oyy9+bNdGcA== ------END PRIVATE KEY----- diff --git a/tests/tls/root.key.pem b/tests/tls/root.key.pem deleted file mode 100644 index 9e71685d..00000000 --- a/tests/tls/root.key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCgRcrbvo/mssvj -SVvMxx5oG2+QRS9lJ2833q3q+Y65Yii+d+iDnB+CVfxJkWZmzikDyudEOzhCqCM+ -v8WhmaABmNTO7uSeQFCZBxcWpO44nrfxtpC3HvuXmrnNFspy8ItJfb51lnyb5T78 -m15MDA8Zo56DUpwBJTXiUN3LnzvR36n31YIuw7JOJey25dlpRKVIr9/PnmpddJzC -P8QymenS+h9C8E+IxuQwkcyK5ZiUKat+66tEJCDMDMvwo07TH+UIiRPOywcX52zo -scG4YHHp1080nW4nz40HheeSHqYJJgucMAi392Uk280p+8VtLlMAp0Vyue/cNvs5 -uU5e/qQzAgMBAAECggEAR0NBE7wDl/xgE8uGeeL/biLk1C0vCbcjCKCGjDgycdNn -cmk2hW5hxD4fU0bHVWbNbdZGRlxeg6TnJvt2EIiSUKN33Br0pDjMnX49kd/73EkW -WO9oIUQxchNmEf7UPY8fH6o9iWNEPL0N6Jvcrcue2zOZQ6Lzor682shCFkvS+VnZ -kzVFMlE928eQEsvp0fVAEY0U49eRFsWdpaUyff9JJsNP4gEpNt4O3XIHuguyhchM -d3HcgDcrnADYGpm7cV+JgDfHh3WGhEewkiJOvskRvGHR8aea/p0IXBT/lozDzcc8 -jENj0sD5nWh/TimJb6cLcsp5lZEMUtC6eXByP5XNIQKBgQDUD4sFvbx9NryJUAE5 -uqIvnD1xtCNPAN1tBV8fJ5vcLIwx1K6yf2+2iALKWa2f44SBm8/0IEWla+kW5OCJ -5F8BWLFRb3+Aft774E87sfbJmyMLgZXe+AgTZhM8SmOZyI9BxoHXFXo2v75qSdcX -9oBWPsmv97d0Ust6jlo0QJ3jrQKBgQDBezlwdlAfb5E0OO3cP5AiMJnfJZju413V -SskrZJXnXSgvYNLJWUHDL7yuYYrLB3z6YRE1c+MoPWqexYiX7N1l/aIRBhlB2MJC -EZoAwwy0qgnqw0k7SUqGGIcftI7s9GmTuO+XCC3djOkgMLan1KRC4cqjyEvN+mNW -sT/dXDCjXwKBgB9UFIPKnhgZiAz5JtUyf1dtS56KsFSxmgTLMFxX66zBYAzUkOKJ -9SUQPulKCl5+rErBjB1Szzc7E/pv4cQ9WtPGGJwhTsLa+3JWlx4Ikp8CLlE62btR -BVBoWhskGkbT3GYpP3FZGO8RsL3fHsnJfvg+2mkGvbGPscPvV+A0U58ZAoGAPBoR -H7RA82Lu0jAVA2PjXBuI0N6XAS4zybvvfcFDJ5myj/UdxVoqqX08uVanjKYI1qYs -eFRFbgyWADgQVFFJ/RKqs2sXkXLJ9UgOdMoiOkTPy9NZ/kaoFbuszdaCx2ytFyxN -kLcDuFy7VjqLotrVI8mL7xCbK6LqFNX+pr6qhTUCgYBmRGlAszsCDd/Uf0KJPJZ6 -wBnriDosdoKq3XJZ9yTckThhWOfzy3UbmhsQ8r3j7QX0qeDqmj1wg8H3XDhIfvo8 -cCyECyV7Z9f2tAQjubApvAqqDwpa9TT29VK8KJ0CB/a9ouBIl5gv1mLzsNdQSHNv -rIk4eBNfIK/oyy9+bNdGcA== ------END PRIVATE KEY----- diff --git a/tests/tls/root.srl b/tests/tls/root.srl deleted file mode 100644 index 6ee70359..00000000 --- a/tests/tls/root.srl +++ /dev/null @@ -1 +0,0 @@ -1597D6F6E2D6FBE4CB94057D78B96EE5D999FB55 diff --git a/tests/tls/root.truststore.jks b/tests/tls/root.truststore.jks deleted file mode 100644 index 473bb81104306249d828c2a988d473c83a0f8553..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1430 zcmV;H1!?*)f(4QS0Ru3C1v~}`Duzgg_YDCD0ic2fEd+uEDKLTsB`|^oAqEL5hDe6@ z4FLxRpn?SwFoFdR0s#Opf&~W#2`Yw2hW8Bt2LUi<1_>&LNQU+thDZTr0|Wso1Q4htvG9wT1!@%!OZCXqiX(u61dua0ttEkCiVk+Ki6zX|>`}pK z#a4Xy`!*^Ij_FSg8PjKEhF6u0Tde)iXX-j9bWBM2!?w| z=Nj_si(%JF3Vi5y%1y3=be}H4P>|-7TT4jCrs{>w^M~)*vm0AfB%TxWA_(!N<&Q42 zT^aO2mFlkvvjI?P9rV380nAcp%ZsF00nJ*}cJD&V!~%s?NY2ZXEj9m`~F)ol26y!2F!$LK2{O5G%k2|1U_n&)SDYL7_S#V%wFqa6APc}ssr zdQNQo-deA$+EUr}lqUWMS%N%Mb$Lt|2FnK+#iYvazhNz(E?U#$=1jLkWM{^|W^m)a zt(mazcW3DZrWx8QhQhyR&r+#F|1TD;Kbkg(9Vos9lhUO6ep|>#MeB#uR3sMyw72-g zTy$Khg!}OGnv4!p9Y&5CJPQtU2|QydV-y~Q>1WUt_MOlmg_n#(+NOpE+H*mu*se_H za6CIVN|_GLJdItMtC};BYkbQ#y8doIxjg~?KwSfnuu&I!c9#+TPkWt+vo_uoxg0J$ zSQ7H47cRj0gq{?8b-|_L$^HJ!la9Tjz($G`)emATWBCH%qU_|rxpB~e-j$1}dm<~Q zez)TH*M8gs9}I5{TlzOA8KVn`w3`Rv!N?Cd-I7iV@tZrEzaKz`c|Ml)*%q9LpV)MO z>%~$|LH)2e+IA;j(#hOI5rjpA0j!0NQ@y5Q=@0;stEtK=zhJV>^Cl>l6@(%z;IP&k zb^bgCJ^gS*Sa-aJbpET3zj$7kzj*G5aICAEI>?0pJZi|@elKJ?W)9MZKGA@}sYIZ9 z@-{@9@Yh&&&(+B^&Z?^|Q>I%AMx-wd{sljv2n?;|TF` z7A-XC5DCR(gI9$4hUnB}RL9?gXa2&-{vPnYAB%^6kPZZM#SlwTl`fG9FU5XYFeDzZ zR=s?bO&tt@v+?OG%iJ%BOr!qN3By9I6Gq1P=rt<1EkassI_mDD=^FYgVMmnn5RJ_- zT>n(>jso?1DGdB>5vtm~JVgsfF<=-S%Bkz)9RH*{1nbJ1zQ40bj|6`Z$1em=?Cfn}hX(Zj9j; zo<@u(qe(DLFflL<1_@w>NC9O71OfpC00bb6$c#iC{VJ_!q40;L+z?z>Flc)(*)p;^ krOA7y36VSm6i?7%myC^`Pk@Bxh#6DX%oh+?4FUou5HI46)Bpeg diff --git a/tests/tls/storepass b/tests/tls/storepass deleted file mode 100755 index b1f833ed..00000000 --- a/tests/tls/storepass +++ /dev/null @@ -1 +0,0 @@ -citrusstore From 9d27d9a6e8a3107f3d88c92a64272b039b5cd381 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 01:02:24 -0600 Subject: [PATCH 188/215] Flaky test update --- .github/workflows/integration_test.yml | 2 +- src/aerospike_vector_search/aio/admin.py | 1 - src/aerospike_vector_search/aio/client.py | 1 - tests/aerospike.conf | 8 + tests/assets/aerospike.conf | 8 + tests/requirements.txt | 1 - tests/standard/aio/test_vector_search.py | 249 +++++++++++++++++++--- tests/standard/sync/test_vector_search.py | 65 ++++-- 8 files changed, 282 insertions(+), 53 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c42cc7b4..0911b480 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -298,7 +298,7 @@ jobs: docker ps - python -m pytest rbac/aio/debug.py -s -vv --host 0.0.0.0 --port 5000 --root_certificate tls/root.crt --timeout=30 + python -m pytest rbac/aio/debug.py -s -vv --host child--port 5000 --root_certificate tls/root.crt --timeout=30 docker logs aerospike-vector-search docker logs aerospike diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index 99765387..e8b3b322 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -43,7 +43,6 @@ def __init__( Exception: Raised when no seed host is provided. """ - print("\n\n\n\n THIS IS RUNNING AT ALL\n\n\n") seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index 1e156570..77fb1c78 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -48,7 +48,6 @@ def __init__( Raises: Exception: Raised when no seed host is provided. """ - print("\n\n\n\n THIS IS RUNNING AT ALL\n\n\n") seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( diff --git a/tests/aerospike.conf b/tests/aerospike.conf index 4e25d373..d7f994f8 100755 --- a/tests/aerospike.conf +++ b/tests/aerospike.conf @@ -70,3 +70,11 @@ namespace test { nsup-period 60 } +namespace index_storage { + replication-factor 2 + storage-engine memory { + data-size 1G + } + nsup-period 60 +} + diff --git a/tests/assets/aerospike.conf b/tests/assets/aerospike.conf index 4e25d373..d7f994f8 100755 --- a/tests/assets/aerospike.conf +++ b/tests/assets/aerospike.conf @@ -70,3 +70,11 @@ namespace test { nsup-period 60 } +namespace index_storage { + replication-factor 2 + storage-engine memory { + data-size 1G + } + nsup-period 60 +} + diff --git a/tests/requirements.txt b/tests/requirements.txt index 32083971..c8defcde 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,7 +1,6 @@ numpy==1.26.4 pytest==7.4.0 pytest-aio==1.5.0 -pytest-timeout pyjwt hypothesis .. \ No newline at end of file diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index 9169a9a3..d4b6e0b7 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -67,20 +67,20 @@ def query_numpy(): return truth_numpy -async def put_vector(client, vector, j): +async def put_vector(client, vector, j, set_name): await client.upsert( - namespace="test", key=str(j), record_data={"unit_test": vector} + namespace="test", key=str(j), record_data={"unit_test": vector}, set_name=set_name ) -async def get_vector(client, j): - result = await client.get(namespace="test", key=str(j)) +async def get_vector(client, j, set_name): + result = await client.get(namespace="test", key=str(j), set_name=set_name) -async def vector_search(client, vector): +async def vector_search(client, vector, name): result = await client.vector_search( namespace="test", - index_name="demo", + index_name=name, query=vector, limit=100, field_names=["unit_test"], @@ -88,10 +88,10 @@ async def vector_search(client, vector): return result -async def vector_search_ef_80(client, vector): +async def vector_search_ef_80(client, vector, name): result = await client.vector_search( namespace="test", - index_name="demo", + index_name=name, query=vector, limit=100, field_names=["unit_test"], @@ -99,39 +99,22 @@ async def vector_search_ef_80(client, vector): ) return result -async def test_vector_search( +async def grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, + name ): - - await session_admin_client.index_create( - namespace="test", - name="demo", - vector_field="unit_test", - dimensions=128, - ) - - # Put base vectors for search - tasks = [] - - for j, vector in enumerate(base_numpy): - tasks.append(put_vector(session_vector_client, vector, j)) - - tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo')) - await asyncio.gather(*tasks) - - # Vector search all query vectors tasks = [] count = 0 for i in query_numpy: if count % 2: - tasks.append(vector_search(session_vector_client, i)) + tasks.append(vector_search(session_vector_client, i, name)) else: - tasks.append(vector_search_ef_80(session_vector_client, i)) + tasks.append(vector_search_ef_80(session_vector_client, i, name)) count += 1 results = await asyncio.gather(*tasks) @@ -167,6 +150,214 @@ async def test_vector_search( assert recall > 0.9 +async def test_vector_search( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, +): + + await session_admin_client.index_create( + namespace="test", + name="demo1", + vector_field="unit_test", + dimensions=128, + ) + + # Put base vectors for search + tasks = [] + + for j, vector in enumerate(base_numpy): + tasks.append(put_vector(session_vector_client, vector, j, None)) + + tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo1')) + await asyncio.gather(*tasks) + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name='demo1' + ) + +async def test_vector_search_with_set_same_as_index( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, +): + + await session_admin_client.index_create( + namespace="test", + name="demo2", + sets="demo2", + vector_field="unit_test", + dimensions=128, + index_storage=types.IndexStorage(namespace="test", set_name="demo2") + ) + + # Put base vectors for search + tasks = [] + + for j, vector in enumerate(base_numpy): + tasks.append(put_vector(session_vector_client, vector, j, "demo2")) + + tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo2')) + await asyncio.gather(*tasks) + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name='demo2' + ) + +async def test_vector_search_with_set_different_than_name( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, +): + + await session_admin_client.index_create( + namespace="test", + name="demo3", + vector_field="unit_test", + dimensions=128, + sets="example1", + index_storage=types.IndexStorage(namespace="test", set_name="demo3") + + ) + + # Put base vectors for search + tasks = [] + + for j, vector in enumerate(base_numpy): + tasks.append(put_vector(session_vector_client, vector, j, "example1")) + + tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo3')) + await asyncio.gather(*tasks) + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name="demo3" + ) + +async def test_vector_search_with_index_storage_different_than_name( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, +): + + await session_admin_client.index_create( + namespace="test", + name="demo4", + vector_field="unit_test", + dimensions=128, + sets="demo4", + index_storage=types.IndexStorage(namespace="test", set_name="example2") + + ) + + # Put base vectors for search + tasks = [] + + for j, vector in enumerate(base_numpy): + tasks.append(put_vector(session_vector_client, vector, j, "demo4")) + + tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo4')) + await asyncio.gather(*tasks) + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name="demo4" + ) + + + +async def test_vector_search_with_index_storage_different_location( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, +): + + await session_admin_client.index_create( + namespace="test", + name="demo5", + vector_field="unit_test", + dimensions=128, + sets="example3", + index_storage=types.IndexStorage(namespace="test", set_name="example4") + + ) + + # Put base vectors for search + tasks = [] + + for j, vector in enumerate(base_numpy): + tasks.append(put_vector(session_vector_client, vector, j, "example3")) + + tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo5')) + await asyncio.gather(*tasks) + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name='demo5' + ) + +async def test_vector_search_with_separate_namespace( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, +): + + await session_admin_client.index_create( + namespace="test", + name="demo6", + vector_field="unit_test", + dimensions=128, + sets="demo6", + index_storage=types.IndexStorage(namespace="index_storage", set_name="demo6") + + ) + + # Put base vectors for search + tasks = [] + + for j, vector in enumerate(base_numpy): + tasks.append(put_vector(session_vector_client, vector, j, "demo6")) + + tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo6')) + await asyncio.gather(*tasks) + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name='demo6' + ) + async def test_vector_is_indexed(session_vector_client, session_admin_client, local_latency): if local_latency: pytest.skip("Server latency too low to test timeout") diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index 568ca1dd..8215e588 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -100,33 +100,17 @@ def vector_search_ef_80(client, vector): ) return result -def test_vector_search( + +async def grade_results( + base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, + set_name ): - session_admin_client.index_create( - namespace="test", - name="demo", - vector_field="unit_test", - dimensions=128, - sets="demo" - ) - - # Put base vectors for search - for j, vector in enumerate(base_numpy): - put_vector(session_vector_client, vector, j) - - - # Put base vectors for search - for j, vector in enumerate(base_numpy): - get_vector(session_vector_client, j) - - session_vector_client.wait_for_index_completion(namespace='test', name='demo') - # Vector search all query vectors @@ -170,9 +154,50 @@ def test_vector_search( assert recall > 0.9 +def test_vector_search( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, +): + set_name=None + + session_admin_client.index_create( + namespace="test", + name="demo", + vector_field="unit_test", + dimensions=128, + sets=set_name + ) + + # Put base vectors for search + for j, vector in enumerate(base_numpy): + put_vector(session_vector_client, vector, j) + + + # Put base vectors for search + for j, vector in enumerate(base_numpy): + get_vector(session_vector_client, j) + + session_vector_client.wait_for_index_completion(namespace='test', name='demo') + + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client + set_name + ) + + def test_vector_is_indexed(session_vector_client, session_admin_client): val = random.randrange(10_000) + result = session_vector_client.get(namespace="test", key=val, set_name="demo") + + print(result) result = session_vector_client.is_indexed( namespace="test", From 529474c52a7aa06e08072343243e77d3af08209c Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 07:47:50 -0600 Subject: [PATCH 189/215] Added extra set and namespace testing --- .github/workflows/integration_test.yml | 5 +- tests/standard/sync/test_vector_search.py | 251 +++++++++++++++++++--- 2 files changed, 224 insertions(+), 32 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 0911b480..b433ed25 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -218,8 +218,7 @@ jobs: sleep 5 - python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency --timeout=30 - + python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency working-directory: tests @@ -298,7 +297,7 @@ jobs: docker ps - python -m pytest rbac/aio/debug.py -s -vv --host child--port 5000 --root_certificate tls/root.crt --timeout=30 + python -m pytest rbac/aio/debug.py -s -vv --host child--port 5000 --root_certificate tls/root.crt docker logs aerospike-vector-search docker logs aerospike diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index 8215e588..a3daf3ae 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -68,20 +68,20 @@ def query_numpy(): return truth_numpy -def put_vector(client, vector, j): +def put_vector(client, vector, j, set_name): client.upsert( - namespace="test", key=str(j), record_data={"unit_test": vector}, set_name="demo" + namespace="test", key=str(j), record_data={"unit_test": vector}, set_name=set_name ) -def get_vector(client, j): - result = client.get(namespace="test", key=str(j), set_name="demo") - +def get_vector(client, j, set_name): + result = client.get(namespace="test", key=str(j), set_name=set_name) + print(result) -def vector_search(client, vector): +def vector_search(client, vector, name): result = client.vector_search( namespace="test", - index_name="demo", + index_name=name, query=vector, limit=100, field_names=["unit_test"], @@ -89,10 +89,10 @@ def vector_search(client, vector): return result -def vector_search_ef_80(client, vector): +def vector_search_ef_80(client, vector, name): result = client.vector_search( namespace="test", - index_name="demo", + index_name=name, query=vector, limit=100, field_names=["unit_test"], @@ -101,14 +101,14 @@ def vector_search_ef_80(client, vector): return result -async def grade_results( +def grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - set_name + name, ): @@ -118,9 +118,9 @@ async def grade_results( count = 0 for i in query_numpy: if count % 2: - results.append(vector_search(session_vector_client, i)) + results.append(vector_search(session_vector_client, i, name)) else: - results.append(vector_search_ef_80(session_vector_client, i)) + results.append(vector_search_ef_80(session_vector_client, i, name)) count += 1 # Get recall numbers for each query @@ -161,49 +161,242 @@ def test_vector_search( session_vector_client, session_admin_client, ): - set_name=None session_admin_client.index_create( namespace="test", - name="demo", + name="demo1", + vector_field="unit_test", + dimensions=128, + ) + + + + + for j, vector in enumerate(base_numpy): + put_vector(session_vector_client, vector, j, None) + + session_vector_client.wait_for_index_completion(namespace='test', name='demo1') + + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name='demo1' + ) + +def test_vector_search_with_set_same_as_index( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + extensive_vector_search +): + + + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + + session_admin_client.index_create( + namespace="test", + name="demo2", + sets="demo2", + vector_field="unit_test", + dimensions=128, + index_storage=types.IndexStorage(namespace="test", set_name="demo2") + ) + + + for j, vector in enumerate(base_numpy): + put_vector(session_vector_client, vector, j, "demo2") + + for j, vector in enumerate(base_numpy): + get_vector(session_vector_client, j, "demo2") + + session_vector_client.wait_for_index_completion(namespace='test', name='demo2') + + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name='demo2' + ) + +def test_vector_search_with_set_different_than_name( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + extensive_vector_search +): + + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + + + session_admin_client.index_create( + namespace="test", + name="demo3", + vector_field="unit_test", + dimensions=128, + sets="example1", + index_storage=types.IndexStorage(namespace="test", set_name="demo3") + + ) + + + + + for j, vector in enumerate(base_numpy): + put_vector(session_vector_client, vector, j, "example1") + + session_vector_client.wait_for_index_completion(namespace='test', name='demo3') + + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name="demo3" + ) + +def test_vector_search_with_index_storage_different_than_name( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + extensive_vector_search +): + + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + + session_admin_client.index_create( + namespace="test", + name="demo4", vector_field="unit_test", dimensions=128, - sets=set_name + sets="demo4", + index_storage=types.IndexStorage(namespace="test", set_name="example2") + ) - # Put base vectors for search + + + for j, vector in enumerate(base_numpy): - put_vector(session_vector_client, vector, j) + put_vector(session_vector_client, vector, j, "demo4") + session_vector_client.wait_for_index_completion(namespace='test', name='demo4') + + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name="demo4" + ) + + + +def test_vector_search_with_index_storage_different_location( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + extensive_vector_search +): + + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + + session_admin_client.index_create( + namespace="test", + name="demo5", + vector_field="unit_test", + dimensions=128, + sets="example3", + index_storage=types.IndexStorage(namespace="test", set_name="example4") + + ) + + + - # Put base vectors for search for j, vector in enumerate(base_numpy): - get_vector(session_vector_client, j) + put_vector(session_vector_client, vector, j, "example3") + + session_vector_client.wait_for_index_completion(namespace='test', name='demo5') + + grade_results( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + name='demo5' + ) + +def test_vector_search_with_separate_namespace( + base_numpy, + truth_numpy, + query_numpy, + session_vector_client, + session_admin_client, + extensive_vector_search +): + + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + + session_admin_client.index_create( + namespace="test", + name="demo6", + vector_field="unit_test", + dimensions=128, + sets="demo6", + index_storage=types.IndexStorage(namespace="index_storage", set_name="demo6") + + ) + + + - session_vector_client.wait_for_index_completion(namespace='test', name='demo') + for j, vector in enumerate(base_numpy): + put_vector(session_vector_client, vector, j, "demo6") + session_vector_client.wait_for_index_completion(namespace='test', name='demo6') + grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, - session_admin_client - set_name + session_admin_client, + name='demo6' ) def test_vector_is_indexed(session_vector_client, session_admin_client): val = random.randrange(10_000) - result = session_vector_client.get(namespace="test", key=val, set_name="demo") + result = session_vector_client.get(namespace="test", key=val, set_name="demo1") - print(result) result = session_vector_client.is_indexed( namespace="test", key=str(val), - index_name="demo", - set_name="demo" + index_name="demo2", + set_name="demo2" ) @@ -218,7 +411,7 @@ def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, result = session_vector_client.is_indexed( namespace="test", key=500, - index_name="demo", + index_name="demo2", timeout=0.0001 ) except AVSServerError as se: @@ -235,7 +428,7 @@ def test_vector_vector_search_timeout(session_vector_client, session_admin_clien try: result = session_vector_client.vector_search( namespace="test", - index_name="demo", + index_name="demo2", query=[0, 1, 2], limit=100, field_names=["unit_test"], From 82b3e996474b633f75b416588eead85eb0c58080 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 08:00:34 -0600 Subject: [PATCH 190/215] Flaky tests --- .github/workflows/integration_test.yml | 2 +- tests/standard/aio/test_vector_search.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index b433ed25..dd2d99f0 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -297,7 +297,7 @@ jobs: docker ps - python -m pytest rbac/aio/debug.py -s -vv --host child--port 5000 --root_certificate tls/root.crt + python -m pytest rbac/aio -s -vv --host child--port 5000 --root_certificate tls/root.crt docker logs aerospike-vector-search docker logs aerospike diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index d4b6e0b7..f93edef0 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -188,8 +188,12 @@ async def test_vector_search_with_set_same_as_index( query_numpy, session_vector_client, session_admin_client, + extensive_vector_search ): + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + await session_admin_client.index_create( namespace="test", name="demo2", @@ -222,8 +226,12 @@ async def test_vector_search_with_set_different_than_name( query_numpy, session_vector_client, session_admin_client, + extensive_vector_search ): + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + await session_admin_client.index_create( namespace="test", name="demo3", @@ -257,8 +265,12 @@ async def test_vector_search_with_index_storage_different_than_name( query_numpy, session_vector_client, session_admin_client, + extensive_vector_search ): + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + await session_admin_client.index_create( namespace="test", name="demo4", @@ -294,8 +306,12 @@ async def test_vector_search_with_index_storage_different_location( query_numpy, session_vector_client, session_admin_client, + extensive_vector_search ): + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + await session_admin_client.index_create( namespace="test", name="demo5", @@ -329,8 +345,12 @@ async def test_vector_search_with_separate_namespace( query_numpy, session_vector_client, session_admin_client, + extensive_vector_search ): + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + await session_admin_client.index_create( namespace="test", name="demo6", From ef7c872475072126f00661d6aa61185423ef20b5 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 08:16:20 -0600 Subject: [PATCH 191/215] Fixing flaky tests --- .github/workflows/integration_test.yml | 28 ++------------------------ tests/standard/conftest.py | 5 +++++ 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index dd2d99f0..a9a77af4 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -297,7 +297,7 @@ jobs: docker ps - python -m pytest rbac/aio -s -vv --host child--port 5000 --root_certificate tls/root.crt + python -m pytest rbac/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt docker logs aerospike-vector-search docker logs aerospike @@ -532,7 +532,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.11"] steps: @@ -554,33 +554,9 @@ jobs: working-directory: tests - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - name: create config - run: | - assets/call_gen.sh - cat aerospike-vector-search.yml - cat aerospike.conf - cat /etc/hosts - - working-directory: tests - name: Run unit tests run: | - - docker ps python -m pytest standard -s --host 34.42.225.207 --port 5000 --local_latency working-directory: tests \ No newline at end of file diff --git a/tests/standard/conftest.py b/tests/standard/conftest.py index e24f50ce..525d28ac 100644 --- a/tests/standard/conftest.py +++ b/tests/standard/conftest.py @@ -10,6 +10,7 @@ def pytest_addoption(parser): parser.addoption("--certificate_chain", action="store", default=None, help="Path to certificate chain") parser.addoption("--private_key", action="store", default=None, help="Path to private key") parser.addoption("--local_latency", action="store_true", help="Skip the test if latency is too low to effectively trigger timeout") + parser.addoption("--extensive_vector_search", action="store_true", help="Run extensive vector search testing") @pytest.fixture(scope="module", autouse=True) @@ -43,3 +44,7 @@ def port(request): @pytest.fixture(scope="module", autouse=True) def local_latency(request): return request.config.getoption("--local_latency") + +@pytest.fixture(scope="module", autouse=True) +def extensive_vector_search(request): + return request.config.getoption("--extensive_vector_search") \ No newline at end of file From 5a32674c92ec5383bbe4e4d81c0a53d4b3fe9947 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 08:22:06 -0600 Subject: [PATCH 192/215] Update test_vector_search.py --- tests/standard/sync/test_vector_search.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index a3daf3ae..3a3de39a 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -160,8 +160,14 @@ def test_vector_search( query_numpy, session_vector_client, session_admin_client, + extensive_vector_search ): + + + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + session_admin_client.index_create( namespace="test", name="demo1", @@ -192,12 +198,8 @@ def test_vector_search_with_set_same_as_index( query_numpy, session_vector_client, session_admin_client, - extensive_vector_search ): - - - if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + session_admin_client.index_create( namespace="test", From 38f08b35674fae97c304342b4dd1863dfa94491f Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 08:23:32 -0600 Subject: [PATCH 193/215] Update test_vector_search.py --- tests/standard/aio/test_vector_search.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index f93edef0..8217349b 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -156,8 +156,14 @@ async def test_vector_search( query_numpy, session_vector_client, session_admin_client, + extensive_vector_search ): + + + if not extensive_vector_search: + pytest.skip("Extensive vector tests disabled") + await session_admin_client.index_create( namespace="test", name="demo1", @@ -188,11 +194,8 @@ async def test_vector_search_with_set_same_as_index( query_numpy, session_vector_client, session_admin_client, - extensive_vector_search ): - if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") await session_admin_client.index_create( namespace="test", From e76273509f79742bf64805997f7434853891770e Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 08:47:40 -0600 Subject: [PATCH 194/215] Fixing flaky tests --- tests/standard/aio/test_vector_search.py | 6 +++--- tests/standard/sync/test_vector_search.py | 8 ++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index 8217349b..625a41d2 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -387,7 +387,7 @@ async def test_vector_is_indexed(session_vector_client, session_admin_client, lo result = await session_vector_client.is_indexed( namespace="test", key=str(random.randrange(10_000)), - index_name="demo", + index_name="demo2", ) assert result is True @@ -399,7 +399,7 @@ async def test_vector_is_indexed_timeout(session_vector_client, session_admin_cl result = await session_vector_client.is_indexed( namespace="test", key=str(random.randrange(10_000)), - index_name="demo", + index_name="demo2", timeout=0.0001 ) except AVSServerError as se: @@ -416,7 +416,7 @@ async def test_vector_vector_search_timeout(session_vector_client, session_admin try: result = await session_vector_client.vector_search( namespace="test", - index_name="demo", + index_name="demo2", query=[0, 1, 2], limit=100, field_names=["unit_test"], diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index 3a3de39a..4a4e7049 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -76,7 +76,6 @@ def put_vector(client, vector, j, set_name): def get_vector(client, j, set_name): result = client.get(namespace="test", key=str(j), set_name=set_name) - print(result) def vector_search(client, vector, name): result = client.vector_search( @@ -167,7 +166,7 @@ def test_vector_search( if not extensive_vector_search: pytest.skip("Extensive vector tests disabled") - + session_admin_client.index_create( namespace="test", name="demo1", @@ -389,14 +388,11 @@ def test_vector_search_with_separate_namespace( def test_vector_is_indexed(session_vector_client, session_admin_client): - val = random.randrange(10_000) - - result = session_vector_client.get(namespace="test", key=val, set_name="demo1") result = session_vector_client.is_indexed( namespace="test", - key=str(val), + key=str(random.randrange(10_000)), index_name="demo2", set_name="demo2" ) From 627527b3506e7ca6a447010a2e369aadc992edd3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 08:58:26 -0600 Subject: [PATCH 195/215] Changed local_latency flag --- .github/workflows/integration_test.yml | 12 ++++++------ tests/rbac/aio/conftest.py | 2 -- tests/rbac/aio/debug.py | 1 - .../standard/aio/test_admin_client_index_create.py | 4 ++-- tests/standard/aio/test_admin_client_index_drop.py | 4 ++-- tests/standard/aio/test_admin_client_index_get.py | 4 ++-- .../aio/test_admin_client_index_get_status.py | 4 ++-- tests/standard/aio/test_admin_client_index_list.py | 4 ++-- tests/standard/aio/test_vector_client_delete.py | 4 ++-- tests/standard/aio/test_vector_client_exists.py | 4 ++-- tests/standard/aio/test_vector_client_get.py | 4 ++-- tests/standard/aio/test_vector_client_insert.py | 4 ++-- tests/standard/aio/test_vector_client_update.py | 4 ++-- tests/standard/aio/test_vector_client_upsert.py | 4 ++-- tests/standard/aio/test_vector_search.py | 14 +++++++------- tests/standard/conftest.py | 6 +++--- .../sync/test_admin_client_index_create.py | 4 ++-- .../standard/sync/test_admin_client_index_drop.py | 4 ++-- tests/standard/sync/test_admin_client_index_get.py | 4 ++-- .../sync/test_admin_client_index_get_status.py | 4 ++-- .../standard/sync/test_admin_client_index_list.py | 4 ++-- tests/standard/sync/test_vector_client_delete.py | 4 ++-- tests/standard/sync/test_vector_client_exists.py | 4 ++-- tests/standard/sync/test_vector_client_get.py | 4 ++-- tests/standard/sync/test_vector_client_insert.py | 4 ++-- tests/standard/sync/test_vector_client_update.py | 4 ++-- tests/standard/sync/test_vector_client_upsert.py | 4 ++-- tests/standard/sync/test_vector_search.py | 8 ++++---- 28 files changed, 64 insertions(+), 67 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index a9a77af4..4f51c0a3 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -69,7 +69,7 @@ jobs: sleep 5 docker ps - python -m pytest standard -s --host 0.0.0.0 --port 5000 --local_latency + python -m pytest standard -s --host 0.0.0.0 --port 5000 working-directory: tests test-tls: @@ -145,7 +145,7 @@ jobs: docker ps - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt --local_latency -vs + python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt -vs docker logs aerospike-vector-search docker logs aerospike @@ -218,7 +218,7 @@ jobs: sleep 5 - python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin --local_latency + python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin working-directory: tests @@ -371,7 +371,7 @@ jobs: sleep 5 - python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --local_latency -vs + python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs @@ -445,7 +445,7 @@ jobs: sleep 5 - python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin --local_latency -vs + python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin -vs @@ -558,5 +558,5 @@ jobs: - name: Run unit tests run: | - python -m pytest standard -s --host 34.42.225.207 --port 5000 --local_latency + python -m pytest standard -s --host 34.42.225.207 --port 5000 --with_latency working-directory: tests \ No newline at end of file diff --git a/tests/rbac/aio/conftest.py b/tests/rbac/aio/conftest.py index 1ca59d6d..419d3d3b 100644 --- a/tests/rbac/aio/conftest.py +++ b/tests/rbac/aio/conftest.py @@ -27,7 +27,6 @@ def certificate_chain(request): """ @pytest.fixture(scope="module", autouse=True) async def drop_all_indexes(username, password, host, port, root_certificate, certificate_chain, private_key): - print("\n\n\n\n MADE IT TO FUNCTION") async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: @@ -42,7 +41,6 @@ async def drop_all_indexes(username, password, host, port, root_certificate, cer @pytest.fixture(scope="module") async def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): - print("\n\n\n\n MADE IT TO FUNCTION") client = AdminClient( seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) diff --git a/tests/rbac/aio/debug.py b/tests/rbac/aio/debug.py index f0ca9965..cdc4d23f 100644 --- a/tests/rbac/aio/debug.py +++ b/tests/rbac/aio/debug.py @@ -2,7 +2,6 @@ from ...utils import random_int async def test_add_user(session_rbac_admin_client): - print("WE ARE IN THIS") await session_rbac_admin_client.add_user( username="admin", password="admin", diff --git a/tests/standard/aio/test_admin_client_index_create.py b/tests/standard/aio/test_admin_client_index_create.py index 64723b13..dc9254e6 100644 --- a/tests/standard/aio/test_admin_client_index_create.py +++ b/tests/standard/aio/test_admin_client_index_create.py @@ -509,9 +509,9 @@ async def test_index_create_index_storage(session_admin_client, test_case, rando ), ], ) -async def test_index_create_timeout(session_admin_client, test_case, random_name, local_latency): +async def test_index_create_timeout(session_admin_client, test_case, random_name, with_latency): - if local_latency: + if not with_latency: pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: diff --git a/tests/standard/aio/test_admin_client_index_drop.py b/tests/standard/aio/test_admin_client_index_drop.py index 97f25295..4edf9ab1 100644 --- a/tests/standard/aio/test_admin_client_index_drop.py +++ b/tests/standard/aio/test_admin_client_index_drop.py @@ -30,8 +30,8 @@ async def test_index_drop(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None, None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -async def test_index_drop_timeout(session_admin_client, empty_test_case, random_name, local_latency): - if local_latency: +async def test_index_drop_timeout(session_admin_client, empty_test_case, random_name, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") await session_admin_client.index_create( namespace="test", diff --git a/tests/standard/aio/test_admin_client_index_get.py b/tests/standard/aio/test_admin_client_index_get.py index 3083fd4e..2500c53f 100644 --- a/tests/standard/aio/test_admin_client_index_get.py +++ b/tests/standard/aio/test_admin_client_index_get.py @@ -38,9 +38,9 @@ async def test_index_get(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None, None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -async def test_index_get_timeout(session_admin_client, empty_test_case, random_name, local_latency): +async def test_index_get_timeout(session_admin_client, empty_test_case, random_name, with_latency): - if local_latency: + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): diff --git a/tests/standard/aio/test_admin_client_index_get_status.py b/tests/standard/aio/test_admin_client_index_get_status.py index c0a750eb..a49bbfa9 100644 --- a/tests/standard/aio/test_admin_client_index_get_status.py +++ b/tests/standard/aio/test_admin_client_index_get_status.py @@ -27,8 +27,8 @@ async def test_index_get_status(session_admin_client, empty_test_case, random_na @pytest.mark.parametrize("empty_test_case",[None, None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -async def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name, local_latency): - if local_latency: +async def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") try: await session_admin_client.index_create( diff --git a/tests/standard/aio/test_admin_client_index_list.py b/tests/standard/aio/test_admin_client_index_list.py index ac6e7073..99b57d30 100644 --- a/tests/standard/aio/test_admin_client_index_list.py +++ b/tests/standard/aio/test_admin_client_index_list.py @@ -35,8 +35,8 @@ async def test_index_list(session_admin_client, empty_test_case, random_name): assert isinstance(index['storage']['set'], str) await drop_specified_index(session_admin_client, "test", random_name) -async def test_index_list_timeout(session_admin_client, local_latency): - if local_latency: +async def test_index_list_timeout(session_admin_client, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): try: diff --git a/tests/standard/aio/test_vector_client_delete.py b/tests/standard/aio/test_vector_client_delete.py index a31de83e..3a29db00 100644 --- a/tests/standard/aio/test_vector_client_delete.py +++ b/tests/standard/aio/test_vector_client_delete.py @@ -89,8 +89,8 @@ async def test_vector_delete_without_record(session_vector_client, test_case, ra ), ], ) -async def test_vector_delete_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +async def test_vector_delete_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): diff --git a/tests/standard/aio/test_vector_client_exists.py b/tests/standard/aio/test_vector_client_exists.py index 0c52dc3d..33f1d1ce 100644 --- a/tests/standard/aio/test_vector_client_exists.py +++ b/tests/standard/aio/test_vector_client_exists.py @@ -69,8 +69,8 @@ async def test_vector_exists(session_vector_client, test_case, random_key): ), ], ) -async def test_vector_exists_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +async def test_vector_exists_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): diff --git a/tests/standard/aio/test_vector_client_get.py b/tests/standard/aio/test_vector_client_get.py index d19e1928..42d35890 100644 --- a/tests/standard/aio/test_vector_client_get.py +++ b/tests/standard/aio/test_vector_client_get.py @@ -84,8 +84,8 @@ async def test_vector_get(session_vector_client, test_case, random_key): timeout=0.0001 ), ], ) -async def test_vector_get_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +async def test_vector_get_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): diff --git a/tests/standard/aio/test_vector_client_insert.py b/tests/standard/aio/test_vector_client_insert.py index ba2a7f63..7ff9afd2 100644 --- a/tests/standard/aio/test_vector_client_insert.py +++ b/tests/standard/aio/test_vector_client_insert.py @@ -112,8 +112,8 @@ async def test_vector_insert_with_existing_record(session_vector_client, test_ca ) ], ) -async def test_vector_insert_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +async def test_vector_insert_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): diff --git a/tests/standard/aio/test_vector_client_update.py b/tests/standard/aio/test_vector_client_update.py index 566dd4c4..19abe698 100644 --- a/tests/standard/aio/test_vector_client_update.py +++ b/tests/standard/aio/test_vector_client_update.py @@ -105,8 +105,8 @@ async def test_vector_update_without_existing_record(session_vector_client, test ) ], ) -async def test_vector_update_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +async def test_vector_update_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): diff --git a/tests/standard/aio/test_vector_client_upsert.py b/tests/standard/aio/test_vector_client_upsert.py index 10900b24..38a0885f 100644 --- a/tests/standard/aio/test_vector_client_upsert.py +++ b/tests/standard/aio/test_vector_client_upsert.py @@ -97,8 +97,8 @@ async def test_vector_upsert_with_existing_record(session_vector_client, test_ca ) ], ) -async def test_vector_upsert_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +async def test_vector_upsert_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index 625a41d2..61880c25 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -381,9 +381,9 @@ async def test_vector_search_with_separate_namespace( name='demo6' ) -async def test_vector_is_indexed(session_vector_client, session_admin_client, local_latency): - if local_latency: - pytest.skip("Server latency too low to test timeout") +async def test_vector_is_indexed(session_vector_client, session_admin_client, with_latency): + + result = await session_vector_client.is_indexed( namespace="test", key=str(random.randrange(10_000)), @@ -391,8 +391,8 @@ async def test_vector_is_indexed(session_vector_client, session_admin_client, lo ) assert result is True -async def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, local_latency): - if local_latency: +async def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): try: @@ -408,8 +408,8 @@ async def test_vector_is_indexed_timeout(session_vector_client, session_admin_cl return assert "In several attempts, the timeout did not happen" == "TEST FAIL" -async def test_vector_vector_search_timeout(session_vector_client, session_admin_client, local_latency): - if local_latency: +async def test_vector_vector_search_timeout(session_vector_client, session_admin_client, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): diff --git a/tests/standard/conftest.py b/tests/standard/conftest.py index 525d28ac..c5f276cb 100644 --- a/tests/standard/conftest.py +++ b/tests/standard/conftest.py @@ -9,7 +9,7 @@ def pytest_addoption(parser): parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") parser.addoption("--certificate_chain", action="store", default=None, help="Path to certificate chain") parser.addoption("--private_key", action="store", default=None, help="Path to private key") - parser.addoption("--local_latency", action="store_true", help="Skip the test if latency is too low to effectively trigger timeout") + parser.addoption("--with_latency", action="store_true", help="Skip the test if latency is too low to effectively trigger timeout") parser.addoption("--extensive_vector_search", action="store_true", help="Run extensive vector search testing") @@ -42,8 +42,8 @@ def port(request): return request.config.getoption("--port") @pytest.fixture(scope="module", autouse=True) -def local_latency(request): - return request.config.getoption("--local_latency") +def with_latency(request): + return request.config.getoption("--with_latency") @pytest.fixture(scope="module", autouse=True) def extensive_vector_search(request): diff --git a/tests/standard/sync/test_admin_client_index_create.py b/tests/standard/sync/test_admin_client_index_create.py index 1644c8a5..d5a84f33 100644 --- a/tests/standard/sync/test_admin_client_index_create.py +++ b/tests/standard/sync/test_admin_client_index_create.py @@ -593,9 +593,9 @@ def test_index_create_index_storage(session_admin_client, test_case, random_name ), ], ) -def test_index_create_timeout(session_admin_client, test_case, random_name, local_latency): +def test_index_create_timeout(session_admin_client, test_case, random_name, with_latency): - if local_latency: + if not with_latency: pytest.skip("Server latency too low to test timeout") try: session_admin_client.index_drop(namespace="test", name=random_name) diff --git a/tests/standard/sync/test_admin_client_index_drop.py b/tests/standard/sync/test_admin_client_index_drop.py index db645179..5aaa4682 100644 --- a/tests/standard/sync/test_admin_client_index_drop.py +++ b/tests/standard/sync/test_admin_client_index_drop.py @@ -37,8 +37,8 @@ def test_index_drop(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_drop_timeout(session_admin_client, empty_test_case, random_name, local_latency): - if local_latency: +def test_index_drop_timeout(session_admin_client, empty_test_case, random_name, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") try: diff --git a/tests/standard/sync/test_admin_client_index_get.py b/tests/standard/sync/test_admin_client_index_get.py index b475bb26..6a3d483e 100644 --- a/tests/standard/sync/test_admin_client_index_get.py +++ b/tests/standard/sync/test_admin_client_index_get.py @@ -46,8 +46,8 @@ def test_index_get(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_get_timeout(session_admin_client, empty_test_case, random_name, local_latency): - if local_latency: +def test_index_get_timeout(session_admin_client, empty_test_case, random_name, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") try: session_admin_client.index_create( diff --git a/tests/standard/sync/test_admin_client_index_get_status.py b/tests/standard/sync/test_admin_client_index_get_status.py index c185bdc3..772c24b3 100644 --- a/tests/standard/sync/test_admin_client_index_get_status.py +++ b/tests/standard/sync/test_admin_client_index_get_status.py @@ -32,8 +32,8 @@ def test_index_get_status(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name, local_latency): - if local_latency: +def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): diff --git a/tests/standard/sync/test_admin_client_index_list.py b/tests/standard/sync/test_admin_client_index_list.py index eaac05eb..02d15c89 100644 --- a/tests/standard/sync/test_admin_client_index_list.py +++ b/tests/standard/sync/test_admin_client_index_list.py @@ -37,9 +37,9 @@ def test_index_list(session_admin_client, empty_test_case, random_name): @pytest.mark.parametrize("empty_test_case",[None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_list_timeout(session_admin_client, empty_test_case, random_name, local_latency): +def test_index_list_timeout(session_admin_client, empty_test_case, random_name, with_latency): - if local_latency: + if not with_latency: pytest.skip("Server latency too low to test timeout") try: session_admin_client.index_create( diff --git a/tests/standard/sync/test_vector_client_delete.py b/tests/standard/sync/test_vector_client_delete.py index 44e32781..a6f740ef 100644 --- a/tests/standard/sync/test_vector_client_delete.py +++ b/tests/standard/sync/test_vector_client_delete.py @@ -91,8 +91,8 @@ def test_vector_delete_without_record(session_vector_client, test_case, random_k ), ], ) -def test_vector_delete_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +def test_vector_delete_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): diff --git a/tests/standard/sync/test_vector_client_exists.py b/tests/standard/sync/test_vector_client_exists.py index 19971a1b..95f2775a 100644 --- a/tests/standard/sync/test_vector_client_exists.py +++ b/tests/standard/sync/test_vector_client_exists.py @@ -71,8 +71,8 @@ def test_vector_exists(session_vector_client, test_case, random_key): ), ], ) -def test_vector_exists_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +def test_vector_exists_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): diff --git a/tests/standard/sync/test_vector_client_get.py b/tests/standard/sync/test_vector_client_get.py index e2bd0654..8c25455a 100644 --- a/tests/standard/sync/test_vector_client_get.py +++ b/tests/standard/sync/test_vector_client_get.py @@ -86,8 +86,8 @@ def test_vector_get(session_vector_client, test_case, random_key): ), ], ) -def test_vector_get_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +def test_vector_get_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): diff --git a/tests/standard/sync/test_vector_client_insert.py b/tests/standard/sync/test_vector_client_insert.py index 68360094..26ddbd5a 100644 --- a/tests/standard/sync/test_vector_client_insert.py +++ b/tests/standard/sync/test_vector_client_insert.py @@ -150,8 +150,8 @@ def test_vector_insert_without_existing_record_ignore_mem_queue_full(session_vec ) ], ) -def test_vector_insert_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +def test_vector_insert_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): diff --git a/tests/standard/sync/test_vector_client_update.py b/tests/standard/sync/test_vector_client_update.py index fd30c410..0092648f 100644 --- a/tests/standard/sync/test_vector_client_update.py +++ b/tests/standard/sync/test_vector_client_update.py @@ -102,8 +102,8 @@ def test_vector_update_without_existing_record(session_vector_client, test_case, ) ], ) -def test_vector_update_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +def test_vector_update_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): diff --git a/tests/standard/sync/test_vector_client_upsert.py b/tests/standard/sync/test_vector_client_upsert.py index 857a1e1f..f3bf24dd 100644 --- a/tests/standard/sync/test_vector_client_upsert.py +++ b/tests/standard/sync/test_vector_client_upsert.py @@ -97,8 +97,8 @@ def test_vector_upsert_with_existing_record(session_vector_client, test_case, ra ) ], ) -def test_vector_upsert_timeout(session_vector_client, test_case, random_key, local_latency): - if local_latency: +def test_vector_upsert_timeout(session_vector_client, test_case, random_key, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index 4a4e7049..aca5bdd2 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -400,8 +400,8 @@ def test_vector_is_indexed(session_vector_client, session_admin_client): assert result is True -def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, local_latency): - if local_latency: +def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): @@ -418,8 +418,8 @@ def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, return assert "In several attempts, the timeout did not happen" == "TEST FAIL" -def test_vector_vector_search_timeout(session_vector_client, session_admin_client, local_latency): - if local_latency: +def test_vector_vector_search_timeout(session_vector_client, session_admin_client, with_latency): + if not with_latency: pytest.skip("Server latency too low to test timeout") for i in range(10): From 7da4ccbe675136efffe1bbb2d19f81b0fa6f0ba3 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 09:11:41 -0600 Subject: [PATCH 196/215] Flaky tests --- tests/rbac/aio/debug.py | 11 ----------- tests/standard/aio/test_vector_search.py | 12 ++++++------ 2 files changed, 6 insertions(+), 17 deletions(-) delete mode 100644 tests/rbac/aio/debug.py diff --git a/tests/rbac/aio/debug.py b/tests/rbac/aio/debug.py deleted file mode 100644 index cdc4d23f..00000000 --- a/tests/rbac/aio/debug.py +++ /dev/null @@ -1,11 +0,0 @@ -import pytest -from ...utils import random_int - -async def test_add_user(session_rbac_admin_client): - await session_rbac_admin_client.add_user( - username="admin", - password="admin", - roles=None - - ) - assert 1 == 1 \ No newline at end of file diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index 61880c25..2fac75cd 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -179,7 +179,7 @@ async def test_vector_search( tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo1')) await asyncio.gather(*tasks) - grade_results( + await grade_results( base_numpy, truth_numpy, query_numpy, @@ -214,7 +214,7 @@ async def test_vector_search_with_set_same_as_index( tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo2')) await asyncio.gather(*tasks) - grade_results( + await grade_results( base_numpy, truth_numpy, query_numpy, @@ -253,7 +253,7 @@ async def test_vector_search_with_set_different_than_name( tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo3')) await asyncio.gather(*tasks) - grade_results( + await grade_results( base_numpy, truth_numpy, query_numpy, @@ -292,7 +292,7 @@ async def test_vector_search_with_index_storage_different_than_name( tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo4')) await asyncio.gather(*tasks) - grade_results( + await grade_results( base_numpy, truth_numpy, query_numpy, @@ -333,7 +333,7 @@ async def test_vector_search_with_index_storage_different_location( tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo5')) await asyncio.gather(*tasks) - grade_results( + await grade_results( base_numpy, truth_numpy, query_numpy, @@ -372,7 +372,7 @@ async def test_vector_search_with_separate_namespace( tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo6')) await asyncio.gather(*tasks) - grade_results( + await grade_results( base_numpy, truth_numpy, query_numpy, From 25d3e7b01c89cbaa7465dea95e55f706dd713a14 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 09:22:45 -0600 Subject: [PATCH 197/215] Fixing flaky tests --- tests/standard/aio/test_vector_search.py | 1 + tests/standard/sync/test_vector_search.zip | Bin 1837 -> 0 bytes 2 files changed, 1 insertion(+) delete mode 100644 tests/standard/sync/test_vector_search.zip diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index 2fac75cd..07da30ff 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -388,6 +388,7 @@ async def test_vector_is_indexed(session_vector_client, session_admin_client, wi namespace="test", key=str(random.randrange(10_000)), index_name="demo2", + set_name="demo2" ) assert result is True diff --git a/tests/standard/sync/test_vector_search.zip b/tests/standard/sync/test_vector_search.zip deleted file mode 100644 index 399d132025ce2e0ab13959222c2e544e2742996a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1837 zcmbW2XE@u79>@QQO;A0F#%g1=u_EQDS*v0MHAA9^*~BaoB~A}D>e{n4LaEW(o7O5q zX;JIgHA;`3W3~<{ZBe&9&ppq*ukZK!{MPe*@q78PG-Y9h0-WEiRIrB!{v$0o0KfnQ zK=q_hiMKu7skefN6i?S6cQPt~hO^}bIM4&RH~*>NP#yrpy1@bff43d{4WG3u(D1`L zODF91KqzTap%j#j%A4QmwH9oYzvqgkH)vVCyCJPUU&QP_Tz9*%HNPW)c=sQad{Ep(3w; z5qFu3MYp7*Tt22|)t|ihqj$ga)`XFvoaNW7M}EWb$kPixw=Jr~hLAR-182jaDHnDL zwGoW$rfp=l+rX|i(zxZPX9DBd0&jqrjVB|NUKfm;fHRF#n>PeZep%}KLVJDmUM#9Y zH3Xr^gsR8Y60*F7)dYbM=G8D*F@=fETvNFQoxo~%8$mQB&BF%@nnx+uS$7}x^sFvq z`oH4)EL9?T@|59E$I47uWyt19Gwa@3-@z?Dq#CRC(W-=_!pwS} z0ayoL)6;kVr{?2E>EyczuH$Dpf>PItXZ&rQ^&QTDM@kD5pI%+WBr~!%LoXb0H|y;}g4(6j#y1|j&+Xus>~f2fH=r@7JOV^zUIyV% zSrGfqU?O4Mj5o;_11*=mdJ)kwmBX+d4n|L#zC`0}CqWxZIT)MF6AJka;LwoD7@@;JUc1dGNxg@VvYOQD z!u0p&bN}VGeimogHP#zuA%SGR;rOGf@R#g5;#(iqY~lb`Cl zx`$F!y1iDu27ahblvSS*xEqJ|>IW)RmIP$RCp50Y6Ykkl^0ds;MKEj zCLAH?RXti7NNQw-4{Q587zyAX(d}qeo*LpO%-Q=moh@P;zC&njs)mV1SD=yJdmqR9 z$-hndx-aUM41!ffNiIdJ==Jod%t>`RH~>tn`JnEotdX|NKtNzl#U&zXd_WXP$&;#j zFnm*XNj!vVFQ#jQ#+3WBl?eq#zZhy77qT*bGnLN`r-rq{6dhlcOK9GyXJb?jcvMtl zL8h|_<4Ze+7-Z69tA6El3f5AuZQOxhM5ELEA@yg~w7yQU_AYo%@Q3lz2D>4dz*T$( zH_1MY;V0Ga;pm2|eW1~qf>F4~QFP6MB4@$@b9!Pk*U>#De#LjQ&oZC+8+o-ev0glk zPwKfY1K&I>EgA^#e+zUiZu7hmar9jP2jHHOmb1!7aj&#iilrA*NNu^s87|g65YuD8 ze?g#y^o;{0IDC%NaOe`j4RxvZ8*_{-aLRNq#Ih^W?iIYd9NJfZnVFCnGRGz}t8(9i zBJEb`n#>WmA?x>-c2U{j#K<9IEGT^Pqgump36Y!GVGKVnrma7A*_nhgDn#TIG-^M% zg-P=vM(f8U2=|yj-mmhrXCS8YJ*$p3s(8A~%vZMTr99$R=)}GTBid57!K-qX5WdeB z-(Gh{W)mEjnzW$c9G$_G--oK$i<58Hj(DVMm;rUkKNJX{9KDr-P z%A~VK`D_f*WGd0=j$}RgiwHicF1xNyr}NY=7ZnlFdD1=3@SekNhb_nmyS+N7a4>DPr og1}Ig|5EFJvmey@N6nExw*QM^mZogqp8){qyWPLf=D)9h1NYfKCjbBd From fc2553e77e8d9676f550315012210ac7f60cfee9 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 09:36:27 -0600 Subject: [PATCH 198/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 72 +++++++++++++------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 4f51c0a3..b446e2a2 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -524,39 +524,39 @@ jobs: working-directory: tests - - test-timeout-on-sandbox: - runs-on: ubuntu-24.04 - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.11"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - - working-directory: tests - - - - - name: Run unit tests - run: | - - python -m pytest standard -s --host 34.42.225.207 --port 5000 --with_latency - working-directory: tests \ No newline at end of file +# +# test-timeout-on-sandbox: +# runs-on: ubuntu-24.04 +# continue-on-error: true +# +# +# strategy: +# matrix: +# python-version: ["3.11"] +# +# +# steps: +# - name: Checkout code +# uses: actions/checkout@v3 +# +# - name: Set up Python +# uses: actions/setup-python@v2 +# with: +# python-version: ${{ matrix.python-version }} +# +# +# - name: Install dependencies +# run: | +# python -m pip install --upgrade pip +# python setup.py +# pip install -r requirements.txt +# +# working-directory: tests +# +# +# +# - name: Run unit tests +# run: | +# +# python -m pytest standard -s --host 34.42.225.207 --port 5000 --with_latency +# working-directory: tests \ No newline at end of file From fb23cdb297112c5ce0ffc3543545684248adbaf9 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 12:52:41 -0600 Subject: [PATCH 199/215] Added changes from final review Ran black format --- .github/workflows/integration_test.yml | 145 +++++++++++++++ src/aerospike_vector_search/admin.py | 169 +++++++++++------- src/aerospike_vector_search/aio/admin.py | 138 ++++++++++---- src/aerospike_vector_search/aio/client.py | 114 +++++++++--- .../aio/internal/channel_provider.py | 80 ++++++--- src/aerospike_vector_search/client.py | 130 ++++++++++---- .../internal/channel_provider.py | 80 +++++++-- .../shared/admin_helpers.py | 89 ++++++--- .../shared/base_channel_provider.py | 34 ++-- .../shared/client_helpers.py | 92 ++++++++-- src/aerospike_vector_search/shared/helpers.py | 6 +- src/aerospike_vector_search/types.py | 36 +++- tests/rbac/aio/conftest.py | 12 +- tests/rbac/conftest.py | 4 + tests/rbac/sync/conftest.py | 8 +- tests/standard/aio/conftest.py | 16 +- .../aio/test_admin_client_index_create.py | 1 + .../standard/aio/test_vector_client_delete.py | 1 + .../standard/aio/test_vector_client_exists.py | 1 + tests/standard/aio/test_vector_client_get.py | 1 + .../standard/aio/test_vector_client_insert.py | 1 + .../standard/aio/test_vector_client_update.py | 4 +- .../standard/aio/test_vector_client_upsert.py | 44 ++++- tests/standard/conftest.py | 6 + tests/standard/sync/conftest.py | 21 +-- .../sync/test_vector_client_upsert.py | 39 ++++ 26 files changed, 968 insertions(+), 304 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index b446e2a2..c9a1d504 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -524,6 +524,151 @@ jobs: working-directory: tests + + test-is-loadbalancer: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + + - name: create config + run: | + assets/call_gen.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest standard -s --is_loadbalancer --host 0.0.0.0 --port 5000 -vs + + + working-directory: tests + + test-is-loadbalancer: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: Add hosts to /etc/hosts + run: | + sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts + + - name: create config + run: | + assets/call_gen.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest standard -s --is_loadbalancer --host 0.0.0.0 --port 5000 -vs + + + working-directory: tests + # # test-timeout-on-sandbox: # runs-on: ubuntu-24.04 diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index bfdb224a..237788c1 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -10,6 +10,7 @@ logger = logging.getLogger(__name__) + class Client(BaseClient): """ Aerospike Vector Search Admin Client @@ -45,7 +46,15 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path + seeds, + listener_name, + is_loadbalancer, + username, + password, + root_certificate, + certificate_chain, + private_key, + service_config_path, ) def index_create( @@ -90,8 +99,6 @@ def index_create( It waits for up to 100,000 seconds for the index creation to complete. """ - - (index_stub, index_create_request) = self._prepare_index_create( namespace, name, @@ -106,14 +113,16 @@ def index_create( logger, ) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout - + kwargs["timeout"] = timeout try: - index_stub.Create(index_create_request, credentials=self._channel_provider._token, **kwargs) + index_stub.Create( + index_create_request, + credentials=self._channel_provider._token, + **kwargs, + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -125,7 +134,9 @@ def index_create( logger.error("Failed waiting for creation with error: %s", e) raise types.AVSServerError(rpc_error=e) - def index_drop(self, *, namespace: str, name: str, timeout: Optional[int] = None) -> None: + def index_drop( + self, *, namespace: str, name: str, timeout: Optional[int] = None + ) -> None: """ Drop an index. @@ -141,19 +152,19 @@ def index_drop(self, *, namespace: str, name: str, timeout: Optional[int] = None This method drops an index with the specified parameters and waits for the index deletion to complete. It waits for up to 100,000 seconds for the index deletion to complete. """ - (index_stub, index_drop_request) = self._prepare_index_drop( namespace, name, timeout, logger ) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - index_stub.Drop(index_drop_request, credentials=self._channel_provider._token, **kwargs) + index_stub.Drop( + index_drop_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -176,17 +187,17 @@ def index_list(self, timeout: Optional[int] = None) -> list[dict]: grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (index_stub, index_list_request) = self._prepare_index_list(timeout, logger) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = index_stub.List(index_list_request, credentials=self._channel_provider._token, **kwargs) + response = index_stub.List( + index_list_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -210,7 +221,6 @@ def index_get( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (index_stub, index_get_request) = self._prepare_index_get( namespace, name, timeout, logger @@ -218,16 +228,20 @@ def index_get( kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = index_stub.Get(index_get_request, credentials=self._channel_provider._token, **kwargs) + response = index_stub.Get( + index_get_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get(response) - def index_get_status(self, *, namespace: str, name: str, timeout: Optional[int] = None) -> int: + def index_get_status( + self, *, namespace: str, name: str, timeout: Optional[int] = None + ) -> int: """ Retrieve the number of records queued to be merged into an index. @@ -248,96 +262,104 @@ def index_get_status(self, *, namespace: str, name: str, timeout: Optional[int] Warning: This API is subject to change. """ - (index_stub, index_get_status_request) = self._prepare_index_get_status( namespace, name, timeout, logger ) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = index_stub.GetStatus(index_get_status_request, credentials=self._channel_provider._token, **kwargs) + response = index_stub.GetStatus( + index_get_status_request, + credentials=self._channel_provider._token, + **kwargs, + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get_status(response) - def add_user(self, *, username: str, password: str, roles: list[str], timeout: Optional[int] = None) -> int: - + def add_user( + self, + *, + username: str, + password: str, + roles: list[str], + timeout: Optional[int] = None, + ) -> int: (user_admin_stub, add_user_request) = self._prepare_add_user( username, password, roles, timeout, logger ) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout - + kwargs["timeout"] = timeout try: - user_admin_stub.AddUser(add_user_request, credentials=self._channel_provider._token, **kwargs) + user_admin_stub.AddUser( + add_user_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - def update_credentials(self, *, username: str, password: str, timeout: Optional[int] = None) -> int: - + def update_credentials( + self, *, username: str, password: str, timeout: Optional[int] = None + ) -> int: - (user_admin_stub, update_credentials_request) = self._prepare_update_credentials( - username, password, timeout, logger + (user_admin_stub, update_credentials_request) = ( + self._prepare_update_credentials(username, password, timeout, logger) ) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout - + kwargs["timeout"] = timeout try: - user_admin_stub.UpdateCredentials(update_credentials_request, credentials=self._channel_provider._token) + user_admin_stub.UpdateCredentials( + update_credentials_request, credentials=self._channel_provider._token + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) def drop_user(self, *, username: str, timeout: Optional[int] = None) -> int: - (user_admin_stub, drop_user_request) = self._prepare_drop_user( username, timeout, logger ) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout - + kwargs["timeout"] = timeout try: - user_admin_stub.DropUser(drop_user_request, credentials=self._channel_provider._token, **kwargs) + user_admin_stub.DropUser( + drop_user_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: - (user_admin_stub, get_user_request) = self._prepare_get_user( username, timeout, logger ) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = user_admin_stub.GetUser(get_user_request, credentials=self._channel_provider._token, **kwargs) + response = user_admin_stub.GetUser( + get_user_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -345,43 +367,47 @@ def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: return self._respond_get_user(response) def list_users(self, timeout: Optional[int] = None) -> int: - (user_admin_stub, list_users_request) = self._prepare_list_users( timeout, logger ) - + kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = user_admin_stub.ListUsers(list_users_request, credentials=self._channel_provider._token, **kwargs) + response = user_admin_stub.ListUsers( + list_users_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_list_users(response) - def grant_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: - + def grant_roles( + self, *, username: str, roles: list[str], timeout: Optional[int] = None + ) -> int: (user_admin_stub, grant_roles_request) = self._prepare_grant_roles( username, roles, timeout, logger ) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - user_admin_stub.GrantRoles(grant_roles_request, credentials=self._channel_provider._token, **kwargs) + user_admin_stub.GrantRoles( + grant_roles_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - def revoke_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: - + def revoke_roles( + self, *, username: str, roles: list[str], timeout: Optional[int] = None + ) -> int: (user_admin_stub, revoke_roles_request) = self._prepare_revoke_roles( username, roles, timeout, logger @@ -389,29 +415,32 @@ def revoke_roles(self, *, username: str, roles: list[str], timeout: Optional[int kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - user_admin_stub.RevokeRoles(revoke_roles_request, credentials=self._channel_provider._token, **kwargs) + user_admin_stub.RevokeRoles( + revoke_roles_request, + credentials=self._channel_provider._token, + **kwargs, + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) def list_roles(self, timeout: Optional[int] = None) -> int: - (user_admin_stub, list_roles_request) = self._prepare_list_roles( timeout, logger ) - kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout - + kwargs["timeout"] = timeout try: - response = user_admin_stub.ListRoles(list_roles_request, credentials=self._channel_provider._token, **kwargs) + response = user_admin_stub.ListRoles( + list_roles_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -428,7 +457,6 @@ def _wait_for_index_creation( """ Wait for the index to be created. """ - (index_stub, wait_interval, start_time, _, _, index_creation_request) = ( self._prepare_wait_for_index_waiting(namespace, name, wait_interval) @@ -436,7 +464,9 @@ def _wait_for_index_creation( while True: self._check_timeout(start_time, timeout) try: - index_stub.GetStatus(index_creation_request, credentials=self._channel_provider._token) + index_stub.GetStatus( + index_creation_request, credentials=self._channel_provider._token + ) logger.debug("Index created succesfully") # Index has been created return @@ -460,7 +490,6 @@ def _wait_for_index_deletion( """ Wait for the index to be deleted. """ - # Wait interval between polling (index_stub, wait_interval, start_time, _, _, index_deletion_request) = ( @@ -471,7 +500,9 @@ def _wait_for_index_deletion( self._check_timeout(start_time, timeout) try: - index_stub.GetStatus(index_deletion_request, credentials=self._channel_provider._token) + index_stub.GetStatus( + index_deletion_request, credentials=self._channel_provider._token + ) # Wait for some more time. time.sleep(wait_interval) except grpc.RpcError as e: diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index e8b3b322..a9cddbf0 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -46,7 +46,15 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path + seeds, + listener_name, + is_loadbalancer, + username, + password, + root_certificate, + certificate_chain, + private_key, + service_config_path, ) async def index_create( @@ -94,7 +102,6 @@ async def index_create( if not self._channel_provider.client_server_compatible: await self._channel_provider._is_ready() - (index_stub, index_create_request) = self._prepare_index_create( namespace, name, @@ -111,10 +118,14 @@ async def index_create( kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await index_stub.Create(index_create_request, credentials=self._channel_provider._token, **kwargs) + await index_stub.Create( + index_create_request, + credentials=self._channel_provider._token, + **kwargs, + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -126,7 +137,9 @@ async def index_create( logger.error("Failed waiting for creation with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def index_drop(self, *, namespace: str, name: str, timeout: Optional[int] = None) -> None: + async def index_drop( + self, *, namespace: str, name: str, timeout: Optional[int] = None + ) -> None: """ Drop an index. @@ -151,10 +164,12 @@ async def index_drop(self, *, namespace: str, name: str, timeout: Optional[int] kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await index_stub.Drop(index_drop_request, credentials=self._channel_provider._token, **kwargs) + await index_stub.Drop( + index_drop_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -184,10 +199,12 @@ async def index_list(self, timeout: Optional[int] = None) -> list[dict]: kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = await index_stub.List(index_list_request, credentials=self._channel_provider._token, **kwargs) + response = await index_stub.List( + index_list_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -220,16 +237,20 @@ async def index_get( kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = await index_stub.Get(index_get_request, credentials=self._channel_provider._token, **kwargs) + response = await index_stub.Get( + index_get_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get(response) - async def index_get_status(self, *, namespace: str, name: str, timeout: Optional[int] = None) -> int: + async def index_get_status( + self, *, namespace: str, name: str, timeout: Optional[int] = None + ) -> int: """ Retrieve the number of records queued to be merged into an index. @@ -259,17 +280,28 @@ async def index_get_status(self, *, namespace: str, name: str, timeout: Optional kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = await index_stub.GetStatus(index_get_status_request, credentials=self._channel_provider._token, **kwargs) + response = await index_stub.GetStatus( + index_get_status_request, + credentials=self._channel_provider._token, + **kwargs, + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get_status(response) - async def add_user(self, *, username: str, password: str, roles: list[str], timeout: Optional[int] = None) -> int: + async def add_user( + self, + *, + username: str, + password: str, + roles: list[str], + timeout: Optional[int] = None, + ) -> int: if not self._channel_provider.client_server_compatible: await self._channel_provider._is_ready() @@ -279,28 +311,36 @@ async def add_user(self, *, username: str, password: str, roles: list[str], time kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await user_admin_stub.AddUser(add_user_request, credentials=self._channel_provider._token, **kwargs) + await user_admin_stub.AddUser( + add_user_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def update_credentials(self, *, username: str, password: str, timeout: Optional[int] = None) -> int: + async def update_credentials( + self, *, username: str, password: str, timeout: Optional[int] = None + ) -> int: if not self._channel_provider.client_server_compatible: await self._channel_provider._is_ready() - (user_admin_stub, update_credentials_request) = self._prepare_update_credentials( - username, password, timeout, logger + (user_admin_stub, update_credentials_request) = ( + self._prepare_update_credentials(username, password, timeout, logger) ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await user_admin_stub.UpdateCredentials(update_credentials_request, credentials=self._channel_provider._token, **kwargs) + await user_admin_stub.UpdateCredentials( + update_credentials_request, + credentials=self._channel_provider._token, + **kwargs, + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -315,10 +355,12 @@ async def drop_user(self, *, username: str, timeout: Optional[int] = None) -> in kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await user_admin_stub.DropUser(drop_user_request, credentials=self._channel_provider._token, **kwargs) + await user_admin_stub.DropUser( + drop_user_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -333,10 +375,12 @@ async def get_user(self, *, username: str, timeout: Optional[int] = None) -> int kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = await user_admin_stub.GetUser(get_user_request, credentials=self._channel_provider._token, **kwargs) + response = await user_admin_stub.GetUser( + get_user_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -353,16 +397,20 @@ async def list_users(self, timeout: Optional[int] = None) -> int: kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = await user_admin_stub.ListUsers(list_users_request, credentials=self._channel_provider._token, **kwargs) + response = await user_admin_stub.ListUsers( + list_users_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_list_users(response) - async def grant_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: + async def grant_roles( + self, *, username: str, roles: list[str], timeout: Optional[int] = None + ) -> int: if not self._channel_provider.client_server_compatible: await self._channel_provider._is_ready() @@ -372,15 +420,19 @@ async def grant_roles(self, *, username: str, roles: list[str], timeout: Optiona kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await user_admin_stub.GrantRoles(grant_roles_request, credentials=self._channel_provider._token, **kwargs) + await user_admin_stub.GrantRoles( + grant_roles_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def revoke_roles(self, *, username: str, roles: list[str], timeout: Optional[int] = None) -> int: + async def revoke_roles( + self, *, username: str, roles: list[str], timeout: Optional[int] = None + ) -> int: if not self._channel_provider.client_server_compatible: await self._channel_provider._is_ready() @@ -390,10 +442,14 @@ async def revoke_roles(self, *, username: str, roles: list[str], timeout: Option kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await user_admin_stub.RevokeRoles(revoke_roles_request, credentials=self._channel_provider._token, **kwargs) + await user_admin_stub.RevokeRoles( + revoke_roles_request, + credentials=self._channel_provider._token, + **kwargs, + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -408,10 +464,12 @@ async def list_roles(self, timeout: Optional[int] = None) -> int: kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = await user_admin_stub.ListRoles(list_roles_request, credentials=self._channel_provider._token, **kwargs) + response = await user_admin_stub.ListRoles( + list_roles_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -437,7 +495,9 @@ async def _wait_for_index_creation( while True: self._check_timeout(start_time, timeout) try: - await index_stub.GetStatus(index_creation_request, credentials=self._channel_provider._token) + await index_stub.GetStatus( + index_creation_request, credentials=self._channel_provider._token + ) logger.debug("Index created succesfully") # Index has been created return @@ -473,7 +533,9 @@ async def _wait_for_index_deletion( self._check_timeout(start_time, timeout) try: - await index_stub.GetStatus(index_deletion_request, credentials=self._channel_provider._token) + await index_stub.GetStatus( + index_deletion_request, credentials=self._channel_provider._token + ) # Wait for some more time. await asyncio.sleep(wait_interval) except grpc.RpcError as e: diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index 77fb1c78..239d78da 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -51,7 +51,15 @@ def __init__( seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path + seeds, + listener_name, + is_loadbalancer, + username, + password, + root_certificate, + certificate_chain, + private_key, + service_config_path, ) async def insert( @@ -86,15 +94,23 @@ async def insert( await self._channel_provider._is_ready() (transact_stub, insert_request) = self._prepare_insert( - namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger + namespace, + key, + record_data, + set_name, + ignore_mem_queue_full, + timeout, + logger, ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await transact_stub.Put(insert_request, credentials=self._channel_provider._token, **kwargs) + await transact_stub.Put( + insert_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -131,15 +147,23 @@ async def update( await self._channel_provider._is_ready() (transact_stub, update_request) = self._prepare_update( - namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger + namespace, + key, + record_data, + set_name, + ignore_mem_queue_full, + timeout, + logger, ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await transact_stub.Put(update_request, credentials=self._channel_provider._token, **kwargs) + await transact_stub.Put( + update_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -176,15 +200,23 @@ async def upsert( await self._channel_provider._is_ready() (transact_stub, upsert_request) = self._prepare_upsert( - namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger + namespace, + key, + record_data, + set_name, + ignore_mem_queue_full, + timeout, + logger, ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await transact_stub.Put(upsert_request, credentials=self._channel_provider._token, **kwargs) + await transact_stub.Put( + upsert_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -225,10 +257,12 @@ async def get( kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = await transact_stub.Get(get_request, credentials=self._channel_provider._token, **kwargs) + response = await transact_stub.Get( + get_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -236,7 +270,12 @@ async def get( return self._respond_get(response, key) async def exists( - self, *, namespace: str, key: Any, set_name: Optional[str] = None, timeout: Optional[int] = None, + self, + *, + namespace: str, + key: Any, + set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> bool: """ Check if a record exists in Aerospike Vector Search. @@ -263,10 +302,12 @@ async def exists( kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = await transact_stub.Exists(exists_request, credentials=self._channel_provider._token, **kwargs) + response = await transact_stub.Exists( + exists_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -274,7 +315,12 @@ async def exists( return self._respond_exists(response) async def delete( - self, *, namespace: str, key: Any, set_name: Optional[str] = None, timeout: Optional[int] = None, + self, + *, + namespace: str, + key: Any, + set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> None: """ Delete a record from Aerospike Vector Search. @@ -298,10 +344,12 @@ async def delete( kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - await transact_stub.Delete(delete_request, credentials=self._channel_provider._token, **kwargs) + await transact_stub.Delete( + delete_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -344,10 +392,12 @@ async def is_indexed( kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = await transact_stub.IsIndexed(is_indexed_request, credentials=self._channel_provider._token, **kwargs) + response = await transact_stub.IsIndexed( + is_indexed_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -388,15 +438,29 @@ async def vector_search( await self._channel_provider._is_ready() (transact_stub, vector_search_request) = self._prepare_vector_search( - namespace, index_name, query, limit, search_params, field_names, timeout, logger + namespace, + index_name, + query, + limit, + search_params, + field_names, + timeout, + logger, ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - return [self._respond_neighbor(result) async for result in transact_stub.VectorSearch(vector_search_request, credentials=self._channel_provider._token, **kwargs)] + return [ + self._respond_neighbor(result) + async for result in transact_stub.VectorSearch( + vector_search_request, + credentials=self._channel_provider._token, + **kwargs, + ) + ] except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -444,7 +508,9 @@ async def wait_for_index_completion( ) = self._prepare_wait_for_index_waiting(namespace, name, wait_interval) while True: try: - index_status = await index_stub.GetStatus(index_completion_request, credentials=self._channel_provider._token) + index_status = await index_stub.GetStatus( + index_completion_request, credentials=self._channel_provider._token + ) except grpc.RpcError as e: diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 8af94ad0..e5d0b1be 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -33,10 +33,19 @@ def __init__( certificate_chain: Optional[str] = None, private_key: Optional[str] = None, service_config_path: Optional[str] = None, - ) -> None: - super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path) + super().__init__( + seeds, + listener_name, + is_loadbalancer, + username, + password, + root_certificate, + certificate_chain, + private_key, + service_config_path, + ) self._tend_initalized: asyncio.Event = asyncio.Event() self._tend_ended: asyncio.Event = asyncio.Event() @@ -62,16 +71,32 @@ async def _is_ready(self): await self._tend_initalized.wait() if not self.client_server_compatible: - raise types.AVSClientError(message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + self.minimum_required_version) + raise types.AVSClientError( + message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + + self.minimum_required_version + ) async def _tend(self): try: - (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() + (temp_endpoints, update_endpoints_stub, channels, end_tend) = ( + self.init_tend() + ) if self._token: if self._check_if_token_refresh_needed(): await self._update_token_and_ttl() if end_tend: + + if not self.client_server_compatible: + + stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) + about_request = vector_db_pb2.AboutRequest() + + self.current_server_version = ( + await stub.Get(about_request, credentials=self._token) + ).version + self.client_server_compatible = self.verify_compatibile_server() + self._tend_initalized.set() self._tend_ended.set() @@ -85,7 +110,9 @@ async def _tend(self): stub = vector_db_pb2_grpc.ClusterInfoServiceStub(channel) stubs.append(stub) try: - tasks.append(await stub.GetClusterId(empty, credentials=self._token)) + tasks.append( + await stub.GetClusterId(empty, credentials=self._token) + ) except Exception as e: logger.debug( "While tending, failed to get cluster id with error:" + str(e) @@ -95,14 +122,13 @@ async def _tend(self): new_cluster_ids = tasks except Exception as e: logger.debug( - "While tending, failed to gather results from GetClusterId:" + str(e) + "While tending, failed to gather results from GetClusterId:" + + str(e) ) for index, value in enumerate(new_cluster_ids): if self.check_cluster_id(value.id): update_endpoints_stubs.append(stubs[index]) - - for stub in update_endpoints_stubs: try: @@ -110,9 +136,11 @@ async def _tend(self): vector_db_pb2.ClusterNodeEndpointsRequest( listenerName=self.listener_name ), - credentials=self._token + credentials=self._token, + ) + temp_endpoints = self.update_temp_endpoints( + response, temp_endpoints ) - temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) except Exception as e: logger.debug( "While tending, failed to get cluster endpoints with error:" @@ -156,10 +184,12 @@ async def _tend(self): stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) about_request = vector_db_pb2.AboutRequest() - self.current_server_version = (await stub.Get(about_request, credentials=self._token)).version + self.current_server_version = ( + await stub.Get(about_request, credentials=self._token) + ).version self.client_server_compatible = self.verify_compatibile_server() - self._tend_initalized.set() + self._tend_initalized.set() # TODO: check tend interval. await asyncio.sleep(1) @@ -168,10 +198,9 @@ async def _tend(self): print(e) - def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: host = re.sub(r"%.*", "", host) - + if self.service_config_json: options = [] options.append(("grpc.service_config", self.service_config_json)) @@ -179,31 +208,34 @@ def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: options = None if self._root_certificate: - with open(self._root_certificate, 'rb') as f: + with open(self._root_certificate, "rb") as f: root_certificate = f.read() if self._private_key: - with open(self._private_key, 'rb') as f: + with open(self._private_key, "rb") as f: private_key = f.read() else: private_key = None - + if self._certificate_chain: - with open(self._certificate_chain, 'rb') as f: + with open(self._certificate_chain, "rb") as f: certificate_chain = f.read() else: certificate_chain = None + ssl_credentials = grpc.ssl_channel_credentials( + root_certificates=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, + ) - ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate, certificate_chain=certificate_chain, private_key=private_key) - - - return grpc.aio.secure_channel(f"{host}:{port}", ssl_credentials, options=options) + return grpc.aio.secure_channel( + f"{host}:{port}", ssl_credentials, options=options + ) else: return grpc.aio.insecure_channel(f"{host}:{port}", options=options) - async def _update_token_and_ttl( self, ) -> None: @@ -217,4 +249,4 @@ async def _update_token_and_ttl( print("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) - self._respond_authenticate(response.token) \ No newline at end of file + self._respond_authenticate(response.token) diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index ac9a03f9..91ba8776 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -11,6 +11,7 @@ logger = logging.getLogger(__name__) + class Client(BaseClient): """ Aerospike Vector Search Vector Client @@ -49,7 +50,15 @@ def __init__( """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( - seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path + seeds, + listener_name, + is_loadbalancer, + username, + password, + root_certificate, + certificate_chain, + private_key, + service_config_path, ) def insert( @@ -80,18 +89,24 @@ def insert( """ - - (transact_stub, insert_request) = self._prepare_insert( - namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger + namespace, + key, + record_data, + set_name, + ignore_mem_queue_full, + timeout, + logger, ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - transact_stub.Put(insert_request, credentials=self._channel_provider._token, **kwargs) + transact_stub.Put( + insert_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -124,15 +139,23 @@ def update( """ (transact_stub, update_request) = self._prepare_update( - namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger + namespace, + key, + record_data, + set_name, + ignore_mem_queue_full, + timeout, + logger, ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - transact_stub.Put(update_request, credentials=self._channel_provider._token, **kwargs) + transact_stub.Put( + update_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -165,18 +188,24 @@ def upsert( """ - - (transact_stub, upsert_request) = self._prepare_upsert( - namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger + namespace, + key, + record_data, + set_name, + ignore_mem_queue_full, + timeout, + logger, ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - transact_stub.Put(upsert_request, credentials=self._channel_provider._token, **kwargs) + transact_stub.Put( + upsert_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -208,18 +237,18 @@ def get( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - - (transact_stub, key, get_request) = self._prepare_get( namespace, key, field_names, set_name, timeout, logger ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = transact_stub.Get(get_request, credentials=self._channel_provider._token, **kwargs) + response = transact_stub.Get( + get_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -227,7 +256,12 @@ def get( return self._respond_get(response, key) def exists( - self, *, namespace: str, key: Any, set_name: Optional[str] = None, timeout: Optional[int] = None, + self, + *, + namespace: str, + key: Any, + set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> bool: """ Check if a record exists in Aerospike Vector Search. @@ -245,19 +279,18 @@ def exists( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - - (transact_stub, exists_request) = self._prepare_exists( namespace, key, set_name, timeout, logger ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout - + kwargs["timeout"] = timeout try: - response = transact_stub.Exists(exists_request, credentials=self._channel_provider._token, **kwargs) + response = transact_stub.Exists( + exists_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -265,7 +298,12 @@ def exists( return self._respond_exists(response) def delete( - self, *, namespace: str, key: Any, set_name: Optional[str] = None, timeout: Optional[int] = None, + self, + *, + namespace: str, + key: Any, + set_name: Optional[str] = None, + timeout: Optional[int] = None, ) -> None: """ Delete a record from Aerospike Vector Search. @@ -280,18 +318,18 @@ def delete( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - - (transact_stub, delete_request) = self._prepare_delete( namespace, key, set_name, timeout, logger ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - transact_stub.Delete(delete_request, credentials=self._channel_provider._token, **kwargs) + transact_stub.Delete( + delete_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -325,18 +363,18 @@ def is_indexed( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - - (transact_stub, is_indexed_request) = self._prepare_is_indexed( namespace, key, index_name, index_namespace, set_name, timeout, logger ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - response = transact_stub.IsIndexed(is_indexed_request, credentials=self._channel_provider._token, **kwargs) + response = transact_stub.IsIndexed( + is_indexed_request, credentials=self._channel_provider._token, **kwargs + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -373,18 +411,31 @@ def vector_search( grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (transact_stub, vector_search_request) = self._prepare_vector_search( - namespace, index_name, query, limit, search_params, field_names, timeout, logger + namespace, + index_name, + query, + limit, + search_params, + field_names, + timeout, + logger, ) kwargs = {} if timeout is not None: - kwargs['timeout'] = timeout + kwargs["timeout"] = timeout try: - return [self._respond_neighbor(result) for result in transact_stub.VectorSearch(vector_search_request, credentials=self._channel_provider._token, **kwargs)] + return [ + self._respond_neighbor(result) + for result in transact_stub.VectorSearch( + vector_search_request, + credentials=self._channel_provider._token, + **kwargs, + ) + ] except grpc.RpcError as e: logger.error("Failed with error: %s", e) raise types.AVSServerError(rpc_error=e) @@ -418,7 +469,6 @@ def wait_for_index_completion( The function polls the index status with a wait interval of 10 seconds until either the timeout is reached or the index has no pending index update operations. """ - # Wait interval between polling ( @@ -432,7 +482,9 @@ def wait_for_index_completion( while True: try: - index_status = index_stub.GetStatus(index_completion_request, credentials=self._channel_provider._token) + index_status = index_stub.GetStatus( + index_completion_request, credentials=self._channel_provider._token + ) except grpc.RpcError as e: logger.error("Failed with error: %s", e) diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index b5b1c02a..839ccb87 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -32,7 +32,17 @@ def __init__( private_key: Optional[str] = None, service_config_path: Optional[str] = None, ) -> None: - super().__init__(seeds, listener_name, is_loadbalancer, username, password, root_certificate, certificate_chain, private_key, service_config_path) + super().__init__( + seeds, + listener_name, + is_loadbalancer, + username, + password, + root_certificate, + certificate_chain, + private_key, + service_config_path, + ) self._tend_ended = threading.Event() self._timer = None self._tend() @@ -58,26 +68,52 @@ def _tend(self): self._update_token_and_ttl() if end_tend: + + if not self.client_server_compatible: + + stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) + about_request = vector_db_pb2.AboutRequest() + + self.current_server_version = stub.Get( + about_request, credentials=self._token + ).version + self.client_server_compatible = self.verify_compatibile_server() + if not self.client_server_compatible: + self._tend_ended.set() + raise types.AVSClientError( + message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + + self.minimum_required_version + ) + self._tend_ended.set() + return + + update_endpoints_stubs = [] + new_cluster_ids = [] for channel in channels: + stubs = [] + stub = vector_db_pb2_grpc.ClusterInfoServiceStub(channel) + stubs.append(stub) try: - new_cluster_id = stub.GetClusterId(empty, credentials=self._credentials).id - if self.check_cluster_id(new_cluster_id): - update_endpoints_stub = stub - break - else: - continue + new_cluster_ids.append( + stub.GetClusterId(empty, credentials=self._credentials) + ) except Exception as e: logger.debug( "While tending, failed to get cluster id with error:" + str(e) ) - if update_endpoints_stub: + for index, value in enumerate(new_cluster_ids): + if self.check_cluster_id(value.id): + update_endpoints_stubs.append(stubs[index]) + + for stub in update_endpoints_stubs: + try: response = stub.GetClusterEndpoints( vector_db_pb2.ClusterNodeEndpointsRequest( @@ -91,6 +127,7 @@ def _tend(self): + str(e) ) + if update_endpoints_stubs: for node, newEndpoints in temp_endpoints.items(): (channel_endpoints, add_new_channel) = self.check_for_new_endpoints( node, newEndpoints @@ -124,10 +161,15 @@ def _tend(self): stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) about_request = vector_db_pb2.AboutRequest() - self.current_server_version = stub.Get(about_request, credentials=self._token).version + self.current_server_version = stub.Get( + about_request, credentials=self._token + ).version self.client_server_compatible = self.verify_compatibile_server() if not self.client_server_compatible: - raise types.AVSClientError(message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + self.minimum_required_version) + raise types.AVSClientError( + message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + + self.minimum_required_version + ) self._timer = threading.Timer(1, self._tend).start() @@ -141,24 +183,30 @@ def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: options = None if self._root_certificate: - with open(self._root_certificate, 'rb') as f: + with open(self._root_certificate, "rb") as f: root_certificate = f.read() if self._private_key: - with open(self._private_key, 'rb') as f: + with open(self._private_key, "rb") as f: private_key = f.read() else: private_key = None - + if self._certificate_chain: - with open(self._certificate_chain, 'rb') as f: + with open(self._certificate_chain, "rb") as f: certificate_chain = f.read() else: certificate_chain = None - ssl_credentials = grpc.ssl_channel_credentials(root_certificates=root_certificate, certificate_chain=certificate_chain, private_key=private_key) + ssl_credentials = grpc.ssl_channel_credentials( + root_certificates=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, + ) - return grpc.secure_channel(f"{host}:{port}", ssl_credentials, options=options) + return grpc.secure_channel( + f"{host}:{port}", ssl_credentials, options=options + ) else: return grpc.insecure_channel(f"{host}:{port}", options=options) diff --git a/src/aerospike_vector_search/shared/admin_helpers.py b/src/aerospike_vector_search/shared/admin_helpers.py index a951b299..32fcdc4b 100644 --- a/src/aerospike_vector_search/shared/admin_helpers.py +++ b/src/aerospike_vector_search/shared/admin_helpers.py @@ -49,7 +49,7 @@ def _prepare_index_create( index_params, index_meta_data, index_storage, - timeout + timeout, ) if sets and not sets.strip(): @@ -72,13 +72,18 @@ def _prepare_index_create( field=vector_field, dimensions=dimensions, labels=index_meta_data, - storage=index_storage + storage=index_storage, ) return (index_stub, index_create_request) def _prepare_index_drop(self, namespace, name, timeout, logger) -> None: - logger.debug("Dropping index: namespace=%s, name=%s, timeout=%s", namespace, name, timeout) + logger.debug( + "Dropping index: namespace=%s, name=%s, timeout=%s", + namespace, + name, + timeout, + ) index_stub = self._get_index_stub() index_drop_request = self._get_index_id(namespace, name) @@ -97,7 +102,10 @@ def _prepare_index_list(self, timeout, logger) -> None: def _prepare_index_get(self, namespace, name, timeout, logger) -> None: logger.debug( - "Getting index information: namespace=%s, name=%s, timeout=%s", namespace, name, timeout + "Getting index information: namespace=%s, name=%s, timeout=%s", + namespace, + name, + timeout, ) index_stub = self._get_index_stub() @@ -107,7 +115,12 @@ def _prepare_index_get(self, namespace, name, timeout, logger) -> None: def _prepare_index_get_status(self, namespace, name, timeout, logger) -> None: - logger.debug("Getting index status: namespace=%s, name=%s, timeout=%s", namespace, name, timeout) + logger.debug( + "Getting index status: namespace=%s, name=%s, timeout=%s", + namespace, + name, + timeout, + ) index_stub = self._get_index_stub() index_get_status_request = self._get_index_id(namespace, name) @@ -115,20 +128,35 @@ def _prepare_index_get_status(self, namespace, name, timeout, logger) -> None: return (index_stub, index_get_status_request) def _prepare_add_user(self, username, password, roles, timeout, logger) -> None: - logger.debug("Getting index status: username=%s, password=%s, roles=%s, timeout=%s", username, password, roles, timeout) + logger.debug( + "Getting index status: username=%s, password=%s, roles=%s, timeout=%s", + username, + password, + roles, + timeout, + ) user_admin_stub = self._get_user_admin_stub() credentials = helpers._get_credentials(username, password) - add_user_request = user_admin_pb2.AddUserRequest(credentials=credentials, roles=roles) + add_user_request = user_admin_pb2.AddUserRequest( + credentials=credentials, roles=roles + ) return (user_admin_stub, add_user_request) def _prepare_update_credentials(self, username, password, timeout, logger) -> None: - logger.debug("Getting index status: username=%s, password=%s, timeout=%s", username, password, timeout) + logger.debug( + "Getting index status: username=%s, password=%s, timeout=%s", + username, + password, + timeout, + ) user_admin_stub = self._get_user_admin_stub() credentials = helpers._get_credentials(username, password) - update_user_request = user_admin_pb2.UpdateCredentialsRequest(credentials=credentials) + update_user_request = user_admin_pb2.UpdateCredentialsRequest( + credentials=credentials + ) return (user_admin_stub, update_user_request) @@ -157,18 +185,32 @@ def _prepare_list_users(self, timeout, logger) -> None: return (user_admin_stub, list_users_request) def _prepare_grant_roles(self, username, roles, timeout, logger) -> None: - logger.debug("Getting index status: username=%s, roles=%s, timeout=%s", username, roles, timeout) + logger.debug( + "Getting index status: username=%s, roles=%s, timeout=%s", + username, + roles, + timeout, + ) user_admin_stub = self._get_user_admin_stub() - grant_roles_request = user_admin_pb2.GrantRolesRequest(username=username, roles=roles) + grant_roles_request = user_admin_pb2.GrantRolesRequest( + username=username, roles=roles + ) return (user_admin_stub, grant_roles_request) def _prepare_revoke_roles(self, username, roles, timeout, logger) -> None: - logger.debug("Getting index status: username=%s, roles=%s, timeout=%s", username, roles, timeout) + logger.debug( + "Getting index status: username=%s, roles=%s, timeout=%s", + username, + roles, + timeout, + ) user_admin_stub = self._get_user_admin_stub() - revoke_roles_request = user_admin_pb2.RevokeRolesRequest(username=username, roles=roles) + revoke_roles_request = user_admin_pb2.RevokeRolesRequest( + username=username, roles=roles + ) return (user_admin_stub, revoke_roles_request) @@ -198,18 +240,14 @@ def _respond_index_list(self, response) -> None: ) hnsw_params_dict["batching_params"] = batching_params_dict - - caching_params_dict = hnsw_params_dict.pop("cachingParams", None) if caching_params_dict: caching_params_dict["max_entries"] = caching_params_dict.pop( "maxEntries", None ) - caching_params_dict["expiry"] = caching_params_dict.pop( - "expiry", None - ) + caching_params_dict["expiry"] = caching_params_dict.pop("expiry", None) hnsw_params_dict["caching_params"] = caching_params_dict - + healer_params_dict = hnsw_params_dict.pop("healerParams", None) if healer_params_dict: @@ -230,12 +268,12 @@ def _respond_index_list(self, response) -> None: "parallelism", None ) hnsw_params_dict["healer_params"] = healer_params_dict - + merge_params_dict = hnsw_params_dict.pop("mergeParams", None) if merge_params_dict: merge_params_dict["parallelism"] = merge_params_dict.pop( "parallelism", None - ) + ) hnsw_params_dict["merge_params"] = merge_params_dict response_dict["hnsw_params"] = hnsw_params_dict @@ -262,7 +300,6 @@ def _respond_index_get(self, response) -> None: return response_dict def _respond_get_user(self, response) -> None: - return types.User(username=response.username, roles=list(response.roles)) @@ -274,7 +311,7 @@ def _respond_list_users(self, response) -> None: def _respond_list_roles(self, response) -> None: return list(response.roles) - + def _respond_index_get_status(self, response) -> None: return response.unmergedRecordCount @@ -282,7 +319,9 @@ def _get_index_stub(self): return index_pb2_grpc.IndexServiceStub(self._channel_provider.get_channel()) def _get_user_admin_stub(self): - return user_admin_pb2_grpc.UserAdminServiceStub(self._channel_provider.get_channel()) + return user_admin_pb2_grpc.UserAdminServiceStub( + self._channel_provider.get_channel() + ) def _get_index_id(self, namespace, name): return types_pb2.IndexId(namespace=namespace, name=name) @@ -297,4 +336,4 @@ def _prepare_wait_for_index_waiting(self, namespace, name, wait_interval): def _check_timeout(self, start_time, timeout): if start_time + timeout < time.monotonic(): - raise "timed-out waiting for index creation" \ No newline at end of file + raise "timed-out waiting for index creation" diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index 9cd01eae..60943a11 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -42,16 +42,15 @@ def __init__( root_certificate: Optional[str] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, - service_config_path: Optional[str] = None - + service_config_path: Optional[str] = None, ) -> None: self.seeds: tuple[types.HostPort, ...] = seeds self.listener_name: Optional[str] = listener_name self._is_loadbalancer: Optional[bool] = is_loadbalancer if service_config_path: - with open(service_config_path, 'rb') as f: - self.service_config_json = f.read() + with open(service_config_path, "rb") as f: + self.service_config_json = f.read() else: self.service_config_json = None @@ -164,19 +163,18 @@ def check_for_new_endpoints(self, node, newEndpoints): return (channel_endpoints, add_new_channel) - def _get_ttl(self, payload): - return payload['exp'] - payload['iat'] + return payload["exp"] - payload["iat"] def _check_if_token_refresh_needed(self): - if self._token and (time.time() - self._ttl_start) > (self._ttl * self._ttl_threshold): + if self._token and (time.time() - self._ttl_start) > ( + self._ttl * self._ttl_threshold + ): return True return False def _prepare_authenticate(self, credentials, logger): - logger.debug( - "Refreshing auth token" - ) + logger.debug("Refreshing auth token") auth_stub = self._get_auth_stub() auth_request = self._get_authenticate_request(self._credentials) @@ -190,16 +188,18 @@ def _get_authenticate_request(self, credentials): return auth_pb2.AuthRequest(credentials=credentials) def _respond_authenticate(self, token): - payload = jwt.decode(token, "", algorithms=['RS256'], options={"verify_signature": False}) + payload = jwt.decode( + token, "", algorithms=["RS256"], options={"verify_signature": False} + ) self._ttl = self._get_ttl(payload) - self._ttl_start = payload['exp'] + self._ttl_start = payload["exp"] self._token = grpc.access_token_call_credentials(token) def verify_compatibile_server(self) -> bool: def parse_version(v: str): - return tuple(map(int, v.split('.'))) - - return parse_version(self.current_server_version) >= parse_version(self.minimum_required_version) - - \ No newline at end of file + return tuple(map(int, v.split("."))) + + return parse_version(self.current_server_version) >= parse_version( + self.minimum_required_version + ) diff --git a/src/aerospike_vector_search/shared/client_helpers.py b/src/aerospike_vector_search/shared/client_helpers.py index bda5707a..deac89d0 100644 --- a/src/aerospike_vector_search/shared/client_helpers.py +++ b/src/aerospike_vector_search/shared/client_helpers.py @@ -1,6 +1,6 @@ from typing import Any, Optional, Union import time -import numpy +import numpy as np from . import conversions from .proto_generated import transact_pb2 @@ -16,7 +16,15 @@ def _prepare_seeds(self, seeds) -> None: return helpers._prepare_seeds(seeds) def _prepare_put( - self, namespace, key, record_data, set_name, write_type, ignore_mem_queue_full, timeout, logger + self, + namespace, + key, + record_data, + set_name, + write_type, + ignore_mem_queue_full, + timeout, + logger, ) -> None: logger.debug( @@ -26,14 +34,14 @@ def _prepare_put( record_data, set_name, ignore_mem_queue_full, - timeout + timeout, ) key = self._get_key(namespace, set_name, key) field_list = [] for k, v in record_data.items(): - if isinstance(v, numpy.ndarray): + if isinstance(v, np.ndarray): field_list.append( types_pb2.Field( name=k, value=conversions.toVectorDbValue(v.tolist()) @@ -47,12 +55,24 @@ def _prepare_put( transact_stub = self._get_transact_stub() put_request = transact_pb2.PutRequest( - key=key, writeType=write_type, fields=field_list, ignoreMemQueueFull=ignore_mem_queue_full + key=key, + writeType=write_type, + fields=field_list, + ignoreMemQueueFull=ignore_mem_queue_full, ) return (transact_stub, put_request) - def _prepare_insert(self, namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger) -> None: + def _prepare_insert( + self, + namespace, + key, + record_data, + set_name, + ignore_mem_queue_full, + timeout, + logger, + ) -> None: return self._prepare_put( namespace, key, @@ -64,7 +84,16 @@ def _prepare_insert(self, namespace, key, record_data, set_name, ignore_mem_queu logger, ) - def _prepare_update(self, namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger) -> None: + def _prepare_update( + self, + namespace, + key, + record_data, + set_name, + ignore_mem_queue_full, + timeout, + logger, + ) -> None: return self._prepare_put( namespace, key, @@ -76,12 +105,30 @@ def _prepare_update(self, namespace, key, record_data, set_name, ignore_mem_queu logger, ) - def _prepare_upsert(self, namespace, key, record_data, set_name, ignore_mem_queue_full, timeout, logger) -> None: + def _prepare_upsert( + self, + namespace, + key, + record_data, + set_name, + ignore_mem_queue_full, + timeout, + logger, + ) -> None: return self._prepare_put( - namespace, key, record_data, set_name, transact_pb2.WriteType.UPSERT, ignore_mem_queue_full, timeout, logger + namespace, + key, + record_data, + set_name, + transact_pb2.WriteType.UPSERT, + ignore_mem_queue_full, + timeout, + logger, ) - def _prepare_get(self, namespace, key, field_names, set_name, timeout, logger) -> None: + def _prepare_get( + self, namespace, key, field_names, set_name, timeout, logger + ) -> None: logger.debug( "Getting record: namespace=%s, key=%s, field_names:%s, set_name:%s, timeout:%s", @@ -159,7 +206,15 @@ def _prepare_is_indexed( return (transact_stub, is_indexed_request) def _prepare_vector_search( - self, namespace, index_name, query, limit, search_params, field_names, timeout, logger + self, + namespace, + index_name, + query, + limit, + search_params, + field_names, + timeout, + logger, ) -> None: logger.debug( @@ -170,7 +225,7 @@ def _prepare_vector_search( limit, search_params, field_names, - timeout + timeout, ) if search_params != None: @@ -180,7 +235,7 @@ def _prepare_vector_search( index = types_pb2.IndexId(namespace=namespace, name=index_name) - if isinstance(query, numpy.ndarray): + if isinstance(query, np.ndarray): query_vector = conversions.toVectorDbValue(query.tolist()).vectorValue else: query_vector = conversions.toVectorDbValue(query).vectorValue @@ -198,7 +253,9 @@ def _prepare_vector_search( return (transact_stub, vector_search_request) def _get_transact_stub(self): - return transact_pb2_grpc.TransactServiceStub(self._channel_provider.get_channel()) + return transact_pb2_grpc.TransactServiceStub( + self._channel_provider.get_channel() + ) def _respond_get(self, response, key) -> None: return types.RecordWithKey( @@ -251,6 +308,13 @@ def _get_projection_spec( def _get_key( self, namespace: str, set: str, key: Union[int, str, bytes, bytearray] ): + + if isinstance(key, np.ndarray): + key = key.tobytes() + + if isinstance(key, np.generic): + key = key.item() + if isinstance(key, str): key = types_pb2.Key(namespace=namespace, set=set, stringValue=key) elif isinstance(key, int): diff --git a/src/aerospike_vector_search/shared/helpers.py b/src/aerospike_vector_search/shared/helpers.py index ee78e1cf..4b8b871e 100644 --- a/src/aerospike_vector_search/shared/helpers.py +++ b/src/aerospike_vector_search/shared/helpers.py @@ -32,7 +32,11 @@ def _prepare_wait_for_index_waiting(client, namespace, name, wait_interval): index_wait_request, ) + def _get_credentials(username, password): if not username: return None - return types_pb2.Credentials(username=username, passwordCredentials=types_pb2.PasswordCredentials(password=password)) \ No newline at end of file + return types_pb2.Credentials( + username=username, + passwordCredentials=types_pb2.PasswordCredentials(password=password), + ) diff --git a/src/aerospike_vector_search/types.py b/src/aerospike_vector_search/types.py index 5e54106c..f4b0989b 100644 --- a/src/aerospike_vector_search/types.py +++ b/src/aerospike_vector_search/types.py @@ -140,10 +140,11 @@ class VectorDistanceMetric(enum.Enum): MANHATTAN: types_pb2.VectorDistanceMetric = types_pb2.VectorDistanceMetric.MANHATTAN HAMMING: types_pb2.VectorDistanceMetric = types_pb2.VectorDistanceMetric.HAMMING + class User(object): """ - PLACEHOLDER FOR TEXT + PLACEHOLDER FOR TEXT Args: max_records (Optional[int], optional): Maximum number of records to fit in a batch. Defaults to 10000. interval (Optional[int], optional): The maximum amount of time in milliseconds to wait before finalizing a batch. Defaults to 10000. @@ -159,6 +160,7 @@ def __init__( self.username = username self.roles = roles + class HnswBatchingParams(object): """ Parameters for configuring batching behaviour for batch based index update. @@ -186,7 +188,15 @@ def _to_pb2(self): class HnswHealerParams(object): - def __init__(self, *, max_scan_rate_per_node: Optional[int] = None, max_scan_page_size: Optional[int] = None, re_index_percent: Optional[int] = None, schedule_delay: Optional[int] = None, parallelism: Optional[int] = None) -> None: + def __init__( + self, + *, + max_scan_rate_per_node: Optional[int] = None, + max_scan_page_size: Optional[int] = None, + re_index_percent: Optional[int] = None, + schedule_delay: Optional[int] = None, + parallelism: Optional[int] = None, + ) -> None: self.max_scan_rate_per_node = max_scan_rate_per_node self.max_scan_page_size = max_scan_page_size self.re_index_percent = re_index_percent @@ -218,7 +228,9 @@ def _to_pb2(self): class HnswCachingParams(object): - def __init__(self, *, max_entries: Optional[int] = None, expiry: Optional[int] = None) -> None: + def __init__( + self, *, max_entries: Optional[int] = None, expiry: Optional[int] = None + ) -> None: self.max_entries = max_entries self.expiry = expiry @@ -230,6 +242,7 @@ def _to_pb2(self): params.expiry = self.expiry return params + class HnswIndexMergeParams(object): def __init__(self, *, parallelism: Optional[int] = None) -> None: self.parallelism = parallelism @@ -262,7 +275,7 @@ def __init__( max_mem_queue_size: Optional[int] = None, caching_params: Optional[HnswCachingParams] = HnswCachingParams(), healer_params: Optional[HnswHealerParams] = HnswHealerParams(), - merge_params: Optional[HnswIndexMergeParams] = HnswIndexMergeParams() + merge_params: Optional[HnswIndexMergeParams] = HnswIndexMergeParams(), ) -> None: self.m = m self.ef_construction = ef_construction @@ -291,7 +304,6 @@ def _to_pb2(self): return params - class HnswSearchParams(object): def __init__(self, *, ef: Optional[int] = None) -> None: """ @@ -314,8 +326,11 @@ def _to_pb2(self): params.ef = self.ef return params + class IndexStorage(object): - def __init__(self, *, namespace: Optional[str] = None, set_name: Optional[str] = None) -> None: + def __init__( + self, *, namespace: Optional[str] = None, set_name: Optional[str] = None + ) -> None: self.namespace = namespace self.set_name = set_name @@ -354,6 +369,13 @@ class AVSServerError(AVSError): def __init__(self, *, rpc_error) -> None: self.rpc_error = rpc_error + def __str__(self): + return f"AVSServerError(rpc_error={self.rpc_error})" + + class AVSClientError(AVSError): def __init__(self, *, message) -> None: - self.message = message \ No newline at end of file + self.message = message + + def __str__(self): + return f"AVSClientError(message={self.message})" diff --git a/tests/rbac/aio/conftest.py b/tests/rbac/aio/conftest.py index 419d3d3b..ea295a17 100644 --- a/tests/rbac/aio/conftest.py +++ b/tests/rbac/aio/conftest.py @@ -24,11 +24,11 @@ def private_key(request): def certificate_chain(request): return request.config.getoption("--certificate_chain") -""" + @pytest.fixture(scope="module", autouse=True) -async def drop_all_indexes(username, password, host, port, root_certificate, certificate_chain, private_key): +async def drop_all_indexes(username, password, host, port, root_certificate, certificate_chain, private_key, is_loadbalancer): async with AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: index_list = await client.index_list() @@ -37,12 +37,12 @@ async def drop_all_indexes(username, password, host, port, root_certificate, cer tasks.append(client.index_drop(namespace="test", name=item['id']['name'])) await asyncio.gather(*tasks) -""" + @pytest.fixture(scope="module") -async def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): +async def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): client = AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) yield client await client.close() diff --git a/tests/rbac/conftest.py b/tests/rbac/conftest.py index 329d0a6d..64d033b6 100644 --- a/tests/rbac/conftest.py +++ b/tests/rbac/conftest.py @@ -9,6 +9,7 @@ def pytest_addoption(parser): parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") parser.addoption("--certificate_chain", action="store", default=None, help="Path to certificate chain") parser.addoption("--private_key", action="store", default=None, help="Path to private key") + parser.addoption("--is_loadbalancer", action="store_true", help="Enable to use load balancer tending logic") @pytest.fixture(scope="module", autouse=True) @@ -39,3 +40,6 @@ def host(request): def port(request): return request.config.getoption("--port") +@pytest.fixture(scope="module", autouse=True) +def is_loadbalancer(request): + return request.config.getoption("--is_loadbalancer") \ No newline at end of file diff --git a/tests/rbac/sync/conftest.py b/tests/rbac/sync/conftest.py index 6d084552..0238fed6 100644 --- a/tests/rbac/sync/conftest.py +++ b/tests/rbac/sync/conftest.py @@ -6,9 +6,9 @@ @pytest.fixture(scope="module", autouse=True) -def drop_all_indexes(username, password, root_certificate, host, port, certificate_chain, private_key): +def drop_all_indexes(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): with AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: index_list = client.index_list() @@ -18,9 +18,9 @@ def drop_all_indexes(username, password, root_certificate, host, port, certifica @pytest.fixture(scope="module") -def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): +def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): client = AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) yield client client.close() diff --git a/tests/standard/aio/conftest.py b/tests/standard/aio/conftest.py index 01732b5e..12a6ce9e 100644 --- a/tests/standard/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -5,10 +5,10 @@ from aerospike_vector_search import types @pytest.fixture(scope="module", autouse=True) -async def drop_all_indexes(host, port, username, password, root_certificate, certificate_chain, private_key): +async def drop_all_indexes(host, port, username, password, root_certificate, certificate_chain, private_key, is_loadbalancer): async with AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: index_list = await client.index_list() @@ -22,28 +22,28 @@ async def drop_all_indexes(host, port, username, password, root_certificate, cer @pytest.fixture(scope="module") -async def session_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key): +async def session_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key, is_loadbalancer): client = AdminClient( - seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password ) yield client await client.close() @pytest.fixture(scope="module") -async def session_vector_client(host, port, username, password, root_certificate, certificate_chain, private_key): +async def session_vector_client(host, port, username, password, root_certificate, certificate_chain, private_key, is_loadbalancer): client = Client( - seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password ) yield client await client.close() @pytest.fixture -async def function_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key): +async def function_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key, is_loadbalancer): client = AdminClient( - seeds=types.HostPort(host=host, port=port), root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password ) yield client await client.close() diff --git a/tests/standard/aio/test_admin_client_index_create.py b/tests/standard/aio/test_admin_client_index_create.py index dc9254e6..0bfade72 100644 --- a/tests/standard/aio/test_admin_client_index_create.py +++ b/tests/standard/aio/test_admin_client_index_create.py @@ -496,6 +496,7 @@ async def test_index_create_index_storage(session_admin_client, test_case, rando @pytest.mark.parametrize( "test_case", [ + None, index_create_test_case( namespace="test", vector_field="example_15", diff --git a/tests/standard/aio/test_vector_client_delete.py b/tests/standard/aio/test_vector_client_delete.py index 3a29db00..b521d32d 100644 --- a/tests/standard/aio/test_vector_client_delete.py +++ b/tests/standard/aio/test_vector_client_delete.py @@ -81,6 +81,7 @@ async def test_vector_delete_without_record(session_vector_client, test_case, ra @pytest.mark.parametrize( "test_case", [ + None, delete_test_case( namespace="test", set_name=None, diff --git a/tests/standard/aio/test_vector_client_exists.py b/tests/standard/aio/test_vector_client_exists.py index 33f1d1ce..7119207d 100644 --- a/tests/standard/aio/test_vector_client_exists.py +++ b/tests/standard/aio/test_vector_client_exists.py @@ -61,6 +61,7 @@ async def test_vector_exists(session_vector_client, test_case, random_key): @pytest.mark.parametrize( "test_case", [ + None, exists_test_case( namespace="test", set_name=None, diff --git a/tests/standard/aio/test_vector_client_get.py b/tests/standard/aio/test_vector_client_get.py index 42d35890..4fdc3fd1 100644 --- a/tests/standard/aio/test_vector_client_get.py +++ b/tests/standard/aio/test_vector_client_get.py @@ -75,6 +75,7 @@ async def test_vector_get(session_vector_client, test_case, random_key): @pytest.mark.parametrize( "test_case", [ + None, get_test_case( namespace="test", field_names=['skills'], diff --git a/tests/standard/aio/test_vector_client_insert.py b/tests/standard/aio/test_vector_client_insert.py index 7ff9afd2..62c9287a 100644 --- a/tests/standard/aio/test_vector_client_insert.py +++ b/tests/standard/aio/test_vector_client_insert.py @@ -104,6 +104,7 @@ async def test_vector_insert_with_existing_record(session_vector_client, test_ca @pytest.mark.parametrize( "test_case", [ + None, insert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, diff --git a/tests/standard/aio/test_vector_client_update.py b/tests/standard/aio/test_vector_client_update.py index 19abe698..e7737188 100644 --- a/tests/standard/aio/test_vector_client_update.py +++ b/tests/standard/aio/test_vector_client_update.py @@ -97,6 +97,7 @@ async def test_vector_update_without_existing_record(session_vector_client, test @pytest.mark.parametrize( "test_case", [ + None, update_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, @@ -107,7 +108,8 @@ async def test_vector_update_without_existing_record(session_vector_client, test ) async def test_vector_update_timeout(session_vector_client, test_case, random_key, with_latency): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") + print(with_latency) with pytest.raises(AVSServerError) as e_info: for i in range(10): await session_vector_client.update( diff --git a/tests/standard/aio/test_vector_client_upsert.py b/tests/standard/aio/test_vector_client_upsert.py index 38a0885f..35ffe120 100644 --- a/tests/standard/aio/test_vector_client_upsert.py +++ b/tests/standard/aio/test_vector_client_upsert.py @@ -1,6 +1,7 @@ import pytest from ...utils import key_strategy from hypothesis import given, settings, Verbosity +import numpy as np from aerospike_vector_search import AVSServerError import grpc @@ -12,12 +13,15 @@ def __init__( record_data, set_name, timeout, + key=None ): self.namespace = namespace self.record_data = record_data self.set_name = set_name self.timeout = timeout + self.key = key + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -84,11 +88,46 @@ async def test_vector_upsert_with_existing_record(session_vector_client, test_ca key=random_key, ) + +@pytest.mark.parametrize( + "test_case", + [ + upsert_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=None, + key=np.int32(31) + ), + upsert_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=None, + key=np.array([b'a', b'b', b'c']) + ) + ], +) +async def test_vector_upsert_with_numpy_key(session_vector_client, test_case): + await session_vector_client.upsert( + namespace=test_case.namespace, + key=test_case.key, + record_data=test_case.record_data, + set_name=test_case.set_name + ) + + await session_vector_client.delete( + namespace=test_case.namespace, + key=test_case.key, + ) + + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( "test_case", [ + None, upsert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, @@ -99,7 +138,10 @@ async def test_vector_upsert_with_existing_record(session_vector_client, test_ca ) async def test_vector_upsert_timeout(session_vector_client, test_case, random_key, with_latency): if not with_latency: - pytest.skip("Server latency too low to test timeout") + print("INSIDE") + pytest.skip("Server latency too low to test timeout") + + print(with_latency) with pytest.raises(AVSServerError) as e_info: for i in range(10): await session_vector_client.upsert( diff --git a/tests/standard/conftest.py b/tests/standard/conftest.py index c5f276cb..154495c9 100644 --- a/tests/standard/conftest.py +++ b/tests/standard/conftest.py @@ -9,6 +9,7 @@ def pytest_addoption(parser): parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") parser.addoption("--certificate_chain", action="store", default=None, help="Path to certificate chain") parser.addoption("--private_key", action="store", default=None, help="Path to private key") + parser.addoption("--is_loadbalancer", action="store_true", help="Enable to use load balancer tending logic") parser.addoption("--with_latency", action="store_true", help="Skip the test if latency is too low to effectively trigger timeout") parser.addoption("--extensive_vector_search", action="store_true", help="Run extensive vector search testing") @@ -41,6 +42,11 @@ def host(request): def port(request): return request.config.getoption("--port") + +@pytest.fixture(scope="module", autouse=True) +def is_loadbalancer(request): + return request.config.getoption("--is_loadbalancer") + @pytest.fixture(scope="module", autouse=True) def with_latency(request): return request.config.getoption("--with_latency") diff --git a/tests/standard/sync/conftest.py b/tests/standard/sync/conftest.py index 9d7df576..81e17308 100644 --- a/tests/standard/sync/conftest.py +++ b/tests/standard/sync/conftest.py @@ -5,9 +5,9 @@ @pytest.fixture(scope="module", autouse=True) -def drop_all_indexes(username, password, root_certificate, host, port, certificate_chain, private_key): +def drop_all_indexes(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): with AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) as client: index_list = client.index_list() @@ -17,33 +17,34 @@ def drop_all_indexes(username, password, root_certificate, host, port, certifica @pytest.fixture(scope="module") -def session_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): +def session_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): client = AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) yield client client.close() @pytest.fixture(scope="module") -def session_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): +def session_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): client = AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) + print(is_loadbalancer) yield client client.close() @pytest.fixture(scope="module") -def session_vector_client(username, password, root_certificate, host, port, certificate_chain, private_key): +def session_vector_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): client = Client( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) yield client client.close() @pytest.fixture -def function_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key): +def function_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): client = AdminClient( - seeds=types.HostPort(host=host, port=port), username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key ) yield client client.close() diff --git a/tests/standard/sync/test_vector_client_upsert.py b/tests/standard/sync/test_vector_client_upsert.py index f3bf24dd..3c3e5534 100644 --- a/tests/standard/sync/test_vector_client_upsert.py +++ b/tests/standard/sync/test_vector_client_upsert.py @@ -2,6 +2,8 @@ from ...utils import key_strategy from hypothesis import given, settings, Verbosity +import numpy as np + from aerospike_vector_search import AVSServerError import grpc @@ -13,12 +15,14 @@ def __init__( record_data, set_name, timeout, + key=None ): self.namespace = namespace self.record_data = record_data self.set_name = set_name self.timeout = timeout + self.key = key @given(random_key=key_strategy()) @@ -84,6 +88,41 @@ def test_vector_upsert_with_existing_record(session_vector_client, test_case, ra key=random_key, ) + + +@pytest.mark.parametrize( + "test_case", + [ + upsert_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=None, + key=np.int32(31) + ), + upsert_test_case( + namespace="test", + record_data={"math": [i for i in range(1024)]}, + set_name=None, + timeout=None, + key=np.array([b'a', b'b', b'c']) + ) + ], +) +def test_vector_upsert_with_numpy_key(session_vector_client, test_case): + session_vector_client.upsert( + namespace=test_case.namespace, + key=test_case.key, + record_data=test_case.record_data, + set_name=test_case.set_name + ) + + session_vector_client.delete( + namespace=test_case.namespace, + key=test_case.key, + ) + + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( From 740d08279530839691428d1a56fc8b1431450f21 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 12:54:17 -0600 Subject: [PATCH 200/215] Update integration_test.yml Removed duplicate --- .github/workflows/integration_test.yml | 73 -------------------------- 1 file changed, 73 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c9a1d504..03132d9e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -1,4 +1,3 @@ - name: Run Unit Tests on: @@ -530,78 +529,6 @@ jobs: continue-on-error: true - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt - working-directory: tests - - - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - - name: Set up RANDFILE environment variable - run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV - - - name: Create .rnd file if it doesn't exist - run: touch $HOME/.rnd - - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - - - name: create config - run: | - assets/call_gen.sh - cat /etc/hosts - working-directory: tests - - - name: Run unit tests - run: | - - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - sleep 5 - - python -m pytest standard -s --is_loadbalancer --host 0.0.0.0 --port 5000 -vs - - - working-directory: tests - - test-is-loadbalancer: - runs-on: ubuntu-24.04 - continue-on-error: true - - strategy: matrix: python-version: ["3.9", "3.10", "3.11", "3.12"] From 0d682a749eb4a16de7abc2af2a815208b0d62fbb Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 12:58:00 -0600 Subject: [PATCH 201/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 73 -------------------------- 1 file changed, 73 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 03132d9e..dba1c1c7 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -519,82 +519,9 @@ jobs: sleep 5 python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs - - - working-directory: tests - - - test-is-loadbalancer: - runs-on: ubuntu-24.04 - continue-on-error: true - - - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] - - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py - pip install -r requirements.txt working-directory: tests - - name: Retrieve the secret and decode it to a file - env: - FEATURE_FILE: ${{ secrets.FEATURE_FILE }} - run: | - echo $FEATURE_FILE | base64 --decode > features.conf - working-directory: tests - - - name: Docker Login - uses: docker/login-action@v2 - with: - registry: aerospike.jfrog.io - username: ${{ secrets.JFROG_USERNAME }} - password: ${{ secrets.JFROG_PASSWORD }} - - - - name: Set up RANDFILE environment variable - run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV - - - name: Create .rnd file if it doesn't exist - run: touch $HOME/.rnd - - - name: Add hosts to /etc/hosts - run: | - sudo echo "0.0.0.0 brawn" | sudo tee -a /etc/hosts - - - name: create config - run: | - assets/call_gen.sh - cat /etc/hosts - working-directory: tests - - - name: Run unit tests - run: | - - docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 - docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest - - sleep 5 - - python -m pytest standard -s --is_loadbalancer --host 0.0.0.0 --port 5000 -vs - - - working-directory: tests # # test-timeout-on-sandbox: From c763e6519e93f0730199be09de312295c34ca41f Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 12:59:35 -0600 Subject: [PATCH 202/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 66 ++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index dba1c1c7..6fc2e0e6 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -521,6 +521,72 @@ jobs: python -m pytest rbac -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs working-directory: tests + test-is-loadbalancer: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: create config + run: | + assets/call_gen.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest standard -s --host 0.0.0.0 --port 5000 --is_loadbalancer -vs + working-directory: tests + # From 50ef88ba8c82c308a8dc7b02eafca5fc0116e9df Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 13:21:33 -0600 Subject: [PATCH 203/215] Improved error handling --- src/aerospike_vector_search/admin.py | 29 +-- src/aerospike_vector_search/aio/admin.py | 30 +-- src/aerospike_vector_search/aio/client.py | 18 +- .../aio/internal/channel_provider.py | 8 +- src/aerospike_vector_search/client.py | 18 +- .../internal/channel_provider.py | 183 +++++++++--------- 6 files changed, 146 insertions(+), 140 deletions(-) diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index 237788c1..7fb84fb4 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -124,7 +124,7 @@ def index_create( **kwargs, ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to create index with error: %s", e) raise types.AVSServerError(rpc_error=e) try: self._wait_for_index_creation( @@ -166,7 +166,7 @@ def index_drop( index_drop_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to drop index with error: %s", e) raise types.AVSServerError(rpc_error=e) try: self._wait_for_index_deletion( @@ -199,7 +199,7 @@ def index_list(self, timeout: Optional[int] = None) -> list[dict]: index_list_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to list indexes with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_list(response) @@ -235,7 +235,7 @@ def index_get( index_get_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to get index with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get(response) @@ -278,7 +278,7 @@ def index_get_status( **kwargs, ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to get index status with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get_status(response) @@ -305,7 +305,7 @@ def add_user( add_user_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to add user with error: %s", e) raise types.AVSServerError(rpc_error=e) def update_credentials( @@ -325,7 +325,7 @@ def update_credentials( update_credentials_request, credentials=self._channel_provider._token ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to update credentials with error: %s", e) raise types.AVSServerError(rpc_error=e) def drop_user(self, *, username: str, timeout: Optional[int] = None) -> int: @@ -343,7 +343,7 @@ def drop_user(self, *, username: str, timeout: Optional[int] = None) -> int: drop_user_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to drop user with error: %s", e) raise types.AVSServerError(rpc_error=e) def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: @@ -361,7 +361,7 @@ def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: get_user_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to get user with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_get_user(response) @@ -381,7 +381,7 @@ def list_users(self, timeout: Optional[int] = None) -> int: list_users_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to list user with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_list_users(response) @@ -402,7 +402,7 @@ def grant_roles( grant_roles_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to grant roles with error: %s", e) raise types.AVSServerError(rpc_error=e) def revoke_roles( @@ -424,7 +424,7 @@ def revoke_roles( **kwargs, ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to revoke roles with error: %s", e) raise types.AVSServerError(rpc_error=e) def list_roles(self, timeout: Optional[int] = None) -> int: @@ -442,7 +442,7 @@ def list_roles(self, timeout: Optional[int] = None) -> int: list_roles_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to list roles with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_list_roles(response) @@ -476,7 +476,7 @@ def _wait_for_index_creation( # Wait for some more time. time.sleep(wait_interval) else: - logger.error("Failed with error: %s", e) + logger.error("Failed waiting for index creation with error: %s", e) raise types.AVSServerError(rpc_error=e) def _wait_for_index_deletion( @@ -511,6 +511,7 @@ def _wait_for_index_deletion( # Index has been created return else: + logger.error("Failed waiting for index deletion with error: %s", e) raise types.AVSServerError(rpc_error=e) def close(self): diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index a9cddbf0..af7e859b 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -127,7 +127,7 @@ async def index_create( **kwargs, ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to create index with error: %s", e) raise types.AVSServerError(rpc_error=e) try: await self._wait_for_index_creation( @@ -171,7 +171,7 @@ async def index_drop( index_drop_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to drop index with error: %s", e) raise types.AVSServerError(rpc_error=e) try: await self._wait_for_index_deletion( @@ -206,7 +206,7 @@ async def index_list(self, timeout: Optional[int] = None) -> list[dict]: index_list_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to list indexes with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_list(response) @@ -244,7 +244,7 @@ async def index_get( index_get_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to get index with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get(response) @@ -289,7 +289,7 @@ async def index_get_status( **kwargs, ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to get index status with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_index_get_status(response) @@ -318,7 +318,7 @@ async def add_user( add_user_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to add user with error: %s", e) raise types.AVSServerError(rpc_error=e) async def update_credentials( @@ -342,7 +342,7 @@ async def update_credentials( **kwargs, ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to update credentials with error: %s", e) raise types.AVSServerError(rpc_error=e) async def drop_user(self, *, username: str, timeout: Optional[int] = None) -> int: @@ -362,7 +362,7 @@ async def drop_user(self, *, username: str, timeout: Optional[int] = None) -> in drop_user_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to drop user with error: %s", e) raise types.AVSServerError(rpc_error=e) async def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: @@ -382,7 +382,7 @@ async def get_user(self, *, username: str, timeout: Optional[int] = None) -> int get_user_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to get user with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_get_user(response) @@ -404,7 +404,7 @@ async def list_users(self, timeout: Optional[int] = None) -> int: list_users_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to list user with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_list_users(response) @@ -427,7 +427,7 @@ async def grant_roles( grant_roles_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to grant roles with error: %s", e) raise types.AVSServerError(rpc_error=e) async def revoke_roles( @@ -451,7 +451,7 @@ async def revoke_roles( **kwargs, ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to revoke roles with error: %s", e) raise types.AVSServerError(rpc_error=e) async def list_roles(self, timeout: Optional[int] = None) -> int: @@ -471,7 +471,7 @@ async def list_roles(self, timeout: Optional[int] = None) -> int: list_roles_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to list roles with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_list_roles(response) @@ -507,7 +507,7 @@ async def _wait_for_index_creation( # Wait for some more time. await asyncio.sleep(wait_interval) else: - logger.error("Failed with error: %s", e) + logger.error("Failed waiting for index creation with error: %s", e) raise types.AVSServerError(rpc_error=e) async def _wait_for_index_deletion( @@ -544,6 +544,8 @@ async def _wait_for_index_deletion( # Index has been created return else: + logger.error("Failed waiting for index deletion with error: %s", e) + raise types.AVSServerError(rpc_error=e) async def close(self): diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index 239d78da..eaadf0c4 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -112,7 +112,7 @@ async def insert( insert_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to insert vector with error: %s", e) raise types.AVSServerError(rpc_error=e) async def update( @@ -165,7 +165,7 @@ async def update( update_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to update vector with error: %s", e) raise types.AVSServerError(rpc_error=e) async def upsert( @@ -218,7 +218,7 @@ async def upsert( upsert_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to upsert vector with error: %s", e) raise types.AVSServerError(rpc_error=e) async def get( @@ -264,7 +264,7 @@ async def get( get_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to get vector with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_get(response, key) @@ -309,7 +309,7 @@ async def exists( exists_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to verfiy vector existence with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_exists(response) @@ -351,7 +351,7 @@ async def delete( delete_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to delete vector with error: %s", e) raise types.AVSServerError(rpc_error=e) async def is_indexed( @@ -399,7 +399,7 @@ async def is_indexed( is_indexed_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to verify vector indexing status with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_is_indexed(response) @@ -462,7 +462,7 @@ async def vector_search( ) ] except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to vector search with error: %s", e) raise types.AVSServerError(rpc_error=e) async def wait_for_index_completion( @@ -514,7 +514,7 @@ async def wait_for_index_completion( except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed waiting for index completion with error: %s", e) raise types.AVSServerError(rpc_error=e) if self._check_completion_condition( start_time, timeout, index_status, unmerged_record_initialized diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index e5d0b1be..077e8af3 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -161,7 +161,7 @@ async def _tend(self): tasks.append(channel_endpoints.channel.close()) except Exception as e: logger.debug( - "While tending, failed to close GRPC channel:" + str(e) + "While tending, failed to close GRPC channel while replacing up old endpoints:" + str(e) ) self.add_new_channel_to_node_channels(node, newEndpoints) @@ -174,7 +174,7 @@ async def _tend(self): except Exception as e: logger.debug( - "While tending, failed to close GRPC channel:" + str(e) + "While tending, failed to close GRPC channel while removing unused endpoints: " + str(e) ) await asyncio.gather(*tasks) @@ -195,8 +195,8 @@ async def _tend(self): await asyncio.sleep(1) self._task = asyncio.create_task(self._tend()) except Exception as e: + logger.error("Tending failed at unindentified location: %s", e) - print(e) def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: host = re.sub(r"%.*", "", host) @@ -246,7 +246,7 @@ async def _update_token_and_ttl( try: response = await auth_stub.Authenticate(auth_request) except grpc.RpcError as e: - print("Failed with error: %s", e) + print("Failed to refresh authentication token with error: %s", e) raise types.AVSServerError(rpc_error=e) self._respond_authenticate(response.token) diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index 91ba8776..fc68606e 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -108,7 +108,7 @@ def insert( insert_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to insert vector with error: %s", e) raise types.AVSServerError(rpc_error=e) def update( @@ -157,7 +157,7 @@ def update( update_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to update vector with error: %s", e) raise types.AVSServerError(rpc_error=e) def upsert( @@ -207,7 +207,7 @@ def upsert( upsert_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to upsert vector with error: %s", e) raise types.AVSServerError(rpc_error=e) def get( @@ -250,7 +250,7 @@ def get( get_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to get vector with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_get(response, key) @@ -292,7 +292,7 @@ def exists( exists_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to verfiy vector existence with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_exists(response) @@ -331,7 +331,7 @@ def delete( delete_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to delete vector with error: %s", e) raise types.AVSServerError(rpc_error=e) def is_indexed( @@ -376,7 +376,7 @@ def is_indexed( is_indexed_request, credentials=self._channel_provider._token, **kwargs ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to verify vector indexing status with error: %s", e) raise types.AVSServerError(rpc_error=e) return self._respond_is_indexed(response) @@ -437,7 +437,7 @@ def vector_search( ) ] except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed to vector search with error: %s", e) raise types.AVSServerError(rpc_error=e) def wait_for_index_completion( @@ -487,7 +487,7 @@ def wait_for_index_completion( ) except grpc.RpcError as e: - logger.error("Failed with error: %s", e) + logger.error("Failed waiting for index completion with error: %s", e) raise types.AVSServerError(rpc_error=e) if self._check_completion_condition( start_time, timeout, index_status, unmerged_record_initialized diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index 839ccb87..c6c269aa 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -62,116 +62,119 @@ def close(self): self._timer.join() def _tend(self): - (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() - if self._token: - if self._check_if_token_refresh_needed(): - self._update_token_and_ttl() - - if end_tend: + try: + (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() + if self._token: + if self._check_if_token_refresh_needed(): + self._update_token_and_ttl() - if not self.client_server_compatible: + if end_tend: - stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) - about_request = vector_db_pb2.AboutRequest() - - self.current_server_version = stub.Get( - about_request, credentials=self._token - ).version - self.client_server_compatible = self.verify_compatibile_server() if not self.client_server_compatible: - self._tend_ended.set() - raise types.AVSClientError( - message="This AVS Client version is only compatbile with AVS Servers above the following version number: " - + self.minimum_required_version - ) - self._tend_ended.set() - - return - - update_endpoints_stubs = [] - new_cluster_ids = [] - for channel in channels: + stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) + about_request = vector_db_pb2.AboutRequest() + + self.current_server_version = stub.Get( + about_request, credentials=self._token + ).version + self.client_server_compatible = self.verify_compatibile_server() + if not self.client_server_compatible: + self._tend_ended.set() + raise types.AVSClientError( + message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + + self.minimum_required_version + ) - stubs = [] + self._tend_ended.set() - stub = vector_db_pb2_grpc.ClusterInfoServiceStub(channel) - stubs.append(stub) + return - try: - new_cluster_ids.append( - stub.GetClusterId(empty, credentials=self._credentials) - ) + update_endpoints_stubs = [] + new_cluster_ids = [] + for channel in channels: - except Exception as e: - logger.debug( - "While tending, failed to get cluster id with error:" + str(e) - ) + stubs = [] - for index, value in enumerate(new_cluster_ids): - if self.check_cluster_id(value.id): - update_endpoints_stubs.append(stubs[index]) + stub = vector_db_pb2_grpc.ClusterInfoServiceStub(channel) + stubs.append(stub) - for stub in update_endpoints_stubs: + try: + new_cluster_ids.append( + stub.GetClusterId(empty, credentials=self._credentials) + ) - try: - response = stub.GetClusterEndpoints( - vector_db_pb2.ClusterNodeEndpointsRequest( - listenerName=self.listener_name, credentials=self._credentials + except Exception as e: + logger.debug( + "While tending, failed to get cluster id with error:" + str(e) ) - ) - temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) - except Exception as e: - logger.debug( - "While tending, failed to get cluster endpoints with error:" - + str(e) - ) - - if update_endpoints_stubs: - for node, newEndpoints in temp_endpoints.items(): - (channel_endpoints, add_new_channel) = self.check_for_new_endpoints( - node, newEndpoints - ) - - if add_new_channel: - try: - # TODO: Wait for all calls to drain - channel_endpoints.channel.close() - except Exception as e: - logger.debug( - "While tending, failed to close GRPC channel:" + str(e) - ) - self.add_new_channel_to_node_channels(node, newEndpoints) + for index, value in enumerate(new_cluster_ids): + if self.check_cluster_id(value.id): + update_endpoints_stubs.append(stubs[index]) - for node, channel_endpoints in list(self._node_channels.items()): - if not self._node_channels.get(node): - try: - # TODO: Wait for all calls to drain - channel_endpoints.channel.close() - del self._node_channels[node] + for stub in update_endpoints_stubs: - except Exception as e: - logger.debug( - "While tending, failed to close GRPC channel:" + str(e) + try: + response = stub.GetClusterEndpoints( + vector_db_pb2.ClusterNodeEndpointsRequest( + listenerName=self.listener_name, credentials=self._credentials ) + ) + temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) + except Exception as e: + logger.debug( + "While tending, failed to get cluster endpoints with error:" + + str(e) + ) - if not self.client_server_compatible: + if update_endpoints_stubs: + for node, newEndpoints in temp_endpoints.items(): + (channel_endpoints, add_new_channel) = self.check_for_new_endpoints( + node, newEndpoints + ) - stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) - about_request = vector_db_pb2.AboutRequest() + if add_new_channel: + try: + # TODO: Wait for all calls to drain + channel_endpoints.channel.close() + except Exception as e: + logger.debug( + "While tending, failed to close GRPC channel while replacing up old endpoints:" + str(e) + ) + + self.add_new_channel_to_node_channels(node, newEndpoints) + + for node, channel_endpoints in list(self._node_channels.items()): + if not self._node_channels.get(node): + try: + # TODO: Wait for all calls to drain + channel_endpoints.channel.close() + del self._node_channels[node] + + except Exception as e: + logger.debug( + "While tending, failed to close GRPC channel while removing unused endpoints: " + str(e) + ) - self.current_server_version = stub.Get( - about_request, credentials=self._token - ).version - self.client_server_compatible = self.verify_compatibile_server() if not self.client_server_compatible: - raise types.AVSClientError( - message="This AVS Client version is only compatbile with AVS Servers above the following version number: " - + self.minimum_required_version - ) - self._timer = threading.Timer(1, self._tend).start() + stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) + about_request = vector_db_pb2.AboutRequest() + + self.current_server_version = stub.Get( + about_request, credentials=self._token + ).version + self.client_server_compatible = self.verify_compatibile_server() + if not self.client_server_compatible: + raise types.AVSClientError( + message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + + self.minimum_required_version + ) + + self._timer = threading.Timer(1, self._tend).start() + except Exception as e: + logger.error("Tending failed at unindentified location: %s", e) def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: host = re.sub(r"%.*", "", host) @@ -222,7 +225,7 @@ def _update_token_and_ttl( try: response = auth_stub.Authenticate(auth_request) except grpc.RpcError as e: - print("Failed with error: %s", e) + print("Failed to refresh authentication token with error: %s", e) raise types.AVSServerError(rpc_error=e) self._respond_authenticate(response.token) From 56ed5642e8ccd17e2db8c319e6a97670211a31f4 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 13:23:15 -0600 Subject: [PATCH 204/215] Fixed spacing --- .../aio/internal/channel_provider.py | 8 ++++---- src/aerospike_vector_search/internal/channel_provider.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 077e8af3..f3f63f9e 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -115,14 +115,14 @@ async def _tend(self): ) except Exception as e: logger.debug( - "While tending, failed to get cluster id with error:" + str(e) + "While tending, failed to get cluster id with error: " + str(e) ) try: new_cluster_ids = tasks except Exception as e: logger.debug( - "While tending, failed to gather results from GetClusterId:" + "While tending, failed to gather results from GetClusterId: " + str(e) ) @@ -143,7 +143,7 @@ async def _tend(self): ) except Exception as e: logger.debug( - "While tending, failed to get cluster endpoints with error:" + "While tending, failed to get cluster endpoints with error: " + str(e) ) @@ -161,7 +161,7 @@ async def _tend(self): tasks.append(channel_endpoints.channel.close()) except Exception as e: logger.debug( - "While tending, failed to close GRPC channel while replacing up old endpoints:" + str(e) + "While tending, failed to close GRPC channel while replacing up old endpoints: " + str(e) ) self.add_new_channel_to_node_channels(node, newEndpoints) diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index c6c269aa..b212247d 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -106,7 +106,7 @@ def _tend(self): except Exception as e: logger.debug( - "While tending, failed to get cluster id with error:" + str(e) + "While tending, failed to get cluster id with error: " + str(e) ) for index, value in enumerate(new_cluster_ids): @@ -124,7 +124,7 @@ def _tend(self): temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) except Exception as e: logger.debug( - "While tending, failed to get cluster endpoints with error:" + "While tending, failed to get cluster endpoints with error: " + str(e) ) From 54bd524d1f921508f2b688144cec9efe1ffcab7f Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 13:32:14 -0600 Subject: [PATCH 205/215] Corrected syntax --- .../aio/internal/channel_provider.py | 2 ++ .../internal/channel_provider.py | 17 +++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index f3f63f9e..6f97f2c4 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -196,6 +196,8 @@ async def _tend(self): self._task = asyncio.create_task(self._tend()) except Exception as e: logger.error("Tending failed at unindentified location: %s", e) + raise e + def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index b212247d..76454b69 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -161,10 +161,14 @@ def _tend(self): stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) about_request = vector_db_pb2.AboutRequest() - - self.current_server_version = stub.Get( - about_request, credentials=self._token - ).version + try: + self.current_server_version = stub.Get( + about_request, credentials=self._token + ).version + except Exception as e: + logger.debug( + "While tending, failed to close GRPC channel while removing unused endpoints: " + str(e) + ) self.client_server_compatible = self.verify_compatibile_server() if not self.client_server_compatible: raise types.AVSClientError( @@ -173,8 +177,9 @@ def _tend(self): ) self._timer = threading.Timer(1, self._tend).start() - except Exception as e: - logger.error("Tending failed at unindentified location: %s", e) + except Exception as e: + logger.error("Tending failed at unindentified location: %s", e) + raise e def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: host = re.sub(r"%.*", "", host) From ab590a50a7c38390b90ea162fd44edaf0f1dce1a Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Mon, 22 Jul 2024 13:35:23 -0600 Subject: [PATCH 206/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 6fc2e0e6..cc93934f 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -217,7 +217,7 @@ jobs: sleep 5 - python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin + python -m pytest standard -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin working-directory: tests @@ -296,7 +296,7 @@ jobs: docker ps - python -m pytest rbac/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt + python -m pytest rbac -s -vv --host child --port 5000 --root_certificate tls/root.crt docker logs aerospike-vector-search docker logs aerospike From cba172257b0adf6069795b96fdea6e13656d4024 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 23 Jul 2024 06:59:27 -0600 Subject: [PATCH 207/215] Added changes from Jesse's review --- .github/workflows/integration_test.yml | 76 ++- docs/conf.py | 20 +- pyproject.toml | 4 +- src/aerospike_vector_search/admin.py | 414 ++++++++++------ src/aerospike_vector_search/aio/admin.py | 460 ++++++++++++------ src/aerospike_vector_search/aio/client.py | 317 ++++++------ .../aio/internal/channel_provider.py | 50 +- src/aerospike_vector_search/client.py | 280 ++++++----- .../internal/channel_provider.py | 48 +- .../shared/admin_helpers.py | 86 +++- .../shared/base_channel_provider.py | 11 +- .../shared/client_helpers.py | 36 +- src/aerospike_vector_search/shared/helpers.py | 2 +- src/aerospike_vector_search/types.py | 3 +- tests/assets/aerospike-proximus.yml | 122 ----- tests/assets/service_stanza.txt | 2 +- tests/rbac/aio/conftest.py | 81 ++- tests/rbac/aio/test_admin_client_add_user.py | 28 +- tests/rbac/aio/test_admin_client_drop_user.py | 12 +- tests/rbac/aio/test_admin_client_get_user.py | 10 +- .../rbac/aio/test_admin_client_grant_roles.py | 25 +- .../rbac/aio/test_admin_client_list_roles.py | 9 +- .../rbac/aio/test_admin_client_list_users.py | 14 +- .../aio/test_admin_client_revoke_roles.py | 25 +- .../test_admin_client_update_credentials.py | 19 +- tests/rbac/conftest.py | 33 +- tests/rbac/sync/conftest.py | 68 ++- tests/rbac/sync/test_admin_client_add_user.py | 28 +- .../rbac/sync/test_admin_client_drop_user.py | 12 +- tests/rbac/sync/test_admin_client_get_user.py | 10 +- .../sync/test_admin_client_grant_roles.py | 25 +- .../rbac/sync/test_admin_client_list_roles.py | 9 +- .../rbac/sync/test_admin_client_list_users.py | 14 +- .../sync/test_admin_client_revoke_roles.py | 25 +- .../test_admin_client_update_credentials.py | 19 +- tests/standard/aio/conftest.py | 128 ++++- .../aio/test_admin_client_index_create.py | 261 +++++----- .../aio/test_admin_client_index_drop.py | 18 +- .../aio/test_admin_client_index_get.py | 21 +- .../aio/test_admin_client_index_get_status.py | 28 +- .../aio/test_admin_client_index_list.py | 29 +- tests/standard/aio/test_service_config.py | 285 ++++++++--- .../standard/aio/test_vector_client_delete.py | 32 +- .../standard/aio/test_vector_client_exists.py | 27 +- tests/standard/aio/test_vector_client_get.py | 39 +- .../standard/aio/test_vector_client_insert.py | 45 +- .../standard/aio/test_vector_client_update.py | 46 +- .../standard/aio/test_vector_client_upsert.py | 64 +-- tests/standard/aio/test_vector_search.py | 121 +++-- tests/standard/conftest.py | 46 +- tests/standard/sync/conftest.py | 161 +++++- .../sync/test_admin_client_index_create.py | 354 +++++++------- .../sync/test_admin_client_index_drop.py | 21 +- .../sync/test_admin_client_index_get.py | 23 +- .../test_admin_client_index_get_status.py | 16 +- .../sync/test_admin_client_index_list.py | 35 +- tests/standard/sync/test_service_config.py | 288 ++++++++--- .../sync/test_vector_client_delete.py | 32 +- .../sync/test_vector_client_exists.py | 31 +- tests/standard/sync/test_vector_client_get.py | 32 +- .../sync/test_vector_client_insert.py | 62 +-- .../sync/test_vector_client_update.py | 53 +- .../sync/test_vector_client_upsert.py | 59 ++- tests/standard/sync/test_vector_search.py | 135 +++-- tests/utils.py | 36 +- 65 files changed, 2978 insertions(+), 1947 deletions(-) delete mode 100755 tests/assets/aerospike-proximus.yml diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index cc93934f..00839946 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -79,7 +79,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.12"] steps: @@ -158,7 +158,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.12"] steps: @@ -230,7 +230,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.12"] steps: @@ -310,7 +310,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.12"] steps: @@ -528,7 +528,7 @@ jobs: strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.12"] steps: @@ -587,7 +587,71 @@ jobs: python -m pytest standard -s --host 0.0.0.0 --port 5000 --is_loadbalancer -vs working-directory: tests + test-exhaustive-vector-search: + runs-on: ubuntu-24.04 + continue-on-error: true + + + strategy: + matrix: + python-version: ["3.12"] + + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python setup.py + pip install -r requirements.txt + working-directory: tests + + + - name: Retrieve the secret and decode it to a file + env: + FEATURE_FILE: ${{ secrets.FEATURE_FILE }} + run: | + echo $FEATURE_FILE | base64 --decode > features.conf + working-directory: tests + + - name: Docker Login + uses: docker/login-action@v2 + with: + registry: aerospike.jfrog.io + username: ${{ secrets.JFROG_USERNAME }} + password: ${{ secrets.JFROG_PASSWORD }} + + + - name: Set up RANDFILE environment variable + run: echo "RANDFILE=$HOME/.rnd" >> $GITHUB_ENV + - name: Create .rnd file if it doesn't exist + run: touch $HOME/.rnd + + - name: create config + run: | + assets/call_gen.sh + cat /etc/hosts + working-directory: tests + + - name: Run unit tests + run: | + + docker run -d --name aerospike-vector-search --network=host -p 5000:5000 -v $(pwd):/etc/aerospike-vector-search aerospike/aerospike-vector-search:0.9.0 + docker run -d --name aerospike -p 3000:3000 -v .:/etc/aerospike aerospike/aerospike-server-enterprise:latest + + sleep 5 + + python -m pytest standard -s --host 0.0.0.0 --port 5000 --exhaustive_vector_search -vs + working-directory: tests # # test-timeout-on-sandbox: @@ -597,7 +661,7 @@ jobs: # # strategy: # matrix: -# python-version: ["3.11"] +# python-version: ["3.12"] # # # steps: diff --git a/docs/conf.py b/docs/conf.py index 24ea0fd5..36b84300 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -6,24 +6,24 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -project = 'aerospike-vector-search' -copyright = '2024, Dominic Pelini' -author = 'Dominic Pelini' -release = '0.6.1' +project = "aerospike-vector-search" +copyright = "2024, Dominic Pelini" +author = "Dominic Pelini" +release = "0.6.1" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = [ - 'sphinx.ext.autodoc', - 'sphinx_rtd_theme', + "sphinx.ext.autodoc", + "sphinx_rtd_theme", ] -templates_path = ['_templates'] -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +templates_path = ["_templates"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = 'sphinx_rtd_theme' -html_static_path = ['_static'] +html_theme = "sphinx_rtd_theme" +html_static_path = ["_static"] diff --git a/pyproject.toml b/pyproject.toml index afad321e..0f23ee17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Topic :: Database" ] -version = "1.0.0.dev5" +version = "1.0.0.dev6" requires-python = ">3.8" dependencies = [ "grpcio == 1.64.1", @@ -54,4 +54,4 @@ exclude = ''' | src/aerospike_vector_search/__pycache__/* | src/aerospike_vector_search.egg-info/* )/ -''' \ No newline at end of file +''' diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index 7fb84fb4..278963cf 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -16,6 +16,36 @@ class Client(BaseClient): Aerospike Vector Search Admin Client This client is designed to conduct Aerospike Vector Search administrative operation such as creating indexes, querying index information, and dropping indexes. + + :param seeds: Defines the Aerospike Database cluster nodes to which you want AVS to connect. AVS iterates through the seed nodes. After connecting to a node, AVS discovers all of the nodes in the cluster. + :type seeds: Union[types.HostPort, tuple[types.HostPort, ...]] + + :param listener_name: An external (NATed) address and port combination that differs from the actual address and port where AVS is listening. Clients can access AVS on a node using the advertised listener address and port. Defaults to None. + :type listener_name: Optional[str] + + :param is_loadbalancer: If true, the first seed address will be treated as a load balancer node. Defaults to False. + :type is_loadbalancer: Optional[bool] + + :param service_config_path: Path to the service configuration file. Defaults to None. + :type service_config_path: Optional[str] + + :param username: Username for Role-Based Access. Defaults to None. + :type username: Optional[str] + + :param password: Password for Role-Based Access. Defaults to None. + :type password: Optional[str] + + :param root_certificate: The PEM-encoded root certificates as a byte string. Defaults to None. + :type root_certificate: Optional[list[bytes], bytes] + + :param certificate_chain: The PEM-encoded private key as a byte string. Defaults to None. + :type certificate_chain: Optional[bytes] + + :param private_key: The PEM-encoded certificate chain as a byte string. Defaults to None. + :type private_key: Optional[bytes] + + :raises AVSClientError: Raised when no seed host is provided. + """ def __init__( @@ -26,23 +56,11 @@ def __init__( is_loadbalancer: Optional[bool] = False, username: Optional[str] = None, password: Optional[str] = None, - root_certificate: Optional[str] = None, + root_certificate: Optional[Union[list[str], str]] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, service_config_path: Optional[str] = None, ) -> None: - """ - Initialize the Aerospike Vector Search Admin Client. - - Args: - seeds (Union[types.HostPort, tuple[types.HostPort, ...]]): Used to create appropriate gRPC channels for interacting with Aerospike Vector Search. - listener_name (Optional[str], optional): Advertised listener for the client. Defaults to None. - is_loadbalancer (bool, optional): If true, the first seed address will be treated as a load balancer node. - - Raises: - Exception: Raised when no seed host is provided. - - """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( @@ -69,29 +87,46 @@ def index_create( ), sets: Optional[str] = None, index_params: Optional[types.HnswParams] = None, - index_meta_data: Optional[dict[str, str]] = None, + index_labels: Optional[dict[str, str]] = None, index_storage: Optional[types.IndexStorage] = None, timeout: Optional[int] = None, ) -> None: """ Create an index. - Args: - namespace (str): The namespace for the index. - name (str): The name of the index. - vector_field (str): The name of the field containing vector data. - dimensions (int): The number of dimensions in the vector data. - vector_distance_metric (Optional[types.VectorDistanceMetric], optional): + :param namespace: The namespace for the index. + :type namespace: str + + :param name: The name of the index. + :type name: str + + :param vector_field: The name of the field containing vector data. + :type vector_field: str + + :param dimensions: The number of dimensions in the vector data. + :type dimensions: int + + :param vector_distance_metric: The distance metric used to compare when performing a vector search. - Defaults to VectorDistanceMetric.SQUARED_EUCLIDEAN. - sets (Optional[str], optional): The set used for the index. Defaults to None. - index_params (Optional[types.HnswParams], optional): - Parameters used for tuning vector search. Defaults to None. If index_params is None, then the default values specified for - types.HnswParams will be used. - index_meta_data (Optional[dict[str, str]], optional): Meta data associated with the index. Defaults to None. + Defaults to :class:`VectorDistanceMetric.SQUARED_EUCLIDEAN`. + :type dimensions: Optional[types.VectorDistanceMetric] + + :param sets: The set used for the index. Defaults to None. + :type dimensions: Optional[str] + + :param index_params: (Optional[types.HnswParams], optional): Parameters used for tuning + vector search. Defaults to None. If index_params is None, then the default values + specified for :class:`types.HnswParams` will be used. + :type dimensions: Optional[types.HnswParams] + + :param index_labels: Meta data associated with the index. Defaults to None. + :type dimensions: Optional[dict[str, str]] + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. Note: @@ -99,7 +134,7 @@ def index_create( It waits for up to 100,000 seconds for the index creation to complete. """ - (index_stub, index_create_request) = self._prepare_index_create( + (index_stub, index_create_request, kwargs) = self._prepare_index_create( namespace, name, vector_field, @@ -107,20 +142,16 @@ def index_create( vector_distance_metric, sets, index_params, - index_meta_data, + index_labels, index_storage, timeout, logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: index_stub.Create( index_create_request, - credentials=self._channel_provider._token, + credentials=self._channel_provider.get_token(), **kwargs, ) except grpc.RpcError as e: @@ -140,12 +171,17 @@ def index_drop( """ Drop an index. - Args: - namespace (str): The namespace of the index. - name (str): The name of the index. + :param namespace: The namespace of the index. + :type name: str + + :param name: The name of the index. + :type name: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to drop the index.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. Note: @@ -153,17 +189,15 @@ def index_drop( It waits for up to 100,000 seconds for the index deletion to complete. """ - (index_stub, index_drop_request) = self._prepare_index_drop( + (index_stub, index_drop_request, kwargs) = self._prepare_index_drop( namespace, name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: index_stub.Drop( - index_drop_request, credentials=self._channel_provider._token, **kwargs + index_drop_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to drop index with error: %s", e) @@ -180,23 +214,25 @@ def index_list(self, timeout: Optional[int] = None) -> list[dict]: """ List all indices. - Returns: - list[dict]: A list of indices. + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Returns: list[dict]: A list of indices. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to list the index.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (index_stub, index_list_request) = self._prepare_index_list(timeout, logger) - - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout + (index_stub, index_list_request, kwargs) = self._prepare_index_list( + timeout, logger + ) try: response = index_stub.List( - index_list_request, credentials=self._channel_provider._token, **kwargs + index_list_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to list indexes with error: %s", e) @@ -209,30 +245,32 @@ def index_get( """ Retrieve the information related with an index. - Args: - namespace (str): The namespace of the index. - name (str): The name of the index. + :param namespace: The namespace of the index. + :type name: str - Returns: - dict[str, Union[int, str]: Information about an index. + :param name: The name of the index. + :type name: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Returns: dict[str, Union[int, str]: Information about an index. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to get the index.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (index_stub, index_get_request) = self._prepare_index_get( + (index_stub, index_get_request, kwargs) = self._prepare_index_get( namespace, name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = index_stub.Get( - index_get_request, credentials=self._channel_provider._token, **kwargs + index_get_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to get index with error: %s", e) @@ -245,15 +283,19 @@ def index_get_status( """ Retrieve the number of records queued to be merged into an index. - Args: - namespace (str): The namespace of the index. - name (str): The name of the index. + :param namespace: The namespace of the index. + :type name: str - Returns: - int: Records queued to be merged into an index. + :param name: The name of the index. + :type name: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Returns: int: Records queued to be merged into an index. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to get the index status. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. Note: @@ -262,19 +304,14 @@ def index_get_status( Warning: This API is subject to change. """ - - (index_stub, index_get_status_request) = self._prepare_index_get_status( + (index_stub, index_get_status_request, kwargs) = self._prepare_index_get_status( namespace, name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = index_stub.GetStatus( index_get_status_request, - credentials=self._channel_provider._token, + credentials=self._channel_provider.get_token(), **kwargs, ) except grpc.RpcError as e: @@ -290,19 +327,37 @@ def add_user( password: str, roles: list[str], timeout: Optional[int] = None, - ) -> int: + ) -> None: + """ + Add role-based access AVS User to the AVS Server. + + :param username: Username for the new user. + :type username: str + + :param password: Password for the new user. + :type password: str - (user_admin_stub, add_user_request) = self._prepare_add_user( + :param roles: Roles for the new user. + :type password: list[str] + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to add a user. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + (user_admin_stub, add_user_request, kwargs) = self._prepare_add_user( username, password, roles, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: user_admin_stub.AddUser( - add_user_request, credentials=self._channel_provider._token, **kwargs + add_user_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to add user with error: %s", e) @@ -310,55 +365,95 @@ def add_user( def update_credentials( self, *, username: str, password: str, timeout: Optional[int] = None - ) -> int: + ) -> None: + """ + Update AVS User credentials. + + :param username: Username of the user to update. + :type username: str + + :param password: New password for the userr. + :type password: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + - (user_admin_stub, update_credentials_request) = ( + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to update a users credentials. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + (user_admin_stub, update_credentials_request, kwargs) = ( self._prepare_update_credentials(username, password, timeout, logger) ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: user_admin_stub.UpdateCredentials( - update_credentials_request, credentials=self._channel_provider._token + update_credentials_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to update credentials with error: %s", e) raise types.AVSServerError(rpc_error=e) - def drop_user(self, *, username: str, timeout: Optional[int] = None) -> int: + def drop_user(self, *, username: str, timeout: Optional[int] = None) -> None: + """ + Drops AVS User from the AVS Server. + + :param username: Username of the user to drop. + :type username: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int - (user_admin_stub, drop_user_request) = self._prepare_drop_user( + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to drop a user + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + (user_admin_stub, drop_user_request, kwargs) = self._prepare_drop_user( username, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: user_admin_stub.DropUser( - drop_user_request, credentials=self._channel_provider._token, **kwargs + drop_user_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to drop user with error: %s", e) raise types.AVSServerError(rpc_error=e) - def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: + def get_user(self, *, username: str, timeout: Optional[int] = None) -> types.User: + """ + Retrieves AVS User information from the AVS Server - (user_admin_stub, get_user_request) = self._prepare_get_user( + :param username: Username of the user to be retrieved. + :type username: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + return: types.User: AVS User + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to get a user. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + (user_admin_stub, get_user_request, kwargs) = self._prepare_get_user( username, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = user_admin_stub.GetUser( - get_user_request, credentials=self._channel_provider._token, **kwargs + get_user_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to get user with error: %s", e) @@ -366,19 +461,29 @@ def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: return self._respond_get_user(response) - def list_users(self, timeout: Optional[int] = None) -> int: + def list_users(self, timeout: Optional[int] = None) -> list[types.User]: + """ + List all users existing on the AVS Server. + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + return: list[types.User]: list of AVS Users - (user_admin_stub, list_users_request) = self._prepare_list_users( + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to list users. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + (user_admin_stub, list_users_request, kwargs) = self._prepare_list_users( timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = user_admin_stub.ListUsers( - list_users_request, credentials=self._channel_provider._token, **kwargs + list_users_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to list user with error: %s", e) @@ -387,19 +492,33 @@ def list_users(self, timeout: Optional[int] = None) -> int: def grant_roles( self, *, username: str, roles: list[str], timeout: Optional[int] = None - ) -> int: + ) -> None: + """ + grant roles to existing AVS Users. - (user_admin_stub, grant_roles_request) = self._prepare_grant_roles( + :param username: Username of the user which will receive the roles. + :type username: str + + :param roles: Roles the specified user will recieved. + :type roles: list[str] + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to grant roles. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + (user_admin_stub, grant_roles_request, kwargs) = self._prepare_grant_roles( username, roles, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: user_admin_stub.GrantRoles( - grant_roles_request, credentials=self._channel_provider._token, **kwargs + grant_roles_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to grant roles with error: %s", e) @@ -407,39 +526,60 @@ def grant_roles( def revoke_roles( self, *, username: str, roles: list[str], timeout: Optional[int] = None - ) -> int: + ) -> None: + """ + grant roles to existing AVS Users. - (user_admin_stub, revoke_roles_request) = self._prepare_revoke_roles( + :param username: Username of the user undergoing role removal. + :type username: str + + :param roles: Roles the specified user will no longer maintain.. + :type roles: list[str] + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to revoke roles. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + (user_admin_stub, revoke_roles_request, kwargs) = self._prepare_revoke_roles( username, roles, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: user_admin_stub.RevokeRoles( revoke_roles_request, - credentials=self._channel_provider._token, + credentials=self._channel_provider.get_token(), **kwargs, ) except grpc.RpcError as e: logger.error("Failed to revoke roles with error: %s", e) raise types.AVSServerError(rpc_error=e) - def list_roles(self, timeout: Optional[int] = None) -> int: + def list_roles(self, timeout: Optional[int] = None) -> list[str]: + """ + grant roles to existing AVS Users. + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int - (user_admin_stub, list_roles_request) = self._prepare_list_roles( + returns: list[str]: Roles available in the AVS Server. + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to list roles. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + """ + (user_admin_stub, list_roles_request, kwargs) = self._prepare_list_roles( timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = user_admin_stub.ListRoles( - list_roles_request, credentials=self._channel_provider._token, **kwargs + list_roles_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to list roles with error: %s", e) @@ -465,7 +605,8 @@ def _wait_for_index_creation( self._check_timeout(start_time, timeout) try: index_stub.GetStatus( - index_creation_request, credentials=self._channel_provider._token + index_creation_request, + credentials=self._channel_provider.get_token(), ) logger.debug("Index created succesfully") # Index has been created @@ -501,7 +642,8 @@ def _wait_for_index_deletion( try: index_stub.GetStatus( - index_deletion_request, credentials=self._channel_provider._token + index_deletion_request, + credentials=self._channel_provider.get_token(), ) # Wait for some more time. time.sleep(wait_interval) diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index af7e859b..68415f34 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -16,6 +16,36 @@ class Client(BaseClient): Aerospike Vector Search Asyncio Admin Client This client is designed to conduct Aerospike Vector Search administrative operation such as creating indexes, querying index information, and dropping indexes. + + :param seeds: Defines the Aerospike Database cluster nodes to which you want AVS to connect. AVS iterates through the seed nodes. After connecting to a node, AVS discovers all of the nodes in the cluster. + :type seeds: Union[types.HostPort, tuple[types.HostPort, ...]] + + :param listener_name: An external (NATed) address and port combination that differs from the actual address and port where AVS is listening. Clients can access AVS on a node using the advertised listener address and port. Defaults to None. + :type listener_name: Optional[str] + + :param is_loadbalancer: If true, the first seed address will be treated as a load balancer node. Defaults to False. + :type is_loadbalancer: Optional[bool] + + :param service_config_path: Path to the service configuration file. Defaults to None. + :type service_config_path: Optional[str] + + :param username: Username for Role-Based Access. Defaults to None. + :type username: Optional[str] + + :param password: Password for Role-Based Access. Defaults to None. + :type password: Optional[str] + + :param root_certificate: The PEM-encoded root certificates as a byte string. Defaults to None. + :type root_certificate: Optional[list[bytes], bytes] + + :param certificate_chain: The PEM-encoded private key as a byte string. Defaults to None. + :type certificate_chain: Optional[bytes] + + :param private_key: The PEM-encoded certificate chain as a byte string. Defaults to None. + :type private_key: Optional[bytes] + + :raises AVSClientError: Raised when no seed host is provided. + """ def __init__( @@ -27,22 +57,10 @@ def __init__( service_config_path: Optional[str] = None, username: Optional[str] = None, password: Optional[str] = None, - root_certificate: Optional[str] = None, + root_certificate: Optional[Union[list[str], str]] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, ) -> None: - """ - Initialize the Aerospike Vector Search Admin Client. - - Args: - seeds (Union[types.HostPort, tuple[types.HostPort, ...]]): Used to create appropriate gRPC channels for interacting with Aerospike Vector Search. - listener_name (Optional[str], optional): Advertised listener for the client. Defaults to None. - is_loadbalancer (bool, optional): If true, the first seed address will be treated as a load balancer node. - - Raises: - Exception: Raised when no seed host is provided. - - """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( @@ -69,29 +87,46 @@ async def index_create( ), sets: Optional[str] = None, index_params: Optional[types.HnswParams] = None, - index_meta_data: Optional[dict[str, str]] = None, + index_labels: Optional[dict[str, str]] = None, index_storage: Optional[types.IndexStorage] = None, timeout: Optional[int] = None, ) -> None: """ Create an index. - Args: - namespace (str): The namespace for the index. - name (str): The name of the index. - vector_field (str): The name of the field containing vector data. - dimensions (int): The number of dimensions in the vector data. - vector_distance_metric (Optional[types.VectorDistanceMetric], optional): + :param namespace: The namespace for the index. + :type namespace: str + + :param name: The name of the index. + :type name: str + + :param vector_field: The name of the field containing vector data. + :type vector_field: str + + :param dimensions: The number of dimensions in the vector data. + :type dimensions: int + + :param vector_distance_metric: The distance metric used to compare when performing a vector search. - Defaults to VectorDistanceMetric.SQUARED_EUCLIDEAN. - sets (Optional[str], optional): The set used for the index. Defaults to None. - index_params (Optional[types.HnswParams], optional): - Parameters used for tuning vector search. Defaults to None. If index_params is None, then the default values specified for - types.HnswParams will be used. - index_meta_data (Optional[dict[str, str]], optional): Meta data associated with the index. Defaults to None. + Defaults to :class:`VectorDistanceMetric.SQUARED_EUCLIDEAN`. + :type dimensions: Optional[types.VectorDistanceMetric] + + :param sets: The set used for the index. Defaults to None. + :type dimensions: Optional[str] + + :param index_params: (Optional[types.HnswParams], optional): Parameters used for tuning + vector search. Defaults to None. If index_params is None, then the default values + specified for :class:`types.HnswParams` will be used. + :type dimensions: Optional[types.HnswParams] + + :param index_labels: Meta data associated with the index. Defaults to None. + :type dimensions: Optional[dict[str, str]] + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. Note: @@ -99,10 +134,9 @@ async def index_create( It waits for up to 100,000 seconds for the index creation to complete. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (index_stub, index_create_request) = self._prepare_index_create( + (index_stub, index_create_request, kwargs) = self._prepare_index_create( namespace, name, vector_field, @@ -110,20 +144,16 @@ async def index_create( vector_distance_metric, sets, index_params, - index_meta_data, + index_labels, index_storage, timeout, logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await index_stub.Create( index_create_request, - credentials=self._channel_provider._token, + credentials=self._channel_provider.get_token(), **kwargs, ) except grpc.RpcError as e: @@ -143,32 +173,34 @@ async def index_drop( """ Drop an index. - Args: - namespace (str): The namespace of the index. - name (str): The name of the index. + :param namespace: The namespace of the index. + :type name: str + + :param name: The name of the index. + :type name: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to drop the index.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. Note: This method drops an index with the specified parameters and waits for the index deletion to complete. It waits for up to 100,000 seconds for the index deletion to complete. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (index_stub, index_drop_request) = self._prepare_index_drop( + (index_stub, index_drop_request, kwargs) = self._prepare_index_drop( namespace, name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await index_stub.Drop( - index_drop_request, credentials=self._channel_provider._token, **kwargs + index_drop_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to drop index with error: %s", e) @@ -185,25 +217,26 @@ async def index_list(self, timeout: Optional[int] = None) -> list[dict]: """ List all indices. - Returns: - list[dict]: A list of indices. + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Returns: list[dict]: A list of indices. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to list the index.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (index_stub, index_list_request) = self._prepare_index_list(timeout, logger) - - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout + (index_stub, index_list_request, kwargs) = self._prepare_index_list( + timeout, logger + ) try: response = await index_stub.List( - index_list_request, credentials=self._channel_provider._token, **kwargs + index_list_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to list indexes with error: %s", e) @@ -216,32 +249,33 @@ async def index_get( """ Retrieve the information related with an index. - Args: - namespace (str): The namespace of the index. - name (str): The name of the index. + :param namespace: The namespace of the index. + :type name: str - Returns: - dict[str, Union[int, str]: Information about an index. + :param name: The name of the index. + :type name: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Returns: dict[str, Union[int, str]: Information about an index. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to get the index.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (index_stub, index_get_request) = self._prepare_index_get( + (index_stub, index_get_request, kwargs) = self._prepare_index_get( namespace, name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = await index_stub.Get( - index_get_request, credentials=self._channel_provider._token, **kwargs + index_get_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to get index with error: %s", e) @@ -254,15 +288,19 @@ async def index_get_status( """ Retrieve the number of records queued to be merged into an index. - Args: - namespace (str): The namespace of the index. - name (str): The name of the index. + :param namespace: The namespace of the index. + :type name: str - Returns: - int: Records queued to be merged into an index. + :param name: The name of the index. + :type name: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Returns: int: Records queued to be merged into an index. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to get the index status. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. Note: @@ -271,21 +309,16 @@ async def index_get_status( Warning: This API is subject to change. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (index_stub, index_get_status_request) = self._prepare_index_get_status( + (index_stub, index_get_status_request, kwargs) = self._prepare_index_get_status( namespace, name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = await index_stub.GetStatus( index_get_status_request, - credentials=self._channel_provider._token, + credentials=self._channel_provider.get_token(), **kwargs, ) except grpc.RpcError as e: @@ -301,21 +334,39 @@ async def add_user( password: str, roles: list[str], timeout: Optional[int] = None, - ) -> int: - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + ) -> None: + """ + Add role-based access AVS User to the AVS Server. + + :param username: Username for the new user. + :type username: str + + :param password: Password for the new user. + :type password: str + + :param roles: Roles for the new user. + :type password: list[str] - (user_admin_stub, add_user_request) = self._prepare_add_user( + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to add a user. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + await self._channel_provider._is_ready() + + (user_admin_stub, add_user_request, kwargs) = self._prepare_add_user( username, password, roles, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await user_admin_stub.AddUser( - add_user_request, credentials=self._channel_provider._token, **kwargs + add_user_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to add user with error: %s", e) @@ -323,63 +374,103 @@ async def add_user( async def update_credentials( self, *, username: str, password: str, timeout: Optional[int] = None - ) -> int: - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + ) -> None: + """ + Update AVS User credentials. + + :param username: Username of the user to update. + :type username: str - (user_admin_stub, update_credentials_request) = ( + :param password: New password for the userr. + :type password: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to update a users credentials. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + await self._channel_provider._is_ready() + + (user_admin_stub, update_credentials_request, kwargs) = ( self._prepare_update_credentials(username, password, timeout, logger) ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await user_admin_stub.UpdateCredentials( update_credentials_request, - credentials=self._channel_provider._token, + credentials=self._channel_provider.get_token(), **kwargs, ) except grpc.RpcError as e: logger.error("Failed to update credentials with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def drop_user(self, *, username: str, timeout: Optional[int] = None) -> int: - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + async def drop_user(self, *, username: str, timeout: Optional[int] = None) -> None: + """ + Drops AVS User from the AVS Server. + + :param username: Username of the user to drop. + :type username: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + - (user_admin_stub, drop_user_request) = self._prepare_drop_user( + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to drop a user + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + await self._channel_provider._is_ready() + + (user_admin_stub, drop_user_request, kwargs) = self._prepare_drop_user( username, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await user_admin_stub.DropUser( - drop_user_request, credentials=self._channel_provider._token, **kwargs + drop_user_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to drop user with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def get_user(self, *, username: str, timeout: Optional[int] = None) -> int: - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + async def get_user( + self, *, username: str, timeout: Optional[int] = None + ) -> types.User: + """ + Retrieves AVS User information from the AVS Server + + :param username: Username of the user to be retrieved. + :type username: str + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + return: types.User: AVS User - (user_admin_stub, get_user_request) = self._prepare_get_user( + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to get a user. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + await self._channel_provider._is_ready() + + (user_admin_stub, get_user_request, kwargs) = self._prepare_get_user( username, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = await user_admin_stub.GetUser( - get_user_request, credentials=self._channel_provider._token, **kwargs + get_user_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to get user with error: %s", e) @@ -387,21 +478,31 @@ async def get_user(self, *, username: str, timeout: Optional[int] = None) -> int return self._respond_get_user(response) - async def list_users(self, timeout: Optional[int] = None) -> int: - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + async def list_users(self, timeout: Optional[int] = None) -> list[types.User]: + """ + List all users existing on the AVS Server. + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + return: list[types.User]: list of AVS Users - (user_admin_stub, list_users_request) = self._prepare_list_users( + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to list users. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + await self._channel_provider._is_ready() + + (user_admin_stub, list_users_request, kwargs) = self._prepare_list_users( timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = await user_admin_stub.ListUsers( - list_users_request, credentials=self._channel_provider._token, **kwargs + list_users_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to list user with error: %s", e) @@ -411,20 +512,34 @@ async def list_users(self, timeout: Optional[int] = None) -> int: async def grant_roles( self, *, username: str, roles: list[str], timeout: Optional[int] = None ) -> int: - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + """ + grant roles to existing AVS Users. + + :param username: Username of the user which will receive the roles. + :type username: str - (user_admin_stub, grant_roles_request) = self._prepare_grant_roles( + :param roles: Roles the specified user will recieved. + :type roles: list[str] + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to grant roles. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + await self._channel_provider._is_ready() + + (user_admin_stub, grant_roles_request, kwargs) = self._prepare_grant_roles( username, roles, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await user_admin_stub.GrantRoles( - grant_roles_request, credentials=self._channel_provider._token, **kwargs + grant_roles_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to grant roles with error: %s", e) @@ -433,21 +548,33 @@ async def grant_roles( async def revoke_roles( self, *, username: str, roles: list[str], timeout: Optional[int] = None ) -> int: - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + """ + grant roles to existing AVS Users. + + :param username: Username of the user undergoing role removal. + :type username: str + + :param roles: Roles the specified user will no longer maintain.. + :type roles: list[str] - (user_admin_stub, revoke_roles_request) = self._prepare_revoke_roles( + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to revoke roles. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + + """ + await self._channel_provider._is_ready() + + (user_admin_stub, revoke_roles_request, kwargs) = self._prepare_revoke_roles( username, roles, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await user_admin_stub.RevokeRoles( revoke_roles_request, - credentials=self._channel_provider._token, + credentials=self._channel_provider.get_token(), **kwargs, ) except grpc.RpcError as e: @@ -455,20 +582,29 @@ async def revoke_roles( raise types.AVSServerError(rpc_error=e) async def list_roles(self, timeout: Optional[int] = None) -> int: - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + """ + grant roles to existing AVS Users. - (user_admin_stub, list_roles_request) = self._prepare_list_roles( + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + returns: list[str]: Roles available in the AVS Server. + + Raises: + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to list roles. + This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + """ + await self._channel_provider._is_ready() + + (user_admin_stub, list_roles_request, kwargs) = self._prepare_list_roles( timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = await user_admin_stub.ListRoles( - list_roles_request, credentials=self._channel_provider._token, **kwargs + list_roles_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to list roles with error: %s", e) @@ -486,8 +622,7 @@ async def _wait_for_index_creation( """ Wait for the index to be created. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() (index_stub, wait_interval, start_time, _, _, index_creation_request) = ( self._prepare_wait_for_index_waiting(namespace, name, wait_interval) @@ -496,7 +631,8 @@ async def _wait_for_index_creation( self._check_timeout(start_time, timeout) try: await index_stub.GetStatus( - index_creation_request, credentials=self._channel_provider._token + index_creation_request, + credentials=self._channel_provider.get_token(), ) logger.debug("Index created succesfully") # Index has been created @@ -521,8 +657,7 @@ async def _wait_for_index_deletion( """ Wait for the index to be deleted. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() # Wait interval between polling (index_stub, wait_interval, start_time, _, _, index_deletion_request) = ( @@ -534,7 +669,8 @@ async def _wait_for_index_deletion( try: await index_stub.GetStatus( - index_deletion_request, credentials=self._channel_provider._token + index_deletion_request, + credentials=self._channel_provider.get_token(), ) # Wait for some more time. await asyncio.sleep(wait_interval) diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index eaadf0c4..6501d1d3 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -4,6 +4,7 @@ from typing import Any, Optional, Union import grpc +import numpy as np from .. import types from .internal import channel_provider @@ -19,6 +20,36 @@ class Client(BaseClient): This client specializes in performing database operations with vector data. Moreover, the client supports Hierarchical Navigable Small World (HNSW) vector searches, allowing users to find vectors similar to a given query vector within an index. + + :param seeds: Defines the Aerospike Database cluster nodes to which you want AVS to connect. AVS iterates through the seed nodes. After connecting to a node, AVS discovers all of the nodes in the cluster. + :type seeds: Union[types.HostPort, tuple[types.HostPort, ...]] + + :param listener_name: An external (NATed) address and port combination that differs from the actual address and port where AVS is listening. Clients can access AVS on a node using the advertised listener address and port. Defaults to None. + :type listener_name: Optional[str] + + :param is_loadbalancer: If true, the first seed address will be treated as a load balancer node. Defaults to False. + :type is_loadbalancer: Optional[bool] + + :param service_config_path: Path to the service configuration file. Defaults to None. + :type service_config_path: Optional[str] + + :param username: Username for Role-Based Access. Defaults to None. + :type username: Optional[str] + + :param password: Password for Role-Based Access. Defaults to None. + :type password: Optional[str] + + :param root_certificate: The PEM-encoded root certificates as a byte string. Defaults to None. + :type root_certificate: Optional[list[bytes], bytes] + + :param certificate_chain: The PEM-encoded private key as a byte string. Defaults to None. + :type certificate_chain: Optional[bytes] + + :param private_key: The PEM-encoded certificate chain as a byte string. Defaults to None. + :type private_key: Optional[bytes] + + :raises AVSClientError: Raised when no seed host is provided. + """ def __init__( @@ -29,25 +60,11 @@ def __init__( is_loadbalancer: Optional[bool] = False, username: Optional[str] = None, password: Optional[str] = None, - root_certificate: Optional[str] = None, + root_certificate: Optional[Union[list[str], str]] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, service_config_path: Optional[str] = None, ) -> None: - """ - Initialize the Aerospike Vector Search Vector Client. - - Args: - seeds (Union[types.HostPort, tuple[types.HostPort, ...]]): - Used to create appropriate gRPC channels for interacting with Aerospike Vector Search. - listener_name (Optional[str], optional): - Advertised listener for the client. Defaults to None. - is_loadbalancer (bool, optional): - If true, the first seed address will be treated as a load balancer node. - - Raises: - Exception: Raised when no seed host is provided. - """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( @@ -66,7 +83,7 @@ async def insert( self, *, namespace: str, - key: Union[int, str, bytes, bytearray], + key: Union[int, str, bytes, bytearray, np.generic, np.ndarray], record_data: dict[str, Any], set_name: Optional[str] = None, ignore_mem_queue_full: Optional[bool] = False, @@ -78,22 +95,27 @@ async def insert( If record does exist, an exception is raised. If record doesn't exist, the record is inserted. - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - record_data (dict[str, Any]): The data to be stored in the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param record_data: The data to be stored in the record. + :type record_data: dict[str, Any] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: Optional[str] Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to insert a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (transact_stub, insert_request) = self._prepare_insert( + (transact_stub, insert_request, kwargs) = self._prepare_insert( namespace, key, record_data, @@ -103,13 +125,9 @@ async def insert( logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await transact_stub.Put( - insert_request, credentials=self._channel_provider._token, **kwargs + insert_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to insert vector with error: %s", e) @@ -119,7 +137,7 @@ async def update( self, *, namespace: str, - key: Union[int, str, bytes, bytearray], + key: Union[int, str, bytes, bytearray, np.generic, np.ndarray], record_data: dict[str, Any], set_name: Optional[str] = None, ignore_mem_queue_full: Optional[bool] = False, @@ -131,22 +149,27 @@ async def update( If record does exist, update the record. If record doesn't exist, an exception is raised. - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - record_data (dict[str, Any]): The data to be stored in the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param record_data: The data to be stored in the record. + :type record_data: dict[str, Any] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: Optional[str] Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to update a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (transact_stub, update_request) = self._prepare_update( + (transact_stub, update_request, kwargs) = self._prepare_update( namespace, key, record_data, @@ -156,13 +179,9 @@ async def update( logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await transact_stub.Put( - update_request, credentials=self._channel_provider._token, **kwargs + update_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to update vector with error: %s", e) @@ -172,7 +191,7 @@ async def upsert( self, *, namespace: str, - key: Union[int, str, bytes, bytearray], + key: Union[int, str, bytes, bytearray, np.generic, np.ndarray], record_data: dict[str, Any], set_name: Optional[str] = None, ignore_mem_queue_full: Optional[bool] = False, @@ -184,22 +203,27 @@ async def upsert( If record does exist, update the record. If record doesn't exist, the record is inserted. - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - record_data (dict[str, Any]): The data to be stored in the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param record_data: The data to be stored in the record. + :type record_data: dict[str, Any] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: Optional[str] Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to upsert a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (transact_stub, upsert_request) = self._prepare_upsert( + (transact_stub, upsert_request, kwargs) = self._prepare_upsert( namespace, key, record_data, @@ -209,13 +233,9 @@ async def upsert( logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await transact_stub.Put( - upsert_request, credentials=self._channel_provider._token, **kwargs + upsert_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to upsert vector with error: %s", e) @@ -225,7 +245,7 @@ async def get( self, *, namespace: str, - key: Union[int, str, bytes, bytearray], + key: Union[int, str, bytes, bytearray, np.generic, np.ndarray], field_names: Optional[list[str]] = None, set_name: Optional[str] = None, timeout: Optional[int] = None, @@ -233,35 +253,38 @@ async def get( """ Read a record from Aerospike Vector Search. - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - field_names (Optional[list[str]], optional): A list of field names to retrieve from the record. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param field_names: A list of field names to retrieve from the record. If None, all fields are retrieved. Defaults to None. - set_name (Optional[str], optional): The name of the set from which to read the record. Defaults to None. + :type field_names: Optional[list[str]] + + :param set_name: The name of the set from which to read the record. Defaults to None. + :type set_name: Optional[str] + Returns: types.RecordWithKey: A record with its associated key. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to get a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. + """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (transact_stub, key, get_request) = self._prepare_get( + (transact_stub, key, get_request, kwargs) = self._prepare_get( namespace, key, field_names, set_name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = await transact_stub.Get( - get_request, credentials=self._channel_provider._token, **kwargs + get_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to get vector with error: %s", e) @@ -280,33 +303,32 @@ async def exists( """ Check if a record exists in Aerospike Vector Search. - Args: - namespace (str): The namespace for the record. - key (Any): The key for the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: str Returns: bool: True if the record exists, False otherwise. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to see if a given vector exists.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (transact_stub, exists_request) = self._prepare_exists( + (transact_stub, exists_request, kwargs) = self._prepare_exists( namespace, key, set_name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = await transact_stub.Exists( - exists_request, credentials=self._channel_provider._token, **kwargs + exists_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to verfiy vector existence with error: %s", e) @@ -325,30 +347,31 @@ async def delete( """ Delete a record from Aerospike Vector Search. - Args: - namespace (str): The namespace for the record. - key (Any): The key for the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: Optional[str] + Raises: grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (transact_stub, delete_request) = self._prepare_delete( + (transact_stub, delete_request, kwargs) = self._prepare_delete( namespace, key, set_name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: await transact_stub.Delete( - delete_request, credentials=self._channel_provider._token, **kwargs + delete_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to delete vector with error: %s", e) @@ -358,7 +381,7 @@ async def is_indexed( self, *, namespace: str, - key: Union[int, str, bytes, bytearray], + key: Union[int, str, bytes, bytearray, np.generic, np.ndarray], index_name: str, index_namespace: Optional[str] = None, set_name: Optional[str] = None, @@ -367,13 +390,20 @@ async def is_indexed( """ Check if a record is indexed in the Vector DB. - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - index_name (str): The name of the index. - index_namespace (Optional[str], optional): The namespace of the index. - If None, defaults to the namespace of the record. Defaults to None. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :params namespace: The namespace for the record. + :type namespace: str + + :params key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :params index_name: The name of the index. + :type index_name: str + + :params index_namespace: The namespace of the index. If None, defaults to the namespace of the record. Defaults to None. + :type index_namespace: optional[str] + + :params set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: optional[str] Returns: bool: True if the record is indexed, False otherwise. @@ -383,20 +413,17 @@ async def is_indexed( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (transact_stub, is_indexed_request) = self._prepare_is_indexed( + (transact_stub, is_indexed_request, kwargs) = self._prepare_is_indexed( namespace, key, index_name, index_namespace, set_name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = await transact_stub.IsIndexed( - is_indexed_request, credentials=self._channel_provider._token, **kwargs + is_indexed_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to verify vector indexing status with error: %s", e) @@ -417,15 +444,26 @@ async def vector_search( """ Perform a Hierarchical Navigable Small World (HNSW) vector search in Aerospike Vector Search. - Args: - namespace (str): The namespace for the records. - index_name (str): The name of the index. - query (list[Union[bool, float]]): The query vector for the search. - limit (int): The maximum number of neighbors to return. K value. - search_params (Optional[types_pb2.HnswSearchParams], optional): Parameters for the HNSW algorithm. + :params namespace: The namespace for the records. + :type namespace: str + + :params index_name: The name of the index. + :type index_name: str + + :params query: The query vector for the search. + :type query: list[Union[bool, float]] + + :params limit: The maximum number of neighbors to return. K value. + :type limit: int + + :params search_params: Parameters for the HNSW algorithm. If None, the default parameters for the index are used. Defaults to None. - field_names (Optional[list[str]], optional): A list of field names to retrieve from the results. + :type search_params: Optional[types_pb2.HnswSearchParams] + + :params field_names: A list of field names to retrieve from the results. If None, all fields are retrieved. Defaults to None. + :type field_names: Optional[list[str]] + Returns: list[types.Neighbor]: A list of neighbors records found by the search. @@ -434,10 +472,9 @@ async def vector_search( grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() - (transact_stub, vector_search_request) = self._prepare_vector_search( + (transact_stub, vector_search_request, kwargs) = self._prepare_vector_search( namespace, index_name, query, @@ -448,16 +485,12 @@ async def vector_search( logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: return [ self._respond_neighbor(result) async for result in transact_stub.VectorSearch( vector_search_request, - credentials=self._channel_provider._token, + credentials=self._channel_provider.get_token(), **kwargs, ) ] @@ -477,13 +510,19 @@ async def wait_for_index_completion( """ Wait for the index to have no pending index update operations. - Args: - namespace (str): The namespace of the index. - name (str): The name of the index. - timeout (int, optional): The maximum time (in seconds) to wait for the index to complete. + :param namespace (str): The namespace of the index. + :type namespace: str + + :param name (str): The name of the index. + :type name: str + + :param timeout (int, optional): The maximum time (in seconds) to wait for the index to complete. Defaults to sys.maxsize. - wait_interval (int, optional): The time (in seconds) to wait between index completion status request to the server. + :type timeout: int + + :param wait_interval: The time (in seconds) to wait between index completion status request to the server. Lowering this value increases the chance that the index completion status is incorrect, which can result in poor search accuracy. + :type wait_interval: int Raises: Exception: Raised when the timeout occurs while waiting for index completion. @@ -494,8 +533,7 @@ async def wait_for_index_completion( The function polls the index status with a wait interval of 10 seconds until either the timeout is reached or the index has no pending index update operations. """ - if not self._channel_provider.client_server_compatible: - await self._channel_provider._is_ready() + await self._channel_provider._is_ready() # Wait interval between polling ( @@ -509,7 +547,8 @@ async def wait_for_index_completion( while True: try: index_status = await index_stub.GetStatus( - index_completion_request, credentials=self._channel_provider._token + index_completion_request, + credentials=self._channel_provider.get_token(), ) except grpc.RpcError as e: diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 6f97f2c4..2dab121e 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -29,7 +29,7 @@ def __init__( is_loadbalancer: Optional[bool] = False, username: Optional[str] = None, password: Optional[str] = None, - root_certificate: Optional[str] = None, + root_certificate: Optional[Union[list[str], str]] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, service_config_path: Optional[str] = None, @@ -68,13 +68,14 @@ async def close(self): await self._task async def _is_ready(self): - await self._tend_initalized.wait() - if not self.client_server_compatible: - raise types.AVSClientError( - message="This AVS Client version is only compatbile with AVS Servers above the following version number: " - + self.minimum_required_version - ) + await self._tend_initalized.wait() + + if not self.client_server_compatible: + raise types.AVSClientError( + message="This AVS Client version is only compatbile with AVS Servers above the following version number: " + + self.minimum_required_version + ) async def _tend(self): try: @@ -161,7 +162,8 @@ async def _tend(self): tasks.append(channel_endpoints.channel.close()) except Exception as e: logger.debug( - "While tending, failed to close GRPC channel while replacing up old endpoints: " + str(e) + "While tending, failed to close GRPC channel while replacing up old endpoints: " + + str(e) ) self.add_new_channel_to_node_channels(node, newEndpoints) @@ -174,21 +176,21 @@ async def _tend(self): except Exception as e: logger.debug( - "While tending, failed to close GRPC channel while removing unused endpoints: " + str(e) + "While tending, failed to close GRPC channel while removing unused endpoints: " + + str(e) ) await asyncio.gather(*tasks) if not self.client_server_compatible: - stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) - about_request = vector_db_pb2.AboutRequest() + (stub, about_request) = self._prepare_about() self.current_server_version = ( await stub.Get(about_request, credentials=self._token) ).version - self.client_server_compatible = self.verify_compatibile_server() + self.client_server_compatible = self.verify_compatibile_server() self._tend_initalized.set() # TODO: check tend interval. @@ -198,8 +200,6 @@ async def _tend(self): logger.error("Tending failed at unindentified location: %s", e) raise e - - def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: host = re.sub(r"%.*", "", host) @@ -210,25 +210,11 @@ def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: options = None if self._root_certificate: - with open(self._root_certificate, "rb") as f: - root_certificate = f.read() - - if self._private_key: - with open(self._private_key, "rb") as f: - private_key = f.read() - else: - private_key = None - - if self._certificate_chain: - with open(self._certificate_chain, "rb") as f: - certificate_chain = f.read() - else: - certificate_chain = None ssl_credentials = grpc.ssl_channel_credentials( - root_certificates=root_certificate, - certificate_chain=certificate_chain, - private_key=private_key, + root_certificates=self._root_certificate, + certificate_chain=self._certificate_chain, + private_key=self._private_key, ) return grpc.aio.secure_channel( @@ -248,7 +234,7 @@ async def _update_token_and_ttl( try: response = await auth_stub.Authenticate(auth_request) except grpc.RpcError as e: - print("Failed to refresh authentication token with error: %s", e) + logger.error("Failed to refresh authentication token with error: %s", e) raise types.AVSServerError(rpc_error=e) self._respond_authenticate(response.token) diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index fc68606e..42cceb10 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -19,6 +19,36 @@ class Client(BaseClient): This client specializes in performing database operations with vector data. Moreover, the client supports Hierarchical Navigable Small World (HNSW) vector searches, allowing users to find vectors similar to a given query vector within an index. + + :param seeds: Defines the Aerospike Database cluster nodes to which you want AVS to connect. AVS iterates through the seed nodes. After connecting to a node, AVS discovers all of the nodes in the cluster. + :type seeds: Union[types.HostPort, tuple[types.HostPort, ...]] + + :param listener_name: An external (NATed) address and port combination that differs from the actual address and port where AVS is listening. Clients can access AVS on a node using the advertised listener address and port. Defaults to None. + :type listener_name: Optional[str] + + :param is_loadbalancer: If true, the first seed address will be treated as a load balancer node. Defaults to False. + :type is_loadbalancer: Optional[bool] + + :param service_config_path: Path to the service configuration file. Defaults to None. + :type service_config_path: Optional[str] + + :param username: Username for Role-Based Access. Defaults to None. + :type username: Optional[str] + + :param password: Password for Role-Based Access. Defaults to None. + :type password: Optional[str] + + :param root_certificate: The PEM-encoded root certificates as a byte string. Defaults to None. + :type root_certificate: Optional[list[bytes], bytes] + + :param certificate_chain: The PEM-encoded private key as a byte string. Defaults to None. + :type certificate_chain: Optional[bytes] + + :param private_key: The PEM-encoded certificate chain as a byte string. Defaults to None. + :type private_key: Optional[bytes] + + :raises AVSClientError: Raised when no seed host is provided. + """ def __init__( @@ -29,25 +59,12 @@ def __init__( is_loadbalancer: Optional[bool] = False, username: Optional[str] = None, password: Optional[str] = None, - root_certificate: Optional[str] = None, + root_certificate: Optional[Union[list[str], str]] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, service_config_path: Optional[str] = None, ) -> None: - """ - Initialize the Aerospike Vector Search Vector Client. - Args: - seeds (Union[types.HostPort, tuple[types.HostPort, ...]]): - Used to create appropriate gRPC channels for interacting with Aerospike Vector Search. - listener_name (Optional[str], optional): - Advertised listener for the client. Defaults to None. - is_loadbalancer (bool, optional): - If true, the first seed address will be treated as a load balancer node. - - Raises: - Exception: Raised when no seed host is provided. - """ seeds = self._prepare_seeds(seeds) self._channel_provider = channel_provider.ChannelProvider( seeds, @@ -77,19 +94,25 @@ def insert( If record does exist, an exception is raised. If record doesn't exist, the record is inserted. - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - record_data (dict[str, Any]): The data to be stored in the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param record_data: The data to be stored in the record. + :type record_data: dict[str, Any] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: Optional[str] Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to insert a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (transact_stub, insert_request) = self._prepare_insert( + (transact_stub, insert_request, kwargs) = self._prepare_insert( namespace, key, record_data, @@ -99,13 +122,9 @@ def insert( logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: transact_stub.Put( - insert_request, credentials=self._channel_provider._token, **kwargs + insert_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to insert vector with error: %s", e) @@ -124,21 +143,24 @@ def update( """ Update a record in Aerospike Vector Search. - If record does exist, update the record. - If record doesn't exist, an exception is raised. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - record_data (dict[str, Any]): The data to be stored in the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :param record_data: The data to be stored in the record. + :type record_data: dict[str, Any] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: Optional[str] Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to update a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (transact_stub, update_request) = self._prepare_update( + (transact_stub, update_request, kwargs) = self._prepare_update( namespace, key, record_data, @@ -148,13 +170,9 @@ def update( logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: transact_stub.Put( - update_request, credentials=self._channel_provider._token, **kwargs + update_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to update vector with error: %s", e) @@ -176,19 +194,25 @@ def upsert( If record does exist, update the record. If record doesn't exist, the record is inserted. - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - record_data (dict[str, Any]): The data to be stored in the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param record_data: The data to be stored in the record. + :type record_data: dict[str, Any] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: Optional[str] Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to upsert a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (transact_stub, upsert_request) = self._prepare_upsert( + (transact_stub, upsert_request, kwargs) = self._prepare_upsert( namespace, key, record_data, @@ -198,13 +222,9 @@ def upsert( logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: transact_stub.Put( - upsert_request, credentials=self._channel_provider._token, **kwargs + upsert_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to upsert vector with error: %s", e) @@ -222,32 +242,36 @@ def get( """ Read a record from Aerospike Vector Search. - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - field_names (Optional[list[str]], optional): A list of field names to retrieve from the record. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + + :param field_names: A list of field names to retrieve from the record. If None, all fields are retrieved. Defaults to None. - set_name (Optional[str], optional): The name of the set from which to read the record. Defaults to None. + :type field_names: Optional[list[str]] + + :param set_name: The name of the set from which to read the record. Defaults to None. + :type set_name: Optional[str] + Returns: types.RecordWithKey: A record with its associated key. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to get a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (transact_stub, key, get_request) = self._prepare_get( + (transact_stub, key, get_request, kwargs) = self._prepare_get( namespace, key, field_names, set_name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = transact_stub.Get( - get_request, credentials=self._channel_provider._token, **kwargs + get_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to get vector with error: %s", e) @@ -266,30 +290,30 @@ def exists( """ Check if a record exists in Aerospike Vector Search. - Args: - namespace (str): The namespace for the record. - key (Any): The key for the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: str Returns: bool: True if the record exists, False otherwise. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to see if a given vector exists.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (transact_stub, exists_request) = self._prepare_exists( + (transact_stub, exists_request, kwargs) = self._prepare_exists( namespace, key, set_name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = transact_stub.Exists( - exists_request, credentials=self._channel_provider._token, **kwargs + exists_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to verfiy vector existence with error: %s", e) @@ -308,27 +332,28 @@ def delete( """ Delete a record from Aerospike Vector Search. - Args: - namespace (str): The namespace for the record. - key (Any): The key for the record. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :param namespace: The namespace for the record. + :type namespace: str + + :param key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :param set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: Optional[str] + Raises: grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (transact_stub, delete_request) = self._prepare_delete( + (transact_stub, delete_request, kwargs) = self._prepare_delete( namespace, key, set_name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: transact_stub.Delete( - delete_request, credentials=self._channel_provider._token, **kwargs + delete_request, credentials=self._channel_provider.get_token(), **kwargs ) except grpc.RpcError as e: logger.error("Failed to delete vector with error: %s", e) @@ -347,13 +372,20 @@ def is_indexed( """ Check if a record is indexed in the Vector DB. - Args: - namespace (str): The namespace for the record. - key (Union[int, str, bytes, bytearray]): The key for the record. - index_name (str): The name of the index. - index_namespace (Optional[str], optional): The namespace of the index. - If None, defaults to the namespace of the record. Defaults to None. - set_name (Optional[str], optional): The name of the set to which the record belongs. Defaults to None. + :params namespace: The namespace for the record. + :type namespace: str + + :params key: The key for the record. + :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] + + :params index_name: The name of the index. + :type index_name: str + + :params index_namespace: The namespace of the index. If None, defaults to the namespace of the record. Defaults to None. + :type index_namespace: optional[str] + + :params set_name: The name of the set to which the record belongs. Defaults to None. + :type set_name: optional[str] Returns: bool: True if the record is indexed, False otherwise. @@ -363,17 +395,15 @@ def is_indexed( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (transact_stub, is_indexed_request) = self._prepare_is_indexed( + (transact_stub, is_indexed_request, kwargs) = self._prepare_is_indexed( namespace, key, index_name, index_namespace, set_name, timeout, logger ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: response = transact_stub.IsIndexed( - is_indexed_request, credentials=self._channel_provider._token, **kwargs + is_indexed_request, + credentials=self._channel_provider.get_token(), + **kwargs, ) except grpc.RpcError as e: logger.error("Failed to verify vector indexing status with error: %s", e) @@ -394,15 +424,26 @@ def vector_search( """ Perform a Hierarchical Navigable Small World (HNSW) vector search in Aerospike Vector Search. - Args: - namespace (str): The namespace for the records. - index_name (str): The name of the index. - query (list[Union[bool, float]]): The query vector for the search. - limit (int): The maximum number of neighbors to return. K value. - search_params (Optional[types_pb2.HnswSearchParams], optional): Parameters for the HNSW algorithm. + :params namespace: The namespace for the records. + :type namespace: str + + :params index_name: The name of the index. + :type index_name: str + + :params query: The query vector for the search. + :type query: list[Union[bool, float]] + + :params limit: The maximum number of neighbors to return. K value. + :type limit: int + + :params search_params: Parameters for the HNSW algorithm. If None, the default parameters for the index are used. Defaults to None. - field_names (Optional[list[str]], optional): A list of field names to retrieve from the results. + :type search_params: Optional[types_pb2.HnswSearchParams] + + :params field_names: A list of field names to retrieve from the results. If None, all fields are retrieved. Defaults to None. + :type field_names: Optional[list[str]] + Returns: list[types.Neighbor]: A list of neighbors records found by the search. @@ -412,7 +453,7 @@ def vector_search( This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ - (transact_stub, vector_search_request) = self._prepare_vector_search( + (transact_stub, vector_search_request, kwargs) = self._prepare_vector_search( namespace, index_name, query, @@ -423,16 +464,12 @@ def vector_search( logger, ) - kwargs = {} - if timeout is not None: - kwargs["timeout"] = timeout - try: return [ self._respond_neighbor(result) for result in transact_stub.VectorSearch( vector_search_request, - credentials=self._channel_provider._token, + credentials=self._channel_provider.get_token(), **kwargs, ) ] @@ -452,13 +489,19 @@ def wait_for_index_completion( """ Wait for the index to have no pending index update operations. - Args: - namespace (str): The namespace of the index. - name (str): The name of the index. - timeout (int, optional): The maximum time (in seconds) to wait for the index to complete. + :param namespace (str): The namespace of the index. + :type namespace: str + + :param name (str): The name of the index. + :type name: str + + :param timeout (int, optional): The maximum time (in seconds) to wait for the index to complete. Defaults to sys.maxsize. - wait_interval (int, optional): The time (in seconds) to wait between index completion status request to the server. + :type timeout: int + + :param wait_interval: The time (in seconds) to wait between index completion status request to the server. Lowering this value increases the chance that the index completion status is incorrect, which can result in poor search accuracy. + :type wait_interval: int Raises: Exception: Raised when the timeout occurs while waiting for index completion. @@ -469,8 +512,6 @@ def wait_for_index_completion( The function polls the index status with a wait interval of 10 seconds until either the timeout is reached or the index has no pending index update operations. """ - - # Wait interval between polling ( index_stub, wait_interval, @@ -483,7 +524,8 @@ def wait_for_index_completion( while True: try: index_status = index_stub.GetStatus( - index_completion_request, credentials=self._channel_provider._token + index_completion_request, + credentials=self._channel_provider.get_token(), ) except grpc.RpcError as e: diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index 76454b69..0b240a5d 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -27,7 +27,7 @@ def __init__( is_loadbalancer: Optional[bool] = False, username: Optional[str] = None, password: Optional[str] = None, - root_certificate: Optional[str] = None, + root_certificate: Optional[Union[list[str], str]] = None, certificate_chain: Optional[str] = None, private_key: Optional[str] = None, service_config_path: Optional[str] = None, @@ -63,7 +63,9 @@ def close(self): def _tend(self): try: - (temp_endpoints, update_endpoints_stub, channels, end_tend) = self.init_tend() + (temp_endpoints, update_endpoints_stub, channels, end_tend) = ( + self.init_tend() + ) if self._token: if self._check_if_token_refresh_needed(): self._update_token_and_ttl() @@ -118,10 +120,13 @@ def _tend(self): try: response = stub.GetClusterEndpoints( vector_db_pb2.ClusterNodeEndpointsRequest( - listenerName=self.listener_name, credentials=self._credentials + listenerName=self.listener_name, + credentials=self._credentials, ) ) - temp_endpoints = self.update_temp_endpoints(response, temp_endpoints) + temp_endpoints = self.update_temp_endpoints( + response, temp_endpoints + ) except Exception as e: logger.debug( "While tending, failed to get cluster endpoints with error: " @@ -140,7 +145,8 @@ def _tend(self): channel_endpoints.channel.close() except Exception as e: logger.debug( - "While tending, failed to close GRPC channel while replacing up old endpoints:" + str(e) + "While tending, failed to close GRPC channel while replacing up old endpoints:" + + str(e) ) self.add_new_channel_to_node_channels(node, newEndpoints) @@ -154,20 +160,22 @@ def _tend(self): except Exception as e: logger.debug( - "While tending, failed to close GRPC channel while removing unused endpoints: " + str(e) + "While tending, failed to close GRPC channel while removing unused endpoints: " + + str(e) ) if not self.client_server_compatible: - stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) - about_request = vector_db_pb2.AboutRequest() + (stub, about_request) = self._prepare_about() + try: self.current_server_version = stub.Get( about_request, credentials=self._token ).version except Exception as e: logger.debug( - "While tending, failed to close GRPC channel while removing unused endpoints: " + str(e) + "While tending, failed to close GRPC channel while removing unused endpoints: " + + str(e) ) self.client_server_compatible = self.verify_compatibile_server() if not self.client_server_compatible: @@ -191,25 +199,11 @@ def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: options = None if self._root_certificate: - with open(self._root_certificate, "rb") as f: - root_certificate = f.read() - - if self._private_key: - with open(self._private_key, "rb") as f: - private_key = f.read() - else: - private_key = None - - if self._certificate_chain: - with open(self._certificate_chain, "rb") as f: - certificate_chain = f.read() - else: - certificate_chain = None ssl_credentials = grpc.ssl_channel_credentials( - root_certificates=root_certificate, - certificate_chain=certificate_chain, - private_key=private_key, + root_certificates=self._root_certificate, + certificate_chain=self._certificate_chain, + private_key=self._private_key, ) return grpc.secure_channel( @@ -230,7 +224,7 @@ def _update_token_and_ttl( try: response = auth_stub.Authenticate(auth_request) except grpc.RpcError as e: - print("Failed to refresh authentication token with error: %s", e) + logger.error("Failed to refresh authentication token with error: %s", e) raise types.AVSServerError(rpc_error=e) self._respond_authenticate(response.token) diff --git a/src/aerospike_vector_search/shared/admin_helpers.py b/src/aerospike_vector_search/shared/admin_helpers.py index 32fcdc4b..fe00e42b 100644 --- a/src/aerospike_vector_search/shared/admin_helpers.py +++ b/src/aerospike_vector_search/shared/admin_helpers.py @@ -31,7 +31,7 @@ def _prepare_index_create( vector_distance_metric, sets, index_params, - index_meta_data, + index_labels, index_storage, timeout, logger, @@ -39,7 +39,7 @@ def _prepare_index_create( logger.debug( "Creating index: namespace=%s, name=%s, vector_field=%s, dimensions=%d, vector_distance_metric=%s, " - "sets=%s, index_params=%s, index_meta_data=%s, index_storage=%s, timeout=%s", + "sets=%s, index_params=%s, index_labels=%s, index_storage=%s, timeout=%s", namespace, name, vector_field, @@ -47,11 +47,15 @@ def _prepare_index_create( vector_distance_metric, sets, index_params, - index_meta_data, + index_labels, index_storage, timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + if sets and not sets.strip(): sets = None if index_params != None: @@ -71,10 +75,10 @@ def _prepare_index_create( hnswParams=index_params, field=vector_field, dimensions=dimensions, - labels=index_meta_data, + labels=index_labels, storage=index_storage, ) - return (index_stub, index_create_request) + return (index_stub, index_create_request, kwargs) def _prepare_index_drop(self, namespace, name, timeout, logger) -> None: @@ -85,19 +89,27 @@ def _prepare_index_drop(self, namespace, name, timeout, logger) -> None: timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + index_stub = self._get_index_stub() index_drop_request = self._get_index_id(namespace, name) - return (index_stub, index_drop_request) + return (index_stub, index_drop_request, kwargs) def _prepare_index_list(self, timeout, logger) -> None: logger.debug("Getting index list: timeout=%s", timeout) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + index_stub = self._get_index_stub() index_list_request = empty - return (index_stub, index_list_request) + return (index_stub, index_list_request, kwargs) def _prepare_index_get(self, namespace, name, timeout, logger) -> None: @@ -108,10 +120,14 @@ def _prepare_index_get(self, namespace, name, timeout, logger) -> None: timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + index_stub = self._get_index_stub() index_get_request = self._get_index_id(namespace, name) - return (index_stub, index_get_request) + return (index_stub, index_get_request, kwargs) def _prepare_index_get_status(self, namespace, name, timeout, logger) -> None: @@ -122,10 +138,14 @@ def _prepare_index_get_status(self, namespace, name, timeout, logger) -> None: timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + index_stub = self._get_index_stub() index_get_status_request = self._get_index_id(namespace, name) - return (index_stub, index_get_status_request) + return (index_stub, index_get_status_request, kwargs) def _prepare_add_user(self, username, password, roles, timeout, logger) -> None: logger.debug( @@ -136,13 +156,17 @@ def _prepare_add_user(self, username, password, roles, timeout, logger) -> None: timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + user_admin_stub = self._get_user_admin_stub() credentials = helpers._get_credentials(username, password) add_user_request = user_admin_pb2.AddUserRequest( credentials=credentials, roles=roles ) - return (user_admin_stub, add_user_request) + return (user_admin_stub, add_user_request, kwargs) def _prepare_update_credentials(self, username, password, timeout, logger) -> None: logger.debug( @@ -152,37 +176,53 @@ def _prepare_update_credentials(self, username, password, timeout, logger) -> No timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + user_admin_stub = self._get_user_admin_stub() credentials = helpers._get_credentials(username, password) update_user_request = user_admin_pb2.UpdateCredentialsRequest( credentials=credentials ) - return (user_admin_stub, update_user_request) + return (user_admin_stub, update_user_request, kwargs) def _prepare_drop_user(self, username, timeout, logger) -> None: logger.debug("Getting index status: username=%s, timeout=%s", username, timeout) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + user_admin_stub = self._get_user_admin_stub() drop_user_request = user_admin_pb2.DropUserRequest(username=username) - return (user_admin_stub, drop_user_request) + return (user_admin_stub, drop_user_request, kwargs) def _prepare_get_user(self, username, timeout, logger) -> None: logger.debug("Getting index status: username=%s, timeout=%s", username, timeout) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + user_admin_stub = self._get_user_admin_stub() get_user_request = user_admin_pb2.GetUserRequest(username=username) - return (user_admin_stub, get_user_request) + return (user_admin_stub, get_user_request, kwargs) def _prepare_list_users(self, timeout, logger) -> None: logger.debug("Getting index status") + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + user_admin_stub = self._get_user_admin_stub() list_users_request = empty - return (user_admin_stub, list_users_request) + return (user_admin_stub, list_users_request, kwargs) def _prepare_grant_roles(self, username, roles, timeout, logger) -> None: logger.debug( @@ -192,12 +232,16 @@ def _prepare_grant_roles(self, username, roles, timeout, logger) -> None: timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + user_admin_stub = self._get_user_admin_stub() grant_roles_request = user_admin_pb2.GrantRolesRequest( username=username, roles=roles ) - return (user_admin_stub, grant_roles_request) + return (user_admin_stub, grant_roles_request, kwargs) def _prepare_revoke_roles(self, username, roles, timeout, logger) -> None: logger.debug( @@ -207,20 +251,28 @@ def _prepare_revoke_roles(self, username, roles, timeout, logger) -> None: timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + user_admin_stub = self._get_user_admin_stub() revoke_roles_request = user_admin_pb2.RevokeRolesRequest( username=username, roles=roles ) - return (user_admin_stub, revoke_roles_request) + return (user_admin_stub, revoke_roles_request, kwargs) def _prepare_list_roles(self, timeout, logger) -> None: logger.debug("Getting index status: timeout=%s", timeout) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + user_admin_stub = self._get_user_admin_stub() list_roles_request = empty - return (user_admin_stub, list_roles_request) + return (user_admin_stub, list_roles_request, kwargs) def _respond_index_list(self, response) -> None: response_list = [] diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index 60943a11..ef3889dc 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -15,6 +15,7 @@ from .proto_generated import vector_db_pb2, auth_pb2 from .proto_generated import auth_pb2_grpc +from .proto_generated import vector_db_pb2_grpc logger = logging.getLogger(__name__) @@ -76,6 +77,14 @@ def __init__( self.minimum_required_version = "0.9.0" self.client_server_compatible = False + def get_token(self) -> grpc.access_token_call_credentials: + return self._token + + def _prepare_about(self) -> grpc.Channel: + stub = vector_db_pb2_grpc.AboutServiceStub(self.get_channel()) + about_request = vector_db_pb2.AboutRequest() + return (stub, about_request) + def get_channel(self) -> Union[grpc.aio.Channel, grpc.Channel]: if not self._is_loadbalancer: discovered_channels: list[ChannelAndEndpoints] = list( @@ -192,7 +201,7 @@ def _respond_authenticate(self, token): token, "", algorithms=["RS256"], options={"verify_signature": False} ) self._ttl = self._get_ttl(payload) - self._ttl_start = payload["exp"] + self._ttl_start = payload["iat"] self._token = grpc.access_token_call_credentials(token) diff --git a/src/aerospike_vector_search/shared/client_helpers.py b/src/aerospike_vector_search/shared/client_helpers.py index deac89d0..97db6c96 100644 --- a/src/aerospike_vector_search/shared/client_helpers.py +++ b/src/aerospike_vector_search/shared/client_helpers.py @@ -37,6 +37,10 @@ def _prepare_put( timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + key = self._get_key(namespace, set_name, key) field_list = [] @@ -61,7 +65,7 @@ def _prepare_put( ignoreMemQueueFull=ignore_mem_queue_full, ) - return (transact_stub, put_request) + return (transact_stub, put_request, kwargs) def _prepare_insert( self, @@ -139,13 +143,17 @@ def _prepare_get( timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + key = self._get_key(namespace, set_name, key) projection_spec = self._get_projection_spec(field_names=field_names) transact_stub = self._get_transact_stub() get_request = transact_pb2.GetRequest(key=key, projection=projection_spec) - return (transact_stub, key, get_request) + return (transact_stub, key, get_request, kwargs) def _prepare_exists(self, namespace, key, set_name, timeout, logger) -> None: @@ -157,12 +165,16 @@ def _prepare_exists(self, namespace, key, set_name, timeout, logger) -> None: timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + key = self._get_key(namespace, set_name, key) transact_stub = self._get_transact_stub() exists_request = transact_pb2.ExistsRequest(key=key) - return (transact_stub, exists_request) + return (transact_stub, exists_request, kwargs) def _prepare_delete(self, namespace, key, set_name, timeout, logger) -> None: @@ -174,17 +186,25 @@ def _prepare_delete(self, namespace, key, set_name, timeout, logger) -> None: timeout, ) + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + key = self._get_key(namespace, set_name, key) transact_stub = self._get_transact_stub() delete_request = transact_pb2.DeleteRequest(key=key) - return (transact_stub, delete_request) + return (transact_stub, delete_request, kwargs) def _prepare_is_indexed( self, namespace, key, index_name, index_namespace, set_name, timeout, logger ) -> None: + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + logger.debug( "Checking if index exists: namespace=%s, key=%s, index_name=%s, index_namespace=%s, set_name=%s, timeout:%s", namespace, @@ -203,7 +223,7 @@ def _prepare_is_indexed( transact_stub = self._get_transact_stub() is_indexed_request = transact_pb2.IsIndexedRequest(key=key, indexId=index_id) - return (transact_stub, is_indexed_request) + return (transact_stub, is_indexed_request, kwargs) def _prepare_vector_search( self, @@ -217,6 +237,10 @@ def _prepare_vector_search( logger, ) -> None: + kwargs = {} + if timeout is not None: + kwargs["timeout"] = timeout + logger.debug( "Performing vector search: namespace=%s, index_name=%s, query=%s, limit=%s, search_params=%s, field_names=%s, timeout:%s", namespace, @@ -250,7 +274,7 @@ def _prepare_vector_search( projection=projection_spec, ) - return (transact_stub, vector_search_request) + return (transact_stub, vector_search_request, kwargs) def _get_transact_stub(self): return transact_pb2_grpc.TransactServiceStub( diff --git a/src/aerospike_vector_search/shared/helpers.py b/src/aerospike_vector_search/shared/helpers.py index 4b8b871e..65772284 100644 --- a/src/aerospike_vector_search/shared/helpers.py +++ b/src/aerospike_vector_search/shared/helpers.py @@ -7,7 +7,7 @@ def _prepare_seeds(seeds) -> None: if not seeds: - raise Exception("at least one seed host needed") + raise types.AVSClientError(message="at least one seed host needed") if isinstance(seeds, types.HostPort): seeds = (seeds,) diff --git a/src/aerospike_vector_search/types.py b/src/aerospike_vector_search/types.py index f4b0989b..92c0af76 100644 --- a/src/aerospike_vector_search/types.py +++ b/src/aerospike_vector_search/types.py @@ -143,8 +143,7 @@ class VectorDistanceMetric(enum.Enum): class User(object): """ - - PLACEHOLDER FOR TEXT + Representation Args: max_records (Optional[int], optional): Maximum number of records to fit in a batch. Defaults to 10000. interval (Optional[int], optional): The maximum amount of time in milliseconds to wait before finalizing a batch. Defaults to 10000. diff --git a/tests/assets/aerospike-proximus.yml b/tests/assets/aerospike-proximus.yml deleted file mode 100755 index 545f5ebe..00000000 --- a/tests/assets/aerospike-proximus.yml +++ /dev/null @@ -1,122 +0,0 @@ -# Change the configuration for your use case. -# See: https://aerospike.com/docs/vector - -cluster: - # Unique identifier for this cluster. - cluster-name: aerospike-vector-search - - # Custom node-id as 8 byte long in Hexadecimal format. - # It will be auto-generated if not specified. - # node-id: a1 - -# If TLS is desired, TLS configuration ids used -# and associated TLS configurations. -# -#tls: -# service-tls: -# trust-store: -# store-file: /etc/aerospike-vector-search/tls/$root_certificate_name.truststore.jks -# store-password-file: /etc/aerospike-vector-search/tls/storepass -# key-store: -# store-file: /etc/aerospike-vector-search/tls/$server_name.keystore.jks -# store-password-file: /etc/aerospike-vector-search/tls/storepass -# key-password-file: /etc/aerospike-vector-search/tls/keypass -# mutual-auth: true -# # Client certificate subject names that are allowed -# allowed-peer-names: -# - $client_name -# interconnect-tls: -# trust-store: -# store-file: tls/ca.aerospike.com.truststore.jks -# store-password-file: tls/storepass -# key-store: -# store-file: tls/proximus.aerospike.com.keystore.jks -# store-password-file: tls/storepass -# key-password-file: tls/keypass -# override-tls-hostname: proximus.aerospike.com -# -# aerospike-tls: -# trust-store: -# store-file: tls/ca.aerospike.com.truststore.jks -# store-password-file: tls/storepass -# key-store: -# store-file: tls/proximus.aerospike.com.keystore.jks -# store-password-file: tls/storepass -# key-password-file: tls/keypass -# override-tls-hostname: asd.aerospike.com - - -# The Proximus service listening ports, TLS and network interface. -service: - ports: - 5000: - addresses: - localhost - # If TLS needs to be enabled, tls configuration id. - #tls-id: service-tls - - # Required when running behind NAT - #advertised-listeners: - # default: - # # List of externally accessible addresses and - # # ports for this Proximus instance. - # - address: $server_name - # port: 5000 - -# Management API listening ports, TLS and network interface. -manage: - ports: - 5040: - addresses: - localhost - # If TLS needs to be enabled, tls configuration id. - #tls-id: service-tls - - -# Intra cluster interconnect listening ports, TLS and network interface. -interconnect: - # Interconnect client side TLS configuration - # when TLS is enabled for interconnect - # client-tls-id: interconnect-tls - ports: - 5001: - addresses: - localhost - # If interconnect TLS needs to be enabled. - #tls-id: interconnect-tls - -#heartbeat: -# # Seed nodes to discover and form a cluster. -# seeds: -# - address: localhost -# port: 6001 - -# To enable client authentication - -#security: -# auth-token: -# private-key: /etc/aerospike-vector-search/tls/jwt/private_key.pem -# public-key: /etc/aerospike-vector-search/tls/jwt/public_key.pem -# token-expiry: 300_000 - -# Target Aerospike cluster -aerospike: - seeds: - - localhost: - port: 3000 - - client-policy: - max-conns-per-node: 1000 - #tls-id: aerospike-tls - # - # Aerospike credentials if required. - #credentials: - # username: admin - # password-file: aerospike-password.txt - -# The logging properties. -#logging: -# #file: /var/log/aerospike-vector-search/aerospike-vector-search.log -# enable-console-logging: true -# levels: -# root: debug diff --git a/tests/assets/service_stanza.txt b/tests/assets/service_stanza.txt index 8164bf0c..e7fd0929 100755 --- a/tests/assets/service_stanza.txt +++ b/tests/assets/service_stanza.txt @@ -5,5 +5,5 @@ default: # List of externally accessible addresses and # ports for this Proximus instance. - - address: 127.0.0.1 + - address: child port: 5000 diff --git a/tests/rbac/aio/conftest.py b/tests/rbac/aio/conftest.py index ea295a17..8919512e 100644 --- a/tests/rbac/aio/conftest.py +++ b/tests/rbac/aio/conftest.py @@ -4,48 +4,77 @@ from aerospike_vector_search.aio.admin import Client as AdminClient from aerospike_vector_search import types -@pytest.fixture(scope="module", autouse=True) -def username(request): - return request.config.getoption("--username") - -@pytest.fixture(scope="module", autouse=True) -def password(request): - return request.config.getoption("--password") - -@pytest.fixture(scope="module", autouse=True) -def root_certificate(request): - return request.config.getoption("--root_certificate") - -@pytest.fixture(scope="module", autouse=True) -def private_key(request): - return request.config.getoption("--private_key") @pytest.fixture(scope="module", autouse=True) -def certificate_chain(request): - return request.config.getoption("--certificate_chain") +async def drop_all_indexes( + username, + password, + host, + port, + root_certificate, + certificate_chain, + private_key, + is_loadbalancer, +): + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() -@pytest.fixture(scope="module", autouse=True) -async def drop_all_indexes(username, password, host, port, root_certificate, certificate_chain, private_key, is_loadbalancer): async with AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) as client: index_list = await client.index_list() tasks = [] for item in index_list: - tasks.append(client.index_drop(namespace="test", name=item['id']['name'])) + tasks.append(client.index_drop(namespace="test", name=item["id"]["name"])) await asyncio.gather(*tasks) @pytest.fixture(scope="module") -async def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): +async def session_rbac_admin_client( + username, + password, + root_certificate, + host, + port, + certificate_chain, + private_key, + is_loadbalancer, +): + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + client = AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) yield client await client.close() - - - diff --git a/tests/rbac/aio/test_admin_client_add_user.py b/tests/rbac/aio/test_admin_client_add_user.py index 31b5d824..f7bf2d6d 100644 --- a/tests/rbac/aio/test_admin_client_add_user.py +++ b/tests/rbac/aio/test_admin_client_add_user.py @@ -1,6 +1,7 @@ import pytest from ...utils import random_int + class add_user_test_case: def __init__( self, @@ -13,62 +14,55 @@ def __init__( self.password = password self.roles = roles + @pytest.mark.parametrize( "test_case", [ add_user_test_case( username="aio-add-user-" + str(random_int()), password="alphanumeric", - roles=None + roles=None, ), ], ) async def test_add_user(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles - + username=test_case.username, password=test_case.password, roles=test_case.roles ) - result = await session_rbac_admin_client.get_user( - username=test_case.username - ) + result = await session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username assert result.roles == [] + @pytest.mark.parametrize( "test_case", [ add_user_test_case( username="aio-add-user-" + str(random_int()), password="eu123#$%", - roles=["admin"] + roles=["admin"], ), add_user_test_case( username="aio-add-user-" + str(random_int()), password="radical", - roles=["read-write"] + roles=["read-write"], ), add_user_test_case( username="aio-add-user-" + str(random_int()), password="marshall", - roles=["admin", "read-write"] + roles=["admin", "read-write"], ), ], ) async def test_add_user_with_roles(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles + username=test_case.username, password=test_case.password, roles=test_case.roles ) - result = await session_rbac_admin_client.get_user( - username=test_case.username - ) + result = await session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username diff --git a/tests/rbac/aio/test_admin_client_drop_user.py b/tests/rbac/aio/test_admin_client_drop_user.py index 69d04f83..449e9e96 100644 --- a/tests/rbac/aio/test_admin_client_drop_user.py +++ b/tests/rbac/aio/test_admin_client_drop_user.py @@ -3,6 +3,7 @@ from aerospike_vector_search import AVSServerError import grpc + class drop_user_test_case: def __init__( self, @@ -13,6 +14,7 @@ def __init__( self.username = username self.password = password + @pytest.mark.parametrize( "test_case", [ @@ -24,17 +26,11 @@ def __init__( ) async def test_drop_user(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=None - + username=test_case.username, password=test_case.password, roles=None ) await session_rbac_admin_client.drop_user( username=test_case.username, - ) with pytest.raises(AVSServerError) as e_info: - result = await session_rbac_admin_client.get_user( - username=test_case.username - ) + result = await session_rbac_admin_client.get_user(username=test_case.username) assert e_info.value.rpc_error.code() == grpc.StatusCode.NOT_FOUND diff --git a/tests/rbac/aio/test_admin_client_get_user.py b/tests/rbac/aio/test_admin_client_get_user.py index 13efe163..c253a0bb 100644 --- a/tests/rbac/aio/test_admin_client_get_user.py +++ b/tests/rbac/aio/test_admin_client_get_user.py @@ -12,6 +12,7 @@ def __init__( self.username = username self.password = password + @pytest.mark.parametrize( "test_case", [ @@ -23,15 +24,10 @@ def __init__( ) async def test_get_user(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=None - + username=test_case.username, password=test_case.password, roles=None ) - result = await session_rbac_admin_client.get_user( - username=test_case.username - ) + result = await session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username diff --git a/tests/rbac/aio/test_admin_client_grant_roles.py b/tests/rbac/aio/test_admin_client_grant_roles.py index b2d76679..cf03c0ea 100644 --- a/tests/rbac/aio/test_admin_client_grant_roles.py +++ b/tests/rbac/aio/test_admin_client_grant_roles.py @@ -3,19 +3,13 @@ class grant_roles_test_case: - def __init__( - self, - *, - username, - password, - roles, - granted_roles - ): + def __init__(self, *, username, password, roles, granted_roles): self.username = username self.password = password self.roles = roles self.granted_roles = granted_roles + @pytest.mark.parametrize( "test_case", [ @@ -23,28 +17,21 @@ def __init__( username="aio-update-credentials-" + str(random_int()), password="yeoldpassword", roles=[], - granted_roles=["admin", "read-write"] + granted_roles=["admin", "read-write"], ), ], ) async def test_grant_roles(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles - + username=test_case.username, password=test_case.password, roles=test_case.roles ) await session_rbac_admin_client.grant_roles( - username=test_case.username, - roles=test_case.granted_roles + username=test_case.username, roles=test_case.granted_roles ) - result = await session_rbac_admin_client.get_user( - username=test_case.username - ) + result = await session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username assert result.roles == test_case.granted_roles - diff --git a/tests/rbac/aio/test_admin_client_list_roles.py b/tests/rbac/aio/test_admin_client_list_roles.py index c6c979e5..4179c75e 100644 --- a/tests/rbac/aio/test_admin_client_list_roles.py +++ b/tests/rbac/aio/test_admin_client_list_roles.py @@ -14,25 +14,22 @@ def __init__( self.password = password self.roles = roles + @pytest.mark.parametrize( "test_case", [ list_roles_test_case( username="aio-list-roles-" + str(random_int()), password="yeoldpassword", - roles=["admin", "read-write"] + roles=["admin", "read-write"], ), ], ) async def test_list_roles(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles - + username=test_case.username, password=test_case.password, roles=test_case.roles ) result = await session_rbac_admin_client.list_roles() for role in result: assert role.id in test_case.roles - diff --git a/tests/rbac/aio/test_admin_client_list_users.py b/tests/rbac/aio/test_admin_client_list_users.py index 9871a99d..02ac6e8c 100644 --- a/tests/rbac/aio/test_admin_client_list_users.py +++ b/tests/rbac/aio/test_admin_client_list_users.py @@ -3,15 +3,11 @@ class list_users_test_case: - def __init__( - self, - *, - username, - password - ): + def __init__(self, *, username, password): self.username = username self.password = password + @pytest.mark.parametrize( "test_case", [ @@ -23,10 +19,7 @@ def __init__( ) async def test_list_users(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=None - + username=test_case.username, password=test_case.password, roles=None ) result = await session_rbac_admin_client.list_users() @@ -37,4 +30,3 @@ async def test_list_users(session_rbac_admin_client, test_case): user_found = True assert user_found - diff --git a/tests/rbac/aio/test_admin_client_revoke_roles.py b/tests/rbac/aio/test_admin_client_revoke_roles.py index 2f6dfbb8..7ca68a41 100644 --- a/tests/rbac/aio/test_admin_client_revoke_roles.py +++ b/tests/rbac/aio/test_admin_client_revoke_roles.py @@ -3,19 +3,13 @@ class revoke_roles_test_case: - def __init__( - self, - *, - username, - password, - roles, - revoked_roles - ): + def __init__(self, *, username, password, roles, revoked_roles): self.username = username self.password = password self.roles = roles self.revoked_roles = revoked_roles + @pytest.mark.parametrize( "test_case", [ @@ -23,28 +17,21 @@ def __init__( username="aio-revoke-roles-" + str(random_int()), password="yeoldpassword", roles=["admin", "read-write"], - revoked_roles=[] + revoked_roles=[], ), ], ) async def test_revoke_roles(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles - + username=test_case.username, password=test_case.password, roles=test_case.roles ) await session_rbac_admin_client.revoke_roles( - username=test_case.username, - roles=test_case.roles + username=test_case.username, roles=test_case.roles ) - result = await session_rbac_admin_client.get_user( - username=test_case.username - ) + result = await session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username assert result.roles == test_case.revoked_roles - diff --git a/tests/rbac/aio/test_admin_client_update_credentials.py b/tests/rbac/aio/test_admin_client_update_credentials.py index 945aa3d4..edffbcd6 100644 --- a/tests/rbac/aio/test_admin_client_update_credentials.py +++ b/tests/rbac/aio/test_admin_client_update_credentials.py @@ -3,17 +3,12 @@ class update_credentials_test_case: - def __init__( - self, - *, - username, - old_password, - new_password - ): + def __init__(self, *, username, old_password, new_password): self.username = username self.old_password = old_password self.new_password = new_password + @pytest.mark.parametrize( "test_case", [ @@ -26,10 +21,7 @@ def __init__( ) async def test_update_credentials(session_rbac_admin_client, test_case): await session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.old_password, - roles=None - + username=test_case.username, password=test_case.old_password, roles=None ) await session_rbac_admin_client.update_credentials( @@ -37,11 +29,8 @@ async def test_update_credentials(session_rbac_admin_client, test_case): password=test_case.new_password, ) - result = await session_rbac_admin_client.get_user( - username=test_case.username - ) + result = await session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username assert result.roles == [] - diff --git a/tests/rbac/conftest.py b/tests/rbac/conftest.py index 64d033b6..b1344aba 100644 --- a/tests/rbac/conftest.py +++ b/tests/rbac/conftest.py @@ -6,40 +6,63 @@ def pytest_addoption(parser): parser.addoption("--password", action="store", default="admin", help="AVS Password") parser.addoption("--host", action="store", default="localhost", help="AVS Host") parser.addoption("--port", action="store", default=5000, help="AVS Port") - parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") - parser.addoption("--certificate_chain", action="store", default=None, help="Path to certificate chain") - parser.addoption("--private_key", action="store", default=None, help="Path to private key") - parser.addoption("--is_loadbalancer", action="store_true", help="Enable to use load balancer tending logic") + parser.addoption( + "--root_certificate", + action="store", + default=None, + help="Path to root CA certificate", + ) + parser.addoption( + "--certificate_chain", + action="store", + default=None, + help="Path to certificate chain", + ) + parser.addoption( + "--private_key", action="store", default=None, help="Path to private key" + ) + parser.addoption( + "--is_loadbalancer", + action="store_true", + help="Enable to use load balancer tending logic", + ) @pytest.fixture(scope="module", autouse=True) def username(request): return request.config.getoption("--username") + @pytest.fixture(scope="module", autouse=True) def password(request): return request.config.getoption("--password") + @pytest.fixture(scope="module", autouse=True) def private_key(request): return request.config.getoption("--private_key") + @pytest.fixture(scope="module", autouse=True) def certificate_chain(request): return request.config.getoption("--certificate_chain") + @pytest.fixture(scope="module", autouse=True) def root_certificate(request): return request.config.getoption("--root_certificate") + @pytest.fixture(scope="module", autouse=True) def host(request): return request.config.getoption("--host") + @pytest.fixture(scope="module", autouse=True) def port(request): return request.config.getoption("--port") + @pytest.fixture(scope="module", autouse=True) def is_loadbalancer(request): - return request.config.getoption("--is_loadbalancer") \ No newline at end of file + return request.config.getoption("--is_loadbalancer") diff --git a/tests/rbac/sync/conftest.py b/tests/rbac/sync/conftest.py index 0238fed6..2bdead0e 100644 --- a/tests/rbac/sync/conftest.py +++ b/tests/rbac/sync/conftest.py @@ -6,25 +6,75 @@ @pytest.fixture(scope="module", autouse=True) -def drop_all_indexes(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): +def drop_all_indexes( + username, + password, + root_certificate, + host, + port, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + with AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) as client: index_list = client.index_list() tasks = [] for item in index_list: - client.index_drop(namespace="test", name=item['id']['name']) + client.index_drop(namespace="test", name=item["id"]["name"]) @pytest.fixture(scope="module") -def session_rbac_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): +def session_rbac_admin_client( + username, + password, + root_certificate, + host, + port, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + client = AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) yield client client.close() - - - - diff --git a/tests/rbac/sync/test_admin_client_add_user.py b/tests/rbac/sync/test_admin_client_add_user.py index 21c7a126..aa5a27c6 100644 --- a/tests/rbac/sync/test_admin_client_add_user.py +++ b/tests/rbac/sync/test_admin_client_add_user.py @@ -1,6 +1,7 @@ import pytest from ...utils import random_int + class add_user_test_case: def __init__( self, @@ -13,62 +14,55 @@ def __init__( self.password = password self.roles = roles + @pytest.mark.parametrize( "test_case", [ add_user_test_case( username="aio-add-user-" + str(random_int()), password="alphanumeric", - roles=None + roles=None, ), ], ) def test_add_user(session_rbac_admin_client, test_case): session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles - + username=test_case.username, password=test_case.password, roles=test_case.roles ) - result = session_rbac_admin_client.get_user( - username=test_case.username - ) + result = session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username assert result.roles == [] + @pytest.mark.parametrize( "test_case", [ add_user_test_case( username="aio-add-user-" + str(random_int()), password="eu123#$%", - roles=["admin"] + roles=["admin"], ), add_user_test_case( username="aio-add-user-" + str(random_int()), password="radical", - roles=["read-write"] + roles=["read-write"], ), add_user_test_case( username="aio-add-user-" + str(random_int()), password="marshall", - roles=["admin", "read-write"] + roles=["admin", "read-write"], ), ], ) def test_add_user_with_roles(session_rbac_admin_client, test_case): session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles + username=test_case.username, password=test_case.password, roles=test_case.roles ) - result = session_rbac_admin_client.get_user( - username=test_case.username - ) + result = session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username diff --git a/tests/rbac/sync/test_admin_client_drop_user.py b/tests/rbac/sync/test_admin_client_drop_user.py index ef45208a..a18bee71 100644 --- a/tests/rbac/sync/test_admin_client_drop_user.py +++ b/tests/rbac/sync/test_admin_client_drop_user.py @@ -3,6 +3,7 @@ from aerospike_vector_search import AVSServerError import grpc + class drop_user_test_case: def __init__( self, @@ -13,6 +14,7 @@ def __init__( self.username = username self.password = password + @pytest.mark.parametrize( "test_case", [ @@ -24,17 +26,11 @@ def __init__( ) def test_drop_user(session_rbac_admin_client, test_case): session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=None - + username=test_case.username, password=test_case.password, roles=None ) session_rbac_admin_client.drop_user( username=test_case.username, - ) with pytest.raises(AVSServerError) as e_info: - result = session_rbac_admin_client.get_user( - username=test_case.username - ) + result = session_rbac_admin_client.get_user(username=test_case.username) assert e_info.value.rpc_error.code() == grpc.StatusCode.NOT_FOUND diff --git a/tests/rbac/sync/test_admin_client_get_user.py b/tests/rbac/sync/test_admin_client_get_user.py index 2ea401c1..69c76a92 100644 --- a/tests/rbac/sync/test_admin_client_get_user.py +++ b/tests/rbac/sync/test_admin_client_get_user.py @@ -12,6 +12,7 @@ def __init__( self.username = username self.password = password + @pytest.mark.parametrize( "test_case", [ @@ -23,15 +24,10 @@ def __init__( ) def test_get_user(session_rbac_admin_client, test_case): session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=None - + username=test_case.username, password=test_case.password, roles=None ) - result = session_rbac_admin_client.get_user( - username=test_case.username - ) + result = session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username diff --git a/tests/rbac/sync/test_admin_client_grant_roles.py b/tests/rbac/sync/test_admin_client_grant_roles.py index 85dc031d..dc74bef0 100644 --- a/tests/rbac/sync/test_admin_client_grant_roles.py +++ b/tests/rbac/sync/test_admin_client_grant_roles.py @@ -3,19 +3,13 @@ class grant_roles_test_case: - def __init__( - self, - *, - username, - password, - roles, - granted_roles - ): + def __init__(self, *, username, password, roles, granted_roles): self.username = username self.password = password self.roles = roles self.granted_roles = granted_roles + @pytest.mark.parametrize( "test_case", [ @@ -23,28 +17,21 @@ def __init__( username="aio-update-credentials-" + str(random_int()), password="yeoldpassword", roles=[], - granted_roles=["admin", "read-write"] + granted_roles=["admin", "read-write"], ), ], ) def test_grant_roles(session_rbac_admin_client, test_case): session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles - + username=test_case.username, password=test_case.password, roles=test_case.roles ) session_rbac_admin_client.grant_roles( - username=test_case.username, - roles=test_case.granted_roles + username=test_case.username, roles=test_case.granted_roles ) - result = session_rbac_admin_client.get_user( - username=test_case.username - ) + result = session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username assert result.roles == test_case.granted_roles - diff --git a/tests/rbac/sync/test_admin_client_list_roles.py b/tests/rbac/sync/test_admin_client_list_roles.py index e88c72ca..a3d1bf82 100644 --- a/tests/rbac/sync/test_admin_client_list_roles.py +++ b/tests/rbac/sync/test_admin_client_list_roles.py @@ -14,25 +14,22 @@ def __init__( self.password = password self.roles = roles + @pytest.mark.parametrize( "test_case", [ list_roles_test_case( username="aio-list-roles-" + str(random_int()), password="yeoldpassword", - roles=["admin", "read-write"] + roles=["admin", "read-write"], ), ], ) def test_list_roles(session_rbac_admin_client, test_case): session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles - + username=test_case.username, password=test_case.password, roles=test_case.roles ) result = session_rbac_admin_client.list_roles() for role in result: assert role.id in test_case.roles - diff --git a/tests/rbac/sync/test_admin_client_list_users.py b/tests/rbac/sync/test_admin_client_list_users.py index 1ac7f1b0..0b713250 100644 --- a/tests/rbac/sync/test_admin_client_list_users.py +++ b/tests/rbac/sync/test_admin_client_list_users.py @@ -3,15 +3,11 @@ class list_users_test_case: - def __init__( - self, - *, - username, - password - ): + def __init__(self, *, username, password): self.username = username self.password = password + @pytest.mark.parametrize( "test_case", [ @@ -23,10 +19,7 @@ def __init__( ) def test_list_users(session_rbac_admin_client, test_case): session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=None - + username=test_case.username, password=test_case.password, roles=None ) result = session_rbac_admin_client.list_users() @@ -37,4 +30,3 @@ def test_list_users(session_rbac_admin_client, test_case): user_found = True assert user_found - diff --git a/tests/rbac/sync/test_admin_client_revoke_roles.py b/tests/rbac/sync/test_admin_client_revoke_roles.py index 16a5367d..0620fb24 100644 --- a/tests/rbac/sync/test_admin_client_revoke_roles.py +++ b/tests/rbac/sync/test_admin_client_revoke_roles.py @@ -3,19 +3,13 @@ class revoke_roles_test_case: - def __init__( - self, - *, - username, - password, - roles, - revoked_roles - ): + def __init__(self, *, username, password, roles, revoked_roles): self.username = username self.password = password self.roles = roles self.revoked_roles = revoked_roles + @pytest.mark.parametrize( "test_case", [ @@ -23,28 +17,21 @@ def __init__( username="aio-revoke-roles-" + str(random_int()), password="yeoldpassword", roles=["admin", "read-write"], - revoked_roles=[] + revoked_roles=[], ), ], ) def test_revoke_roles(session_rbac_admin_client, test_case): session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.password, - roles=test_case.roles - + username=test_case.username, password=test_case.password, roles=test_case.roles ) session_rbac_admin_client.revoke_roles( - username=test_case.username, - roles=test_case.roles + username=test_case.username, roles=test_case.roles ) - result = session_rbac_admin_client.get_user( - username=test_case.username - ) + result = session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username assert result.roles == test_case.revoked_roles - diff --git a/tests/rbac/sync/test_admin_client_update_credentials.py b/tests/rbac/sync/test_admin_client_update_credentials.py index a66d8a9d..3e2d7894 100644 --- a/tests/rbac/sync/test_admin_client_update_credentials.py +++ b/tests/rbac/sync/test_admin_client_update_credentials.py @@ -3,17 +3,12 @@ class update_credentials_test_case: - def __init__( - self, - *, - username, - old_password, - new_password - ): + def __init__(self, *, username, old_password, new_password): self.username = username self.old_password = old_password self.new_password = new_password + @pytest.mark.parametrize( "test_case", [ @@ -26,10 +21,7 @@ def __init__( ) def test_update_credentials(session_rbac_admin_client, test_case): session_rbac_admin_client.add_user( - username=test_case.username, - password=test_case.old_password, - roles=None - + username=test_case.username, password=test_case.old_password, roles=None ) session_rbac_admin_client.update_credentials( @@ -37,11 +29,8 @@ def test_update_credentials(session_rbac_admin_client, test_case): password=test_case.new_password, ) - result = session_rbac_admin_client.get_user( - username=test_case.username - ) + result = session_rbac_admin_client.get_user(username=test_case.username) assert result.username == test_case.username assert result.roles == [] - diff --git a/tests/standard/aio/conftest.py b/tests/standard/aio/conftest.py index 12a6ce9e..9b9db6e3 100644 --- a/tests/standard/aio/conftest.py +++ b/tests/standard/aio/conftest.py @@ -4,46 +4,150 @@ from aerospike_vector_search.aio.admin import Client as AdminClient from aerospike_vector_search import types + @pytest.fixture(scope="module", autouse=True) -async def drop_all_indexes(host, port, username, password, root_certificate, certificate_chain, private_key, is_loadbalancer): +async def drop_all_indexes( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + is_loadbalancer, +): + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() - async with AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + async with AdminClient( + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) as client: index_list = await client.index_list() tasks = [] for item in index_list: - tasks.append(client.index_drop(namespace="test", name=item['id']['name'])) - + tasks.append(client.index_drop(namespace="test", name=item["id"]["name"])) await asyncio.gather(*tasks) @pytest.fixture(scope="module") -async def session_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key, is_loadbalancer): +async def session_admin_client( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() client = AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, + username=username, + password=password, ) yield client await client.close() + @pytest.fixture(scope="module") -async def session_vector_client(host, port, username, password, root_certificate, certificate_chain, private_key, is_loadbalancer): +async def session_vector_client( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() client = Client( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, + username=username, + password=password, ) yield client await client.close() + @pytest.fixture -async def function_admin_client(host, port, username, password, root_certificate, certificate_chain, private_key, is_loadbalancer): +async def function_admin_client( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() client = AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, username=username, password=password - ) + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, + username=username, + password=password, + ) yield client await client.close() diff --git a/tests/standard/aio/test_admin_client_index_create.py b/tests/standard/aio/test_admin_client_index_create.py index 0bfade72..d5742bd8 100644 --- a/tests/standard/aio/test_admin_client_index_create.py +++ b/tests/standard/aio/test_admin_client_index_create.py @@ -6,6 +6,7 @@ from .aio_utils import drop_specified_index from hypothesis import given, settings, Verbosity + class index_create_test_case: def __init__( self, @@ -16,7 +17,7 @@ def __init__( vector_distance_metric, sets, index_params, - index_meta_data, + index_labels, index_storage, timeout ): @@ -29,10 +30,11 @@ def __init__( self.vector_distance_metric = vector_distance_metric self.sets = sets self.index_params = index_params - self.index_meta_data = index_meta_data + self.index_labels = index_labels self.index_storage = index_storage self.timeout = timeout + @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -46,10 +48,10 @@ def __init__( vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, - ) + ), ], ) async def test_index_create(session_admin_client, test_case, random_name): @@ -63,25 +65,25 @@ async def test_index_create(session_admin_client, test_case, random_name): vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True await drop_specified_index(session_admin_client, test_case.namespace, random_name) @@ -99,7 +101,7 @@ async def test_index_create(session_admin_client, test_case, random_name): vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -110,13 +112,15 @@ async def test_index_create(session_admin_client, test_case, random_name): vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), ], ) -async def test_index_create_with_dimnesions(session_admin_client, test_case, random_name): +async def test_index_create_with_dimnesions( + session_admin_client, test_case, random_name +): await session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -125,35 +129,33 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) - results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True await drop_specified_index(session_admin_client, test_case.namespace, random_name) - @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -167,7 +169,7 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran vector_distance_metric=types.VectorDistanceMetric.COSINE, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -178,7 +180,7 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran vector_distance_metric=types.VectorDistanceMetric.DOT_PRODUCT, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -189,7 +191,7 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran vector_distance_metric=types.VectorDistanceMetric.MANHATTAN, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -200,7 +202,7 @@ async def test_index_create_with_dimnesions(session_admin_client, test_case, ran vector_distance_metric=types.VectorDistanceMetric.HAMMING, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -210,7 +212,6 @@ async def test_index_create_with_vector_distance_metric( session_admin_client, test_case, random_name ): - await session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -219,25 +220,25 @@ async def test_index_create_with_vector_distance_metric( vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True await drop_specified_index(session_admin_client, test_case.namespace, random_name) @@ -255,7 +256,7 @@ async def test_index_create_with_vector_distance_metric( vector_distance_metric=None, sets="Demo", index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -266,7 +267,7 @@ async def test_index_create_with_vector_distance_metric( vector_distance_metric=None, sets="Cheese", index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -282,25 +283,25 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True await drop_specified_index(session_admin_client, test_case.namespace, random_name) @@ -322,7 +323,7 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na ef_construction=200, ef=400, ), - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -337,7 +338,7 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na ef_construction=50, ef=25, ), - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -348,17 +349,17 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na vector_distance_metric=None, sets=None, index_params=types.HnswParams( - batching_params=types.HnswBatchingParams( - max_records=500, interval=500 - ) + batching_params=types.HnswBatchingParams(max_records=500, interval=500) ), - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), ], ) -async def test_index_create_with_index_params(session_admin_client, test_case, random_name): +async def test_index_create_with_index_params( + session_admin_client, test_case, random_name +): await session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -367,25 +368,34 @@ async def test_index_create_with_index_params(session_admin_client, test_case, r vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == test_case.index_params.m - assert result['hnsw_params']['ef_construction'] == test_case.index_params.ef_construction - assert result['hnsw_params']['ef'] == test_case.index_params.ef - assert result['hnsw_params']['batching_params']['max_records'] == test_case.index_params.batching_params.max_records - assert result['hnsw_params']['batching_params']['interval'] == test_case.index_params.batching_params.interval - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == test_case.index_params.m + assert ( + result["hnsw_params"]["ef_construction"] + == test_case.index_params.ef_construction + ) + assert result["hnsw_params"]["ef"] == test_case.index_params.ef + assert ( + result["hnsw_params"]["batching_params"]["max_records"] + == test_case.index_params.batching_params.max_records + ) + assert ( + result["hnsw_params"]["batching_params"]["interval"] + == test_case.index_params.batching_params.interval + ) + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True await drop_specified_index(session_admin_client, test_case.namespace, random_name) @@ -403,13 +413,13 @@ async def test_index_create_with_index_params(session_admin_client, test_case, r vector_distance_metric=None, sets=None, index_params=None, - index_meta_data={"size": "large", "price": "$4.99", "currencyType": "CAN"}, + index_labels={"size": "large", "price": "$4.99", "currencyType": "CAN"}, index_storage=None, timeout=None, - ) + ), ], ) -async def test_index_create_index_meta_data(session_admin_client, test_case, random_name): +async def test_index_create_index_labels(session_admin_client, test_case, random_name): if test_case == None: return await session_admin_client.index_create( @@ -420,28 +430,29 @@ async def test_index_create_index_meta_data(session_admin_client, test_case, ran vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True await drop_specified_index(session_admin_client, test_case.namespace, random_name) + @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -454,7 +465,7 @@ async def test_index_create_index_meta_data(session_admin_client, test_case, ran vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=types.IndexStorage(namespace="test", set_name="foo"), timeout=None, ), @@ -469,25 +480,25 @@ async def test_index_create_index_storage(session_admin_client, test_case, rando vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) results = await session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == test_case.name: + if result["id"]["name"] == test_case.name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.index_storage.namespace - assert result['storage']['set'] == test_case.index_storage.set_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.index_storage.namespace + assert result["storage"]["set"] == test_case.index_storage.set_name assert found == True @@ -504,17 +515,19 @@ async def test_index_create_index_storage(session_admin_client, test_case, rando vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=0.0001, ), ], ) -async def test_index_create_timeout(session_admin_client, test_case, random_name, with_latency): +async def test_index_create_timeout( + session_admin_client, test_case, random_name, with_latency +): if not with_latency: pytest.skip("Server latency too low to test timeout") - + with pytest.raises(AVSServerError) as e_info: for i in range(10): @@ -526,8 +539,8 @@ async def test_index_create_timeout(session_admin_client, test_case, random_name vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_admin_client_index_drop.py b/tests/standard/aio/test_admin_client_index_drop.py index 4edf9ab1..e740351e 100644 --- a/tests/standard/aio/test_admin_client_index_drop.py +++ b/tests/standard/aio/test_admin_client_index_drop.py @@ -7,11 +7,9 @@ from hypothesis import given, settings, Verbosity - - -@pytest.mark.parametrize("empty_test_case",[None, None]) +@pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=5, deadline=2000) async def test_index_drop(session_admin_client, empty_test_case, random_name): await session_admin_client.index_create( namespace="test", @@ -27,10 +25,12 @@ async def test_index_drop(session_admin_client, empty_test_case, random_name): assert index["id"]["name"] != random_name -@pytest.mark.parametrize("empty_test_case",[None, None]) +@pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -async def test_index_drop_timeout(session_admin_client, empty_test_case, random_name, with_latency): +async def test_index_drop_timeout( + session_admin_client, empty_test_case, random_name, with_latency +): if not with_latency: pytest.skip("Server latency too low to test timeout") await session_admin_client.index_create( @@ -42,6 +42,8 @@ async def test_index_drop_timeout(session_admin_client, empty_test_case, random_ with pytest.raises(AVSServerError) as e_info: for i in range(10): - await session_admin_client.index_drop(namespace="test", name=random_name, timeout=0.0001) + await session_admin_client.index_drop( + namespace="test", name=random_name, timeout=0.0001 + ) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_admin_client_index_get.py b/tests/standard/aio/test_admin_client_index_get.py index 2500c53f..3de77078 100644 --- a/tests/standard/aio/test_admin_client_index_get.py +++ b/tests/standard/aio/test_admin_client_index_get.py @@ -7,7 +7,7 @@ import grpc -@pytest.mark.parametrize("empty_test_case",[None, None]) +@pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) async def test_index_get(session_admin_client, empty_test_case, random_name): @@ -17,14 +17,12 @@ async def test_index_get(session_admin_client, empty_test_case, random_name): vector_field="science", dimensions=1024, ) - result = await session_admin_client.index_get( - namespace="test", name=random_name - ) - + result = await session_admin_client.index_get(namespace="test", name=random_name) + assert result["id"]["name"] == random_name assert result["id"]["namespace"] == "test" assert result["dimensions"] == 1024 - assert result['field'] == "science" + assert result["field"] == "science" assert result["hnsw_params"]["m"] == 16 assert result["hnsw_params"]["ef_construction"] == 100 assert result["hnsw_params"]["ef"] == 100 @@ -35,15 +33,18 @@ async def test_index_get(session_admin_client, empty_test_case, random_name): await drop_specified_index(session_admin_client, "test", random_name) -@pytest.mark.parametrize("empty_test_case",[None, None]) + +@pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -async def test_index_get_timeout(session_admin_client, empty_test_case, random_name, with_latency): +async def test_index_get_timeout( + session_admin_client, empty_test_case, random_name, with_latency +): if not with_latency: pytest.skip("Server latency too low to test timeout") - for i in range(10): + for i in range(10): try: result = await session_admin_client.index_get( namespace="test", name=random_name, timeout=0.0001 @@ -52,4 +53,4 @@ async def test_index_get_timeout(session_admin_client, empty_test_case, random_n if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/aio/test_admin_client_index_get_status.py b/tests/standard/aio/test_admin_client_index_get_status.py index a49bbfa9..b3dfe6c9 100644 --- a/tests/standard/aio/test_admin_client_index_get_status.py +++ b/tests/standard/aio/test_admin_client_index_get_status.py @@ -7,16 +7,19 @@ import grpc -@pytest.mark.parametrize("empty_test_case",[None, None]) +@pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) async def test_index_get_status(session_admin_client, empty_test_case, random_name): - await session_admin_client.index_create( - namespace="test", - name=random_name, - vector_field="science", - dimensions=1024, - ) + try: + await session_admin_client.index_create( + namespace="test", + name=random_name, + vector_field="science", + dimensions=1024, + ) + except Exception as e: + pass result = await session_admin_client.index_get_status( namespace="test", name=random_name @@ -24,10 +27,13 @@ async def test_index_get_status(session_admin_client, empty_test_case, random_na assert result == 0 await drop_specified_index(session_admin_client, "test", random_name) -@pytest.mark.parametrize("empty_test_case",[None, None]) + +@pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -async def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name, with_latency): +async def test_index_get_status_timeout( + session_admin_client, empty_test_case, random_name, with_latency +): if not with_latency: pytest.skip("Server latency too low to test timeout") try: @@ -37,7 +43,7 @@ async def test_index_get_status_timeout(session_admin_client, empty_test_case, r vector_field="science", dimensions=1024, ) - except Exception as e: + except Exception as e: pass for i in range(10): @@ -49,4 +55,4 @@ async def test_index_get_status_timeout(session_admin_client, empty_test_case, r if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/aio/test_admin_client_index_list.py b/tests/standard/aio/test_admin_client_index_list.py index 99b57d30..0d228d84 100644 --- a/tests/standard/aio/test_admin_client_index_list.py +++ b/tests/standard/aio/test_admin_client_index_list.py @@ -9,7 +9,8 @@ from .aio_utils import drop_specified_index from hypothesis import given, settings, Verbosity -@pytest.mark.parametrize("empty_test_case",[None, None]) + +@pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) async def test_index_list(session_admin_client, empty_test_case, random_name): @@ -22,27 +23,27 @@ async def test_index_list(session_admin_client, empty_test_case, random_name): result = await session_admin_client.index_list() assert len(result) > 0 for index in result: - assert isinstance(index['id']['name'], str) - assert isinstance(index['id']['namespace'], str) - assert isinstance(index['dimensions'], int) - assert isinstance(index['field'], str) - assert isinstance(index['hnsw_params']['m'], int) - assert isinstance(index['hnsw_params']['ef_construction'], int) - assert isinstance(index['hnsw_params']['ef'], int) - assert isinstance(index['hnsw_params']['batching_params']['max_records'], int) - assert isinstance(index['hnsw_params']['batching_params']['interval'], int) - assert isinstance(index['storage']['namespace'], str) - assert isinstance(index['storage']['set'], str) + assert isinstance(index["id"]["name"], str) + assert isinstance(index["id"]["namespace"], str) + assert isinstance(index["dimensions"], int) + assert isinstance(index["field"], str) + assert isinstance(index["hnsw_params"]["m"], int) + assert isinstance(index["hnsw_params"]["ef_construction"], int) + assert isinstance(index["hnsw_params"]["ef"], int) + assert isinstance(index["hnsw_params"]["batching_params"]["max_records"], int) + assert isinstance(index["hnsw_params"]["batching_params"]["interval"], int) + assert isinstance(index["storage"]["namespace"], str) + assert isinstance(index["storage"]["set"], str) await drop_specified_index(session_admin_client, "test", random_name) + async def test_index_list_timeout(session_admin_client, with_latency): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: result = await session_admin_client.index_list(timeout=0.0001) - except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_service_config.py b/tests/standard/aio/test_service_config.py index f30eeee9..fd0114a5 100644 --- a/tests/standard/aio/test_service_config.py +++ b/tests/standard/aio/test_service_config.py @@ -7,14 +7,12 @@ from aerospike_vector_search import AVSServerError, types from aerospike_vector_search.aio import AdminClient + class service_config_parse_test_case: - def __init__( - self, - *, - service_config_path - ): + def __init__(self, *, service_config_path): self.service_config_path = service_config_path + @pytest.mark.parametrize( "test_case", [ @@ -23,7 +21,28 @@ def __init__( ), ], ) -async def test_admin_client_service_config_parse(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +async def test_admin_client_service_config_parse( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -31,67 +50,99 @@ async def test_admin_client_service_config_parse(host, port, username, password root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path + service_config_path=test_case.service_config_path, ) as client: pass + + class service_config_test_case: def __init__( - self, - *, - service_config_path, - namespace, - name, - vector_field, - dimensions + self, *, service_config_path, namespace, name, vector_field, dimensions ): script_dir = os.path.dirname(os.path.abspath(__file__)) - self.service_config_path = os.path.abspath(os.path.join(script_dir, '..', '..', service_config_path)) + self.service_config_path = os.path.abspath( + os.path.join(script_dir, "..", "..", service_config_path) + ) - with open(self.service_config_path, 'rb') as f: + with open(self.service_config_path, "rb") as f: self.service_config = json.load(f) - - - - self.max_attempts = self.service_config["methodConfig"][0]["retryPolicy"]["maxAttempts"] - self.initial_backoff = int(self.service_config["methodConfig"][0]["retryPolicy"]["initialBackoff"][:-1]) - self.max_backoff = int(self.service_config["methodConfig"][0]["retryPolicy"]["maxBackoff"][:-1]) - self.backoff_multiplier = self.service_config["methodConfig"][0]["retryPolicy"]["backoffMultiplier"] - self.retryable_status_codes = self.service_config["methodConfig"][0]["retryPolicy"]["retryableStatusCodes"] + self.max_attempts = self.service_config["methodConfig"][0]["retryPolicy"][ + "maxAttempts" + ] + self.initial_backoff = int( + self.service_config["methodConfig"][0]["retryPolicy"]["initialBackoff"][:-1] + ) + self.max_backoff = int( + self.service_config["methodConfig"][0]["retryPolicy"]["maxBackoff"][:-1] + ) + self.backoff_multiplier = self.service_config["methodConfig"][0]["retryPolicy"][ + "backoffMultiplier" + ] + self.retryable_status_codes = self.service_config["methodConfig"][0][ + "retryPolicy" + ]["retryableStatusCodes"] self.namespace = namespace self.name = name self.vector_field = vector_field self.dimensions = dimensions -def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, max_backoff, retryable_status_codes): +def calculate_expected_time( + max_attempts, + initial_backoff, + backoff_multiplier, + max_backoff, + retryable_status_codes, +): current_backkoff = initial_backoff expected_time = 0 - for attempt in range(max_attempts-1): + for attempt in range(max_attempts - 1): expected_time += current_backkoff current_backkoff *= backoff_multiplier - current_backkoff = min(current_backkoff, max_backoff ) + current_backkoff = min(current_backkoff, max_backoff) return expected_time + @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/retries.json", namespace="test", name="service_config_index_1", vector_field="example_1", - dimensions=1024 + dimensions=1024, ) ], ) -async def test_admin_client_service_config_retries(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +async def test_admin_client_service_config_retries( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -99,7 +150,7 @@ async def test_admin_client_service_config_retries(host, port, username, passwo root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path + service_config_path=test_case.service_config_path, ) as client: try: await client.index_create( @@ -110,7 +161,13 @@ async def test_admin_client_service_config_retries(host, port, username, passwo ) except: pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() with pytest.raises(AVSServerError) as e_info: @@ -124,22 +181,43 @@ async def test_admin_client_service_config_retries(host, port, username, passwo end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + assert abs(elapsed_time - expected_time) < 1.5 + @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/initial_backoff.json", namespace="test", name="service_config_index_2", vector_field="example_1", - dimensions=1024 + dimensions=1024, ) ], ) -async def test_admin_client_service_config_initial_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +async def test_admin_client_service_config_initial_backoff( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -147,7 +225,7 @@ async def test_admin_client_service_config_initial_backoff(host, port, username, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path + service_config_path=test_case.service_config_path, ) as client: try: @@ -160,7 +238,13 @@ async def test_admin_client_service_config_initial_backoff(host, port, username, except: pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() with pytest.raises(AVSServerError) as e_info: @@ -174,29 +258,50 @@ async def test_admin_client_service_config_initial_backoff(host, port, username, end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + assert abs(elapsed_time - expected_time) < 1.5 + @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/max_backoff.json", namespace="test", name="service_config_index_3", vector_field="example_1", - dimensions=1024 + dimensions=1024, ), service_config_test_case( service_config_path="service_configs/max_backoff_lower_than_initial.json", namespace="test", name="service_config_index_4", vector_field="example_1", - dimensions=1024 - ) + dimensions=1024, + ), ], ) -async def test_admin_client_service_config_max_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +async def test_admin_client_service_config_max_backoff( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -204,7 +309,7 @@ async def test_admin_client_service_config_max_backoff(host, port, username, pas root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path + service_config_path=test_case.service_config_path, ) as client: try: @@ -216,7 +321,13 @@ async def test_admin_client_service_config_max_backoff(host, port, username, pas ) except: pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() with pytest.raises(AVSServerError) as e_info: @@ -229,23 +340,43 @@ async def test_admin_client_service_config_max_backoff(host, port, username, pas end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + assert abs(elapsed_time - expected_time) < 1.5 @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/backoff_multiplier.json", namespace="test", name="service_config_index_5", vector_field="example_1", - dimensions=1024 + dimensions=1024, ) ], ) -async def test_admin_client_service_config_backoff_multiplier(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +async def test_admin_client_service_config_backoff_multiplier( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -253,7 +384,7 @@ async def test_admin_client_service_config_backoff_multiplier(host, port, userna root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path + service_config_path=test_case.service_config_path, ) as client: try: @@ -267,7 +398,13 @@ async def test_admin_client_service_config_backoff_multiplier(host, port, userna except: pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() with pytest.raises(AVSServerError) as e_info: @@ -280,23 +417,43 @@ async def test_admin_client_service_config_backoff_multiplier(host, port, userna end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + assert abs(elapsed_time - expected_time) < 1.5 @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/retryable_status_codes.json", namespace="test", name="service_config_index_6", vector_field=None, - dimensions=None + dimensions=None, ) ], ) -async def test_admin_client_service_config_retryable_status_codes(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +async def test_admin_client_service_config_retryable_status_codes( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + async with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -304,12 +461,18 @@ async def test_admin_client_service_config_retryable_status_codes(host, port, us root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path + service_config_path=test_case.service_config_path, ) as client: - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() - + with pytest.raises(AVSServerError) as e_info: await client.index_get_status( namespace=test_case.namespace, @@ -318,6 +481,4 @@ async def test_admin_client_service_config_retryable_status_codes(host, port, us end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 - - + assert abs(elapsed_time - expected_time) < 1.5 diff --git a/tests/standard/aio/test_vector_client_delete.py b/tests/standard/aio/test_vector_client_delete.py index b521d32d..45ba790e 100644 --- a/tests/standard/aio/test_vector_client_delete.py +++ b/tests/standard/aio/test_vector_client_delete.py @@ -4,6 +4,7 @@ from hypothesis import given, settings, Verbosity import grpc + class delete_test_case: def __init__( self, @@ -12,7 +13,6 @@ def __init__( record_data, set_name, timeout, - ): self.namespace = namespace self.set_name = set_name @@ -30,14 +30,14 @@ def __init__( namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=None + timeout=None, ), delete_test_case( namespace="test", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, - timeout=None - ) + timeout=None, + ), ], ) async def test_vector_delete(session_vector_client, test_case, random_key): @@ -45,7 +45,7 @@ async def test_vector_delete(session_vector_client, test_case, random_key): namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) await session_vector_client.delete( namespace=test_case.namespace, @@ -54,7 +54,9 @@ async def test_vector_delete(session_vector_client, test_case, random_key): with pytest.raises(AVSServerError) as e_info: result = await session_vector_client.get( namespace=test_case.namespace, key=random_key - ) + ) + + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -65,11 +67,13 @@ async def test_vector_delete(session_vector_client, test_case, random_key): namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=None + timeout=None, ), ], ) -async def test_vector_delete_without_record(session_vector_client, test_case, random_key): +async def test_vector_delete_without_record( + session_vector_client, test_case, random_key +): await session_vector_client.delete( namespace=test_case.namespace, key=random_key, @@ -86,19 +90,19 @@ async def test_vector_delete_without_record(session_vector_client, test_case, ra namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=0.0001 + timeout=0.0001, ), ], ) -async def test_vector_delete_timeout(session_vector_client, test_case, random_key, with_latency): +async def test_vector_delete_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): await session_vector_client.delete( - namespace=test_case.namespace, - key=random_key, - timeout=test_case.timeout + namespace=test_case.namespace, key=random_key, timeout=test_case.timeout ) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_vector_client_exists.py b/tests/standard/aio/test_vector_client_exists.py index 7119207d..9dcd3cff 100644 --- a/tests/standard/aio/test_vector_client_exists.py +++ b/tests/standard/aio/test_vector_client_exists.py @@ -3,6 +3,7 @@ from ...utils import key_strategy from hypothesis import given, settings, Verbosity + class exists_test_case: def __init__( self, @@ -17,6 +18,7 @@ def __init__( self.record_data = record_data self.timeout = timeout + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -27,15 +29,14 @@ def __init__( namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=None - + timeout=None, ), exists_test_case( namespace="test", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, - timeout=None - ) + timeout=None, + ), ], ) async def test_vector_exists(session_vector_client, test_case, random_key): @@ -43,8 +44,7 @@ async def test_vector_exists(session_vector_client, test_case, random_key): namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name - + set_name=test_case.set_name, ) result = await session_vector_client.exists( namespace=test_case.namespace, @@ -56,6 +56,8 @@ async def test_vector_exists(session_vector_client, test_case, random_key): namespace=test_case.namespace, key=random_key, ) + + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -63,21 +65,18 @@ async def test_vector_exists(session_vector_client, test_case, random_key): [ None, exists_test_case( - namespace="test", - set_name=None, - record_data=None, - timeout=0.0001 + namespace="test", set_name=None, record_data=None, timeout=0.0001 ), ], ) -async def test_vector_exists_timeout(session_vector_client, test_case, random_key, with_latency): +async def test_vector_exists_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): result = await session_vector_client.exists( - namespace=test_case.namespace, - key=random_key, - timeout=test_case.timeout + namespace=test_case.namespace, key=random_key, timeout=test_case.timeout ) assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_vector_client_get.py b/tests/standard/aio/test_vector_client_get.py index 4fdc3fd1..20aaedaa 100644 --- a/tests/standard/aio/test_vector_client_get.py +++ b/tests/standard/aio/test_vector_client_get.py @@ -4,6 +4,8 @@ from ...utils import key_strategy from hypothesis import given, settings, Verbosity + + class get_test_case: def __init__( self, @@ -22,6 +24,7 @@ def __init__( self.expected_fields = expected_fields self.timeout = timeout + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -30,20 +33,20 @@ def __init__( None, get_test_case( namespace="test", - field_names=['skills'], + field_names=["skills"], set_name=None, record_data={"skills": [i for i in range(1024)]}, expected_fields={"skills": [i for i in range(1024)]}, - timeout=None + timeout=None, ), get_test_case( namespace="test", - field_names=['english'], + field_names=["english"], set_name=None, record_data={"english": [float(i) for i in range(1024)]}, expected_fields={"english": [float(i) for i in range(1024)]}, - timeout=None - ) + timeout=None, + ), ], ) async def test_vector_get(session_vector_client, test_case, random_key): @@ -51,14 +54,13 @@ async def test_vector_get(session_vector_client, test_case, random_key): namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name - + set_name=test_case.set_name, ) result = await session_vector_client.get( namespace=test_case.namespace, key=random_key, field_names=test_case.field_names ) assert result.key.namespace == test_case.namespace - if(test_case.set_name == None): + if test_case.set_name == None: test_case.set_name = "" assert result.key.set == test_case.set_name assert result.key.key == random_key @@ -70,6 +72,7 @@ async def test_vector_get(session_vector_client, test_case, random_key): key=random_key, ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -78,19 +81,25 @@ async def test_vector_get(session_vector_client, test_case, random_key): None, get_test_case( namespace="test", - field_names=['skills'], + field_names=["skills"], set_name=None, record_data=None, expected_fields=None, - timeout=0.0001 - ), ], + timeout=0.0001, + ), + ], ) -async def test_vector_get_timeout(session_vector_client, test_case, random_key, with_latency): +async def test_vector_get_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): result = await session_vector_client.get( - namespace=test_case.namespace, key=random_key, field_names=test_case.field_names, timeout=test_case.timeout + namespace=test_case.namespace, + key=random_key, + field_names=test_case.field_names, + timeout=test_case.timeout, ) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_vector_client_insert.py b/tests/standard/aio/test_vector_client_insert.py index 62c9287a..4979282a 100644 --- a/tests/standard/aio/test_vector_client_insert.py +++ b/tests/standard/aio/test_vector_client_insert.py @@ -22,6 +22,7 @@ def __init__( self.set_name = set_name self.timeout = timeout + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -32,23 +33,25 @@ def __init__( namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), insert_test_case( namespace="test", record_data={"homeSkills": [float(i) for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), insert_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None, - timeout=None - ) + timeout=None, + ), ], ) -async def test_vector_insert_without_existing_record(session_vector_client, test_case, random_key): +async def test_vector_insert_without_existing_record( + session_vector_client, test_case, random_key +): await session_vector_client.delete( namespace=test_case.namespace, key=random_key, @@ -57,9 +60,10 @@ async def test_vector_insert_without_existing_record(session_vector_client, test namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -70,19 +74,20 @@ async def test_vector_insert_without_existing_record(session_vector_client, test namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None - - ) + timeout=None, + ), ], ) -async def test_vector_insert_with_existing_record(session_vector_client, test_case, random_key): +async def test_vector_insert_with_existing_record( + session_vector_client, test_case, random_key +): try: await session_vector_client.insert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name - ) + set_name=test_case.set_name, + ) except Exception as e: pass @@ -91,14 +96,14 @@ async def test_vector_insert_with_existing_record(session_vector_client, test_ca namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) await session_vector_client.delete( namespace=test_case.namespace, key=random_key, ) - + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -109,13 +114,15 @@ async def test_vector_insert_with_existing_record(session_vector_client, test_ca namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0.0001 - ) + timeout=0.0001, + ), ], ) -async def test_vector_insert_timeout(session_vector_client, test_case, random_key, with_latency): +async def test_vector_insert_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") with pytest.raises(AVSServerError) as e_info: for i in range(10): await session_vector_client.insert( @@ -123,6 +130,6 @@ async def test_vector_insert_timeout(session_vector_client, test_case, random_ke key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - timeout=test_case.timeout + timeout=test_case.timeout, ) assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_vector_client_update.py b/tests/standard/aio/test_vector_client_update.py index e7737188..6963ccfd 100644 --- a/tests/standard/aio/test_vector_client_update.py +++ b/tests/standard/aio/test_vector_client_update.py @@ -4,6 +4,7 @@ from hypothesis import given, settings, Verbosity import grpc + class update_test_case: def __init__( self, @@ -18,6 +19,7 @@ def __init__( self.set_name = set_name self.timeout = timeout + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -28,29 +30,31 @@ def __init__( namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), update_test_case( namespace="test", record_data={"english": [float(i) for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), update_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None, - timeout=None - ) + timeout=None, + ), ], ) -async def test_vector_update_with_existing_record(session_vector_client, test_case, random_key): +async def test_vector_update_with_existing_record( + session_vector_client, test_case, random_key +): try: await session_vector_client.insert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) except Exception as e: pass @@ -58,13 +62,14 @@ async def test_vector_update_with_existing_record(session_vector_client, test_ca namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) await session_vector_client.delete( namespace=test_case.namespace, key=random_key, ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -75,11 +80,13 @@ async def test_vector_update_with_existing_record(session_vector_client, test_ca namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None - ) + timeout=None, + ), ], ) -async def test_vector_update_without_existing_record(session_vector_client, test_case, random_key): +async def test_vector_update_without_existing_record( + session_vector_client, test_case, random_key +): await session_vector_client.delete( namespace=test_case.namespace, key=random_key, @@ -89,9 +96,10 @@ async def test_vector_update_without_existing_record(session_vector_client, test namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -102,14 +110,16 @@ async def test_vector_update_without_existing_record(session_vector_client, test namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0.0001 - ) + timeout=0.0001, + ), ], ) -async def test_vector_update_timeout(session_vector_client, test_case, random_key, with_latency): +async def test_vector_update_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") - print(with_latency) + pytest.skip("Server latency too low to test timeout") + with pytest.raises(AVSServerError) as e_info: for i in range(10): await session_vector_client.update( @@ -117,6 +127,6 @@ async def test_vector_update_timeout(session_vector_client, test_case, random_ke key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - timeout=test_case.timeout + timeout=test_case.timeout, ) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_vector_client_upsert.py b/tests/standard/aio/test_vector_client_upsert.py index 35ffe120..42320b30 100644 --- a/tests/standard/aio/test_vector_client_upsert.py +++ b/tests/standard/aio/test_vector_client_upsert.py @@ -5,16 +5,10 @@ from aerospike_vector_search import AVSServerError import grpc + + class upsert_test_case: - def __init__( - self, - *, - namespace, - record_data, - set_name, - timeout, - key=None - ): + def __init__(self, *, namespace, record_data, set_name, timeout, key=None): self.namespace = namespace self.record_data = record_data self.set_name = set_name @@ -22,6 +16,7 @@ def __init__( self.key = key + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -32,35 +27,38 @@ def __init__( namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), upsert_test_case( namespace="test", record_data={"english": [float(i) for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), upsert_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None, - timeout=None - ) + timeout=None, + ), ], ) -async def test_vector_upsert_without_existing_record(session_vector_client, test_case, random_key): +async def test_vector_upsert_without_existing_record( + session_vector_client, test_case, random_key +): await session_vector_client.upsert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) await session_vector_client.delete( namespace=test_case.namespace, key=random_key, ) - + + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -71,16 +69,18 @@ async def test_vector_upsert_without_existing_record(session_vector_client, test namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None - ) + timeout=None, + ), ], ) -async def test_vector_upsert_with_existing_record(session_vector_client, test_case, random_key): +async def test_vector_upsert_with_existing_record( + session_vector_client, test_case, random_key +): await session_vector_client.upsert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) await session_vector_client.delete( @@ -97,15 +97,15 @@ async def test_vector_upsert_with_existing_record(session_vector_client, test_ca record_data={"math": [i for i in range(1024)]}, set_name=None, timeout=None, - key=np.int32(31) + key=np.int32(31), ), upsert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, timeout=None, - key=np.array([b'a', b'b', b'c']) - ) + key=np.array([b"a", b"b", b"c"]), + ), ], ) async def test_vector_upsert_with_numpy_key(session_vector_client, test_case): @@ -113,7 +113,7 @@ async def test_vector_upsert_with_numpy_key(session_vector_client, test_case): namespace=test_case.namespace, key=test_case.key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) await session_vector_client.delete( @@ -132,16 +132,16 @@ async def test_vector_upsert_with_numpy_key(session_vector_client, test_case): namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0.0001 - ) + timeout=0.0001, + ), ], ) -async def test_vector_upsert_timeout(session_vector_client, test_case, random_key, with_latency): +async def test_vector_upsert_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: - print("INSIDE") - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") - print(with_latency) with pytest.raises(AVSServerError) as e_info: for i in range(10): await session_vector_client.upsert( @@ -149,6 +149,6 @@ async def test_vector_upsert_timeout(session_vector_client, test_case, random_ke key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - timeout=test_case.timeout + timeout=test_case.timeout, ) - assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED \ No newline at end of file + assert e_info.value.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED diff --git a/tests/standard/aio/test_vector_search.py b/tests/standard/aio/test_vector_search.py index 07da30ff..400999c9 100644 --- a/tests/standard/aio/test_vector_search.py +++ b/tests/standard/aio/test_vector_search.py @@ -67,9 +67,13 @@ def query_numpy(): return truth_numpy + async def put_vector(client, vector, j, set_name): await client.upsert( - namespace="test", key=str(j), record_data={"unit_test": vector}, set_name=set_name + namespace="test", + key=str(j), + record_data={"unit_test": vector}, + set_name=set_name, ) @@ -95,17 +99,18 @@ async def vector_search_ef_80(client, vector, name): query=vector, limit=100, field_names=["unit_test"], - search_params=types.HnswSearchParams(ef=80) + search_params=types.HnswSearchParams(ef=80), ) return result + async def grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - name + name, ): # Vector search all query vectors tasks = [] @@ -156,13 +161,11 @@ async def test_vector_search( query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): - - if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + pytest.skip("Extensive vector tests disabled") await session_admin_client.index_create( namespace="test", @@ -177,7 +180,9 @@ async def test_vector_search( for j, vector in enumerate(base_numpy): tasks.append(put_vector(session_vector_client, vector, j, None)) - tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo1')) + tasks.append( + session_vector_client.wait_for_index_completion(namespace="test", name="demo1") + ) await asyncio.gather(*tasks) await grade_results( base_numpy, @@ -185,9 +190,10 @@ async def test_vector_search( query_numpy, session_vector_client, session_admin_client, - name='demo1' + name="demo1", ) + async def test_vector_search_with_set_same_as_index( base_numpy, truth_numpy, @@ -196,14 +202,13 @@ async def test_vector_search_with_set_same_as_index( session_admin_client, ): - await session_admin_client.index_create( namespace="test", name="demo2", sets="demo2", vector_field="unit_test", dimensions=128, - index_storage=types.IndexStorage(namespace="test", set_name="demo2") + index_storage=types.IndexStorage(namespace="test", set_name="demo2"), ) # Put base vectors for search @@ -212,7 +217,9 @@ async def test_vector_search_with_set_same_as_index( for j, vector in enumerate(base_numpy): tasks.append(put_vector(session_vector_client, vector, j, "demo2")) - tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo2')) + tasks.append( + session_vector_client.wait_for_index_completion(namespace="test", name="demo2") + ) await asyncio.gather(*tasks) await grade_results( base_numpy, @@ -220,20 +227,21 @@ async def test_vector_search_with_set_same_as_index( query_numpy, session_vector_client, session_admin_client, - name='demo2' + name="demo2", ) + async def test_vector_search_with_set_different_than_name( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + pytest.skip("Extensive vector tests disabled") await session_admin_client.index_create( namespace="test", @@ -241,8 +249,7 @@ async def test_vector_search_with_set_different_than_name( vector_field="unit_test", dimensions=128, sets="example1", - index_storage=types.IndexStorage(namespace="test", set_name="demo3") - + index_storage=types.IndexStorage(namespace="test", set_name="demo3"), ) # Put base vectors for search @@ -251,7 +258,9 @@ async def test_vector_search_with_set_different_than_name( for j, vector in enumerate(base_numpy): tasks.append(put_vector(session_vector_client, vector, j, "example1")) - tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo3')) + tasks.append( + session_vector_client.wait_for_index_completion(namespace="test", name="demo3") + ) await asyncio.gather(*tasks) await grade_results( base_numpy, @@ -259,20 +268,21 @@ async def test_vector_search_with_set_different_than_name( query_numpy, session_vector_client, session_admin_client, - name="demo3" + name="demo3", ) + async def test_vector_search_with_index_storage_different_than_name( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + pytest.skip("Extensive vector tests disabled") await session_admin_client.index_create( namespace="test", @@ -280,17 +290,18 @@ async def test_vector_search_with_index_storage_different_than_name( vector_field="unit_test", dimensions=128, sets="demo4", - index_storage=types.IndexStorage(namespace="test", set_name="example2") - + index_storage=types.IndexStorage(namespace="test", set_name="example2"), ) # Put base vectors for search tasks = [] for j, vector in enumerate(base_numpy): - tasks.append(put_vector(session_vector_client, vector, j, "demo4")) + tasks.append(put_vector(session_vector_client, vector, j, "demo4")) - tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo4')) + tasks.append( + session_vector_client.wait_for_index_completion(namespace="test", name="demo4") + ) await asyncio.gather(*tasks) await grade_results( base_numpy, @@ -298,22 +309,21 @@ async def test_vector_search_with_index_storage_different_than_name( query_numpy, session_vector_client, session_admin_client, - name="demo4" + name="demo4", ) - async def test_vector_search_with_index_storage_different_location( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + pytest.skip("Extensive vector tests disabled") await session_admin_client.index_create( namespace="test", @@ -321,8 +331,7 @@ async def test_vector_search_with_index_storage_different_location( vector_field="unit_test", dimensions=128, sets="example3", - index_storage=types.IndexStorage(namespace="test", set_name="example4") - + index_storage=types.IndexStorage(namespace="test", set_name="example4"), ) # Put base vectors for search @@ -331,7 +340,9 @@ async def test_vector_search_with_index_storage_different_location( for j, vector in enumerate(base_numpy): tasks.append(put_vector(session_vector_client, vector, j, "example3")) - tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo5')) + tasks.append( + session_vector_client.wait_for_index_completion(namespace="test", name="demo5") + ) await asyncio.gather(*tasks) await grade_results( base_numpy, @@ -339,20 +350,21 @@ async def test_vector_search_with_index_storage_different_location( query_numpy, session_vector_client, session_admin_client, - name='demo5' + name="demo5", ) + async def test_vector_search_with_separate_namespace( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + pytest.skip("Extensive vector tests disabled") await session_admin_client.index_create( namespace="test", @@ -360,8 +372,7 @@ async def test_vector_search_with_separate_namespace( vector_field="unit_test", dimensions=128, sets="demo6", - index_storage=types.IndexStorage(namespace="index_storage", set_name="demo6") - + index_storage=types.IndexStorage(namespace="index_storage", set_name="demo6"), ) # Put base vectors for search @@ -370,7 +381,9 @@ async def test_vector_search_with_separate_namespace( for j, vector in enumerate(base_numpy): tasks.append(put_vector(session_vector_client, vector, j, "demo6")) - tasks.append(session_vector_client.wait_for_index_completion(namespace='test', name='demo6')) + tasks.append( + session_vector_client.wait_for_index_completion(namespace="test", name="demo6") + ) await asyncio.gather(*tasks) await grade_results( base_numpy, @@ -378,41 +391,49 @@ async def test_vector_search_with_separate_namespace( query_numpy, session_vector_client, session_admin_client, - name='demo6' + name="demo6", ) -async def test_vector_is_indexed(session_vector_client, session_admin_client, with_latency): +async def test_vector_is_indexed( + session_vector_client, session_admin_client, with_latency +): result = await session_vector_client.is_indexed( namespace="test", key=str(random.randrange(10_000)), index_name="demo2", - set_name="demo2" + set_name="demo2", ) assert result is True -async def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, with_latency): + +async def test_vector_is_indexed_timeout( + session_vector_client, session_admin_client, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: result = await session_vector_client.is_indexed( namespace="test", key=str(random.randrange(10_000)), index_name="demo2", - timeout=0.0001 + timeout=0.0001, ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED - return + return assert "In several attempts, the timeout did not happen" == "TEST FAIL" -async def test_vector_vector_search_timeout(session_vector_client, session_admin_client, with_latency): + +async def test_vector_vector_search_timeout( + session_vector_client, session_admin_client, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") - + pytest.skip("Server latency too low to test timeout") + for i in range(10): try: result = await session_vector_client.vector_search( @@ -421,10 +442,10 @@ async def test_vector_vector_search_timeout(session_vector_client, session_admin query=[0, 1, 2], limit=100, field_names=["unit_test"], - timeout=0.0001 + timeout=0.0001, ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/conftest.py b/tests/standard/conftest.py index 154495c9..f91adc1a 100644 --- a/tests/standard/conftest.py +++ b/tests/standard/conftest.py @@ -6,38 +6,68 @@ def pytest_addoption(parser): parser.addoption("--password", action="store", default=None, help="AVS Password") parser.addoption("--host", action="store", default="localhost", help="AVS Host") parser.addoption("--port", action="store", default=5000, help="AVS Port") - parser.addoption("--root_certificate", action="store", default=None, help="Path to root CA certificate") - parser.addoption("--certificate_chain", action="store", default=None, help="Path to certificate chain") - parser.addoption("--private_key", action="store", default=None, help="Path to private key") - parser.addoption("--is_loadbalancer", action="store_true", help="Enable to use load balancer tending logic") - parser.addoption("--with_latency", action="store_true", help="Skip the test if latency is too low to effectively trigger timeout") - parser.addoption("--extensive_vector_search", action="store_true", help="Run extensive vector search testing") + parser.addoption( + "--root_certificate", + action="store", + default=None, + help="Path the root certificate", + ) + parser.addoption( + "--certificate_chain", + action="store", + default=None, + help="Path to certificate chain", + ) + parser.addoption( + "--private_key", action="store", default=None, help="Path to private key" + ) + parser.addoption( + "--is_loadbalancer", + action="store_true", + help="Enable to use load balancer tending logic", + ) + parser.addoption( + "--with_latency", + action="store_true", + help="Skip the test if latency is too low to effectively trigger timeout", + ) + parser.addoption( + "--extensive_vector_search", + action="store_true", + help="Run extensive vector search testing", + ) @pytest.fixture(scope="module", autouse=True) def username(request): return request.config.getoption("--username") + @pytest.fixture(scope="module", autouse=True) def password(request): return request.config.getoption("--password") + @pytest.fixture(scope="module", autouse=True) def private_key(request): return request.config.getoption("--private_key") + @pytest.fixture(scope="module", autouse=True) def certificate_chain(request): return request.config.getoption("--certificate_chain") + @pytest.fixture(scope="module", autouse=True) def root_certificate(request): return request.config.getoption("--root_certificate") + @pytest.fixture(scope="module", autouse=True) def host(request): return request.config.getoption("--host") + @pytest.fixture(scope="module", autouse=True) def port(request): return request.config.getoption("--port") @@ -47,10 +77,12 @@ def port(request): def is_loadbalancer(request): return request.config.getoption("--is_loadbalancer") + @pytest.fixture(scope="module", autouse=True) def with_latency(request): return request.config.getoption("--with_latency") + @pytest.fixture(scope="module", autouse=True) def extensive_vector_search(request): - return request.config.getoption("--extensive_vector_search") \ No newline at end of file + return request.config.getoption("--extensive_vector_search") diff --git a/tests/standard/sync/conftest.py b/tests/standard/sync/conftest.py index 81e17308..4b1323f9 100644 --- a/tests/standard/sync/conftest.py +++ b/tests/standard/sync/conftest.py @@ -5,46 +5,183 @@ @pytest.fixture(scope="module", autouse=True) -def drop_all_indexes(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): +def drop_all_indexes( + username, + password, + root_certificate, + host, + port, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + with AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) as client: index_list = client.index_list() tasks = [] for item in index_list: - client.index_drop(namespace="test", name=item['id']['name']) + client.index_drop(namespace="test", name=item["id"]["name"]) @pytest.fixture(scope="module") -def session_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): +def session_admin_client( + username, + password, + root_certificate, + host, + port, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + client = AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) yield client client.close() + @pytest.fixture(scope="module") -def session_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): +def session_admin_client( + username, + password, + root_certificate, + host, + port, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + client = AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) - print(is_loadbalancer) yield client client.close() + @pytest.fixture(scope="module") -def session_vector_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): +def session_vector_client( + username, + password, + root_certificate, + host, + port, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + client = Client( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) yield client client.close() + @pytest.fixture -def function_admin_client(username, password, root_certificate, host, port, certificate_chain, private_key, is_loadbalancer): +def function_admin_client( + username, + password, + root_certificate, + host, + port, + certificate_chain, + private_key, + is_loadbalancer, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + client = AdminClient( - seeds=types.HostPort(host=host, port=port), is_loadbalancer=is_loadbalancer, username=username, password=password, root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key + seeds=types.HostPort(host=host, port=port), + is_loadbalancer=is_loadbalancer, + username=username, + password=password, + root_certificate=root_certificate, + certificate_chain=certificate_chain, + private_key=private_key, ) yield client client.close() diff --git a/tests/standard/sync/test_admin_client_index_create.py b/tests/standard/sync/test_admin_client_index_create.py index d5a84f33..79d342c4 100644 --- a/tests/standard/sync/test_admin_client_index_create.py +++ b/tests/standard/sync/test_admin_client_index_create.py @@ -6,6 +6,7 @@ from .sync_utils import drop_specified_index from hypothesis import given, settings, Verbosity + class index_create_test_case: def __init__( self, @@ -16,7 +17,7 @@ def __init__( vector_distance_metric, sets, index_params, - index_meta_data, + index_labels, index_storage, timeout ): @@ -29,10 +30,11 @@ def __init__( self.vector_distance_metric = vector_distance_metric self.sets = sets self.index_params = index_params - self.index_meta_data = index_meta_data + self.index_labels = index_labels self.index_storage = index_storage self.timeout = timeout + @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -45,20 +47,19 @@ def __init__( vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ) ], ) def test_index_create(session_admin_client, test_case, random_name): - try: + try: session_admin_client.index_drop(namespace="test", name=random_name) except AVSServerError as se: if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: pass - session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -67,27 +68,26 @@ def test_index_create(session_admin_client, test_case, random_name): vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) - results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True drop_specified_index(session_admin_client, test_case.namespace, random_name) @@ -104,7 +104,7 @@ def test_index_create(session_admin_client, test_case, random_name): vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -115,7 +115,7 @@ def test_index_create(session_admin_client, test_case, random_name): vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -123,13 +123,12 @@ def test_index_create(session_admin_client, test_case, random_name): ) def test_index_create_with_dimnesions(session_admin_client, test_case, random_name): - try: + try: session_admin_client.index_drop(namespace="test", name=random_name) except AVSServerError as se: if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: pass - session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -138,35 +137,33 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) - results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True drop_specified_index(session_admin_client, test_case.namespace, random_name) - @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -179,7 +176,7 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na vector_distance_metric=types.VectorDistanceMetric.COSINE, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -190,7 +187,7 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na vector_distance_metric=types.VectorDistanceMetric.DOT_PRODUCT, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -201,7 +198,7 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na vector_distance_metric=types.VectorDistanceMetric.MANHATTAN, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -212,7 +209,7 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na vector_distance_metric=types.VectorDistanceMetric.HAMMING, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -222,7 +219,7 @@ def test_index_create_with_vector_distance_metric( session_admin_client, test_case, random_name ): - try: + try: session_admin_client.index_drop(namespace="test", name=random_name) except AVSServerError as se: if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: @@ -236,25 +233,25 @@ def test_index_create_with_vector_distance_metric( vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True drop_specified_index(session_admin_client, test_case.namespace, random_name) @@ -271,7 +268,7 @@ def test_index_create_with_vector_distance_metric( vector_distance_metric=None, sets="Demo", index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -282,7 +279,7 @@ def test_index_create_with_vector_distance_metric( vector_distance_metric=None, sets="Cheese", index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -290,7 +287,7 @@ def test_index_create_with_vector_distance_metric( ) def test_index_create_with_sets(session_admin_client, test_case, random_name): - try: + try: session_admin_client.index_drop(namespace="test", name=random_name) except AVSServerError as se: if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: @@ -304,25 +301,25 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True drop_specified_index(session_admin_client, test_case.namespace, random_name) @@ -343,7 +340,7 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): ef_construction=200, ef=400, ), - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -354,12 +351,9 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): vector_distance_metric=None, sets=None, index_params=types.HnswParams( - m=8, - ef_construction=50, - ef=25, - max_mem_queue_size=16384 + m=8, ef_construction=50, ef=25, max_mem_queue_size=16384 ), - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -370,12 +364,9 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): vector_distance_metric=None, sets=None, index_params=types.HnswParams( - batching_params=types.HnswBatchingParams( - max_records=500, interval=500 - ), - + batching_params=types.HnswBatchingParams(max_records=500, interval=500), ), - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, ), @@ -394,22 +385,20 @@ def test_index_create_with_sets(session_admin_client, test_case, random_name): schedule_delay=5, parallelism=4, ), - merge_params=types.HnswIndexMergeParams( - parallelism=10 - ) + merge_params=types.HnswIndexMergeParams(parallelism=10), ), - index_meta_data=None, + index_labels=None, index_storage=None, timeout=None, - ) + ), ], ) def test_index_create_with_index_params(session_admin_client, test_case, random_name): - try: + try: session_admin_client.index_drop(namespace="test", name=random_name) except AVSServerError as se: if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: - pass + pass session_admin_client.index_create( namespace=test_case.namespace, name=random_name, @@ -418,46 +407,82 @@ def test_index_create_with_index_params(session_admin_client, test_case, random_ vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) - - results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert result['hnsw_params']['m'] == test_case.index_params.m - assert result['hnsw_params']['ef_construction'] == test_case.index_params.ef_construction - assert result['hnsw_params']['ef'] == test_case.index_params.ef - if 'max_mem_queue_size' in result.get('hnsw_params', {}): - assert result['hnsw_params']['max_mem_queue_size'] == test_case.index_params.max_mem_queue_size - - assert result['hnsw_params']['batching_params']['max_records'] == test_case.index_params.batching_params.max_records - assert result['hnsw_params']['batching_params']['interval'] == test_case.index_params.batching_params.interval - if 'caching_params' in result.get('hnsw_params', {}): - - assert int(result['hnsw_params']['caching_params']['max_entries']) == test_case.index_params.caching_params.max_entries - assert int(result['hnsw_params']['caching_params']['expiry']) == test_case.index_params.caching_params.expiry - - if 'merge_params' in result.get('hnsw_params', {}): - assert result['hnsw_params']['merge_params']['parallelism'] == test_case.index_params.merge_params.parallelism - - if 'healer_params' in result.get('hnsw_params', {}): - assert int(result['hnsw_params']['healer_params']['max_scan_rate_per_node']) == test_case.index_params.healer_params.max_scan_rate_per_node - assert int(result['hnsw_params']['healer_params']['max_scan_page_size']) == test_case.index_params.healer_params.max_scan_page_size - assert int(result['hnsw_params']['healer_params']['re_index_percent']) == test_case.index_params.healer_params.re_index_percent - assert int(result['hnsw_params']['healer_params']['schedule_delay']) == test_case.index_params.healer_params.schedule_delay - assert result['hnsw_params']['healer_params']['parallelism'] == test_case.index_params.healer_params.parallelism - - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert result["hnsw_params"]["m"] == test_case.index_params.m + assert ( + result["hnsw_params"]["ef_construction"] + == test_case.index_params.ef_construction + ) + assert result["hnsw_params"]["ef"] == test_case.index_params.ef + if "max_mem_queue_size" in result.get("hnsw_params", {}): + assert ( + result["hnsw_params"]["max_mem_queue_size"] + == test_case.index_params.max_mem_queue_size + ) + + assert ( + result["hnsw_params"]["batching_params"]["max_records"] + == test_case.index_params.batching_params.max_records + ) + assert ( + result["hnsw_params"]["batching_params"]["interval"] + == test_case.index_params.batching_params.interval + ) + if "caching_params" in result.get("hnsw_params", {}): + + assert ( + int(result["hnsw_params"]["caching_params"]["max_entries"]) + == test_case.index_params.caching_params.max_entries + ) + assert ( + int(result["hnsw_params"]["caching_params"]["expiry"]) + == test_case.index_params.caching_params.expiry + ) + + if "merge_params" in result.get("hnsw_params", {}): + assert ( + result["hnsw_params"]["merge_params"]["parallelism"] + == test_case.index_params.merge_params.parallelism + ) + + if "healer_params" in result.get("hnsw_params", {}): + assert ( + int( + result["hnsw_params"]["healer_params"]["max_scan_rate_per_node"] + ) + == test_case.index_params.healer_params.max_scan_rate_per_node + ) + assert ( + int(result["hnsw_params"]["healer_params"]["max_scan_page_size"]) + == test_case.index_params.healer_params.max_scan_page_size + ) + assert ( + int(result["hnsw_params"]["healer_params"]["re_index_percent"]) + == test_case.index_params.healer_params.re_index_percent + ) + assert ( + int(result["hnsw_params"]["healer_params"]["schedule_delay"]) + == test_case.index_params.healer_params.schedule_delay + ) + assert ( + result["hnsw_params"]["healer_params"]["parallelism"] + == test_case.index_params.healer_params.parallelism + ) + + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True drop_specified_index(session_admin_client, test_case.namespace, random_name) @@ -474,14 +499,14 @@ def test_index_create_with_index_params(session_admin_client, test_case, random_ vector_distance_metric=None, sets=None, index_params=None, - index_meta_data={"size": "large", "price": "$4.99", "currencyType": "CAN"}, + index_labels={"size": "large", "price": "$4.99", "currencyType": "CAN"}, index_storage=None, timeout=None, ) ], ) -def test_index_create_index_meta_data(session_admin_client, test_case, random_name): - try: +def test_index_create_index_labels(session_admin_client, test_case, random_name): + try: session_admin_client.index_drop(namespace="test", name=random_name) except AVSServerError as se: if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: @@ -494,32 +519,32 @@ def test_index_create_index_meta_data(session_admin_client, test_case, random_na vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) - results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert result['field'] == test_case.vector_field - assert isinstance(result['field'], str) - - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.namespace - assert result['storage']['set'] == random_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert result["field"] == test_case.vector_field + assert isinstance(result["field"], str) + + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.namespace + assert result["storage"]["set"] == random_name assert found == True drop_specified_index(session_admin_client, test_case.namespace, random_name) + @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -532,14 +557,14 @@ def test_index_create_index_meta_data(session_admin_client, test_case, random_na vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=types.IndexStorage(namespace="test", set_name="foo"), timeout=None, ), ], ) def test_index_create_index_storage(session_admin_client, test_case, random_name): - try: + try: session_admin_client.index_drop(namespace="test", name=random_name) except AVSServerError as se: if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: @@ -552,29 +577,29 @@ def test_index_create_index_storage(session_admin_client, test_case, random_name vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) - results = session_admin_client.index_list() found = False for result in results: - if result['id']['name'] == random_name: + if result["id"]["name"] == random_name: found = True - assert result['id']['namespace'] == test_case.namespace - assert result['dimensions'] == test_case.dimensions - assert isinstance(result['field'], str) - assert result['hnsw_params']['m'] == 16 - assert result['hnsw_params']['ef_construction'] == 100 - assert result['hnsw_params']['ef'] == 100 - assert result['hnsw_params']['batching_params']['max_records'] == 100000 - assert result['hnsw_params']['batching_params']['interval'] == 30000 - assert result['storage']['namespace'] == test_case.index_storage.namespace - assert result['storage']['set'] == test_case.index_storage.set_name + assert result["id"]["namespace"] == test_case.namespace + assert result["dimensions"] == test_case.dimensions + assert isinstance(result["field"], str) + assert result["hnsw_params"]["m"] == 16 + assert result["hnsw_params"]["ef_construction"] == 100 + assert result["hnsw_params"]["ef"] == 100 + assert result["hnsw_params"]["batching_params"]["max_records"] == 100000 + assert result["hnsw_params"]["batching_params"]["interval"] == 30000 + assert result["storage"]["namespace"] == test_case.index_storage.namespace + assert result["storage"]["set"] == test_case.index_storage.set_name assert found == True + @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( @@ -587,13 +612,15 @@ def test_index_create_index_storage(session_admin_client, test_case, random_name vector_distance_metric=None, sets=None, index_params=None, - index_meta_data=None, + index_labels=None, index_storage=None, timeout=0.0001, ), ], ) -def test_index_create_timeout(session_admin_client, test_case, random_name, with_latency): +def test_index_create_timeout( + session_admin_client, test_case, random_name, with_latency +): if not with_latency: pytest.skip("Server latency too low to test timeout") @@ -603,7 +630,6 @@ def test_index_create_timeout(session_admin_client, test_case, random_name, with if se.rpc_error.code() != grpc.StatusCode.NOT_FOUND: pass - for i in range(10): try: session_admin_client.index_create( @@ -614,12 +640,12 @@ def test_index_create_timeout(session_admin_client, test_case, random_name, with vector_distance_metric=test_case.vector_distance_metric, sets=test_case.sets, index_params=test_case.index_params, - index_meta_data=test_case.index_meta_data, + index_labels=test_case.index_labels, index_storage=test_case.index_storage, - timeout=test_case.timeout + timeout=test_case.timeout, ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_admin_client_index_drop.py b/tests/standard/sync/test_admin_client_index_drop.py index 5aaa4682..7e1c6c90 100644 --- a/tests/standard/sync/test_admin_client_index_drop.py +++ b/tests/standard/sync/test_admin_client_index_drop.py @@ -8,9 +8,7 @@ from hypothesis import given, settings, Verbosity - - -@pytest.mark.parametrize("empty_test_case",[None]) +@pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) def test_index_drop(session_admin_client, empty_test_case, random_name): @@ -34,12 +32,15 @@ def test_index_drop(session_admin_client, empty_test_case, random_name): for index in result: assert index["id"]["name"] != random_name -@pytest.mark.parametrize("empty_test_case",[None]) + +@pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_drop_timeout(session_admin_client, empty_test_case, random_name, with_latency): +def test_index_drop_timeout( + session_admin_client, empty_test_case, random_name, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") try: session_admin_client.index_create( @@ -52,11 +53,13 @@ def test_index_drop_timeout(session_admin_client, empty_test_case, random_name, if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: raise se - for i in range(10): + for i in range(10): try: - session_admin_client.index_drop(namespace="test", name=random_name, timeout=0.0001) + session_admin_client.index_drop( + namespace="test", name=random_name, timeout=0.0001 + ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_admin_client_index_get.py b/tests/standard/sync/test_admin_client_index_get.py index 6a3d483e..e9af212e 100644 --- a/tests/standard/sync/test_admin_client_index_get.py +++ b/tests/standard/sync/test_admin_client_index_get.py @@ -7,12 +7,11 @@ import grpc -@pytest.mark.parametrize("empty_test_case",[None]) +@pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) def test_index_get(session_admin_client, empty_test_case, random_name): - try: session_admin_client.index_create( namespace="test", @@ -24,15 +23,12 @@ def test_index_get(session_admin_client, empty_test_case, random_name): if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: raise se + result = session_admin_client.index_get(namespace="test", name=random_name) - result = session_admin_client.index_get( - namespace="test", name=random_name - ) - assert result["id"]["name"] == random_name assert result["id"]["namespace"] == "test" assert result["dimensions"] == 1024 - assert result['field'] == "science" + assert result["field"] == "science" assert result["hnsw_params"]["m"] == 16 assert result["hnsw_params"]["ef_construction"] == 100 assert result["hnsw_params"]["ef"] == 100 @@ -43,12 +39,15 @@ def test_index_get(session_admin_client, empty_test_case, random_name): drop_specified_index(session_admin_client, "test", random_name) -@pytest.mark.parametrize("empty_test_case",[None]) + +@pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_get_timeout(session_admin_client, empty_test_case, random_name, with_latency): +def test_index_get_timeout( + session_admin_client, empty_test_case, random_name, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") try: session_admin_client.index_create( namespace="test", @@ -60,8 +59,6 @@ def test_index_get_timeout(session_admin_client, empty_test_case, random_name, w if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: raise se - - for i in range(10): try: result = session_admin_client.index_get( @@ -72,4 +69,4 @@ def test_index_get_timeout(session_admin_client, empty_test_case, random_name, w if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_admin_client_index_get_status.py b/tests/standard/sync/test_admin_client_index_get_status.py index 772c24b3..ffa8f0b8 100644 --- a/tests/standard/sync/test_admin_client_index_get_status.py +++ b/tests/standard/sync/test_admin_client_index_get_status.py @@ -8,7 +8,8 @@ from aerospike_vector_search import AVSServerError import grpc -@pytest.mark.parametrize("empty_test_case",[None]) + +@pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) def test_index_get_status(session_admin_client, empty_test_case, random_name): @@ -22,17 +23,18 @@ def test_index_get_status(session_admin_client, empty_test_case, random_name): except AVSServerError as se: if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: raise se - result = session_admin_client.index_get_status( - namespace="test", name=random_name - ) + result = session_admin_client.index_get_status(namespace="test", name=random_name) assert result == 0 drop_specified_index(session_admin_client, "test", random_name) -@pytest.mark.parametrize("empty_test_case",[None]) + +@pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_get_status_timeout(session_admin_client, empty_test_case, random_name, with_latency): +def test_index_get_status_timeout( + session_admin_client, empty_test_case, random_name, with_latency +): if not with_latency: pytest.skip("Server latency too low to test timeout") @@ -46,4 +48,4 @@ def test_index_get_status_timeout(session_admin_client, empty_test_case, random_ assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_admin_client_index_list.py b/tests/standard/sync/test_admin_client_index_list.py index 02d15c89..121a3a32 100644 --- a/tests/standard/sync/test_admin_client_index_list.py +++ b/tests/standard/sync/test_admin_client_index_list.py @@ -7,7 +7,8 @@ from .sync_utils import drop_specified_index from hypothesis import given, settings, Verbosity -@pytest.mark.parametrize("empty_test_case",[None]) + +@pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) @settings(max_examples=5, deadline=1000) def test_index_list(session_admin_client, empty_test_case, random_name): @@ -20,24 +21,26 @@ def test_index_list(session_admin_client, empty_test_case, random_name): result = session_admin_client.index_list() assert len(result) > 0 for index in result: - assert isinstance(index['id']['name'], str) - assert isinstance(index['id']['namespace'], str) - assert isinstance(index['dimensions'], int) - assert isinstance(index['field'], str) - assert isinstance(index['hnsw_params']['m'], int) - assert isinstance(index['hnsw_params']['ef_construction'], int) - assert isinstance(index['hnsw_params']['ef'], int) - assert isinstance(index['hnsw_params']['batching_params']['max_records'], int) - assert isinstance(index['hnsw_params']['batching_params']['interval'], int) - assert isinstance(index['storage']['namespace'], str) - assert isinstance(index['storage']['set'], str) + assert isinstance(index["id"]["name"], str) + assert isinstance(index["id"]["namespace"], str) + assert isinstance(index["dimensions"], int) + assert isinstance(index["field"], str) + assert isinstance(index["hnsw_params"]["m"], int) + assert isinstance(index["hnsw_params"]["ef_construction"], int) + assert isinstance(index["hnsw_params"]["ef"], int) + assert isinstance(index["hnsw_params"]["batching_params"]["max_records"], int) + assert isinstance(index["hnsw_params"]["batching_params"]["interval"], int) + assert isinstance(index["storage"]["namespace"], str) + assert isinstance(index["storage"]["set"], str) drop_specified_index(session_admin_client, "test", random_name) -@pytest.mark.parametrize("empty_test_case",[None]) +@pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) @settings(max_examples=1, deadline=1000) -def test_index_list_timeout(session_admin_client, empty_test_case, random_name, with_latency): +def test_index_list_timeout( + session_admin_client, empty_test_case, random_name, with_latency +): if not with_latency: pytest.skip("Server latency too low to test timeout") @@ -51,7 +54,7 @@ def test_index_list_timeout(session_admin_client, empty_test_case, random_name, except AVSServerError as se: if se.rpc_error.code() != grpc.StatusCode.ALREADY_EXISTS: raise se - + for i in range(10): try: @@ -61,4 +64,4 @@ def test_index_list_timeout(session_admin_client, empty_test_case, random_name, if se.rpc_error.code() != grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_service_config.py b/tests/standard/sync/test_service_config.py index 990578b1..73926b7d 100644 --- a/tests/standard/sync/test_service_config.py +++ b/tests/standard/sync/test_service_config.py @@ -7,14 +7,12 @@ from aerospike_vector_search import AVSServerError, types from aerospike_vector_search import AdminClient + class service_config_parse_test_case: - def __init__( - self, - *, - service_config_path - ): + def __init__(self, *, service_config_path): self.service_config_path = service_config_path + @pytest.mark.parametrize( "test_case", [ @@ -23,7 +21,28 @@ def __init__( ), ], ) -def test_admin_client_service_config_parse(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +def test_admin_client_service_config_parse( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -31,68 +50,99 @@ def test_admin_client_service_config_parse(host, port, username, password, root root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path + service_config_path=test_case.service_config_path, ) as client: pass + class service_config_test_case: def __init__( - self, - *, - service_config_path, - namespace, - name, - vector_field, - dimensions + self, *, service_config_path, namespace, name, vector_field, dimensions ): script_dir = os.path.dirname(os.path.abspath(__file__)) - self.service_config_path = os.path.abspath(os.path.join(script_dir, '..', '..', service_config_path)) + self.service_config_path = os.path.abspath( + os.path.join(script_dir, "..", "..", service_config_path) + ) - with open(self.service_config_path, 'rb') as f: + with open(self.service_config_path, "rb") as f: self.service_config = json.load(f) - - - - self.max_attempts = self.service_config["methodConfig"][0]["retryPolicy"]["maxAttempts"] - self.initial_backoff = int(self.service_config["methodConfig"][0]["retryPolicy"]["initialBackoff"][:-1]) - self.max_backoff = int(self.service_config["methodConfig"][0]["retryPolicy"]["maxBackoff"][:-1]) - self.backoff_multiplier = self.service_config["methodConfig"][0]["retryPolicy"]["backoffMultiplier"] - self.retryable_status_codes = self.service_config["methodConfig"][0]["retryPolicy"]["retryableStatusCodes"] + self.max_attempts = self.service_config["methodConfig"][0]["retryPolicy"][ + "maxAttempts" + ] + self.initial_backoff = int( + self.service_config["methodConfig"][0]["retryPolicy"]["initialBackoff"][:-1] + ) + self.max_backoff = int( + self.service_config["methodConfig"][0]["retryPolicy"]["maxBackoff"][:-1] + ) + self.backoff_multiplier = self.service_config["methodConfig"][0]["retryPolicy"][ + "backoffMultiplier" + ] + self.retryable_status_codes = self.service_config["methodConfig"][0][ + "retryPolicy" + ]["retryableStatusCodes"] self.namespace = namespace self.name = name self.vector_field = vector_field self.dimensions = dimensions -def calculate_expected_time(max_attempts, initial_backoff, backoff_multiplier, max_backoff, retryable_status_codes): +def calculate_expected_time( + max_attempts, + initial_backoff, + backoff_multiplier, + max_backoff, + retryable_status_codes, +): current_backkoff = initial_backoff expected_time = 0 - for attempt in range(max_attempts-1): + for attempt in range(max_attempts - 1): expected_time += current_backkoff current_backkoff *= backoff_multiplier current_backkoff = min(current_backkoff, max_backoff) return expected_time + @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/retries.json", namespace="test", name="service_config_index_1", vector_field="example_1", - dimensions=1024 + dimensions=1024, ) ], ) -def test_admin_client_service_config_retries(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +def test_admin_client_service_config_retries( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -100,7 +150,7 @@ def test_admin_client_service_config_retries(host, port, username, password, ro root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path + service_config_path=test_case.service_config_path, ) as client: try: @@ -112,7 +162,13 @@ def test_admin_client_service_config_retries(host, port, username, password, ro ) except: pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() with pytest.raises(AVSServerError) as e_info: @@ -126,22 +182,43 @@ def test_admin_client_service_config_retries(host, port, username, password, ro end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + assert abs(elapsed_time - expected_time) < 1.5 + @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/initial_backoff.json", namespace="test", name="service_config_index_2", vector_field="example_1", - dimensions=1024 + dimensions=1024, ) ], ) -def test_admin_client_service_config_initial_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +def test_admin_client_service_config_initial_backoff( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -149,8 +226,7 @@ def test_admin_client_service_config_initial_backoff(host, port, username, pass root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path - + service_config_path=test_case.service_config_path, ) as client: try: @@ -162,7 +238,13 @@ def test_admin_client_service_config_initial_backoff(host, port, username, pass ) except: pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() with pytest.raises(AVSServerError) as e_info: @@ -176,29 +258,50 @@ def test_admin_client_service_config_initial_backoff(host, port, username, pass end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + assert abs(elapsed_time - expected_time) < 1.5 + @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/max_backoff.json", namespace="test", name="service_config_index_3", vector_field="example_1", - dimensions=1024 + dimensions=1024, ), service_config_test_case( service_config_path="service_configs/max_backoff_lower_than_initial.json", namespace="test", name="service_config_index_4", vector_field="example_1", - dimensions=1024 - ) + dimensions=1024, + ), ], ) -def test_admin_client_service_config_max_backoff(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +def test_admin_client_service_config_max_backoff( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -206,8 +309,7 @@ def test_admin_client_service_config_max_backoff(host, port, username, password root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path - + service_config_path=test_case.service_config_path, ) as client: try: @@ -219,7 +321,13 @@ def test_admin_client_service_config_max_backoff(host, port, username, password ) except: pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() with pytest.raises(AVSServerError) as e_info: @@ -232,23 +340,43 @@ def test_admin_client_service_config_max_backoff(host, port, username, password end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + assert abs(elapsed_time - expected_time) < 1.5 @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/backoff_multiplier.json", namespace="test", name="service_config_index_5", vector_field="example_1", - dimensions=1024 + dimensions=1024, ) ], ) -def test_admin_client_service_config_backoff_multiplier(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +def test_admin_client_service_config_backoff_multiplier( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -256,8 +384,7 @@ def test_admin_client_service_config_backoff_multiplier(host, port, username, p root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path - + service_config_path=test_case.service_config_path, ) as client: try: @@ -269,7 +396,13 @@ def test_admin_client_service_config_backoff_multiplier(host, port, username, p ) except: pass - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() with pytest.raises(AVSServerError) as e_info: @@ -282,23 +415,43 @@ def test_admin_client_service_config_backoff_multiplier(host, port, username, p end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 + assert abs(elapsed_time - expected_time) < 1.5 @pytest.mark.parametrize( "test_case", [ - service_config_test_case( service_config_path="service_configs/retryable_status_codes.json", namespace="test", name="service_config_index_6", vector_field=None, - dimensions=None + dimensions=None, ) ], ) -def test_admin_client_service_config_retryable_status_codes(host, port, username, password, root_certificate, certificate_chain, private_key, test_case): +def test_admin_client_service_config_retryable_status_codes( + host, + port, + username, + password, + root_certificate, + certificate_chain, + private_key, + test_case, +): + + if root_certificate: + with open(root_certificate, "rb") as f: + root_certificate = f.read() + + if certificate_chain: + with open(certificate_chain, "rb") as f: + certificate_chain = f.read() + if private_key: + with open(private_key, "rb") as f: + private_key = f.read() + with AdminClient( seeds=types.HostPort(host=host, port=port), username=username, @@ -306,21 +459,24 @@ def test_admin_client_service_config_retryable_status_codes(host, port, usernam root_certificate=root_certificate, certificate_chain=certificate_chain, private_key=private_key, - service_config_path=test_case.service_config_path - + service_config_path=test_case.service_config_path, ) as client: - expected_time = calculate_expected_time(test_case.max_attempts, test_case.initial_backoff, test_case.backoff_multiplier, test_case.max_backoff, test_case.retryable_status_codes) + expected_time = calculate_expected_time( + test_case.max_attempts, + test_case.initial_backoff, + test_case.backoff_multiplier, + test_case.max_backoff, + test_case.retryable_status_codes, + ) start_time = time.time() - + with pytest.raises(AVSServerError) as e_info: client.index_get_status( namespace=test_case.namespace, name=test_case.name, ) - + end_time = time.time() elapsed_time = end_time - start_time - assert abs(elapsed_time - expected_time) < 1.2 - - + assert abs(elapsed_time - expected_time) < 1.5 diff --git a/tests/standard/sync/test_vector_client_delete.py b/tests/standard/sync/test_vector_client_delete.py index a6f740ef..237b09ff 100644 --- a/tests/standard/sync/test_vector_client_delete.py +++ b/tests/standard/sync/test_vector_client_delete.py @@ -6,6 +6,7 @@ from ...utils import key_strategy from hypothesis import given, settings, Verbosity + class delete_test_case: def __init__( self, @@ -14,7 +15,6 @@ def __init__( record_data, set_name, timeout, - ): self.namespace = namespace self.set_name = set_name @@ -31,15 +31,14 @@ def __init__( namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=None - + timeout=None, ), delete_test_case( namespace="test", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, - timeout=None - ) + timeout=None, + ), ], ) def test_vector_delete(session_vector_client, test_case, random_key): @@ -47,7 +46,7 @@ def test_vector_delete(session_vector_client, test_case, random_key): namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) session_vector_client.delete( namespace=test_case.namespace, @@ -56,7 +55,8 @@ def test_vector_delete(session_vector_client, test_case, random_key): with pytest.raises(AVSServerError) as e_info: result = session_vector_client.get( namespace=test_case.namespace, key=random_key - ) + ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @@ -67,8 +67,7 @@ def test_vector_delete(session_vector_client, test_case, random_key): namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=None - + timeout=None, ), ], ) @@ -78,6 +77,7 @@ def test_vector_delete_without_record(session_vector_client, test_case, random_k key=random_key, ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -87,23 +87,23 @@ def test_vector_delete_without_record(session_vector_client, test_case, random_k namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=0.0001 + timeout=0.0001, ), ], ) -def test_vector_delete_timeout(session_vector_client, test_case, random_key, with_latency): +def test_vector_delete_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: session_vector_client.delete( - namespace=test_case.namespace, - key=random_key, - timeout=test_case.timeout + namespace=test_case.namespace, key=random_key, timeout=test_case.timeout ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_vector_client_exists.py b/tests/standard/sync/test_vector_client_exists.py index 95f2775a..e470a981 100644 --- a/tests/standard/sync/test_vector_client_exists.py +++ b/tests/standard/sync/test_vector_client_exists.py @@ -5,6 +5,7 @@ from hypothesis import given, settings, Verbosity from aerospike_vector_search import types, AVSServerError + class exists_test_case: def __init__( self, @@ -19,6 +20,7 @@ def __init__( self.record_data = record_data self.timeout = timeout + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -28,14 +30,14 @@ def __init__( namespace="test", set_name=None, record_data={"skills": [i for i in range(1024)]}, - timeout=None + timeout=None, ), exists_test_case( namespace="test", set_name=None, record_data={"english": [float(i) for i in range(1024)]}, - timeout=None - ) + timeout=None, + ), ], ) def test_vector_exists(session_vector_client, test_case, random_key): @@ -44,47 +46,44 @@ def test_vector_exists(session_vector_client, test_case, random_key): key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - timeout=None - + timeout=None, ) result = session_vector_client.exists( namespace=test_case.namespace, key=random_key, ) assert result is True - + session_vector_client.delete( namespace=test_case.namespace, key=random_key, ) + @given(random_key=key_strategy()) @settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ exists_test_case( - namespace="test", - set_name=None, - record_data=None, - timeout=0.0001 + namespace="test", set_name=None, record_data=None, timeout=0.0001 ), ], ) -def test_vector_exists_timeout(session_vector_client, test_case, random_key, with_latency): +def test_vector_exists_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: result = session_vector_client.exists( - namespace=test_case.namespace, - key=random_key, - timeout=test_case.timeout + namespace=test_case.namespace, key=random_key, timeout=test_case.timeout ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_vector_client_get.py b/tests/standard/sync/test_vector_client_get.py index 8c25455a..3c847ee9 100644 --- a/tests/standard/sync/test_vector_client_get.py +++ b/tests/standard/sync/test_vector_client_get.py @@ -5,6 +5,7 @@ from aerospike_vector_search import types, AVSServerError + class get_test_case: def __init__( self, @@ -31,20 +32,20 @@ def __init__( [ get_test_case( namespace="test", - field_names=['skills'], + field_names=["skills"], set_name=None, record_data={"skills": [i for i in range(1024)]}, expected_fields={"skills": [i for i in range(1024)]}, - timeout=None + timeout=None, ), get_test_case( namespace="test", - field_names=['english'], + field_names=["english"], set_name=None, record_data={"english": [float(i) for i in range(1024)]}, expected_fields={"english": [float(i) for i in range(1024)]}, - timeout=None - ) + timeout=None, + ), ], ) def test_vector_get(session_vector_client, test_case, random_key): @@ -52,14 +53,13 @@ def test_vector_get(session_vector_client, test_case, random_key): namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name - + set_name=test_case.set_name, ) result = session_vector_client.get( namespace=test_case.namespace, key=random_key, field_names=test_case.field_names ) assert result.key.namespace == test_case.namespace - if(test_case.set_name == None): + if test_case.set_name == None: test_case.set_name = "" assert result.key.set == test_case.set_name assert result.key.key == random_key @@ -71,6 +71,7 @@ def test_vector_get(session_vector_client, test_case, random_key): key=random_key, ) + @given(random_key=key_strategy()) @settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( @@ -78,25 +79,28 @@ def test_vector_get(session_vector_client, test_case, random_key): [ get_test_case( namespace="test", - field_names=['skills'], + field_names=["skills"], set_name=None, record_data=None, expected_fields=None, - timeout=0.0001 - ), + timeout=0.0001, + ), ], ) def test_vector_get_timeout(session_vector_client, test_case, random_key, with_latency): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: result = session_vector_client.get( - namespace=test_case.namespace, key=random_key, field_names=test_case.field_names, timeout=test_case.timeout + namespace=test_case.namespace, + key=random_key, + field_names=test_case.field_names, + timeout=test_case.timeout, ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_vector_client_insert.py b/tests/standard/sync/test_vector_client_insert.py index 26ddbd5a..307d5f28 100644 --- a/tests/standard/sync/test_vector_client_insert.py +++ b/tests/standard/sync/test_vector_client_insert.py @@ -7,15 +7,10 @@ from hypothesis import given, settings + class insert_test_case: def __init__( - self, - *, - namespace, - record_data, - set_name, - ignore_mem_queue_full, - timeout + self, *, namespace, record_data, set_name, ignore_mem_queue_full, timeout ): self.namespace = namespace self.record_data = record_data @@ -23,6 +18,7 @@ def __init__( self.ignore_mem_queue_full = ignore_mem_queue_full self.timeout = timeout + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -33,35 +29,37 @@ def __init__( record_data={"math": [i for i in range(1024)]}, set_name=None, ignore_mem_queue_full=None, - timeout=None + timeout=None, ), insert_test_case( namespace="test", record_data={"homeSkills": [float(i) for i in range(1024)]}, set_name=None, ignore_mem_queue_full=None, - timeout=None + timeout=None, ), insert_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None, ignore_mem_queue_full=None, - timeout=None - ) + timeout=None, + ), ], ) -def test_vector_insert_without_existing_record(session_vector_client, test_case, random_key): +def test_vector_insert_without_existing_record( + session_vector_client, test_case, random_key +): session_vector_client.delete( namespace=test_case.namespace, key=random_key, ) - + session_vector_client.insert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) session_vector_client.delete( @@ -69,6 +67,7 @@ def test_vector_insert_without_existing_record(session_vector_client, test_case, key=random_key, ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -79,29 +78,32 @@ def test_vector_insert_without_existing_record(session_vector_client, test_case, record_data={"math": [i for i in range(1024)]}, set_name=None, ignore_mem_queue_full=None, - timeout=None + timeout=None, ) ], ) -def test_vector_insert_with_existing_record(session_vector_client, test_case, random_key): +def test_vector_insert_with_existing_record( + session_vector_client, test_case, random_key +): session_vector_client.upsert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name - ) + set_name=test_case.set_name, + ) with pytest.raises(AVSServerError) as e_info: session_vector_client.insert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) session_vector_client.delete( namespace=test_case.namespace, key=random_key, ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -112,22 +114,24 @@ def test_vector_insert_with_existing_record(session_vector_client, test_case, ra record_data={"english": [bool(i) for i in range(1024)]}, set_name=None, ignore_mem_queue_full=True, - timeout=None + timeout=None, ) ], ) -def test_vector_insert_without_existing_record_ignore_mem_queue_full(session_vector_client, test_case, random_key): +def test_vector_insert_without_existing_record_ignore_mem_queue_full( + session_vector_client, test_case, random_key +): session_vector_client.delete( namespace=test_case.namespace, key=random_key, ) - + session_vector_client.insert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - ignore_mem_queue_full=test_case.ignore_mem_queue_full + ignore_mem_queue_full=test_case.ignore_mem_queue_full, ) session_vector_client.delete( @@ -146,13 +150,15 @@ def test_vector_insert_without_existing_record_ignore_mem_queue_full(session_vec record_data={"math": [i for i in range(1024)]}, set_name=None, ignore_mem_queue_full=None, - timeout=0.0001 + timeout=0.0001, ) ], ) -def test_vector_insert_timeout(session_vector_client, test_case, random_key, with_latency): +def test_vector_insert_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: @@ -161,10 +167,10 @@ def test_vector_insert_timeout(session_vector_client, test_case, random_key, wit key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - timeout=test_case.timeout + timeout=test_case.timeout, ) except AVSServerError as e: if e.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert e.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_vector_client_update.py b/tests/standard/sync/test_vector_client_update.py index 0092648f..43374ed6 100644 --- a/tests/standard/sync/test_vector_client_update.py +++ b/tests/standard/sync/test_vector_client_update.py @@ -5,20 +5,15 @@ from ...utils import key_strategy from hypothesis import given, settings, Verbosity + class update_test_case: - def __init__( - self, - *, - namespace, - record_data, - set_name, - timeout - ): + def __init__(self, *, namespace, record_data, set_name, timeout): self.namespace = namespace self.record_data = record_data self.set_name = set_name self.timeout = timeout + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -28,40 +23,42 @@ def __init__( namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), update_test_case( namespace="test", record_data={"english": [float(i) for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), update_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None, - timeout=None - ) + timeout=None, + ), ], ) -def test_vector_update_with_existing_record(session_vector_client, test_case, random_key): +def test_vector_update_with_existing_record( + session_vector_client, test_case, random_key +): session_vector_client.upsert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - timeout=None + timeout=None, ) - session_vector_client.update( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - timeout=None + timeout=None, ) + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -71,12 +68,13 @@ def test_vector_update_with_existing_record(session_vector_client, test_case, ra namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None - + timeout=None, ) ], ) -def test_vector_update_without_existing_record(session_vector_client, test_case, random_key): +def test_vector_update_without_existing_record( + session_vector_client, test_case, random_key +): session_vector_client.delete( namespace=test_case.namespace, key=random_key, @@ -86,9 +84,10 @@ def test_vector_update_without_existing_record(session_vector_client, test_case, namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) - + + @given(random_key=key_strategy()) @settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( @@ -98,13 +97,15 @@ def test_vector_update_without_existing_record(session_vector_client, test_case, namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0.0001 + timeout=0.0001, ) ], ) -def test_vector_update_timeout(session_vector_client, test_case, random_key, with_latency): +def test_vector_update_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: @@ -113,12 +114,10 @@ def test_vector_update_timeout(session_vector_client, test_case, random_key, wit key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - timeout=test_case.timeout + timeout=test_case.timeout, ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return assert "In several attempts, the timeout did not happen" == "TEST FAIL" - - diff --git a/tests/standard/sync/test_vector_client_upsert.py b/tests/standard/sync/test_vector_client_upsert.py index 3c3e5534..d2d4d7b8 100644 --- a/tests/standard/sync/test_vector_client_upsert.py +++ b/tests/standard/sync/test_vector_client_upsert.py @@ -2,22 +2,14 @@ from ...utils import key_strategy from hypothesis import given, settings, Verbosity -import numpy as np +import numpy as np from aerospike_vector_search import AVSServerError import grpc + class upsert_test_case: - def __init__( - self, - *, - namespace, - record_data, - set_name, - timeout, - key=None - - ): + def __init__(self, *, namespace, record_data, set_name, timeout, key=None): self.namespace = namespace self.record_data = record_data self.set_name = set_name @@ -34,34 +26,38 @@ def __init__( namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), upsert_test_case( namespace="test", record_data={"english": [float(i) for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ), upsert_test_case( namespace="test", record_data={"english": [bool(i) for i in range(1024)]}, set_name=None, - timeout=None - ) + timeout=None, + ), ], ) -def test_vector_upsert_without_existing_record(session_vector_client, test_case, random_key): +def test_vector_upsert_without_existing_record( + session_vector_client, test_case, random_key +): session_vector_client.upsert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) session_vector_client.delete( namespace=test_case.namespace, key=random_key, ) + + @given(random_key=key_strategy()) @settings(max_examples=5, deadline=1000) @pytest.mark.parametrize( @@ -71,16 +67,18 @@ def test_vector_upsert_without_existing_record(session_vector_client, test_case, namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=None + timeout=None, ) ], ) -def test_vector_upsert_with_existing_record(session_vector_client, test_case, random_key): +def test_vector_upsert_with_existing_record( + session_vector_client, test_case, random_key +): session_vector_client.upsert( namespace=test_case.namespace, key=random_key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) session_vector_client.delete( @@ -89,7 +87,6 @@ def test_vector_upsert_with_existing_record(session_vector_client, test_case, ra ) - @pytest.mark.parametrize( "test_case", [ @@ -98,15 +95,15 @@ def test_vector_upsert_with_existing_record(session_vector_client, test_case, ra record_data={"math": [i for i in range(1024)]}, set_name=None, timeout=None, - key=np.int32(31) + key=np.int32(31), ), upsert_test_case( namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, timeout=None, - key=np.array([b'a', b'b', b'c']) - ) + key=np.array([b"a", b"b", b"c"]), + ), ], ) def test_vector_upsert_with_numpy_key(session_vector_client, test_case): @@ -114,7 +111,7 @@ def test_vector_upsert_with_numpy_key(session_vector_client, test_case): namespace=test_case.namespace, key=test_case.key, record_data=test_case.record_data, - set_name=test_case.set_name + set_name=test_case.set_name, ) session_vector_client.delete( @@ -132,13 +129,15 @@ def test_vector_upsert_with_numpy_key(session_vector_client, test_case): namespace="test", record_data={"math": [i for i in range(1024)]}, set_name=None, - timeout=0.0001 + timeout=0.0001, ) ], ) -def test_vector_upsert_timeout(session_vector_client, test_case, random_key, with_latency): +def test_vector_upsert_timeout( + session_vector_client, test_case, random_key, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: @@ -147,10 +146,10 @@ def test_vector_upsert_timeout(session_vector_client, test_case, random_key, wit key=random_key, record_data=test_case.record_data, set_name=test_case.set_name, - timeout=test_case.timeout + timeout=test_case.timeout, ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/standard/sync/test_vector_search.py b/tests/standard/sync/test_vector_search.py index aca5bdd2..4a243364 100644 --- a/tests/standard/sync/test_vector_search.py +++ b/tests/standard/sync/test_vector_search.py @@ -70,13 +70,17 @@ def query_numpy(): def put_vector(client, vector, j, set_name): client.upsert( - namespace="test", key=str(j), record_data={"unit_test": vector}, set_name=set_name + namespace="test", + key=str(j), + record_data={"unit_test": vector}, + set_name=set_name, ) def get_vector(client, j, set_name): result = client.get(namespace="test", key=str(j), set_name=set_name) + def vector_search(client, vector, name): result = client.vector_search( namespace="test", @@ -95,13 +99,12 @@ def vector_search_ef_80(client, vector, name): query=vector, limit=100, field_names=["unit_test"], - search_params=types.HnswSearchParams(ef=80) + search_params=types.HnswSearchParams(ef=80), ) return result def grade_results( - base_numpy, truth_numpy, query_numpy, @@ -110,8 +113,6 @@ def grade_results( name, ): - - # Vector search all query vectors results = [] count = 0 @@ -159,13 +160,11 @@ def test_vector_search( query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): - - if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + pytest.skip("Extensive vector tests disabled") session_admin_client.index_create( namespace="test", @@ -174,23 +173,21 @@ def test_vector_search( dimensions=128, ) - - - for j, vector in enumerate(base_numpy): put_vector(session_vector_client, vector, j, None) - session_vector_client.wait_for_index_completion(namespace='test', name='demo1') - + session_vector_client.wait_for_index_completion(namespace="test", name="demo1") + grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - name='demo1' + name="demo1", ) + def test_vector_search_with_set_same_as_index( base_numpy, truth_numpy, @@ -198,7 +195,6 @@ def test_vector_search_with_set_same_as_index( session_vector_client, session_admin_client, ): - session_admin_client.index_create( namespace="test", @@ -206,39 +202,38 @@ def test_vector_search_with_set_same_as_index( sets="demo2", vector_field="unit_test", dimensions=128, - index_storage=types.IndexStorage(namespace="test", set_name="demo2") + index_storage=types.IndexStorage(namespace="test", set_name="demo2"), ) - for j, vector in enumerate(base_numpy): put_vector(session_vector_client, vector, j, "demo2") for j, vector in enumerate(base_numpy): get_vector(session_vector_client, j, "demo2") - session_vector_client.wait_for_index_completion(namespace='test', name='demo2') - + session_vector_client.wait_for_index_completion(namespace="test", name="demo2") + grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - name='demo2' + name="demo2", ) + def test_vector_search_with_set_different_than_name( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") - + pytest.skip("Extensive vector tests disabled") session_admin_client.index_create( namespace="test", @@ -246,38 +241,35 @@ def test_vector_search_with_set_different_than_name( vector_field="unit_test", dimensions=128, sets="example1", - index_storage=types.IndexStorage(namespace="test", set_name="demo3") - + index_storage=types.IndexStorage(namespace="test", set_name="demo3"), ) - - - for j, vector in enumerate(base_numpy): put_vector(session_vector_client, vector, j, "example1") - session_vector_client.wait_for_index_completion(namespace='test', name='demo3') - + session_vector_client.wait_for_index_completion(namespace="test", name="demo3") + grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - name="demo3" + name="demo3", ) + def test_vector_search_with_index_storage_different_than_name( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + pytest.skip("Extensive vector tests disabled") session_admin_client.index_create( namespace="test", @@ -285,40 +277,35 @@ def test_vector_search_with_index_storage_different_than_name( vector_field="unit_test", dimensions=128, sets="demo4", - index_storage=types.IndexStorage(namespace="test", set_name="example2") - + index_storage=types.IndexStorage(namespace="test", set_name="example2"), ) - - - for j, vector in enumerate(base_numpy): - put_vector(session_vector_client, vector, j, "demo4") + put_vector(session_vector_client, vector, j, "demo4") + + session_vector_client.wait_for_index_completion(namespace="test", name="demo4") - session_vector_client.wait_for_index_completion(namespace='test', name='demo4') - grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - name="demo4" + name="demo4", ) - def test_vector_search_with_index_storage_different_location( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + pytest.skip("Extensive vector tests disabled") session_admin_client.index_create( namespace="test", @@ -326,38 +313,35 @@ def test_vector_search_with_index_storage_different_location( vector_field="unit_test", dimensions=128, sets="example3", - index_storage=types.IndexStorage(namespace="test", set_name="example4") - + index_storage=types.IndexStorage(namespace="test", set_name="example4"), ) - - - for j, vector in enumerate(base_numpy): put_vector(session_vector_client, vector, j, "example3") - session_vector_client.wait_for_index_completion(namespace='test', name='demo5') - + session_vector_client.wait_for_index_completion(namespace="test", name="demo5") + grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - name='demo5' + name="demo5", ) + def test_vector_search_with_separate_namespace( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - extensive_vector_search + extensive_vector_search, ): if not extensive_vector_search: - pytest.skip("Extensive vector tests disabled") + pytest.skip("Extensive vector tests disabled") session_admin_client.index_create( namespace="test", @@ -365,52 +349,46 @@ def test_vector_search_with_separate_namespace( vector_field="unit_test", dimensions=128, sets="demo6", - index_storage=types.IndexStorage(namespace="index_storage", set_name="demo6") - + index_storage=types.IndexStorage(namespace="index_storage", set_name="demo6"), ) - - - for j, vector in enumerate(base_numpy): put_vector(session_vector_client, vector, j, "demo6") - session_vector_client.wait_for_index_completion(namespace='test', name='demo6') - + session_vector_client.wait_for_index_completion(namespace="test", name="demo6") + grade_results( base_numpy, truth_numpy, query_numpy, session_vector_client, session_admin_client, - name='demo6' + name="demo6", ) def test_vector_is_indexed(session_vector_client, session_admin_client): - result = session_vector_client.is_indexed( namespace="test", key=str(random.randrange(10_000)), index_name="demo2", - set_name="demo2" + set_name="demo2", ) - assert result is True -def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, with_latency): + +def test_vector_is_indexed_timeout( + session_vector_client, session_admin_client, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: result = session_vector_client.is_indexed( - namespace="test", - key=500, - index_name="demo2", - timeout=0.0001 + namespace="test", key=500, index_name="demo2", timeout=0.0001 ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: @@ -418,9 +396,12 @@ def test_vector_is_indexed_timeout(session_vector_client, session_admin_client, return assert "In several attempts, the timeout did not happen" == "TEST FAIL" -def test_vector_vector_search_timeout(session_vector_client, session_admin_client, with_latency): + +def test_vector_vector_search_timeout( + session_vector_client, session_admin_client, with_latency +): if not with_latency: - pytest.skip("Server latency too low to test timeout") + pytest.skip("Server latency too low to test timeout") for i in range(10): try: @@ -430,10 +411,10 @@ def test_vector_vector_search_timeout(session_vector_client, session_admin_clien query=[0, 1, 2], limit=100, field_names=["unit_test"], - timeout=0.0001 + timeout=0.0001, ) except AVSServerError as se: if se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED: assert se.rpc_error.code() == grpc.StatusCode.DEADLINE_EXCEEDED return - assert "In several attempts, the timeout did not happen" == "TEST FAIL" \ No newline at end of file + assert "In several attempts, the timeout did not happen" == "TEST FAIL" diff --git a/tests/utils.py b/tests/utils.py index 22ce60a9..4cd61f29 100755 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,32 +1,38 @@ -import random +import random import hypothesis.strategies as st from hypothesis import given import string + def random_int(): return str(random.randint(0, 50_000)) + allowed_chars = ( - list(string.ascii_lowercase) + # a-z - list(string.ascii_uppercase) + # A-Z - list(string.digits) + # 0-9 - ['_', '-'] # _, -, $ + list(string.ascii_lowercase) # a-z + + list(string.ascii_uppercase) # A-Z + + list(string.digits) # 0-9 + + ["_", "-"] # _, -, $ ) + def key_strategy(): - return st.text( - alphabet=allowed_chars, min_size=1, max_size=100_000 - ).filter(lambda ns: ns not in ['0', '1', 'null']) + return st.text(alphabet=allowed_chars, min_size=1, max_size=100_000).filter( + lambda ns: ns not in ["0", "1", "null"] + ) + def bin_strategy(): - return st.text( - alphabet=allowed_chars, min_size=1, max_size=15 - ).filter(lambda ns: ns not in ['0', '1', 'null']) + return st.text(alphabet=allowed_chars, min_size=1, max_size=15).filter( + lambda ns: ns not in ["0", "1", "null"] + ) + def index_strategy(): - return st.text( - alphabet=allowed_chars, min_size=1, max_size=63 - ).filter(lambda ns: ns not in ['null']) + return st.text(alphabet=allowed_chars, min_size=1, max_size=63).filter( + lambda ns: ns not in ["null"] + ) + """ TODO: Implement Hypothesis @@ -64,4 +70,4 @@ def index_strategy ) set_name_strategy = st.none() | valid_string_strategy -""" \ No newline at end of file +""" From 550571be6483df95e0879c793e8cba5e54f01d02 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 23 Jul 2024 08:23:06 -0600 Subject: [PATCH 208/215] Polished documentation --- .github/workflows/integration_test.yml | 2 +- docs/aio.rst | 4 +- docs/index.rst | 3 +- docs/sync.rst | 12 ++ src/aerospike_vector_search/aio/client.py | 74 +++++-- .../aio/internal/channel_provider.py | 2 +- src/aerospike_vector_search/client.py | 76 +++++-- .../internal/channel_provider.py | 2 +- .../shared/base_channel_provider.py | 2 +- src/aerospike_vector_search/types.py | 191 +++++++++++++----- 10 files changed, 267 insertions(+), 101 deletions(-) create mode 100644 docs/sync.rst diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 00839946..42e9cc45 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -650,7 +650,7 @@ jobs: sleep 5 - python -m pytest standard -s --host 0.0.0.0 --port 5000 --exhaustive_vector_search -vs + python -m pytest standard -s --host 0.0.0.0 --port 5000 --extensive_vector_search -vs working-directory: tests # diff --git a/docs/aio.rst b/docs/aio.rst index 1d56941a..0ad1b286 100644 --- a/docs/aio.rst +++ b/docs/aio.rst @@ -1,5 +1,5 @@ -aio Module -===================== +Asynchronous Clients leveraging Asyncio +======================================== This module contains clients with coroutine methods used for asynchronous programming. diff --git a/docs/index.rst b/docs/index.rst index d3e8d6e5..35246464 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -23,8 +23,7 @@ Please explore the modules below for more information on API usage and details. :caption: Contents: aio - admin - client + sync types diff --git a/docs/sync.rst b/docs/sync.rst new file mode 100644 index 00000000..04333f6b --- /dev/null +++ b/docs/sync.rst @@ -0,0 +1,12 @@ +Synchronous Clients +===================== + +This module contains clients with coroutine methods used for asynchronous programming. + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + admin + client diff --git a/src/aerospike_vector_search/aio/client.py b/src/aerospike_vector_search/aio/client.py index 6501d1d3..99a671ab 100644 --- a/src/aerospike_vector_search/aio/client.py +++ b/src/aerospike_vector_search/aio/client.py @@ -107,8 +107,15 @@ async def insert( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: Optional[str] + :param ignore_mem_queue_full: Ignore the in-memory queue full error. These records would be written to storage + and later, the index healer would pick for indexing. Defaults to False. + :type dimensions: int + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to insert a vector.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to insert a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -161,8 +168,15 @@ async def update( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: Optional[str] + :param ignore_mem_queue_full: Ignore the in-memory queue full error. These records would be written to storage + and later, the index healer would pick for indexing. Defaults to False. + :type dimensions: int + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to update a vector.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to update a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -215,8 +229,15 @@ async def upsert( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: Optional[str] + :param ignore_mem_queue_full: Ignore the in-memory queue full error. These records would be written to storage + and later, the index healer would pick for indexing. Defaults to False. + :type dimensions: int + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to upsert a vector.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to upsert a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -266,12 +287,14 @@ async def get( :param set_name: The name of the set from which to read the record. Defaults to None. :type set_name: Optional[str] + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int Returns: types.RecordWithKey: A record with its associated key. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to get a vector.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to get a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -312,11 +335,15 @@ async def exists( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: str + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Returns: bool: True if the record exists, False otherwise. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to see if a given vector exists.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to see if a given vector exists.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -357,9 +384,11 @@ async def delete( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: Optional[str] + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -390,26 +419,29 @@ async def is_indexed( """ Check if a record is indexed in the Vector DB. - :params namespace: The namespace for the record. + :param namespace: The namespace for the record. :type namespace: str - :params key: The key for the record. + :param key: The key for the record. :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] - :params index_name: The name of the index. + :param index_name: The name of the index. :type index_name: str - :params index_namespace: The namespace of the index. If None, defaults to the namespace of the record. Defaults to None. + :param index_namespace: The namespace of the index. If None, defaults to the namespace of the record. Defaults to None. :type index_namespace: optional[str] - :params set_name: The name of the set to which the record belongs. Defaults to None. + :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: optional[str] + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + Returns: bool: True if the record is indexed, False otherwise. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -444,32 +476,34 @@ async def vector_search( """ Perform a Hierarchical Navigable Small World (HNSW) vector search in Aerospike Vector Search. - :params namespace: The namespace for the records. + :param namespace: The namespace for the records. :type namespace: str - :params index_name: The name of the index. + :param index_name: The name of the index. :type index_name: str - :params query: The query vector for the search. + :param query: The query vector for the search. :type query: list[Union[bool, float]] - :params limit: The maximum number of neighbors to return. K value. + :param limit: The maximum number of neighbors to return. K value. :type limit: int - :params search_params: Parameters for the HNSW algorithm. + :param search_params: Parameters for the HNSW algorithm. If None, the default parameters for the index are used. Defaults to None. :type search_params: Optional[types_pb2.HnswSearchParams] - :params field_names: A list of field names to retrieve from the results. + :param field_names: A list of field names to retrieve from the results. If None, all fields are retrieved. Defaults to None. :type field_names: Optional[list[str]] + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int Returns: list[types.Neighbor]: A list of neighbors records found by the search. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ await self._channel_provider._is_ready() @@ -526,7 +560,7 @@ async def wait_for_index_completion( Raises: Exception: Raised when the timeout occurs while waiting for index completion. - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. Note: diff --git a/src/aerospike_vector_search/aio/internal/channel_provider.py b/src/aerospike_vector_search/aio/internal/channel_provider.py index 2dab121e..b237f774 100644 --- a/src/aerospike_vector_search/aio/internal/channel_provider.py +++ b/src/aerospike_vector_search/aio/internal/channel_provider.py @@ -200,7 +200,7 @@ async def _tend(self): logger.error("Tending failed at unindentified location: %s", e) raise e - def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: + def _create_channel(self, host: str, port: int) -> grpc.Channel: host = re.sub(r"%.*", "", host) if self.service_config_json: diff --git a/src/aerospike_vector_search/client.py b/src/aerospike_vector_search/client.py index 42cceb10..1eb5cd0f 100644 --- a/src/aerospike_vector_search/client.py +++ b/src/aerospike_vector_search/client.py @@ -106,8 +106,16 @@ def insert( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: Optional[str] + :param ignore_mem_queue_full: Ignore the in-memory queue full error. These records would be written to storage + and later, the index healer would pick for indexing. Defaults to False. + :type dimensions: int + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + + Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to insert a vector.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to insert a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -155,8 +163,15 @@ def update( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: Optional[str] + :param ignore_mem_queue_full: Ignore the in-memory queue full error. These records would be written to storage + and later, the index healer would pick for indexing. Defaults to False. + :type dimensions: int + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to update a vector.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to update a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -206,8 +221,15 @@ def upsert( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: Optional[str] + :param ignore_mem_queue_full: Ignore the in-memory queue full error. These records would be written to storage + and later, the index healer would pick for indexing. Defaults to False. + :type dimensions: int + + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to upsert a vector.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to upsert a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -256,12 +278,14 @@ def get( :param set_name: The name of the set from which to read the record. Defaults to None. :type set_name: Optional[str] + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int Returns: types.RecordWithKey: A record with its associated key. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to get a vector.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to get a vector.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -299,11 +323,14 @@ def exists( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: str + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + Returns: bool: True if the record exists, False otherwise. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to see if a given vector exists.. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to see if a given vector exists.. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -341,9 +368,11 @@ def delete( :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: Optional[str] + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -372,26 +401,29 @@ def is_indexed( """ Check if a record is indexed in the Vector DB. - :params namespace: The namespace for the record. + :param namespace: The namespace for the record. :type namespace: str - :params key: The key for the record. + :param key: The key for the record. :type key: Union[int, str, bytes, bytearray, np.generic, np.ndarray] - :params index_name: The name of the index. + :param index_name: The name of the index. :type index_name: str - :params index_namespace: The namespace of the index. If None, defaults to the namespace of the record. Defaults to None. + :param index_namespace: The namespace of the index. If None, defaults to the namespace of the record. Defaults to None. :type index_namespace: optional[str] - :params set_name: The name of the set to which the record belongs. Defaults to None. + :param set_name: The name of the set to which the record belongs. Defaults to None. :type set_name: optional[str] + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + Returns: bool: True if the record is indexed, False otherwise. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -424,32 +456,34 @@ def vector_search( """ Perform a Hierarchical Navigable Small World (HNSW) vector search in Aerospike Vector Search. - :params namespace: The namespace for the records. + :param namespace: The namespace for the records. :type namespace: str - :params index_name: The name of the index. + :param index_name: The name of the index. :type index_name: str - :params query: The query vector for the search. + :param query: The query vector for the search. :type query: list[Union[bool, float]] - :params limit: The maximum number of neighbors to return. K value. + :param limit: The maximum number of neighbors to return. K value. :type limit: int - :params search_params: Parameters for the HNSW algorithm. + :param search_params: Parameters for the HNSW algorithm. If None, the default parameters for the index are used. Defaults to None. :type search_params: Optional[types_pb2.HnswSearchParams] - :params field_names: A list of field names to retrieve from the results. + :param field_names: A list of field names to retrieve from the results. If None, all fields are retrieved. Defaults to None. :type field_names: Optional[list[str]] - + :param timeout: Time in seconds this operation will wait before raising an :class:`AVSServerError `. Defaults to None. + :type dimensions: int + Returns: list[types.Neighbor]: A list of neighbors records found by the search. Raises: - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. """ @@ -505,7 +539,7 @@ def wait_for_index_completion( Raises: Exception: Raised when the timeout occurs while waiting for index completion. - grpc.RpcError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. + AVSServerError: Raised if an error occurs during the RPC communication with the server while attempting to create the index. This error could occur due to various reasons such as network issues, server-side failures, or invalid request parameters. Note: diff --git a/src/aerospike_vector_search/internal/channel_provider.py b/src/aerospike_vector_search/internal/channel_provider.py index 0b240a5d..4354c46c 100644 --- a/src/aerospike_vector_search/internal/channel_provider.py +++ b/src/aerospike_vector_search/internal/channel_provider.py @@ -189,7 +189,7 @@ def _tend(self): logger.error("Tending failed at unindentified location: %s", e) raise e - def _create_channel(self, host: str, port: int, is_tls: bool) -> grpc.Channel: + def _create_channel(self, host: str, port: int) -> grpc.Channel: host = re.sub(r"%.*", "", host) if self.service_config_json: diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index ef3889dc..65da90c0 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -103,7 +103,7 @@ def get_channel(self) -> Union[grpc.aio.Channel, grpc.Channel]: def _create_channel_from_host_port( self, host: types.HostPort ) -> Union[grpc.aio.Channel, grpc.Channel]: - return self._create_channel(host.host, host.port, host.is_tls) + return self._create_channel(host.host, host.port) def _create_channel_from_server_endpoint_list( self, endpoints: vector_db_pb2.ServerEndpointList diff --git a/src/aerospike_vector_search/types.py b/src/aerospike_vector_search/types.py index 92c0af76..58ece4d3 100644 --- a/src/aerospike_vector_search/types.py +++ b/src/aerospike_vector_search/types.py @@ -9,16 +9,17 @@ class HostPort(object): represents host, port and TLS usage information. Used primarily when intializing client. - Args: - host (str): The host address. - port (int): The port number. - is_tls (Optional[bool], optional): Indicates if TLS is enabled. Defaults to False. + :param host: The host address. + :type host: str + + :param port: The port number. + :type port: int + """ - def __init__(self, *, host: str, port: int, is_tls: Optional[bool] = False) -> None: + def __init__(self, *, host: str, port: int) -> None: self.host = host self.port = port - self.is_tls = is_tls class Key(object): @@ -26,12 +27,16 @@ class Key(object): Represents a record key. Used in RecordWithKey. - Args: - namespace (str): The namespace for the key. - set (str): The set for the key. - key (Any): The key itself. - """ + :param namespace (str): The namespace for the key. + :type namespace: str + + :param set: (optional[str]): The set for the key. + :type set: optional[str] + :param key: (Any): The key itself. + :type key: Union[int, str, bytes, bytearray, np.ndarray, np.generic] + + """ def __init__(self, *, namespace: str, set: str, key: Any) -> None: self.namespace = namespace self.set = set @@ -49,9 +54,11 @@ class RecordWithKey(object): Represents a record, including a key and fields. Return value for VectorDbClient.get. - Args: - key (Key): The key of the record. - fields (dict[str, Any]): The fields associated with the record. + :param key: (Key): The key of the record. + :type key: Key + + :param fields: : The fields associated with the record. + :type fields: dict[str, Any] """ def __init__(self, *, key: Key, fields: dict[str, Any]) -> None: @@ -83,12 +90,19 @@ class Neighbor(object): """ Represents a neighboring record in the context of approximate nearest neighbor search. - This class represents a neighboring record in relation to a query record. It includes information such as the key, fields, and distance from the query record. + This class represents a neighboring record in relation to a query record. It includes information such as the key, fields, + and distance from the query record. - Args: - key (Key): The Key instance identifying the neighboring record. - fields (dict[str, Any]): A dictionary representing fields associated with the neighboring record. - distance (float): The distance between the neighboring record and the query record, calculated based on the chosen VectorDistanceMetric. + + :param key: The Key instance identifying the neighboring record. + :type distance: Key + + :param fields: A dictionary representing fields associated with the neighboring record. + :type distance: dict[str, Any] + + :param distance: The distance between the neighboring record and the query record, calculated based on the chosen + VectorDistanceMetric. + :type distance: float Notes: - The distance metric used to calculate the distance between records is determined by the chosen VectorDistanceMetric. @@ -127,9 +141,18 @@ def __str__(self): class VectorDistanceMetric(enum.Enum): """ - Enumeration of vector distance metrics. - """ + Enumeration of vector distance metrics used for comparing vectors. + This enumeration defines various metrics for calculating the distance or similarity between vectors: + + - **SQUARED_EUCLIDEAN**: Represents the squared Euclidean distance metric. + - **COSINE**: Represents the cosine similarity metric. + - **DOT_PRODUCT**: Represents the dot product similarity metric. + - **MANHATTAN**: Represents the Manhattan distance (L1 norm) metric. + - **HAMMING**: Represents the Hamming distance metric. + + Each metric provides a different method for comparing vectors, affecting how distances and similarities are computed in vector-based operations. + """ SQUARED_EUCLIDEAN: types_pb2.VectorDistanceMetric = ( types_pb2.VectorDistanceMetric.SQUARED_EUCLIDEAN ) @@ -143,11 +166,14 @@ class VectorDistanceMetric(enum.Enum): class User(object): """ - Representation - Args: - max_records (Optional[int], optional): Maximum number of records to fit in a batch. Defaults to 10000. - interval (Optional[int], optional): The maximum amount of time in milliseconds to wait before finalizing a batch. Defaults to 10000. - disabled (Optional[bool], optional): Disables batching for index updates. Default is False. + AVS User Object used mainly for role-based authentication. + + :param username: Username associated with user. + :type username: str + + :param roles: roles associated with user. + :type roles: list[str] + """ def __init__( @@ -164,10 +190,8 @@ class HnswBatchingParams(object): """ Parameters for configuring batching behaviour for batch based index update. - Args: - max_records (Optional[int], optional): Maximum number of records to fit in a batch. Defaults to 10000. - interval (Optional[int], optional): The maximum amount of time in milliseconds to wait before finalizing a batch. Defaults to 10000. - disabled (Optional[bool], optional): Disables batching for index updates. Default is False. + :param max_records: Maximum number of records to fit in a batch. Defaults to 10000. + :param interva: The maximum amount of time in milliseconds to wait before finalizing a batch. Defaults to 10000. """ def __init__( @@ -187,6 +211,29 @@ def _to_pb2(self): class HnswHealerParams(object): + """ + Parameters to configure the HNSW healer + + :param max_scan_rate_per_node: Maximum allowed record scan rate per vector db node. Default is the global healer config, which is configured in the AVS Server. + :type max_scan_rate_per_node: Optional[int] + + :param max_scan_page_size: Maximum number of records in a single scanned page. + Default is the global healer config, which is configured in the AVS Server. + :type max_scan_page_size: Optional[int] + + :param re_index_percent: Percentage of good records randomly selected for reindexing in a healer cycle. + Default is the global healer config, which is configured in the AVS Server. + :type re_index_percent: Optional[int] + + :param schedule_delay: The time delay, in milliseconds, between the termination of a healer run and the commencement + of the next one for an index. It only guarantees that the next index healer run for an index will not be scheduled before + this time delay. Default is the global healer config, which is configured in the AVS Server. + :type schedule_delay: Optional[int] + + :param parallelism: Maximum number of records to heal in parallel. + Default is the global healer config, which is configured in the AVS Server. + :type parallelism: Optional[int] + """ def __init__( self, *, @@ -227,6 +274,17 @@ def _to_pb2(self): class HnswCachingParams(object): + """ + Parameters to configure the HNSW index cache + + :param max_entries: maximum number of entries to cache. Default is the global cache config, which is configured in the AVS Server. + :type max_entries: Optional[int] + + :param expiry: Cache entries will expire after this time in millseconds has expired after the entry was add to the cache. + Default is the global cache config, which is configured in the AVS Server. + :type expiry: Optional[int] + + """ def __init__( self, *, max_entries: Optional[int] = None, expiry: Optional[int] = None ) -> None: @@ -243,6 +301,13 @@ def _to_pb2(self): class HnswIndexMergeParams(object): + """ + Parameters to configure the HNSW index merge behavior. + + :param parallelism: The number of vectors merged in parallel from a batch index to main index. + Default is the global healer config, which is configured in the AVS Server. + :type parallelism: Optional[int] + """ def __init__(self, *, parallelism: Optional[int] = None) -> None: self.parallelism = parallelism @@ -257,11 +322,17 @@ class HnswParams(object): """ Parameters for the Hierarchical Navigable Small World (HNSW) algorithm, used for approximate nearest neighbor search. - Args: - m (Optional[int], optional): The number of bi-directional links created per level during construction. Larger 'm' values lead to higher recall but slower construction. Defaults to 16. - ef_construction (Optional[int], optional): The size of the dynamic list for the nearest neighbors (candidates) during the index construction. Larger 'ef_construction' values lead to higher recall but slower construction. Defaults to 100. - ef (Optional[int], optional): The size of the dynamic list for the nearest neighbors (candidates) during the search phase. Larger 'ef' values lead to higher recall but slower search. Defaults to 100. - batching_params (Optional[HnswBatchingParams], optional): Parameters related to configuring batch processing, such as the maximum number of records per batch and batching interval. Defaults to HnswBatchingParams(). + :param m: The number of bi-directional links created per level during construction. Larger 'm' values lead to higher recall but slower construction. Defaults to 16. + :type m: Optional[int] + + :param ef_construction: The size of the dynamic list for the nearest neighbors (candidates) during the index construction. Larger 'ef_construction' values lead to higher recall but slower construction. Defaults to 100. + :type ef_construction: Optional[int] + + :param ef: The size of the dynamic list for the nearest neighbors (candidates) during the search phase. Larger 'ef' values lead to higher recall but slower search. Defaults to 100. + :type ef: Optional[int] + + :param batching_params: Parameters related to configuring batch processing, such as the maximum number of records per batch and batching interval. Defaults to HnswBatchingParams(). + :type batching_params: Optional[HnswBatchingParams] """ def __init__( @@ -304,20 +375,24 @@ def _to_pb2(self): class HnswSearchParams(object): - def __init__(self, *, ef: Optional[int] = None) -> None: - """ - Parameters for Hierarchical Navigable Small World (HNSW) search. + """ + Parameters for Hierarchical Navigable Small World (HNSW) search. - HNSW is an algorithm used for approximate nearest neighbor search. + HNSW is an algorithm used for approximate nearest neighbor search. - Args: - ef (Optional[int], optional): The parameter 'ef' controls the trade-off between search quality and search efficiency. It determines the size of the dynamic list of nearest neighbors (candidates) examined during the search phase. Larger values of 'ef' typically yield higher recall but slower search times. Defaults to None, meaning the algorithm uses a library-defined default value. + :param ef: The parameter 'ef' controls the trade-off between search quality and search efficiency. + It determines the size of the dynamic list of nearest neighbors (candidates) examined during the + search phase. Larger values of 'ef' typically yield higher recall but slower search times. + Defaults to None, meaning the algorithm uses a library-defined default value. + :type ef: Optional[int] - Notes: - - 'ef' stands for "exploration factor." - - Setting 'ef' to a higher value increases the recall (i.e., the likelihood of finding the true nearest neighbors) at the cost of increased computational overhead during the search process. + Notes: + - 'ef' stands for "exploration factor." + - Setting 'ef' to a higher value increases the recall (i.e., the likelihood of finding the true nearest neighbors) at the cost of increased computational overhead during the search process. + + """ + def __init__(self, *, ef: Optional[int] = None) -> None: - """ self.ef = ef def _to_pb2(self): @@ -327,6 +402,16 @@ def _to_pb2(self): class IndexStorage(object): + """ + Helper class primarily used to specify which namespace and set to build the index on. + + :param namespace: The name of the namespace to build the index on.. + :type namespace: str + + :param set_name: The name of the set to build the index on. Defaults to None. + :type set_name: Optional[str] + + """ def __init__( self, *, namespace: Optional[str] = None, set_name: Optional[str] = None ) -> None: @@ -355,14 +440,9 @@ class AVSServerError(AVSError): """ Custom exception raised for errors related to the AVS server. - Attributes: - status (int): The status code associated with the error. - details (str): Details about the error. - debug_error_string (str): Debug error string providing additional error information. + :param rpc_error: exception thrown by the grpc Python library on server calls. Defaults to None. + :type set_name: grpc.RpcError - Args: - rpc_error (Exception): The original gRPC error object from which AVSError is derived. - This error object is used to extract status, details, and debug information. """ def __init__(self, *, rpc_error) -> None: @@ -373,6 +453,13 @@ def __str__(self): class AVSClientError(AVSError): + """ + Custom exception raised for errors related to AVS client-side failures.. + + :param message: error messaging raised by the AVS Client. Defaults to None. + :type set_name: str + + """ def __init__(self, *, message) -> None: self.message = message From fa896458c90cdb40f3bf72ca9f08add10a67c8f2 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Tue, 23 Jul 2024 09:02:11 -0600 Subject: [PATCH 209/215] Update templates/service.config.json.template Co-authored-by: Jesse S --- templates/service.config.json.template | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/service.config.json.template b/templates/service.config.json.template index aef01618..c024f137 100644 --- a/templates/service.config.json.template +++ b/templates/service.config.json.template @@ -189,5 +189,4 @@ Consider the following configuration: For this configuration, `client.index_create` will have a 3 second timeout, all Transact Service methods will have a 2 second timeout, and all other methods will have a 1 second timeout -### Behaviors From 39648cb962219baf68ac4cd61483b8f3fee93b5d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 23 Jul 2024 09:02:35 -0600 Subject: [PATCH 210/215] Update admin.py --- src/aerospike_vector_search/aio/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aerospike_vector_search/aio/admin.py b/src/aerospike_vector_search/aio/admin.py index 68415f34..3a6475f4 100644 --- a/src/aerospike_vector_search/aio/admin.py +++ b/src/aerospike_vector_search/aio/admin.py @@ -581,7 +581,7 @@ async def revoke_roles( logger.error("Failed to revoke roles with error: %s", e) raise types.AVSServerError(rpc_error=e) - async def list_roles(self, timeout: Optional[int] = None) -> int: + async def list_roles(self, timeout: Optional[int] = None) -> None: """ grant roles to existing AVS Users. From dc8546f4e44f4ecae74b3ecf444eef2a94a178c2 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 23 Jul 2024 09:33:48 -0600 Subject: [PATCH 211/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 42e9cc45..1e70824e 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -68,7 +68,7 @@ jobs: sleep 5 docker ps - python -m pytest standard -s --host 0.0.0.0 --port 5000 + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 working-directory: tests test-tls: @@ -144,7 +144,7 @@ jobs: docker ps - python -m pytest standard -s --host child --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt -vs docker logs aerospike-vector-search docker logs aerospike @@ -217,7 +217,7 @@ jobs: sleep 5 - python -m pytest standard -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin + python -m pytest standard/sync -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin working-directory: tests @@ -370,7 +370,7 @@ jobs: sleep 5 - python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs @@ -444,7 +444,7 @@ jobs: sleep 5 - python -m pytest standard -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin -vs + python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin -vs @@ -584,7 +584,7 @@ jobs: sleep 5 - python -m pytest standard -s --host 0.0.0.0 --port 5000 --is_loadbalancer -vs + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --is_loadbalancer -vs working-directory: tests test-exhaustive-vector-search: @@ -650,7 +650,7 @@ jobs: sleep 5 - python -m pytest standard -s --host 0.0.0.0 --port 5000 --extensive_vector_search -vs + python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --extensive_vector_search -vs working-directory: tests # @@ -687,5 +687,5 @@ jobs: # - name: Run unit tests # run: | # -# python -m pytest standard -s --host 34.42.225.207 --port 5000 --with_latency +# python -m pytest standard/sync -s --host 34.42.225.207 --port 5000 --with_latency # working-directory: tests \ No newline at end of file From aab49160d94619ef40f13f8ca9b4fe2b3e8aa7d5 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 23 Jul 2024 09:44:58 -0600 Subject: [PATCH 212/215] Update integration_test.yml --- .github/workflows/integration_test.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 1e70824e..0bc7d55a 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -68,7 +68,7 @@ jobs: sleep 5 docker ps - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 + python -m pytest standard/aio -s --host 0.0.0.0 --port 5000 working-directory: tests test-tls: @@ -144,7 +144,7 @@ jobs: docker ps - python -m pytest standard/sync -s --host child --port 5000 --root_certificate tls/root.crt -vs + python -m pytest standard/aio -s --host child --port 5000 --root_certificate tls/root.crt -vs docker logs aerospike-vector-search docker logs aerospike @@ -217,7 +217,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin + python -m pytest standard/aio -s -vv --host child --port 5000 --root_certificate tls/root.crt --username admin --password admin working-directory: tests @@ -370,7 +370,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs + python -m pytest standard/aio -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt -vs @@ -444,7 +444,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin -vs + python -m pytest standard/aio -s --host brawn --port 5000 --root_certificate tls/root.crt --private_key tls/brawn.key.pem --certificate_chain tls/brawn.crt --username admin --password admin -vs @@ -584,7 +584,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --is_loadbalancer -vs + python -m pytest standard/aio -s --host 0.0.0.0 --port 5000 --is_loadbalancer -vs working-directory: tests test-exhaustive-vector-search: @@ -650,7 +650,7 @@ jobs: sleep 5 - python -m pytest standard/sync -s --host 0.0.0.0 --port 5000 --extensive_vector_search -vs + python -m pytest standard/aio -s --host 0.0.0.0 --port 5000 --extensive_vector_search -vs working-directory: tests # @@ -687,5 +687,5 @@ jobs: # - name: Run unit tests # run: | # -# python -m pytest standard/sync -s --host 34.42.225.207 --port 5000 --with_latency +# python -m pytest standard/aio -s --host 34.42.225.207 --port 5000 --with_latency # working-directory: tests \ No newline at end of file From c1bad930a4931f7a91d285223fefebf829a5ec7b Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 23 Jul 2024 10:06:06 -0600 Subject: [PATCH 213/215] Changed max_examples to 1 --- .../shared/base_channel_provider.py | 2 +- .../aio/test_admin_client_index_create.py | 16 ++++++++-------- .../standard/aio/test_admin_client_index_drop.py | 2 +- .../standard/aio/test_admin_client_index_get.py | 2 +- .../aio/test_admin_client_index_get_status.py | 2 +- .../standard/aio/test_admin_client_index_list.py | 2 +- tests/standard/aio/test_vector_client_delete.py | 6 +++--- tests/standard/aio/test_vector_client_exists.py | 4 ++-- tests/standard/aio/test_vector_client_get.py | 4 ++-- tests/standard/aio/test_vector_client_insert.py | 6 +++--- tests/standard/aio/test_vector_client_update.py | 6 +++--- tests/standard/aio/test_vector_client_upsert.py | 6 +++--- .../sync/test_admin_client_index_create.py | 12 ++++++------ .../sync/test_admin_client_index_drop.py | 2 +- .../standard/sync/test_admin_client_index_get.py | 2 +- .../sync/test_admin_client_index_get_status.py | 2 +- .../sync/test_admin_client_index_list.py | 2 +- tests/standard/sync/test_vector_client_delete.py | 6 +++--- tests/standard/sync/test_vector_client_exists.py | 2 +- tests/standard/sync/test_vector_client_get.py | 2 +- tests/standard/sync/test_vector_client_insert.py | 6 +++--- tests/standard/sync/test_vector_client_update.py | 4 ++-- tests/standard/sync/test_vector_client_upsert.py | 6 +++--- 23 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index 65da90c0..9184a61f 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -115,7 +115,7 @@ def _create_channel_from_server_endpoint_list( continue try: return self._create_channel( - endpoint.address, endpoint.port, endpoint.isTls + endpoint.address, endpoint.port ) except Exception as e: logger.debug("failure creating channel: " + str(e)) diff --git a/tests/standard/aio/test_admin_client_index_create.py b/tests/standard/aio/test_admin_client_index_create.py index d5742bd8..0d024e59 100644 --- a/tests/standard/aio/test_admin_client_index_create.py +++ b/tests/standard/aio/test_admin_client_index_create.py @@ -36,7 +36,7 @@ def __init__( @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -89,7 +89,7 @@ async def test_index_create(session_admin_client, test_case, random_name): @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -157,7 +157,7 @@ async def test_index_create_with_dimnesions( @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -244,7 +244,7 @@ async def test_index_create_with_vector_distance_metric( @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -307,7 +307,7 @@ async def test_index_create_with_sets(session_admin_client, test_case, random_na @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -401,7 +401,7 @@ async def test_index_create_with_index_params( @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -454,7 +454,7 @@ async def test_index_create_index_labels(session_admin_client, test_case, random @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -503,7 +503,7 @@ async def test_index_create_index_storage(session_admin_client, test_case, rando @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/aio/test_admin_client_index_drop.py b/tests/standard/aio/test_admin_client_index_drop.py index e740351e..9395bded 100644 --- a/tests/standard/aio/test_admin_client_index_drop.py +++ b/tests/standard/aio/test_admin_client_index_drop.py @@ -9,7 +9,7 @@ @pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=2000) +@settings(max_examples=1, deadline=2000) async def test_index_drop(session_admin_client, empty_test_case, random_name): await session_admin_client.index_create( namespace="test", diff --git a/tests/standard/aio/test_admin_client_index_get.py b/tests/standard/aio/test_admin_client_index_get.py index 3de77078..c7389400 100644 --- a/tests/standard/aio/test_admin_client_index_get.py +++ b/tests/standard/aio/test_admin_client_index_get.py @@ -9,7 +9,7 @@ @pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) async def test_index_get(session_admin_client, empty_test_case, random_name): await session_admin_client.index_create( namespace="test", diff --git a/tests/standard/aio/test_admin_client_index_get_status.py b/tests/standard/aio/test_admin_client_index_get_status.py index b3dfe6c9..9a500f4f 100644 --- a/tests/standard/aio/test_admin_client_index_get_status.py +++ b/tests/standard/aio/test_admin_client_index_get_status.py @@ -9,7 +9,7 @@ @pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) async def test_index_get_status(session_admin_client, empty_test_case, random_name): try: await session_admin_client.index_create( diff --git a/tests/standard/aio/test_admin_client_index_list.py b/tests/standard/aio/test_admin_client_index_list.py index 0d228d84..4ad71dad 100644 --- a/tests/standard/aio/test_admin_client_index_list.py +++ b/tests/standard/aio/test_admin_client_index_list.py @@ -12,7 +12,7 @@ @pytest.mark.parametrize("empty_test_case", [None, None]) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) async def test_index_list(session_admin_client, empty_test_case, random_name): await session_admin_client.index_create( namespace="test", diff --git a/tests/standard/aio/test_vector_client_delete.py b/tests/standard/aio/test_vector_client_delete.py index 45ba790e..7e022ca4 100644 --- a/tests/standard/aio/test_vector_client_delete.py +++ b/tests/standard/aio/test_vector_client_delete.py @@ -21,7 +21,7 @@ def __init__( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -58,7 +58,7 @@ async def test_vector_delete(session_vector_client, test_case, random_key): @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -81,7 +81,7 @@ async def test_vector_delete_without_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/aio/test_vector_client_exists.py b/tests/standard/aio/test_vector_client_exists.py index 9dcd3cff..26147e46 100644 --- a/tests/standard/aio/test_vector_client_exists.py +++ b/tests/standard/aio/test_vector_client_exists.py @@ -20,7 +20,7 @@ def __init__( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -59,7 +59,7 @@ async def test_vector_exists(session_vector_client, test_case, random_key): @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/aio/test_vector_client_get.py b/tests/standard/aio/test_vector_client_get.py index 20aaedaa..a08ca886 100644 --- a/tests/standard/aio/test_vector_client_get.py +++ b/tests/standard/aio/test_vector_client_get.py @@ -26,7 +26,7 @@ def __init__( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -74,7 +74,7 @@ async def test_vector_get(session_vector_client, test_case, random_key): @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/aio/test_vector_client_insert.py b/tests/standard/aio/test_vector_client_insert.py index 4979282a..9e8fbbee 100644 --- a/tests/standard/aio/test_vector_client_insert.py +++ b/tests/standard/aio/test_vector_client_insert.py @@ -24,7 +24,7 @@ def __init__( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -65,7 +65,7 @@ async def test_vector_insert_without_existing_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -105,7 +105,7 @@ async def test_vector_insert_with_existing_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/aio/test_vector_client_update.py b/tests/standard/aio/test_vector_client_update.py index 6963ccfd..2aad8d68 100644 --- a/tests/standard/aio/test_vector_client_update.py +++ b/tests/standard/aio/test_vector_client_update.py @@ -21,7 +21,7 @@ def __init__( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -71,7 +71,7 @@ async def test_vector_update_with_existing_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -101,7 +101,7 @@ async def test_vector_update_without_existing_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/aio/test_vector_client_upsert.py b/tests/standard/aio/test_vector_client_upsert.py index 42320b30..2e84e702 100644 --- a/tests/standard/aio/test_vector_client_upsert.py +++ b/tests/standard/aio/test_vector_client_upsert.py @@ -18,7 +18,7 @@ def __init__(self, *, namespace, record_data, set_name, timeout, key=None): @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -60,7 +60,7 @@ async def test_vector_upsert_without_existing_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -123,7 +123,7 @@ async def test_vector_upsert_with_numpy_key(session_vector_client, test_case): @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/sync/test_admin_client_index_create.py b/tests/standard/sync/test_admin_client_index_create.py index 79d342c4..627558a0 100644 --- a/tests/standard/sync/test_admin_client_index_create.py +++ b/tests/standard/sync/test_admin_client_index_create.py @@ -36,7 +36,7 @@ def __init__( @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -93,7 +93,7 @@ def test_index_create(session_admin_client, test_case, random_name): @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -165,7 +165,7 @@ def test_index_create_with_dimnesions(session_admin_client, test_case, random_na @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -257,7 +257,7 @@ def test_index_create_with_vector_distance_metric( @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -488,7 +488,7 @@ def test_index_create_with_index_params(session_admin_client, test_case, random_ @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -546,7 +546,7 @@ def test_index_create_index_labels(session_admin_client, test_case, random_name) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/sync/test_admin_client_index_drop.py b/tests/standard/sync/test_admin_client_index_drop.py index 7e1c6c90..095f55ca 100644 --- a/tests/standard/sync/test_admin_client_index_drop.py +++ b/tests/standard/sync/test_admin_client_index_drop.py @@ -10,7 +10,7 @@ @pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) def test_index_drop(session_admin_client, empty_test_case, random_name): try: diff --git a/tests/standard/sync/test_admin_client_index_get.py b/tests/standard/sync/test_admin_client_index_get.py index e9af212e..1ab0a1bb 100644 --- a/tests/standard/sync/test_admin_client_index_get.py +++ b/tests/standard/sync/test_admin_client_index_get.py @@ -9,7 +9,7 @@ @pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) def test_index_get(session_admin_client, empty_test_case, random_name): try: diff --git a/tests/standard/sync/test_admin_client_index_get_status.py b/tests/standard/sync/test_admin_client_index_get_status.py index ffa8f0b8..a9b1a1a3 100644 --- a/tests/standard/sync/test_admin_client_index_get_status.py +++ b/tests/standard/sync/test_admin_client_index_get_status.py @@ -11,7 +11,7 @@ @pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) def test_index_get_status(session_admin_client, empty_test_case, random_name): try: session_admin_client.index_create( diff --git a/tests/standard/sync/test_admin_client_index_list.py b/tests/standard/sync/test_admin_client_index_list.py index 121a3a32..6830609e 100644 --- a/tests/standard/sync/test_admin_client_index_list.py +++ b/tests/standard/sync/test_admin_client_index_list.py @@ -10,7 +10,7 @@ @pytest.mark.parametrize("empty_test_case", [None]) @given(random_name=index_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) def test_index_list(session_admin_client, empty_test_case, random_name): session_admin_client.index_create( namespace="test", diff --git a/tests/standard/sync/test_vector_client_delete.py b/tests/standard/sync/test_vector_client_delete.py index 237b09ff..e726314a 100644 --- a/tests/standard/sync/test_vector_client_delete.py +++ b/tests/standard/sync/test_vector_client_delete.py @@ -23,7 +23,7 @@ def __init__( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -59,7 +59,7 @@ def test_vector_delete(session_vector_client, test_case, random_key): @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -79,7 +79,7 @@ def test_vector_delete_without_record(session_vector_client, test_case, random_k @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/sync/test_vector_client_exists.py b/tests/standard/sync/test_vector_client_exists.py index e470a981..95f5a0c9 100644 --- a/tests/standard/sync/test_vector_client_exists.py +++ b/tests/standard/sync/test_vector_client_exists.py @@ -22,7 +22,7 @@ def __init__( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/sync/test_vector_client_get.py b/tests/standard/sync/test_vector_client_get.py index 3c847ee9..0f3464aa 100644 --- a/tests/standard/sync/test_vector_client_get.py +++ b/tests/standard/sync/test_vector_client_get.py @@ -26,7 +26,7 @@ def __init__( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/sync/test_vector_client_insert.py b/tests/standard/sync/test_vector_client_insert.py index 307d5f28..062886f8 100644 --- a/tests/standard/sync/test_vector_client_insert.py +++ b/tests/standard/sync/test_vector_client_insert.py @@ -20,7 +20,7 @@ def __init__( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -69,7 +69,7 @@ def test_vector_insert_without_existing_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -105,7 +105,7 @@ def test_vector_insert_with_existing_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/sync/test_vector_client_update.py b/tests/standard/sync/test_vector_client_update.py index 43374ed6..03ba0ae6 100644 --- a/tests/standard/sync/test_vector_client_update.py +++ b/tests/standard/sync/test_vector_client_update.py @@ -15,7 +15,7 @@ def __init__(self, *, namespace, record_data, set_name, timeout): @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -60,7 +60,7 @@ def test_vector_update_with_existing_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ diff --git a/tests/standard/sync/test_vector_client_upsert.py b/tests/standard/sync/test_vector_client_upsert.py index d2d4d7b8..8d4a4932 100644 --- a/tests/standard/sync/test_vector_client_upsert.py +++ b/tests/standard/sync/test_vector_client_upsert.py @@ -18,7 +18,7 @@ def __init__(self, *, namespace, record_data, set_name, timeout, key=None): @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -59,7 +59,7 @@ def test_vector_upsert_without_existing_record( @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ @@ -121,7 +121,7 @@ def test_vector_upsert_with_numpy_key(session_vector_client, test_case): @given(random_key=key_strategy()) -@settings(max_examples=5, deadline=1000) +@settings(max_examples=1, deadline=1000) @pytest.mark.parametrize( "test_case", [ From a2dbc1032d802a9876bcb46cc00a4664e1398b06 Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 23 Jul 2024 11:11:44 -0600 Subject: [PATCH 214/215] Fixed Jesse comments --- src/aerospike_vector_search/admin.py | 2 +- src/aerospike_vector_search/shared/base_channel_provider.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/aerospike_vector_search/admin.py b/src/aerospike_vector_search/admin.py index 278963cf..b4cf9aba 100644 --- a/src/aerospike_vector_search/admin.py +++ b/src/aerospike_vector_search/admin.py @@ -558,7 +558,7 @@ def revoke_roles( logger.error("Failed to revoke roles with error: %s", e) raise types.AVSServerError(rpc_error=e) - def list_roles(self, timeout: Optional[int] = None) -> list[str]: + def list_roles(self, timeout: Optional[int] = None) -> list[dict]: """ grant roles to existing AVS Users. diff --git a/src/aerospike_vector_search/shared/base_channel_provider.py b/src/aerospike_vector_search/shared/base_channel_provider.py index 9184a61f..0f22282b 100644 --- a/src/aerospike_vector_search/shared/base_channel_provider.py +++ b/src/aerospike_vector_search/shared/base_channel_provider.py @@ -207,7 +207,8 @@ def _respond_authenticate(self, token): def verify_compatibile_server(self) -> bool: def parse_version(v: str): - return tuple(map(int, v.split("."))) + return tuple(int(part) if part.isdigit() else part for part in v.split(".")) + return parse_version(self.current_server_version) >= parse_version( self.minimum_required_version From a19f6e116f3c7e47c2467c67f4a8cf1aaf7ea24d Mon Sep 17 00:00:00 2001 From: Dominic Pelini Date: Tue, 23 Jul 2024 11:13:14 -0600 Subject: [PATCH 215/215] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0f23ee17..c261e948 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Topic :: Database" ] -version = "1.0.0.dev6" +version = "1.0.0" requires-python = ">3.8" dependencies = [ "grpcio == 1.64.1",