apollo-federation 2.17.0

Apollo Federation
Documentation
#[global_allocator]
pub(crate) static ALLOC: dhat::Alloc = dhat::Alloc;

// Failure of the test can be diagnosed using the dhat-heap.json file.

// The figures have a 5% buffer from the actual profiling stats. This
// should help us keep an eye on allocation increases, (hopefully) without
// too much flakiness.
#[test]
fn valid_query_plan() {
    const SCHEMA: &str = "../examples/graphql/supergraph.graphql";
    const OPERATION: &str = "query fetchUser {
      me {
        id
        name
        username
        reviews {
          ...reviews
        }
      }
      recommendedProducts {
        ...products
      } 
      topProducts {
        ...products
      }
    }
    fragment products on Product {
        upc
        weight
        price
        shippingEstimate
        reviews {
          ...reviews
        }
    }
    fragment reviews on Review {
      id
      author {
        id
        name
      }
    }
    ";

    // Number of bytes when the heap size reached its global maximum with a 5% buffer.
    // Actual number: 803_785.
    const MAX_BYTES_QUERY_PLANNER: usize = 843_974; // ~824 KiB

    // Total number of allocations with a 5% buffer.
    // Actual number: 17_303.
    const MAX_ALLOCATIONS_QUERY_PLANNER: u64 = 18_168;

    // Number of bytes when the heap size reached its global maximum with a 5% buffer.
    // Actual number: 928_923.
    //
    // Planning adds 125_138 bytes to heap max (928_923-803_785=125_138).
    const MAX_BYTES_QUERY_PLAN: usize = 975_369; // ~953 KiB

    // Total number of allocations with a 5% buffer.
    // Actual number: 24_559.
    //
    // Planning adds 7_256 allocations (24_559-17_303=7_256).
    const MAX_ALLOCATIONS_QUERY_PLAN: u64 = 25_787;

    let schema = std::fs::read_to_string(SCHEMA).unwrap();

    let _profiler = dhat::Profiler::builder().testing().build();

    let supergraph =
        apollo_federation::Supergraph::new(&schema).expect("supergraph should be valid");
    let api_options = apollo_federation::ApiSchemaOptions::default();
    let api_schema = supergraph
        .to_api_schema(api_options)
        .expect("api schema should be valid");
    let qp_config = apollo_federation::query_plan::query_planner::QueryPlannerConfig::default();
    let planner =
        apollo_federation::query_plan::query_planner::QueryPlanner::new(&supergraph, qp_config)
            .expect("query planner should be created");
    let stats = dhat::HeapStats::get();
    println!("QueryPlanner::new: {stats:?}");
    dhat::assert!(stats.max_bytes < MAX_BYTES_QUERY_PLANNER);
    dhat::assert!(stats.total_blocks < MAX_ALLOCATIONS_QUERY_PLANNER);
    let document = apollo_compiler::ExecutableDocument::parse_and_validate(
        api_schema.schema(),
        OPERATION,
        "operation.graphql",
    )
    .expect("operation should be valid");
    let qp_options = apollo_federation::query_plan::query_planner::QueryPlanOptions::default();
    planner
        .build_query_plan(&document, None, qp_options)
        .expect("valid query plan");
    let stats = dhat::HeapStats::get();
    println!("QueryPlanner::build_query_plan: {stats:?}");
    dhat::assert!(stats.max_bytes < MAX_BYTES_QUERY_PLAN);
    dhat::assert!(stats.total_blocks < MAX_ALLOCATIONS_QUERY_PLAN);
}