rusticity-core 0.1.10

Core AWS SDK integration for Rusticity
Documentation
use super::*;

#[test]
fn finder_query_threshold_excludes_service_qualifiers_and_supports_unicode() {
    for input in ["", "@dynamodb", "@s3 ab", " a b "] {
        assert!(!SearchQuery::parse(input).unwrap().ready(), "{input}");
    }
    let query = SearchQuery::parse("@DDB abc").unwrap();
    assert!(query.ready());
    assert_eq!(query.kinds, [ResourceKind::Table]);
    assert!(SearchQuery::parse("@rds 数据库").unwrap().ready());
    assert!(SearchQuery::parse("@unknown abc").is_err());
    assert!(SearchQuery::parse("@ abc").is_err());
    let union = SearchQuery::parse("rusticity @s3 @dynamodb").unwrap();
    assert_eq!(union.text, "rusticity");
    assert_eq!(union.kinds.len(), 2);
    assert!(union.kinds.contains(&ResourceKind::Bucket));
}

#[test]
fn finder_index_query_quotes_input_and_limits_resource_types_and_region() {
    let query = SearchQuery::parse("@dynamodb orders service:iam")
        .unwrap()
        .index_query("us-east-2");
    assert_eq!(
        query,
        "orders* \"service:iam\" resourcetype:dynamodb:table region:us-east-2,global"
    );
    assert!(SearchQuery::parse("@apig test")
        .unwrap()
        .index_query("us-east-2")
        .contains("apigateway:restapis,apigateway:apis"));
}

#[test]
fn finder_normalizes_only_supported_openable_resource_types() {
    for (kind, typ, arn, id) in [
        (
            ResourceKind::Table,
            "dynamodb:table",
            "arn:aws:dynamodb:us-east-2:123456789012:table/orders",
            "orders",
        ),
        (
            ResourceKind::Bucket,
            "s3:bucket",
            "arn:aws:s3:::bucket",
            "bucket",
        ),
        (
            ResourceKind::Role,
            "iam:role",
            "arn:aws:iam::123456789012:role/path/role",
            "role",
        ),
        (
            ResourceKind::LogGroup,
            "logs:log-group",
            "arn:aws:logs:us-east-2:123456789012:log-group:/aws/lambda/fn:*",
            "/aws/lambda/fn",
        ),
        (
            ResourceKind::Database,
            "rds:db",
            "arn:aws:rds:us-east-2:123456789012:db:orders",
            "orders",
        ),
        (
            ResourceKind::Api,
            "apigateway:restapis",
            "arn:aws:apigateway:us-east-2::/restapis/abc",
            "abc",
        ),
        (
            ResourceKind::Stack,
            "cloudformation:stack",
            "arn:aws:cloudformation:us-east-2:123456789012:stack/orders/uuid",
            "orders",
        ),
        (
            ResourceKind::Repository,
            "ecr:repository",
            "arn:aws:ecr:us-east-2:123456789012:repository/path/repo",
            "path/repo",
        ),
    ] {
        let resource = Resource::from_index(typ, arn, "us-east-2").unwrap();
        assert_eq!(resource.kind, kind);
        assert_eq!(resource.id, id);
        assert_eq!(resource.arn, arn);
    }
    assert!(Resource::from_index(
        "rds:cluster",
        "arn:aws:rds:us-east-2:123456789012:cluster:c",
        "us-east-2"
    )
    .is_none());
    assert!(Resource::from_index(
        "lambda:function",
        "arn:aws:lambda:us-east-2:123456789012:function:fn:version",
        "us-east-2"
    )
    .is_none());
    assert!(Resource::from_index("s3:bucket", "bad-arn", "global").is_none());
}

#[tokio::test]
async fn finder_cached_fallback_streams_matching_sources_without_aws_calls() {
    let cache = Arc::new(Mutex::new(SearchCache::default()));
    {
        let mut cache = cache.lock().await;
        cache.index_unavailable = Some(Instant::now());
        cache.inventory.insert(
            ResourceKind::Table,
            (
                Instant::now(),
                vec![
                    Resource::new(
                        ResourceKind::Table,
                        "rusticity-orders",
                        "Orders",
                        "us-east-2",
                    ),
                    Resource::new(ResourceKind::Table, "unrelated", "Other", "us-east-2"),
                ],
                false,
            ),
        );
        cache.inventory.insert(
            ResourceKind::Bucket,
            (
                Instant::now(),
                vec![Resource::new(
                    ResourceKind::Bucket,
                    "rusticity-bucket",
                    "Bucket",
                    "global",
                )],
                true,
            ),
        );
    }
    // Dummy config has no credentials; cached inventories must not access AWS.
    let (tx, mut rx) = mpsc::channel(8);
    search(
        AwsConfig::dummy(Some("us-east-2".into())),
        SearchQuery::parse("@s3 @ddb rusticity").unwrap(),
        cache,
        tx,
    )
    .await;
    let mut rows = Vec::new();
    let mut finished = false;
    while let Some(update) = rx.recv().await {
        match update {
            SearchUpdate::Results(batch) => rows.extend(batch),
            SearchUpdate::Finished { limited } => {
                finished = true;
                assert!(limited);
            }
            SearchUpdate::Warning(warning) => panic!("Unexpected AWS read: {warning}"),
            _ => {}
        }
    }
    assert!(finished);
    assert_eq!(rows.len(), 2);
    assert!(rows.iter().all(|r| r.id.starts_with("rusticity")));
}

