Skip to content

Commit

Permalink
fix: add an ai feature so that ai features are not compiled by default.
Browse files Browse the repository at this point in the history
Fixes trustification#1219

Signed-off-by: Hiram Chirino <hiram@hiramchirino.com>
  • Loading branch information
chirino committed Jan 30, 2025
1 parent 9f2764d commit 520a8b6
Showing 18 changed files with 88 additions and 362 deletions.
1 change: 1 addition & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[alias]
xtask = "run --package xtask --"
xtask-ai = "run --features ai --package xtask --"

[env]
CARGO_WORKSPACE_ROOT = { value = "", relative = true }
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ jobs:
key: ${{ runner.os }}-theseus-postgresql-${{ hashFiles('**/Cargo.lock') }}

- name: Test
run: cargo test -- --nocapture
run: cargo test --all-features -- --nocapture
env:
RUST_LOG: warn,sqlx=error,sea_orm=error
- name: Export and Validate Generated Openapi Spec
3 changes: 3 additions & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@ edition.workspace = true
publish.workspace = true
license.workspace = true

[features]
ai = [ "trustify-migration/ai" ]

[dependencies]
trustify-migration = { workspace = true }

4 changes: 4 additions & 0 deletions common/src/db/mod.rs
Original file line number Diff line number Diff line change
@@ -47,6 +47,8 @@ impl Database {
pub async fn migrate(&self) -> Result<(), anyhow::Error> {
log::debug!("applying migrations");
Migrator::up(&self.db, None).await?;
#[cfg(feature = "ai")]
migration::ai::Migrator::up(&self.db, None).await?;
log::debug!("applied migrations");

Ok(())
@@ -56,6 +58,8 @@ impl Database {
pub async fn refresh(&self) -> Result<(), anyhow::Error> {
log::warn!("refreshing database schema...");
Migrator::refresh(&self.db).await?;
#[cfg(feature = "ai")]
migration::ai::Migrator::refresh(&self.db).await?;
log::warn!("refreshing database schema... done!");

Ok(())
3 changes: 3 additions & 0 deletions migration/Cargo.toml
Original file line number Diff line number Diff line change
@@ -9,6 +9,9 @@ license.workspace = true
name = "migration"
path = "src/lib.rs"

[features]
ai = ["trustify-common/ai"]

[dependencies]
sea-orm-migration = { workspace = true, features = ["runtime-tokio-rustls", "sqlx-postgres", "with-uuid"] }
serde_json = { workspace = true }
19 changes: 19 additions & 0 deletions migration/src/ai.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pub use sea_orm_migration::prelude::*;

pub struct Migrator;

#[async_trait::async_trait]
impl MigratorTrait for Migrator {
fn migration_table_name() -> DynIden {
#[derive(DeriveIden)]
enum AiTables {
AiMigrations,
}

AiTables::AiMigrations.into_iden()
}

fn migrations() -> Vec<Box<dyn MigrationTrait>> {
vec![Box::new(crate::m0000820_create_conversation::Migration)]
}
}
4 changes: 3 additions & 1 deletion migration/src/lib.rs
Original file line number Diff line number Diff line change
@@ -103,6 +103,9 @@ mod m0000830_perf_indexes;
mod m0000840_add_relationship_14_15;
mod m0000850_python_version;

#[cfg(feature = "ai")]
pub mod ai;

pub struct Migrator;

#[async_trait::async_trait]
@@ -207,7 +210,6 @@ impl MigratorTrait for Migrator {
Box::new(m0000790_alter_sbom_alter_document_id::Migration),
Box::new(m0000800_alter_product_version_range_scheme::Migration),
Box::new(m0000810_fix_get_purl::Migration),
Box::new(m0000820_create_conversation::Migration),
Box::new(m0000830_perf_indexes::Migration),
Box::new(m0000840_add_relationship_14_15::Migration),
Box::new(m0000850_python_version::Migration),
20 changes: 20 additions & 0 deletions migration/tests/tests.rs
Original file line number Diff line number Diff line change
@@ -21,6 +21,26 @@ async fn test_migrations(ctx: TrustifyContext) -> Result<(), anyhow::Error> {
Ok(())
}

#[cfg(feature = "ai")]
#[test_context(TrustifyContext, skip_teardown)]
#[test(tokio::test)]
async fn test_ai_migrations(ctx: TrustifyContext) -> Result<(), anyhow::Error> {
let db = ctx.db;

let migrations = migration::ai::Migrator::get_applied_migrations(&db).await?;
// 'Migrator.up' was called in bootstrap function when using TrustifyContext.
// At this point we already have migrations.
assert!(!migrations.is_empty());

db.refresh().await?;

let rolled_back_and_reapplied_migrations =
migration::ai::Migrator::get_applied_migrations(&db).await?;
assert!(!rolled_back_and_reapplied_migrations.is_empty());

Ok(())
}

#[test_context(TrustifyContext, skip_teardown)]
#[test(tokio::test)]
async fn only_up_migration(_ctx: TrustifyContext) -> Result<(), anyhow::Error> {
6 changes: 5 additions & 1 deletion modules/fundamental/Cargo.toml
Original file line number Diff line number Diff line change
@@ -5,9 +5,13 @@ edition.workspace = true
publish.workspace = true
license.workspace = true

[features]
default = []
ai = [ "trustify-common/ai" ]

[dependencies]
trustify-auth = { workspace = true }
trustify-common = { workspace = true }
trustify-common = { workspace = true}
trustify-cvss = { workspace = true }
trustify-entity = { workspace = true }
trustify-module-analysis = { workspace = true }
1 change: 1 addition & 0 deletions modules/fundamental/src/ai/endpoints/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(feature = "ai")]
#[cfg(test)]
mod test;

25 changes: 15 additions & 10 deletions modules/fundamental/src/ai/endpoints/test.rs
Original file line number Diff line number Diff line change
@@ -173,20 +173,25 @@ async fn conversation_crud(ctx: &TrustifyContext) -> anyhow::Result<()> {

// Verify that there are no conversations
let request = TestRequest::get()
.uri("/api/v1/ai/conversations")
.uri("/api/v2/ai/conversations")
.to_request()
.test_auth("user-a");

let response = app.call_service(request).await;
assert_eq!(response.status(), StatusCode::OK);
assert_eq!(
response.status(),
StatusCode::OK,
"response: {:?}",
read_text(response).await
);

let result: PaginatedResults<ConversationSummary> = read_body_json(response).await;
assert_eq!(result.total, 0);
assert_eq!(result.items.len(), 0);

// Create a conversation
let request = TestRequest::post()
.uri("/api/v1/ai/conversations")
.uri("/api/v2/ai/conversations")
.to_request()
.test_auth("user-a");

@@ -208,7 +213,7 @@ async fn conversation_crud(ctx: &TrustifyContext) -> anyhow::Result<()> {
));

let request = TestRequest::put()
.uri(format!("/api/v1/ai/conversations/{}", conversation_v1.id).as_str())
.uri(format!("/api/v2/ai/conversations/{}", conversation_v1.id).as_str())
.set_json(update1.clone())
.to_request()
.test_auth("user-a");
@@ -225,7 +230,7 @@ async fn conversation_crud(ctx: &TrustifyContext) -> anyhow::Result<()> {

// Verify that the conversation can be listed
let request = TestRequest::get()
.uri("/api/v1/ai/conversations")
.uri("/api/v2/ai/conversations")
.to_request()
.test_auth("user-a");

@@ -239,7 +244,7 @@ async fn conversation_crud(ctx: &TrustifyContext) -> anyhow::Result<()> {

// Verify that we can retrieve the conversation by ID
let request = TestRequest::get()
.uri(format!("/api/v1/ai/conversations/{}", conversation_v1.id).as_str())
.uri(format!("/api/v2/ai/conversations/{}", conversation_v1.id).as_str())
.to_request()
.test_auth("user-a");

@@ -256,7 +261,7 @@ async fn conversation_crud(ctx: &TrustifyContext) -> anyhow::Result<()> {
));

let request = TestRequest::put()
.uri(format!("/api/v1/ai/conversations/{}", conversation_v1.id).as_str())
.uri(format!("/api/v2/ai/conversations/{}", conversation_v1.id).as_str())
.append_header(("if-match", format!("\"{}\"", conversation_v2.seq).as_str()))
.set_json(update2.clone())
.to_request()
@@ -274,7 +279,7 @@ async fn conversation_crud(ctx: &TrustifyContext) -> anyhow::Result<()> {

// Verify that we can retrieve the updated conversation by ID
let request = TestRequest::get()
.uri(format!("/api/v1/ai/conversations/{}", conversation_v1.id).as_str())
.uri(format!("/api/v2/ai/conversations/{}", conversation_v1.id).as_str())
.to_request()
.test_auth("user-a");

@@ -286,7 +291,7 @@ async fn conversation_crud(ctx: &TrustifyContext) -> anyhow::Result<()> {

// Verify that we can delete the conversation
let request = TestRequest::delete()
.uri(format!("/api/v1/ai/conversations/{}", conversation_v1.id).as_str())
.uri(format!("/api/v2/ai/conversations/{}", conversation_v1.id).as_str())
.to_request()
.test_auth("user-a");

@@ -295,7 +300,7 @@ async fn conversation_crud(ctx: &TrustifyContext) -> anyhow::Result<()> {

// Verify that the conversation is deleted
let request = TestRequest::get()
.uri("/api/v1/ai/conversations")
.uri("/api/v2/ai/conversations")
.to_request()
.test_auth("user-a");

1 change: 1 addition & 0 deletions modules/fundamental/src/endpoints.rs
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ pub fn configure(

crate::advisory::endpoints::configure(svc, db.clone(), config.advisory_upload_limit);
crate::license::endpoints::configure(svc, db.clone());
#[cfg(feature = "ai")]
crate::ai::endpoints::configure(svc, db.clone());
crate::organization::endpoints::configure(svc, db.clone());
crate::purl::endpoints::configure(svc, db.clone());
1 change: 1 addition & 0 deletions modules/fundamental/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod advisory;
#[cfg(feature = "ai")]
pub mod ai;
pub mod endpoints;
pub mod error;
Loading

0 comments on commit 520a8b6

Please sign in to comment.