-
Notifications
You must be signed in to change notification settings - Fork 0
chore: support sharding/parallel runs, namespace scopes via COMPLEMENT_CRYPTO_NAMESPACE
#1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2c1bded
ae35784
379f122
5aac0ba
250527b
9277df7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -41,9 +41,22 @@ _build-rust-sdk dir: | |||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||
| set -euxo pipefail | ||||||||||||||||||
|
|
||||||||||||||||||
| cd "{{ dir }}" | ||||||||||||||||||
| cd "{{ dir }}" | ||||||||||||||||||
|
|
||||||||||||||||||
| cargo build -p matrix-sdk-ffi --features 'sentry, _only-for-testing-disable-megolm-minimum-rotation-period-ms' | ||||||||||||||||||
| # The `_disable-minimum-rotation-period-ms` feature lives on matrix-sdk-crypto, | ||||||||||||||||||
| # not on matrix-sdk-ffi, so it cannot be passed via `--features` here. Patch the | ||||||||||||||||||
| # workspace Cargo.toml to inject it into the crypto dep (mirroring upstream | ||||||||||||||||||
| # rebuild_rust_sdk.sh), and restore both files afterwards. | ||||||||||||||||||
| cp Cargo.toml Cargo.toml.backup | ||||||||||||||||||
| cp Cargo.lock Cargo.lock.backup | ||||||||||||||||||
| trap 'mv -f Cargo.toml.backup Cargo.toml; mv -f Cargo.lock.backup Cargo.lock' EXIT | ||||||||||||||||||
| sed -i.bak 's#matrix-sdk-crypto = {#matrix-sdk-crypto = {features = ["_disable-minimum-rotation-period-ms"],#' Cargo.toml | ||||||||||||||||||
|
cubic-dev-ai[bot] marked this conversation as resolved.
|
||||||||||||||||||
| rm -f Cargo.toml.bak | ||||||||||||||||||
| if ! grep -q "_disable-minimum-rotation-period-ms" Cargo.toml; then | ||||||||||||||||||
| echo "Failed to inject _disable-minimum-rotation-period-ms feature" >&2 | ||||||||||||||||||
| exit 1 | ||||||||||||||||||
| fi | ||||||||||||||||||
|
Comment on lines
+55
to
+58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Validate the Line 55 checks only for the feature token anywhere in Proposed fix- if ! grep -q "_disable-minimum-rotation-period-ms" Cargo.toml; then
+ if ! grep -Eq '^[[:space:]]*matrix-sdk-crypto[[:space:]]*=[[:space:]]*\{[^}]*_disable-minimum-rotation-period-ms' Cargo.toml; then📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| cargo build -p matrix-sdk-ffi --features 'sentry' | ||||||||||||||||||
| uniffi-bindgen-go -o {{ COMPLEMENT_DIR }}/internal/api/rust --config {{ COMPLEMENT_DIR }}/uniffi.toml --library ./target/debug/libmatrix_sdk_ffi.a | ||||||||||||||||||
|
|
||||||||||||||||||
| # Add the cgo LDFLAGS directive to the generated bindings. | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package tests | ||
|
|
||
| import "testing" | ||
|
|
||
| func TestResolveNamespace(t *testing.T) { | ||
| // acceptable values pass through unchanged | ||
| valid := []string{"crypto", "shard_01", "a.B-c9", "_", ".-"} | ||
| for _, v := range valid { | ||
| if got := resolveNamespace(v); got != v { | ||
| t.Fatalf("resolveNamespace(%q) = %q, want %q", v, got, v) | ||
| } | ||
| } | ||
|
|
||
| // empty defaults to "crypto" | ||
| if got := resolveNamespace(""); got != "crypto" { | ||
| t.Fatalf("resolveNamespace(\"\") = %q, want %q", got, "crypto") | ||
| } | ||
|
|
||
| // invalid values are rejected with a clear panic | ||
| invalid := []string{"crypto name", "shard/01", "a:b", "ns$", "shard,2", "a=B"} | ||
| for _, v := range invalid { | ||
| func() { | ||
| defer func() { | ||
| rec := recover() | ||
| if rec == nil { | ||
| t.Fatalf("resolveNamespace(%q) did not panic", v) | ||
| } | ||
| want := "COMPLEMENT_CRYPTO_NAMESPACE must contain only characters in [A-Za-z0-9_.-], got: " + v | ||
| if rec != want { | ||
| t.Fatalf("resolveNamespace(%q) panic = %q, want %q", v, rec, want) | ||
| } | ||
| }() | ||
| resolveNamespace(v) | ||
| }() | ||
|
gamesguru marked this conversation as resolved.
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,19 +21,38 @@ import ( | |
| "github.com/tidwall/gjson" | ||
| ) | ||
|
|
||
| // mustClaimFallbackKey claims the fallback key for the target user. | ||
| // The SDK uploads its fallback key asynchronously after learning it needs | ||
| // one (via device_unused_fallback_key_types in the sync response), so it | ||
| // may not have landed yet when the test first claims it. Retry until it | ||
| // appears rather than failing on the first (empty) claim. | ||
| func mustClaimFallbackKey(t *testing.T, claimer *client.CSAPI, target *cc.User) (fallbackKeyID string, keyJSON gjson.Result) { | ||
| t.Helper() | ||
| res := claimer.MustDo(t, "POST", []string{ | ||
| // The SDK uploads its fallback key asynchronously after learning it needs | ||
| // one (via device_unused_fallback_key_types in the sync response), so it | ||
| // may not have landed yet when the test first claims it. Retry until it | ||
| // appears rather than failing on the first (empty) claim. | ||
| var result gjson.Result | ||
| claimer.MustDo(t, "POST", []string{ | ||
| "_matrix", "client", "v3", "keys", "claim", | ||
| }, client.WithJSONBody(t, map[string]any{ | ||
| "one_time_keys": map[string]any{ | ||
| target.UserID: map[string]any{ | ||
| target.DeviceID: "signed_curve25519", | ||
| }, | ||
| }, | ||
| }), client.WithRetryUntil(10*time.Second, func(res *http.Response) bool { | ||
| result = must.ParseJSON(t, res.Body) | ||
| res.Body.Close() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- target file ---'
sed -n '1,120p' tests/one_time_keys_test.go
printf '%s\n' '--- lint configuration references ---'
rg -n --hidden -g '!vendor' -g '!node_modules' \
'errcheck|golangci|Body\.Close|res\.Body\.Close' \
.golangci.yml .golangci.yaml .golangci.toml golangci.yml golangci.yaml golangci.toml \
tests 2>/dev/null || true
printf '%s\n' '--- repository status and Go files ---'
git status --short
git ls-files '*.go' | sed -n '1,80p'Repository: Wombat-Foundation/complement-crypto Length of output: 6591 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- retry helper call sites ---'
rg -n -C 8 'WithRetryUntil|func .*RetryUntil|RetryUntil' . --glob '*.go'
printf '%s\n' '--- nearby response handling ---'
sed -n '170,225p' tests/one_time_keys_test.go
printf '%s\n' '--- module and lint configuration files ---'
git ls-files | rg '(^|/)(go\.mod|go\.sum|\.golangci\.(yml|yaml|toml)|golangci\.(yml|yaml|toml))$' | xargs -r -n1 sh -c 'echo "--- $0"; sed -n "1,220p" "$0"'Repository: Wombat-Foundation/complement-crypto Length of output: 29128 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- cached Complement source candidates ---'
find /root/go/pkg/mod /go/pkg/mod -type f -path '*complement*' -name '*.go' 2>/dev/null \
| rg 'client|request|retry' | sed -n '1,80p' || true
printf '%s\n' '--- all tracked close calls and explicit error handling ---'
rg -n -C 3 'Body\.Close\(\)' . --glob '*.go'
printf '%s\n' '--- Go tool availability and standard API declaration ---'
if command -v go >/dev/null 2>&1; then
go version
go env GOMODCACHE GOPATH
go doc net/http.Response 2>/dev/null | rg -n -A 8 'Body|Close' || true
else
echo 'go command unavailable'
fiRepository: Wombat-Foundation/complement-crypto Length of output: 4509 Handle the response-body close error. Check the error from 🧰 Tools🪛 golangci-lint (2.12.2)[error] 46-46: Error return value of (errcheck) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| otks := result.Get(fmt.Sprintf( | ||
| "one_time_keys.%s.%s", client.GjsonEscape(target.UserID), client.GjsonEscape(target.DeviceID), | ||
| )) | ||
| if otks.Exists() { | ||
| return true | ||
| } | ||
| t.Logf("fallback key not yet uploaded for %s|%s, retrying: %v", target.UserID, target.DeviceID, result.Raw) | ||
| return false | ||
| })) | ||
| defer res.Body.Close() | ||
| result := must.ParseJSON(t, res.Body) | ||
| otks := result.Get(fmt.Sprintf( | ||
| "one_time_keys.%s.%s", client.GjsonEscape(target.UserID), client.GjsonEscape(target.DeviceID), | ||
| )) | ||
|
|
@@ -49,6 +68,7 @@ func mustClaimFallbackKey(t *testing.T, claimer *client.CSAPI, target *cc.User) | |
| return fallbackKeyID, fallbackKey | ||
| } | ||
|
|
||
| // mustClaimOTKs repeatedly claims one-time keys for the target user until otkCount keys have been claimed. | ||
| func mustClaimOTKs(t *testing.T, claimer *client.CSAPI, target *cc.User, otkCount int) { | ||
| t.Helper() | ||
| for i := 0; i < otkCount; i++ { | ||
|
|
@@ -157,6 +177,7 @@ func TestFallbackKeyIsUsedIfOneTimeKeysRunOut(t *testing.T) { | |
| }) | ||
| } | ||
|
|
||
| // TestFailedOneTimeKeyUploadRetries tests that the client retries uploading one-time keys if the upload fails. | ||
| func TestFailedOneTimeKeyUploadRetries(t *testing.T) { | ||
| Instance().ForEachClientType(t, func(t *testing.T, clientType api.ClientType) { | ||
| tc := Instance().CreateTestContext(t, clientType, clientType) | ||
|
|
@@ -205,6 +226,7 @@ func TestFailedOneTimeKeyUploadRetries(t *testing.T) { | |
| }) | ||
| } | ||
|
|
||
| // TestFailedKeysClaimRetries tests that the client retries claiming one-time keys if the claim fails. | ||
| func TestFailedKeysClaimRetries(t *testing.T) { | ||
| Instance().ForEachClientType(t, func(t *testing.T, clientType api.ClientType) { | ||
| tc := Instance().CreateTestContext(t, clientType, clientType) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: The sed patch fails silently if
matrix-sdk-crypto = {is missing or already contains afeatureskey. sed returns 0 even when nothing matches, so withset -euxo pipefailthe build proceeds without the hidden feature flag andTestRoomKeyIsCycledAfterEnoughTime(tests/room_keys_test.go) silently stops behaving as intended. Also, if the matched entry already declaresfeatures, the replacement produces a duplicatefeatureskey that cargo rejects. Verify the substitution actually applied before building.Prompt for AI agents