|  | 
| 17 | 17 | 
 | 
| 18 | 18 | use std::process::Command; | 
| 19 | 19 | 
 | 
| 20 |  | -use assert_cmd::prelude::{CommandCargoExt, OutputAssertExt}; | 
| 21 |  | -use predicates::prelude::predicate; | 
| 22 | 20 | use rstest::rstest; | 
| 23 | 21 | 
 | 
|  | 22 | +use insta::{glob, Settings}; | 
|  | 23 | +use insta_cmd::{assert_cmd_snapshot, get_cargo_bin}; | 
|  | 24 | +use std::{env, fs}; | 
|  | 25 | + | 
|  | 26 | +fn cli() -> Command { | 
|  | 27 | +    Command::new(get_cargo_bin("datafusion-cli")) | 
|  | 28 | +} | 
|  | 29 | + | 
|  | 30 | +fn make_settings() -> Settings { | 
|  | 31 | +    let mut settings = Settings::clone_current(); | 
|  | 32 | +    settings.set_prepend_module_to_snapshot(false); | 
|  | 33 | +    settings.add_filter(r"Elapsed .* seconds\.", "[ELAPSED]"); | 
|  | 34 | +    settings.add_filter(r"DataFusion CLI v.*", "[CLI_VERSION]"); | 
|  | 35 | +    settings | 
|  | 36 | +} | 
|  | 37 | + | 
| 24 | 38 | #[cfg(test)] | 
| 25 | 39 | #[ctor::ctor] | 
| 26 | 40 | fn init() { | 
| 27 | 41 |     // Enable RUST_LOG logging configuration for tests | 
| 28 | 42 |     let _ = env_logger::try_init(); | 
| 29 | 43 | } | 
| 30 | 44 | 
 | 
