|
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