use open_feature::{provider::FeatureProvider, EvaluationContext, OpenFeature};
use serde_json::Value;
use superposition_provider::{
data_source::{file::FileDataSource, http::HttpDataSource},
AllFeatureProvider, LocalResolutionProvider, PollingStrategy, RefreshStrategy,
SuperpositionAPIProvider, SuperpositionOptions,
};
use superposition_sdk::{
types::{ContextPut, DimensionType, Variant, WorkspaceStatus},
Client, Config,
};
const WORKSPACE_ID: &str = "rustprovidertest";
const ENDPOINT: &str = "http://localhost:8080";
const TOKEN: &str = "12131";
fn create_sdk_client() -> Client {
use superposition_sdk::config::Token;
let config = Config::builder()
.endpoint_url(ENDPOINT)
.bearer_token(Token::new(TOKEN, None))
.behavior_version_latest()
.build();
Client::from_conf(config)
}
async fn create_organisation(client: &Client) -> String {
let output = client
.create_organisation()
.name("rusttestorg")
.admin_email("admin@rusttestorg.com")
.send()
.await
.expect("Failed to create organisation");
println!(
"Organisation created: {} with ID: {}",
output.name, output.id
);
output.id
}
async fn create_workspace(client: &Client, org_id: &str, workspace_name: &str) {
client
.create_workspace()
.org_id(org_id)
.workspace_name(workspace_name)
.workspace_admin_email("test@tests.com")
.workspace_status(WorkspaceStatus::Enabled)
.allow_experiment_self_approval(true)
.auto_populate_control(false) .enable_context_validation(true)
.enable_change_reason_validation(true)
.send()
.await
.expect("Failed to create workspace");
println!("Workspace created: {}", workspace_name);
}
async fn create_dimensions(client: &Client, org_id: &str, workspace_id: &str) {
println!("Creating dimensions:");
use aws_smithy_types::Document;
client
.create_dimension()
.workspace_id(workspace_id)
.org_id(org_id)
.dimension("name")
.position(1)
.schema("type", Document::from("string"))
.description("customer name dimension")
.change_reason("adding name dimension")
.dimension_type(DimensionType::Regular)
.send()
.await
.expect("Failed to create name dimension");
println!(" - Created dimension: name");
client
.create_dimension()
.workspace_id(workspace_id)
.org_id(org_id)
.dimension("city")
.position(2)
.schema("type", Document::from("string"))
.description("city dimension")
.change_reason("adding city dimension")
.dimension_type(DimensionType::Regular)
.send()
.await
.expect("Failed to create city dimension");
println!(" - Created dimension: city");
let enum_array = Document::Array(vec![
Document::from("platinum"),
Document::from("gold"),
Document::from("otherwise"),
]);
let platinum_def = Document::Object(
[(
"in".to_string(),
Document::Array(vec![
Document::Object(
[("var".to_string(), Document::from("name"))]
.into_iter()
.collect(),
),
Document::Array(vec![Document::from("Agush"), Document::from("Sauyav")]),
]),
)]
.into_iter()
.collect(),
);
let gold_def = Document::Object(
[(
"in".to_string(),
Document::Array(vec![
Document::Object(
[("var".to_string(), Document::from("name"))]
.into_iter()
.collect(),
),
Document::Array(vec![Document::from("Angit"), Document::from("Bhrey")]),
]),
)]
.into_iter()
.collect(),
);
let definitions = Document::Object(
[
("platinum".to_string(), platinum_def),
("gold".to_string(), gold_def),
]
.into_iter()
.collect(),
);
client
.create_dimension()
.workspace_id(workspace_id)
.org_id(org_id)
.dimension("customers")
.position(1)
.schema("type", Document::from("string"))
.schema("enum", enum_array)
.schema("definitions", definitions)
.description("customers dimension")
.change_reason("adding customers dimension")
.dimension_type(DimensionType::LocalCohort("name".to_string()))
.send()
.await
.expect("Failed to create customers dimension");
println!(" - Created dimension: customers");
}
async fn create_default_configs(client: &Client, org_id: &str, workspace_id: &str) {
println!("Creating default configs:");
use aws_smithy_types::Document;
client
.create_default_config()
.key("price")
.value(Document::from(10000))
.schema("type", Document::from("number"))
.schema("minimum", Document::from(0))
.description("price as a positive number")
.change_reason("adding price config")
.workspace_id(workspace_id)
.org_id(org_id)
.send()
.await
.expect("Failed to create price config");
println!(" - Created config: price");
let currency_enum = Document::Array(vec![
Document::from("Rupee"),
Document::from("Dollar"),
Document::from("Euro"),
]);
client
.create_default_config()
.key("currency")
.value(Document::from("Rupee"))
.schema("type", Document::from("string"))
.schema("enum", currency_enum)
.description("currency as an enum")
.change_reason("adding currency config")
.workspace_id(workspace_id)
.org_id(org_id)
.send()
.await
.expect("Failed to create currency config");
println!(" - Created config: currency");
}
async fn create_overrides(client: &Client, org_id: &str, workspace_id: &str) {
println!("Creating overrides:");
use aws_smithy_types::Document;
client
.create_context()
.workspace_id(workspace_id)
.org_id(org_id)
.request(
ContextPut::builder()
.context("city", Document::from("Boston"))
.r#override("currency", Document::from("Dollar"))
.description("Bostonian")
.change_reason("testing")
.build()
.expect("Failed to create ContextPut"),
)
.send()
.await
.expect("Failed to create Boston override");
println!(" - Created override: Boston -> Dollar");
client
.create_context()
.workspace_id(workspace_id)
.org_id(org_id)
.request(
ContextPut::builder()
.context("city", Document::from("Berlin"))
.r#override("currency", Document::from("Euro"))
.description("Berlin")
.change_reason("testing")
.build()
.expect("Failed to create ContextPut"),
)
.send()
.await
.expect("Failed to create Berlin override");
println!(" - Created override: Berlin -> Euro");
client
.create_context()
.workspace_id(workspace_id)
.org_id(org_id)
.request(
ContextPut::builder()
.context("customers", Document::from("platinum"))
.r#override("price", Document::from(5000))
.description("platinum customer")
.change_reason("testing")
.build()
.expect("Failed to create ContextPut"),
)
.send()
.await
.expect("Failed to create platinum override");
println!(" - Created override: platinum -> price 5000");
client
.create_context()
.workspace_id(workspace_id)
.org_id(org_id)
.request(
ContextPut::builder()
.context("customers", Document::from("gold"))
.r#override("price", Document::from(8000))
.description("gold customers")
.change_reason("testing")
.build()
.expect("Failed to create ContextPut"),
)
.send()
.await
.expect("Failed to create gold override");
println!(" - Created override: gold -> price 8000");
client
.create_context()
.workspace_id(workspace_id)
.org_id(org_id)
.request(
ContextPut::builder()
.context("name", Document::from("karbik"))
.r#override("price", Document::from(1))
.description("edge case customer karbik")
.change_reason("testing")
.build()
.expect("Failed to create ContextPut"),
)
.send()
.await
.expect("Failed to create karbik override");
println!(" - Created override: karbik -> price 1");
}
async fn create_experiments(client: &Client, org_id: &str, workspace_id: &str) {
println!("Creating experiment:");
use aws_smithy_types::Document;
let response = client
.create_experiment()
.workspace_id(workspace_id)
.org_id(org_id)
.name("Kolkata Pricing Experiment")
.context("city", Document::from("Kolkata"))
.variants(
Variant::builder()
.id("control".to_string())
.variant_type(superposition_sdk::types::VariantType::Control)
.overrides("price", Document::from(8000)) .build()
.expect("Failed to build control variant"),
)
.variants(
Variant::builder()
.id("Experimental".to_string())
.variant_type(superposition_sdk::types::VariantType::Experimental)
.overrides("price", Document::from(7000))
.build()
.expect("Failed to build Experimental variant"),
)
.description("A test experiment")
.change_reason("adding test experiment")
.send()
.await
.expect("Failed to create experiment");
println!(" - Created experiment: Kolkata Pricing Experiment");
client
.ramp_experiment()
.workspace_id(workspace_id)
.org_id(org_id)
.id(response.id)
.traffic_percentage(50)
.change_reason("ramping up experiment")
.send()
.await
.expect("Failed to ramp experiment");
}
async fn setup_with_sdk(org_id: &str, workspace_id: &str) {
println!("\n=== Setting up test environment ===\n");
let client = create_sdk_client();
create_workspace(&client, org_id, workspace_id).await;
create_dimensions(&client, org_id, workspace_id).await;
create_default_configs(&client, org_id, workspace_id).await;
create_overrides(&client, org_id, workspace_id).await;
create_experiments(&client, org_id, workspace_id).await;
println!("\n=== Setup complete ===\n");
}
async fn run_provider_tests(org_id: &str, workspace_id: &str) {
println!("\n=== Starting OpenFeature provider tests ===\n");
let refresh_strategy = RefreshStrategy::Polling(PollingStrategy::default());
let http_options = SuperpositionOptions {
endpoint: ENDPOINT.to_string(),
token: TOKEN.to_string(),
org_id: org_id.to_string(),
workspace_id: workspace_id.to_string(),
};
let wrong_http_options = SuperpositionOptions {
endpoint: ENDPOINT.to_string(),
token: "12345678".to_string(),
org_id: org_id.to_string(),
workspace_id: "workspace_id".to_string(),
};
let primary_source = HttpDataSource::new(http_options.clone());
let fallback_source = FileDataSource::new("tests/config.toml".into()).unwrap();
{
println!("Testing LocalResolutionProvider with HTTP data source (no fallback)");
let provider = LocalResolutionProvider::new(
Box::new(primary_source),
None,
refresh_strategy.clone(),
);
println!("Test 0: Verify provider clone works (sanity check)");
{
let mut provider_clone = provider.clone();
provider_clone
.initialize(&EvaluationContext::default())
.await;
let ctx = EvaluationContext::default().with_custom_field("name", "karbik");
let all_fields = provider_clone.resolve_all_features(ctx).await.unwrap();
assert_eq!(
all_fields.get("price").unwrap(),
&Value::from(1),
"Price should be 1 for karbik"
);
assert_eq!(
all_fields.get("currency").unwrap(),
&Value::from("Rupee"),
"Currency should be default Rupee"
);
println!(" ✓ Test passed\n");
}
let mut api = OpenFeature::singleton_mut().await;
api.set_provider(provider).await;
let client = api.create_client();
println!("Test 1: Default values (no context)");
{
let ctx = EvaluationContext::default();
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 10000.0, "Default price should be 10000");
assert_eq!(currency, "Rupee", "Default currency should be Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 2: Platinum customer - Agush (no city)");
{
let ctx = EvaluationContext::default().with_custom_field("name", "Agush");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 5000.0, "Price should be 5000 for platinum customer");
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 3: Platinum customer - Sauyav with city Boston");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "Sauyav")
.with_custom_field("city", "Boston");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 5000.0, "Price should be 5000");
assert_eq!(currency, "Dollar", "Currency should be Dollar");
println!(" ✓ Test passed\n");
}
println!("Test 4: Regular customer - John (no city)");
{
let ctx = EvaluationContext::default().with_custom_field("name", "John");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 10000.0, "Price should be default 10000");
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 5: Platinum customer - Sauyav with city Berlin");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "Sauyav")
.with_custom_field("city", "Berlin");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 5000.0, "Price should be 5000");
assert_eq!(currency, "Euro", "Currency should be Euro in Berlin");
println!(" ✓ Test passed\n");
}
println!("Test 6: Regular customer - John with city Boston");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "John")
.with_custom_field("city", "Boston");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 10000.0, "Price should be default 10000");
assert_eq!(currency, "Dollar", "Currency should be Dollar in Boston");
println!(" ✓ Test passed\n");
}
println!("Test 7: Edge case customer - karbik (specific override)");
{
let ctx = EvaluationContext::default().with_custom_field("name", "karbik");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 1.0, "Price should be 1 for karbik");
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 8: Edge case customer - karbik with city Boston");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "karbik")
.with_custom_field("city", "Boston");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 1.0, "Price should be 1 for karbik");
assert_eq!(currency, "Dollar", "Currency should be Dollar in Boston");
println!(" ✓ Test passed\n");
}
println!("Test 9: Experiment case: Kolkata pricing");
{
let ctx = EvaluationContext::default()
.with_custom_field("city", "Kolkata")
.with_targeting_key("test");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
println!(" Retrieved price: {}, currency: {}", price, currency);
assert!(
price == 8000.0 || price == 7000.0,
"Price should be either 8000 (control) or 7000 (experiment) "
);
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Experiment test passed ");
}
api.shutdown().await;
println!("\n=== All tests passed! ===\n");
}
{
println!("Testing SuperpositionAPIProvider");
let provider = SuperpositionAPIProvider::new(http_options);
let mut api = OpenFeature::singleton_mut().await;
api.set_provider(provider).await;
let client = api.create_client();
println!("Test 1: Default values (no context)");
{
let ctx = EvaluationContext::default();
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 10000.0, "Default price should be 10000");
assert_eq!(currency, "Rupee", "Default currency should be Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 2: Platinum customer - Agush (no city)");
{
let ctx = EvaluationContext::default().with_custom_field("name", "Agush");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 5000.0, "Price should be 5000 for platinum customer");
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 3: Platinum customer - Sauyav with city Boston");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "Sauyav")
.with_custom_field("city", "Boston");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 5000.0, "Price should be 5000");
assert_eq!(currency, "Dollar", "Currency should be Dollar");
println!(" ✓ Test passed\n");
}
println!("Test 4: Regular customer - John (no city)");
{
let ctx = EvaluationContext::default().with_custom_field("name", "John");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 10000.0, "Price should be default 10000");
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 5: Platinum customer - Sauyav with city Berlin");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "Sauyav")
.with_custom_field("city", "Berlin");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 5000.0, "Price should be 5000");
assert_eq!(currency, "Euro", "Currency should be Euro in Berlin");
println!(" ✓ Test passed\n");
}
println!("Test 6: Regular customer - John with city Boston");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "John")
.with_custom_field("city", "Boston");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 10000.0, "Price should be default 10000");
assert_eq!(currency, "Dollar", "Currency should be Dollar in Boston");
println!(" ✓ Test passed\n");
}
println!("Test 7: Edge case customer - karbik (specific override)");
{
let ctx = EvaluationContext::default().with_custom_field("name", "karbik");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 1.0, "Price should be 1 for karbik");
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 8: Edge case customer - karbik with city Boston");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "karbik")
.with_custom_field("city", "Boston");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 1.0, "Price should be 1 for karbik");
assert_eq!(currency, "Dollar", "Currency should be Dollar in Boston");
println!(" ✓ Test passed\n");
}
println!("Test 9: Experiment case: Kolkata pricing");
{
let ctx = EvaluationContext::default()
.with_custom_field("city", "Kolkata")
.with_targeting_key("test");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
println!(" Retrieved price: {}, currency: {}", price, currency);
assert!(
price == 8000.0 || price == 7000.0,
"Price should be either 8000 (control) or 7000 (experiment) "
);
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Experiment test passed ");
}
api.shutdown().await;
println!("\n=== All tests passed! ===\n");
}
{
println!("Testing LocalResolutionProvider with wrong HTTP data source but valid file fallback");
let provider = LocalResolutionProvider::new(
Box::new(HttpDataSource::new(wrong_http_options)),
Some(Box::new(fallback_source)),
refresh_strategy,
);
let mut api = OpenFeature::singleton_mut().await;
api.set_provider(provider).await;
let client = api.create_client();
println!("Test 1: Default values (no context)");
{
let ctx = EvaluationContext::default();
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 10000.0, "Default price should be 10000");
assert_eq!(currency, "Rupee", "Default currency should be Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 2: Platinum customer - Agush (no city)");
{
let ctx = EvaluationContext::default().with_custom_field("name", "Agush");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 5000.0, "Price should be 5000 for platinum customer");
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 3: Platinum customer - Sauyav with city Boston");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "Sauyav")
.with_custom_field("city", "Boston");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 5000.0, "Price should be 5000");
assert_eq!(currency, "Dollar", "Currency should be Dollar");
println!(" ✓ Test passed\n");
}
println!("Test 4: Regular customer - John (no city)");
{
let ctx = EvaluationContext::default().with_custom_field("name", "John");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 10000.0, "Price should be default 10000");
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 5: Platinum customer - Sauyav with city Berlin");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "Sauyav")
.with_custom_field("city", "Berlin");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 5000.0, "Price should be 5000");
assert_eq!(currency, "Euro", "Currency should be Euro in Berlin");
println!(" ✓ Test passed\n");
}
println!("Test 6: Regular customer - John with city Boston");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "John")
.with_custom_field("city", "Boston");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 10000.0, "Price should be default 10000");
assert_eq!(currency, "Dollar", "Currency should be Dollar in Boston");
println!(" ✓ Test passed\n");
}
println!("Test 7: Edge case customer - karbik (specific override)");
{
let ctx = EvaluationContext::default().with_custom_field("name", "karbik");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 1.0, "Price should be 1 for karbik");
assert_eq!(currency, "Rupee", "Currency should be default Rupee");
println!(" ✓ Test passed\n");
}
println!("Test 8: Edge case customer - karbik with city Boston");
{
let ctx = EvaluationContext::default()
.with_custom_field("name", "karbik")
.with_custom_field("city", "Boston");
let price = client
.get_float_value("price", Some(&ctx), None)
.await
.unwrap();
let currency = client
.get_string_value("currency", Some(&ctx), None)
.await
.unwrap();
assert_eq!(price, 1.0, "Price should be 1 for karbik");
assert_eq!(currency, "Dollar", "Currency should be Dollar in Boston");
println!(" ✓ Test passed\n");
}
println!(
"Experiment not supported in file data source, skipping experiment test"
);
println!("\n=== All tests passed! ===\n");
}
}
#[tokio::test]
#[ignore]
async fn test_rust_provider_integration() {
let client = create_sdk_client();
let org_id = create_organisation(&client).await;
setup_with_sdk(&org_id, WORKSPACE_ID).await;
run_provider_tests(&org_id, WORKSPACE_ID).await;
}