| 31 |  | -// Disabled due to https://github.com/apache/datafusion/issues/10793 | 
| 32 |  | -#[cfg(not(target_family = "windows"))] | 
| 33 | 45 | #[rstest] | 
| 34 |  | -#[case::exec_from_commands( | 
| 35 |  | -    ["--command", "select 1", "--format", "json", "-q"], | 
| 36 |  | -    "[{\"Int64(1)\":1}]\n" | 
| 37 |  | -)] | 
| 38 | 46 | #[case::exec_multiple_statements( | 
| 39 |  | -    ["--command", "select 1; select 2;", "--format", "json", "-q"], | 
| 40 |  | -    "[{\"Int64(1)\":1}]\n[{\"Int64(2)\":2}]\n" | 
|  | 47 | +    "statements", | 
|  | 48 | +    ["--command", "select 1; select 2;", "-q"], | 
| 41 | 49 | )] | 
| 42 | 50 | #[case::exec_backslash( | 
| 43 |  | -    ["--file", "tests/data/backslash.txt", "--format", "json", "-q"], | 
| 44 |  | -    "[{\"Utf8(\\\"\\\\\\\")\":\"\\\\\",\"Utf8(\\\"\\\\\\\\\\\")\":\"\\\\\\\\\",\"Utf8(\\\"\\\\\\\\\\\\\\\\\\\\\\\")\":\"\\\\\\\\\\\\\\\\\\\\\",\"Utf8(\\\"dsdsds\\\\\\\\\\\\\\\\\\\")\":\"dsdsds\\\\\\\\\\\\\\\\\",\"Utf8(\\\"\\\\t\\\")\":\"\\\\t\",\"Utf8(\\\"\\\\0\\\")\":\"\\\\0\",\"Utf8(\\\"\\\\n\\\")\":\"\\\\n\"}]\n" | 
|  | 51 | +    "backslash", | 
|  | 52 | +    ["--file", "tests/sql/backslash.sql", "--format", "json", "-q"], | 
| 45 | 53 | )] | 
| 46 | 54 | #[case::exec_from_files( | 
| 47 |  | -    ["--file", "tests/data/sql.txt", "--format", "json", "-q"], | 
| 48 |  | -    "[{\"Int64(1)\":1}]\n" | 
|  | 55 | +    "files", | 
|  | 56 | +    ["--file", "tests/sql/select.sql", "-q"], | 
| 49 | 57 | )] | 
| 50 | 58 | #[case::set_batch_size( | 
| 51 |  | -    ["--command", "show datafusion.execution.batch_size", "--format", "json", "-q", "-b", "1"], | 
| 52 |  | -    "[{\"name\":\"datafusion.execution.batch_size\",\"value\":\"1\"}]\n" | 
|  | 59 | +    "batch_size", | 
|  | 60 | +    ["--command", "show datafusion.execution.batch_size", "-q", "-b", "1"], | 
| 53 | 61 | )] | 
| 54 | 62 | #[test] | 
| 55 | 63 | fn cli_quick_test<'a>( | 
|  | 64 | +    #[case] snapshot_name: &'a str, | 
| 56 | 65 |     #[case] args: impl IntoIterator<Item = &'a str>, | 
| 57 |  | -    #[case] expected: &str, | 
| 58 | 66 | ) { | 
| 59 |  | -    let mut cmd = Command::cargo_bin("datafusion-cli").unwrap(); | 
|  | 67 | +    let mut settings = make_settings(); | 
|  | 68 | +    settings.set_snapshot_suffix(snapshot_name); | 
|  | 69 | +    let _bound = settings.bind_to_scope(); | 
|  | 70 | + | 
|  | 71 | +    let mut cmd = cli(); | 
| 60 | 72 |     cmd.args(args); | 
| 61 |  | -    cmd.assert().stdout(predicate::eq(expected)); | 
|  | 73 | + | 
|  | 74 | +    assert_cmd_snapshot!(cmd); | 
|  | 75 | +} | 
|  | 76 | + | 
|  | 77 | +#[rstest] | 
|  | 78 | +#[case("csv")] | 
|  | 79 | +#[case("tsv")] | 
|  | 80 | +#[case("table")] | 
|  | 81 | +#[case("json")] | 
|  | 82 | +#[case("nd-json")] | 
|  | 83 | +#[case("automatic")] | 
|  | 84 | +#[test] | 
|  | 85 | +fn test_cli_format<'a>(#[case] format: &'a str) { | 
|  | 86 | +    let mut settings = make_settings(); | 
|  | 87 | +    settings.set_snapshot_suffix(format); | 
|  | 88 | +    let _bound = settings.bind_to_scope(); | 
|  | 89 | + | 
|  | 90 | +    let mut cmd = cli(); | 
|  | 91 | +    cmd.args(["--command", "select 1", "-q", "--format", format]); | 
|  | 92 | + | 
|  | 93 | +    assert_cmd_snapshot!(cmd); | 
|  | 94 | +} | 
|  | 95 | + | 
|  | 96 | +#[tokio::test] | 
|  | 97 | +async fn test_cli() { | 
|  | 98 | +    if env::var("TEST_STORAGE_INTEGRATION").is_err() { | 
|  | 99 | +        eprintln!("Skipping external storages integration tests"); | 
|  | 100 | +        return; | 
|  | 101 | +    } | 
|  | 102 | + | 
|  | 103 | +    let settings = make_settings(); | 
|  | 104 | +    let _bound = settings.bind_to_scope(); | 
|  | 105 | + | 
|  | 106 | +    glob!("sql/integration/*.sql", |path| { | 
|  | 107 | +        let input = fs::read_to_string(path).unwrap(); | 
|  | 108 | +        assert_cmd_snapshot!(cli().pass_stdin(input)) | 
|  | 109 | +    }); | 
|  | 110 | +} | 
|  | 111 | + | 
|  | 112 | +#[tokio::test] | 
|  | 113 | +async fn test_aws_options() { | 
|  | 114 | +    // Separate test is needed to pass aws as options in sql and not via env | 
|  | 115 | + | 
|  | 116 | +    if env::var("TEST_STORAGE_INTEGRATION").is_err() { | 
|  | 117 | +        eprintln!("Skipping external storages integration tests"); | 
|  | 118 | +        return; | 
|  | 119 | +    } | 
|  | 120 | + | 
|  | 121 | +    let settings = make_settings(); | 
|  | 122 | +    let _bound = settings.bind_to_scope(); | 
|  | 123 | + | 
|  | 124 | +    let access_key_id = | 
|  | 125 | +        env::var("AWS_ACCESS_KEY_ID").expect("AWS_ACCESS_KEY_ID is not set"); | 
|  | 126 | +    let secret_access_key = | 
|  | 127 | +        env::var("AWS_SECRET_ACCESS_KEY").expect("AWS_SECRET_ACCESS_KEY is not set"); | 
|  | 128 | +    let endpoint_url = env::var("AWS_ENDPOINT").expect("AWS_ENDPOINT is not set"); | 
|  | 129 | + | 
|  | 130 | +    let input = format!( | 
|  | 131 | +        r#"CREATE EXTERNAL TABLE CARS | 
|  | 132 | +STORED AS CSV | 
|  | 133 | +LOCATION 's3://data/cars.csv' | 
|  | 134 | +OPTIONS( | 
|  | 135 | +    'aws.access_key_id' '{}', | 
|  | 136 | +    'aws.secret_access_key' '{}', | 
|  | 137 | +    'aws.endpoint' '{}', | 
|  | 138 | +    'aws.allow_http' 'true' | 
|  | 139 | +); | 
|  | 140 | +
 | 
|  | 141 | +SELECT * FROM CARS limit 1; | 
|  | 142 | +"#, | 
|  | 143 | +        access_key_id, secret_access_key, endpoint_url | 
|  | 144 | +    ); | 
|  | 145 | + | 
|  | 146 | +    assert_cmd_snapshot!(cli().env_clear().pass_stdin(input)); | 
| 62 | 147 | } | 
0 commit comments