Skip to main content
Glama
expand_helpers.rs7.33 kB
//! This module contains helpers for dal test macro expansion. //! //! _Caution:_ functions in this module may appear to be unused, but they are likely used during //! macro expansion. #![allow(clippy::expect_used, clippy::panic)] use dal::{ ChangeSet, ChangeSetId, DalContext, WorkspacePk, }; use jwt_simple::{ algorithms::RSAKeyPairLike, claims::Claims, prelude::Duration, }; use si_db::Tenancy; use si_jwt_public_key::SiJwtClaims; use tracing_subscriber::{ EnvFilter, Registry, fmt, util::SubscriberInitExt, }; use crate::{ WorkspaceSignup, helpers::{ create_user, generate_fake_name, }, jwt_private_signing_key, }; /// Creates a user for each test to run as pub async fn setup_history_actor_ctx(ctx: &mut DalContext) { let user = create_user(ctx).await.expect("unable to create user"); user.associate_workspace( ctx, ctx.tenancy() .workspace_pk_opt() .expect("no workspace pk set on context"), ) .await .expect("unable to associate user with workspace"); ctx.update_history_actor(si_db::HistoryActor::User(user.pk())); } /// This function is used during macro expansion for setting up a [`ChangeSet`] in an integration test. pub async fn create_change_set_and_update_ctx( ctx: &mut DalContext, base_change_set_id: ChangeSetId, ) { let base_change_set = ChangeSet::get_by_id(ctx, base_change_set_id) .await .expect("could not find change set"); let workspace_snapshot_address = base_change_set.workspace_snapshot_address; let change_set = ChangeSet::new( ctx, generate_fake_name().expect("could not generate fake name"), Some(base_change_set_id), workspace_snapshot_address, ) .await .expect("could not create change set"); ctx.update_visibility_and_snapshot_to_visibility(change_set.id) .await .expect("could not update visibility and snapshot"); } /// This function is used during macro expansion for setting up tracing in an integration test. pub fn tracing_init(span_events_env_var: &'static str, log_env_var: &'static str) { use std::thread; thread::spawn(move || { let tokio = ::tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .expect("Failed building the Runtime for Tracing for Testing"); tokio.block_on(async move { tracing_init_inner(span_events_env_var, log_env_var); tokio::time::sleep(std::time::Duration::from_secs(10000000)).await }); }); } fn tracing_init_inner(span_events_env_var: &str, log_env_var: &str) { use tracing_subscriber::layer::SubscriberExt; telemetry::opentelemetry::global::set_text_map_propagator( opentelemetry_sdk::propagation::TraceContextPropagator::new(), ); let span_events_fmt = { use fmt::format::FmtSpan; // Used exclusively in tests & prefixed with `SI_TEST_` #[allow(clippy::disallowed_methods)] match ::std::env::var(span_events_env_var) { Ok(value) => value .to_ascii_lowercase() .split(',') .map(|filter| match filter.trim() { "new" => FmtSpan::NEW, "enter" => FmtSpan::ENTER, "exit" => FmtSpan::EXIT, "close" => FmtSpan::CLOSE, "active" => FmtSpan::ACTIVE, "full" => FmtSpan::FULL, _ => panic!( "{span_events_env_var} must contain filters separated by `,`.\n\t\ For example: `active` or `new,close`\n\t Got: {value}", ), }) .fold(FmtSpan::NONE, |acc, filter| filter | acc), Err(::std::env::VarError::NotUnicode(_)) => { panic!("{span_events_env_var} must contain a valid UTF-8 string",) } Err(::std::env::VarError::NotPresent) => FmtSpan::NONE, } }; let env_filter = EnvFilter::from_env(log_env_var); let format_layer = fmt::layer() .with_thread_ids(true) .with_span_events(span_events_fmt) .with_test_writer() .pretty(); // let otel_layer = { // use std::time::Duration; // // let resource = opentelemetry_sdk::Resource::from_detectors( // Duration::from_secs(3), // vec![ // Box::new(opentelemetry_sdk::resource::EnvResourceDetector::new()), // Box::new(opentelemetry_sdk::resource::OsResourceDetector), // Box::new(opentelemetry_sdk::resource::ProcessResourceDetector), // ], // ) // .merge(&opentelemetry_sdk::Resource::new(vec![ // // TODO(fnichol): make name configurable // telemetry::opentelemetry::KeyValue::new("service.name", "test"), // telemetry::opentelemetry::KeyValue::new("service.namespace", "si"), // ])); // // let otel_tracer = opentelemetry_otlp::new_pipeline() // .tracing() // .with_exporter(opentelemetry_otlp::new_exporter().tonic()) // .with_trace_config(opentelemetry_sdk::trace::config().with_resource(resource)) // .install_batch(opentelemetry_sdk::runtime::Tokio) // .expect("Creating otel_tracer failed"); // // tracing_opentelemetry::layer().with_tracer(otel_tracer) // }; let registry = Registry::default(); let registry = registry.with(env_filter); let registry = registry.with(format_layer); // let registry = registry.with(otel_layer); registry .try_init() .expect("failed to initialize subscriber"); } /// This function is used during macro expansion for setting up the workspace for integration tests. pub async fn workspace_signup(ctx: &mut DalContext) -> crate::Result<(WorkspaceSignup, String)> { use color_eyre::eyre::WrapErr; // Tenancy must be set here or the update_visibility call will fail, since it now needs to check // the workspace snapshot_kind ctx.update_tenancy(Tenancy::new(WorkspacePk::NONE)); let mut ctx = ctx.clone_with_head().await?; let workspace_name = generate_fake_name().expect("could not generate fake name"); let user_name = format!("frank {workspace_name}"); let user_email = format!("{workspace_name}@example.com"); let token = "workspace_name".to_string(); let nw = WorkspaceSignup::new(&mut ctx, &workspace_name, &user_name, &user_email, &token) .await .wrap_err("cannot signup a new workspace")?; let auth_token = create_auth_token(SiJwtClaims::for_web(nw.user.pk(), *nw.workspace.pk())) .await .expect("could not create auth token"); Ok((nw, auth_token)) } async fn create_auth_token(claim: SiJwtClaims) -> crate::Result<String> { let key_pair = jwt_private_signing_key().await?; let claim = Claims::with_custom_claims(claim.clone(), Duration::from_days(1)) .with_audience("https://app.systeminit.com") .with_issuer("https://app.systeminit.com") .with_subject(claim.user_id()); Ok(key_pair.sign(claim).expect("could not sign")) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server