Skip to content

Commit d16e00d

Browse files
authored
initial crud c test
1 parent 3007cb0 commit d16e00d

File tree

7 files changed

+162
-5
lines changed

7 files changed

+162
-5
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/cosmos/azure_data_cosmos_native/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ FetchContent_MakeAvailable(Corrosion)
1919
corrosion_import_crate(
2020
MANIFEST_PATH ./Cargo.toml
2121
CRATETYPES staticlib cdylib
22+
PROFILE dev
2223
)
2324

2425
set(TEST_FILES
25-
./c_tests/version.c)
26+
./c_tests/version.c
27+
./c_tests/item_crud.c)
2628

2729
foreach(test_file ${TEST_FILES})
2830
get_filename_component(test_name ${test_file} NAME_WE)

sdk/cosmos/azure_data_cosmos_native/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ tokio = { workspace = true, optional = true, features = ["rt-multi-thread", "mac
1919
serde_json = { workspace = true, features = ["raw_value"] }
2020
azure_core.workspace = true
2121
azure_data_cosmos = { path = "../azure_data_cosmos", features = [ "key_auth", "preview_query_engine" ] }
22+
tracing.workspace = true
23+
tracing-subscriber = { workspace = true, optional = true, features = ["fmt", "env-filter"] }
2224

2325
[features]
24-
default = ["tokio"]
26+
default = ["tokio", "reqwest", "tracing"]
2527
tokio = ["dep:tokio"]
28+
reqwest = ["azure_core/reqwest"]
29+
tracing = ["dep:tracing-subscriber"]
2630

2731
[build-dependencies]
2832
cbindgen = "0.29.0"
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <string.h>
7+
#include "../include/azurecosmos.h"
8+
9+
#define SENTINEL_VALUE "test-sentinel-12345"
10+
#define ITEM_ID "test-item-id"
11+
#define PARTITION_KEY_VALUE "test-partition"
12+
13+
int main() {
14+
cosmos_enable_tracing();
15+
16+
// Get environment variables
17+
const char *endpoint = getenv("AZURE_COSMOS_ENDPOINT");
18+
const char *key = getenv("AZURE_COSMOS_KEY");
19+
const char *database_name = getenv("AZURE_COSMOS_DATABASE");
20+
const char *container_name = getenv("AZURE_COSMOS_CONTAINER");
21+
22+
if (!endpoint || !key || !database_name || !container_name) {
23+
printf("Error: Missing required environment variables.\n");
24+
printf("Required: AZURE_COSMOS_ENDPOINT, AZURE_COSMOS_KEY, AZURE_COSMOS_DATABASE, AZURE_COSMOS_CONTAINER\n");
25+
return 1;
26+
}
27+
28+
printf("Running Cosmos DB item CRUD test...\n");
29+
printf("Endpoint: %s\n", endpoint);
30+
printf("Database: %s\n", database_name);
31+
printf("Container: %s\n", container_name);
32+
33+
struct CosmosError error = {0};
34+
struct CosmosClient *client = NULL;
35+
struct DatabaseClient *database = NULL;
36+
struct ContainerClient *container = NULL;
37+
char *read_json = NULL;
38+
int result = 0;
39+
40+
// Create Cosmos client
41+
CosmosErrorCode code = cosmos_client_create(endpoint, key, &client, &error);
42+
if (code != Success) {
43+
printf("Failed to create Cosmos client: %s (code: %d)\n", error.message, error.code);
44+
result = 1;
45+
goto cleanup;
46+
}
47+
printf("✓ Created Cosmos client\n");
48+
49+
// Get database client
50+
code = cosmos_client_database_client(client, database_name, &database, &error);
51+
if (code != Success) {
52+
printf("Failed to get database client: %s (code: %d)\n", error.message, error.code);
53+
result = 1;
54+
goto cleanup;
55+
}
56+
printf("✓ Got database client\n");
57+
58+
// Get container client
59+
code = cosmos_database_container_client(database, container_name, &container, &error);
60+
if (code != Success) {
61+
printf("Failed to get container client: %s (code: %d)\n", error.message, error.code);
62+
result = 1;
63+
goto cleanup;
64+
}
65+
printf("✓ Got container client\n");
66+
67+
// Construct JSON document with sentinel value
68+
char json_data[512];
69+
snprintf(json_data, sizeof(json_data),
70+
"{\"id\":\"%s\",\"partitionKey\":\"%s\",\"name\":\"Test Document\",\"sentinel\":\"%s\",\"description\":\"This is a test document for CRUD operations\"}",
71+
ITEM_ID, PARTITION_KEY_VALUE, SENTINEL_VALUE);
72+
73+
printf("Upserting document: %s\n", json_data);
74+
75+
// Upsert the item
76+
code = cosmos_container_upsert_item(container, PARTITION_KEY_VALUE, json_data, &error);
77+
if (code != Success) {
78+
printf("Failed to upsert item: %s (code: %d)\n", error.message, error.code);
79+
result = 1;
80+
goto cleanup;
81+
}
82+
printf("✓ Upserted item successfully\n");
83+
84+
// Read the item back
85+
code = cosmos_container_read_item(container, PARTITION_KEY_VALUE, ITEM_ID, &read_json, &error);
86+
if (code != Success) {
87+
printf("Failed to read item: %s (code: %d)\n", error.message, error.code);
88+
result = 1;
89+
goto cleanup;
90+
}
91+
printf("✓ Read item successfully\n");
92+
93+
printf("Read back JSON: %s\n", read_json);
94+
95+
// Verify the sentinel value is present in the returned JSON
96+
if (strstr(read_json, SENTINEL_VALUE) == NULL) {
97+
printf("❌ FAIL: Sentinel value '%s' not found in returned JSON\n", SENTINEL_VALUE);
98+
result = 1;
99+
goto cleanup;
100+
}
101+
102+
// Verify the item ID is present
103+
if (strstr(read_json, ITEM_ID) == NULL) {
104+
printf("❌ FAIL: Item ID '%s' not found in returned JSON\n", ITEM_ID);
105+
result = 1;
106+
goto cleanup;
107+
}
108+
109+
printf("✓ All assertions passed!\n");
110+
printf("SUCCESS: Item CRUD test completed successfully.\n");
111+
112+
cleanup:
113+
// // Free all allocated resources
114+
// if (read_json) {
115+
// cosmos_string_free(read_json);
116+
// }
117+
// if (container) {
118+
// cosmos_container_free(container);
119+
// }
120+
// if (database) {
121+
// cosmos_database_free(database);
122+
// }
123+
// if (client) {
124+
// cosmos_client_free(client);
125+
// }
126+
// if (error.message) {
127+
// cosmos_error_free(&error);
128+
// }
129+
130+
return result;
131+
}

sdk/cosmos/azure_data_cosmos_native/c_tests/version.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
#include <stdio.h>
55
#include <string.h>
6-
#include "../include/cosmosclient.h"
6+
#include "../include/azurecosmos.h"
77

88
int main() {
9-
const char *version = cosmosclient_version();
9+
const char *version = cosmos_version();
1010
const char *header_version = COSMOSCLIENT_H_VERSION;
1111
printf("Cosmos Client Version: %s\n", version);
1212
printf("Header Version: %s\n", header_version);

sdk/cosmos/azure_data_cosmos_native/src/blocking.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ pub fn block_on<F>(future: F) -> F::Output
99
where
1010
F: Future,
1111
{
12-
let runtime = RUNTIME.get_or_init(|| Runtime::new().expect("Failed to create Tokio runtime"));
12+
let runtime = RUNTIME.get_or_init(|| {
13+
tracing::trace!("Initializing blocking Tokio runtime");
14+
Runtime::new().expect("Failed to create Tokio runtime")
15+
});
1316
runtime.block_on(future)
1417
}
1518

sdk/cosmos/azure_data_cosmos_native/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,18 @@ const VERSION: &CStr = c_str!(env!("CARGO_PKG_VERSION"));
2828
pub extern "C" fn cosmos_version() -> *const c_char {
2929
VERSION.as_ptr()
3030
}
31+
32+
/// Installs tracing listeners that output to stdout/stderr based on the `COSMOS_LOG` environment variable.
33+
///
34+
/// Just calling this function isn't sufficient to get logging output. You must also set the `COSMOS_LOG` environment variable
35+
/// to specify the desired log level and targets. See <https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html>
36+
/// for details on the syntax for this variable.
37+
#[no_mangle]
38+
#[cfg(feature = "tracing")]
39+
pub extern "C" fn cosmos_enable_tracing() {
40+
use tracing_subscriber::EnvFilter;
41+
42+
tracing_subscriber::fmt()
43+
.with_env_filter(EnvFilter::from_env("COSMOS_LOG"))
44+
.init();
45+
}

0 commit comments

Comments
 (0)