Skip to content

Commit 939559f

Browse files
committed
feat: Added CI for in_memory_testing
1 parent 2c504bd commit 939559f

File tree

3 files changed

+203
-29
lines changed

3 files changed

+203
-29
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: In-Memory VSS Server CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
cancel-in-progress: true
11+
12+
jobs:
13+
test-in-memory:
14+
runs-on: ubuntu-latest
15+
timeout-minutes: 5
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Create in-memory config
22+
run: |
23+
mkdir -p rust/server
24+
cat > rust/server/vss-server-config.toml <<EOF
25+
[server_config]
26+
host = "127.0.0.1"
27+
port = 8080
28+
store_type = "in_memory"
29+
EOF
30+
31+
- name: Build server
32+
working-directory: rust
33+
run: cargo build --release --bin server
34+
35+
- name: Start VSS server
36+
working-directory: rust
37+
run: |
38+
./target/release/server server/vss-server-config.toml --in-memory > server.log 2>&1 &
39+
echo "Server PID: $!"
40+
41+
- name: Wait for server
42+
run: |
43+
for i in {1..15}; do
44+
if curl -s http://127.0.0.1:8080 > /dev/null; then
45+
echo "Server is up!"
46+
exit 0
47+
fi
48+
sleep 1
49+
done
50+
echo "Server failed:"
51+
cat rust/server.log
52+
exit 1
53+
54+
- name: HTTP Smoke Test
55+
run: |
56+
# PUT: store="test", key="k1", value="kv1"
57+
curl -f \
58+
-H "Authorization: Bearer test_user" \
59+
--data-binary @<(echo "0A04746573741A150A026B3110FFFFFFFFFFFFFFFFFF011A046B317631" | xxd -r -p) \
60+
http://127.0.0.1:8080/vss/putObjects
61+
62+
# GET: store="test", key="k1"
63+
RESPONSE=$(curl -f \
64+
-H "Authorization: Bearer test_user" \
65+
--data-binary @<(echo "0A047465737412026B31" | xxd -r -p) \
66+
http://127.0.0.1:8080/vss/getObject)
67+
68+
- name: Run unit tests
69+
working-directory: rust
70+
run: cargo test --package impls --lib -- in_memory_store::tests --nocapture

.github/workflows/ldk-node-integration.yml

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ concurrency:
77
cancel-in-progress: true
88

99
jobs:
10-
build-and-test:
10+
test-postgres:
1111
runs-on: ubuntu-latest
12-
12+
timeout-minutes: 20
1313
services:
1414
postgres:
1515
image: postgres:latest
16-
ports:
17-
- 5432:5432
16+
ports: [5432:5432]
1817
env:
1918
POSTGRES_DB: postgres
2019
POSTGRES_USER: postgres
@@ -28,22 +27,102 @@ jobs:
2827
steps:
2928
- name: Checkout code
3029
uses: actions/checkout@v3
31-
with:
32-
path: vss-server
30+
with: { path: vss-server }
3331
- name: Checkout LDK Node
3432
uses: actions/checkout@v3
3533
with:
3634
repository: lightningdevkit/ldk-node
3735
path: ldk-node
3836

39-
- name: Build and Deploy VSS Server
37+
- name: Create Postgres config
38+
run: |
39+
mkdir -p vss-server/rust/server
40+
cat > vss-server/rust/server/vss-server-config.toml <<EOF
41+
[server_config]
42+
host = "127.0.0.1"
43+
port = 8080
44+
store_type = "postgres"
45+
[postgresql_config]
46+
host = "localhost"
47+
port = 5432
48+
database = "postgres"
49+
username = "postgres"
50+
password = "postgres"
51+
EOF
52+
53+
- name: Build & Start VSS Server
4054
run: |
4155
cd vss-server/rust
42-
cargo build
43-
cargo run server/vss-server-config.toml&
56+
cargo build --release --bin server
57+
./target/release/server server/vss-server-config.toml > vss.log 2>&1 &
58+
echo "VSS PID: $!"
59+
60+
- name: Wait for VSS
61+
run: |
62+
for i in {1..30}; do
63+
if curl -s http://127.0.0.1:8080/vss > /dev/null 2>&1; then
64+
echo "VSS ready!"
65+
exit 0
66+
fi
67+
sleep 2
68+
done
69+
echo "VSS failed:"
70+
cat vss-server/rust/server/vss.log
71+
exit 1
72+
4473
- name: Run LDK Node Integration tests
4574
run: |
4675
cd ldk-node
47-
export TEST_VSS_BASE_URL="http://localhost:8080/vss"
76+
export TEST_VSS_BASE_URL="http://127.0.0.1:8080/vss"
4877
RUSTFLAGS="--cfg vss_test" cargo test io::vss_store
4978
RUSTFLAGS="--cfg vss_test" cargo test --test integration_tests_vss
79+
80+
test-in-memory:
81+
runs-on: ubuntu-latest
82+
timeout-minutes: 10
83+
steps:
84+
- name: Checkout code
85+
uses: actions/checkout@v3
86+
with: { path: vss-server }
87+
- name: Checkout LDK Node
88+
uses: actions/checkout@v3
89+
with:
90+
repository: lightningdevkit/ldk-node
91+
path: ldk-node
92+
93+
- name: Create In-Memory config
94+
run: |
95+
mkdir -p vss-server/rust/server
96+
cat > vss-server/rust/server/vss-server-config.toml <<EOF
97+
[server_config]
98+
host = "127.0.0.1"
99+
port = 8080
100+
store_type = "in_memory"
101+
EOF
102+
103+
- name: Build & Start VSS Server
104+
run: |
105+
cd vss-server/rust
106+
cargo build --release --bin server
107+
./target/release/server server/vss-server-config.toml > vss.log 2>&1 &
108+
echo "VSS PID: $!"
109+
110+
- name: Wait for VSS
111+
run: |
112+
for i in {1..30}; do
113+
if curl -s http://127.0.0.1:8080/vss > /dev/null 2>&1; then
114+
echo "VSS ready!"
115+
exit 0
116+
fi
117+
sleep 2
118+
done
119+
echo "VSS failed:"
120+
cat vss-server/rust/server/vss.log
121+
exit 1
122+
123+
- name: Run LDK Node Integration tests
124+
run: |
125+
cd ldk-node
126+
export TEST_VSS_BASE_URL="http://127.0.0.1:8080/vss"
127+
RUSTFLAGS="--cfg vss_test" cargo test io::vss_store
128+
RUSTFLAGS="--cfg vss_test" cargo test --test integration_tests_vss

rust/impls/src/in_memory_store.rs

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ fn build_key(user_token: &str, store_id: &str, key: &str) -> String {
3232
format!("{}#{}#{}", user_token, store_id, key)
3333
}
3434

35+
fn validate_vss_request(store_id: &str, key: Option<&str>) -> Result<(), VssError> {
36+
if store_id.is_empty() {
37+
return Err(VssError::InvalidRequestError("store_id cannot be empty".to_string()));
38+
}
39+
if let Some(k) = key {
40+
if k.is_empty() {
41+
return Err(VssError::InvalidRequestError("key cannot be empty".to_string()));
42+
}
43+
}
44+
45+
Ok(())
46+
}
47+
3548
/// In-memory implementation of the VSS Store.
3649
pub struct InMemoryBackendImpl {
3750
store: Arc<Mutex<HashMap<String, VssDbRecord>>>,
@@ -139,6 +152,9 @@ impl KvStore for InMemoryBackendImpl {
139152
async fn get(
140153
&self, user_token: String, request: GetObjectRequest,
141154
) -> Result<GetObjectResponse, VssError> {
155+
156+
validate_vss_request(&request.store_id, Some(&request.key))?;
157+
142158
let key = build_key(&user_token, &request.store_id, &request.key);
143159
let guard = self.store.lock().unwrap();
144160

@@ -170,6 +186,25 @@ impl KvStore for InMemoryBackendImpl {
170186
async fn put(
171187
&self, user_token: String, request: PutObjectRequest,
172188
) -> Result<PutObjectResponse, VssError> {
189+
190+
validate_vss_request(&request.store_id, None)?;
191+
192+
for kv in &request.transaction_items {
193+
if kv.key.is_empty() {
194+
return Err(VssError::InvalidRequestError(
195+
"key cannot be empty in transaction_items".to_string(),
196+
));
197+
}
198+
}
199+
200+
for kv in &request.delete_items {
201+
if kv.key.is_empty() {
202+
return Err(VssError::InvalidRequestError(
203+
"key cannot be empty in delete_items".to_string(),
204+
));
205+
}
206+
}
207+
173208
if request.transaction_items.len() + request.delete_items.len() > MAX_PUT_REQUEST_ITEM_COUNT
174209
{
175210
return Err(VssError::InvalidRequestError(format!(
@@ -209,6 +244,7 @@ impl KvStore for InMemoryBackendImpl {
209244
}
210245
}
211246
}
247+
212248
for kv in &request.delete_items {
213249
let key = build_key(&user_token, &store_id, &kv.key);
214250
if kv.version != -1 {
@@ -265,6 +301,9 @@ impl KvStore for InMemoryBackendImpl {
265301
let key_value = request.key_value.ok_or_else(|| {
266302
VssError::InvalidRequestError("key_value missing in DeleteObjectRequest".to_string())
267303
})?;
304+
305+
validate_vss_request(&request.store_id, Some(&key_value.key))?;
306+
268307
let store_id = request.store_id.clone();
269308
let mut guard = self.store.lock().unwrap();
270309

@@ -287,25 +326,20 @@ impl KvStore for InMemoryBackendImpl {
287326
async fn list_key_versions(
288327
&self, user_token: String, request: ListKeyVersionsRequest,
289328
) -> Result<ListKeyVersionsResponse, VssError> {
329+
validate_vss_request(&request.store_id, None)?;
330+
290331
let store_id = request.store_id;
291332
let key_prefix = request.key_prefix.unwrap_or_default();
292333
let page_token = request.page_token.unwrap_or_default();
293334
let page_size = request.page_size.unwrap_or(i32::MAX);
294335
let limit = std::cmp::min(page_size, LIST_KEY_VERSIONS_MAX_PAGE_SIZE) as usize;
336+
let guard = self.store.lock().unwrap();
295337

296-
// Global version only on first page
297338
let mut global_version = None;
298339
if page_token.is_empty() {
299-
let get_global = GetObjectRequest {
300-
store_id: store_id.clone(),
301-
key: GLOBAL_VERSION_KEY.to_string(),
302-
};
303-
let resp = self.get(user_token.clone(), get_global).await?;
304-
global_version = resp.value.map(|kv| kv.version);
340+
global_version = Some(self.get_current_global_version(&guard, &user_token, &store_id));
305341
}
306342

307-
let guard = self.store.lock().unwrap();
308-
309343
let mut latest_per_key: std::collections::HashMap<String, KeyValue> =
310344
std::collections::HashMap::new();
311345
for (k, r) in guard.iter() {
@@ -336,16 +370,7 @@ impl KvStore for InMemoryBackendImpl {
336370
let start_idx = if page_token.is_empty() {
337371
0
338372
} else {
339-
match keys.iter().position(|k| k == &page_token) {
340-
Some(i) => i + 1,
341-
None => {
342-
return Ok(ListKeyVersionsResponse {
343-
key_versions: vec![],
344-
next_page_token: None,
345-
global_version,
346-
});
347-
},
348-
}
373+
keys.iter().position(|k| k > &page_token).unwrap_or(keys.len())
349374
};
350375

351376
let page_keys: Vec<String> = keys.into_iter().skip(start_idx).take(limit).collect();

0 commit comments

Comments
 (0)