bucketwarden-server 0.1.0

BucketWarden storage server runtime.
Documentation
use super::*;

#[cfg(test)]
mod tests {
    use super::*;

    fn request(expression: &str, file_header_info: &str, output_kind: &str) -> Vec<u8> {
        format!(
            "<SelectObjectContentRequest>\
<Expression>{expression}</Expression>\
<ExpressionType>SQL</ExpressionType>\
<InputSerialization><CSV><FileHeaderInfo>{file_header_info}</FileHeaderInfo></CSV><CompressionType>NONE</CompressionType></InputSerialization>\
<OutputSerialization><{output_kind}/></OutputSerialization>\
</SelectObjectContentRequest>"
        )
        .into_bytes()
    }

    #[test]
    fn parse_select_request_accepts_csv_limit_query() {
        let plan = parse_select_request(&request("SELECT _1 FROM S3Object s LIMIT 2", "NONE", "CSV"))
            .expect("plan");
        assert_eq!(plan.limit, Some(2));
        assert_eq!(plan.output_format, SelectOutputFormat::Csv);
    }

    #[test]
    fn execute_select_plan_projects_named_headers_to_json() {
        let plan = parse_select_request(&request(
            "SELECT city,temp FROM S3Object s LIMIT 1",
            "USE",
            "JSON",
        ))
        .expect("plan");
        let body = execute_select_plan(&plan, b"city,temp\nAustin,75\nDallas,81\n").expect("body");
        assert_eq!(
            String::from_utf8(body).expect("utf8"),
            "{\"city\":\"Austin\",\"temp\":\"75\"}\n"
        );
    }

    #[test]
    fn execute_select_plan_projects_json_input_rows() {
        let request = b"<SelectObjectContentRequest>\
<Expression>SELECT city,temp FROM S3Object s LIMIT 1</Expression>\
<ExpressionType>SQL</ExpressionType>\
<InputSerialization><JSON><Type>LINES</Type></JSON></InputSerialization>\
<OutputSerialization><JSON/></OutputSerialization>\
</SelectObjectContentRequest>";
        let plan = parse_select_request(request).expect("plan");
        let body =
            execute_select_plan(&plan, br#"{"city":"Austin","temp":"75"}{"city":"Dallas","temp":"81"}"#)
                .expect_err("invalid json lines should fail");
        assert!(matches!(
            body,
            RuntimeError::ServiceSpecificErrorFeature(
                "feat:bucketwarden.s3err.select.objectserializationconflict"
            )
        ));

        let body = execute_select_plan(
            &plan,
            b"{\"city\":\"Austin\",\"temp\":\"75\"}\n{\"city\":\"Dallas\",\"temp\":\"81\"}\n",
        )
        .expect("json lines body");
        assert_eq!(
            String::from_utf8(body).expect("utf8"),
            "{\"city\":\"Austin\",\"temp\":\"75\"}\n"
        );
    }

    #[test]
    fn parse_csv_records_rejects_unescaped_quotes() {
        let error = parse_csv_records(b"alpha,\"broken\n").expect_err("error");
        assert!(matches!(
            error,
            RuntimeError::ServiceSpecificErrorFeature(
                "feat:bucketwarden.s3err.select.csvunescapedquote"
            )
        ));
    }
}