#[tokio::test]
async fn finder_short_queries_do_not_send_requests() {
    let (tx, mut rx) = mpsc::channel(1);
    search(
        AwsConfig::dummy(None),
        SearchQuery::parse("@s3 ab").unwrap(),
        Arc::new(Mutex::new(SearchCache::default())),
        tx,
    )
    .await;
    assert!(rx.recv().await.is_none());
}

#[test]
fn finder_vpc_qualifier_and_ec2_resource_type_are_supported() {
    let query = SearchQuery::parse("@vpc network").unwrap();
    assert_eq!(query.kinds, [ResourceKind::Vpc]);
    assert!(query
        .index_query("us-east-2")
        .contains("resourcetype:ec2:vpc"));
    let ec2 = SearchQuery::parse("@ec2 vpc").unwrap();
    assert!(ec2.kinds.contains(&ResourceKind::Vpc));
    assert!(ec2.kinds.contains(&ResourceKind::Instance));
    let resource = Resource::from_index(
        "ec2:vpc",
        "arn:aws:ec2:us-east-2:123456789012:vpc/vpc-test",
        "us-east-2",
    )
    .unwrap();
    assert_eq!(resource.kind, ResourceKind::Vpc);
    assert_eq!(resource.kind.service(), "vpc");
    assert_eq!(resource.id, "vpc-test");
}

#[test]
fn finder_sns_qualifier_and_topic_resource_type_are_supported() {
    let query = SearchQuery::parse("@sns alerts").unwrap();
    assert_eq!(query.kinds, [ResourceKind::Topic]);
    assert!(query
        .index_query("us-east-2")
        .contains("resourcetype:sns:topic"));
    let resource = Resource::from_index(
        "sns:topic",
        "arn:aws:sns:us-east-2:123456789012:my-topic",
        "us-east-2",
    )
    .unwrap();
    assert_eq!(resource.kind, ResourceKind::Topic);
    assert_eq!(resource.kind.service(), "sns");
    assert_eq!(resource.id, "my-topic");
    assert_eq!(resource.arn, "arn:aws:sns:us-east-2:123456789012:my-topic");
}

#[test]
fn finder_prefix_terms_use_resource_explorer_wildcards_without_quotes() {
    for (input, prefix) in [
        ("@lambda Fsx", "fsx*"),
        (
            "@lambda BETA-SagemakerHyperpodEks-FsxDraKmsGrant",
            "beta-sagemakerhyperpodeks-fsxdrakmsgrant*",
        ),
        ("@lambda my_function.v2", "my_function.v2*"),
        ("@lambda fsx grant", "fsx* grant*"),
    ] {
        assert_eq!(
            SearchQuery::parse(input).unwrap().index_query("us-east-1"),
            format!("{prefix} resourcetype:lambda:function region:us-east-1,global")
        );
    }
}

#[test]
fn finder_syntax_bearing_terms_stay_literal_without_standalone_wildcards() {
    for (input, literal) in [
        ("service:iam", "\"service:iam\""),
        ("region:us-west-2", "\"region:us-west-2\""),
        ("-orders", "\"-orders\""),
        ("fsx*", "\"fsx*\""),
        ("name,other", "\"name,other\""),
        ("name\"quoted", "\"name\\\"quoted\""),
        ("name\\path", "\"name\\\\path\""),
        ("(orders)", "\"(orders)\""),
    ] {
        let query = SearchQuery::parse(&format!("@lambda {input}")).unwrap();
        assert_eq!(
            query.index_query("us-east-1"),
            format!("{literal} resourcetype:lambda:function region:us-east-1,global")
        );
    }
}

#[test]
fn finder_sns_topic_arns_are_openable_but_subscription_arns_remain_references() {
    let arn = "arn:aws:sns:us-east-1:123456789012:orders.fifo";
    let topic = Resource::from_arn(arn).unwrap();
    assert_eq!(topic.kind, ResourceKind::Topic);
    assert_eq!(topic.id, "orders.fifo");
    assert_eq!(topic.arn, arn);
    let subscription = Resource::from_arn(&format!("{arn}:subscription-id")).unwrap();
    assert_eq!(subscription.kind, ResourceKind::Reference);
}