1054 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Rust
		
	
	
			
		
		
	
	
			1054 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			Rust
		
	
	
use std::sync::Arc;
 | 
						|
use std::time::Duration;
 | 
						|
 | 
						|
use assert_cmd::Command;
 | 
						|
use predicates::prelude::*;
 | 
						|
 | 
						|
use data_types::chunk_metadata::ChunkAddr;
 | 
						|
use data_types::{
 | 
						|
    chunk_metadata::ChunkStorage,
 | 
						|
    job::{Job, Operation},
 | 
						|
};
 | 
						|
use test_helpers::make_temp_file;
 | 
						|
use write_buffer::maybe_skip_kafka_integration;
 | 
						|
 | 
						|
use crate::{
 | 
						|
    common::server_fixture::ServerFixture,
 | 
						|
    end_to_end_cases::scenario::{wait_for_exact_chunk_states, DatabaseBuilder},
 | 
						|
};
 | 
						|
 | 
						|
use super::scenario::{create_readable_database, rand_name};
 | 
						|
use crate::end_to_end_cases::scenario::{fixture_broken_catalog, fixture_replay_broken};
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_server_id() {
 | 
						|
    let server_fixture = ServerFixture::create_single_use().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("server")
 | 
						|
        .arg("set")
 | 
						|
        .arg("32")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("server")
 | 
						|
        .arg("get")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("32"));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("server")
 | 
						|
        .arg("set")
 | 
						|
        .arg("42")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains("id already set"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_create_database() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
    let db = &db_name;
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("get")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains("Database not found"));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("create")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
 | 
						|
    // Listing the databases includes the newly created database
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("list")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains(db));
 | 
						|
 | 
						|
    // Retrieving the database includes the name and a mutable buffer configuration
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("get")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(
 | 
						|
            predicate::str::contains(db)
 | 
						|
                .and(predicate::str::contains(format!(r#""name": "{}"#, db)))
 | 
						|
                // validate the defaults have been set reasonably
 | 
						|
                .and(predicate::str::contains("%Y-%m-%d %H:00:00"))
 | 
						|
                .and(predicate::str::contains(r#""bufferSizeHard": 104857600"#))
 | 
						|
                .and(predicate::str::contains("lifecycleRules")),
 | 
						|
        );
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_create_database_size() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
    let db = &db_name;
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("create")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--buffer-size-hard")
 | 
						|
        .arg("1000")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("get")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(
 | 
						|
            predicate::str::contains(r#""bufferSizeHard": 1000"#)
 | 
						|
                .and(predicate::str::contains("lifecycleRules")),
 | 
						|
        );
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_create_database_immutable() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
    let db = &db_name;
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("create")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--immutable")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("get")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        // Should not have a mutable buffer
 | 
						|
        .stdout(predicate::str::contains(r#""immutable": true"#));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn delete_database() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
    let db = &db_name;
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("create")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
 | 
						|
    // Listing the databases includes the newly created database
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("list")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains(db));
 | 
						|
 | 
						|
    // Delete the database
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("delete")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains(format!("Deleted database {}", db)));
 | 
						|
 | 
						|
    // Listing the databases does not include the deleted database
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("list")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains(db).not());
 | 
						|
 | 
						|
    // Deleting the database again is an error
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("delete")
 | 
						|
        .arg(db)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains(
 | 
						|
            "Error deleting database: Database not found",
 | 
						|
        ));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_get_chunks() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    create_readable_database(&db_name, server_fixture.grpc_channel()).await;
 | 
						|
 | 
						|
    let lp_data = vec![
 | 
						|
        "cpu,region=west user=23.2 100",
 | 
						|
        "cpu,region=west user=21.0 150",
 | 
						|
    ];
 | 
						|
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    let predicate = predicate::str::contains(r#""partition_key": "cpu","#)
 | 
						|
        .and(predicate::str::contains(r#""id": 0,"#))
 | 
						|
        .and(predicate::str::contains(
 | 
						|
            r#""storage": "OpenMutableBuffer","#,
 | 
						|
        ))
 | 
						|
        .and(predicate::str::contains(r#""memory_bytes": 1016"#))
 | 
						|
        // Check for a non empty timestamp such as
 | 
						|
        // "time_of_first_write": "2021-03-30T17:11:10.723866Z",
 | 
						|
        .and(predicate::str::contains(r#""time_of_first_write": "20"#));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("chunk")
 | 
						|
        .arg("list")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate);
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_list_chunks_error() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    // note don't make the database, expect error
 | 
						|
 | 
						|
    // list the chunks
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("chunk")
 | 
						|
        .arg("list")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(
 | 
						|
            predicate::str::contains("Some requested entity was not found: Resource database")
 | 
						|
                .and(predicate::str::contains(&db_name)),
 | 
						|
        );
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_remotes() {
 | 
						|
    let server_fixture = ServerFixture::create_single_use().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("server")
 | 
						|
        .arg("set")
 | 
						|
        .arg("32")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("server")
 | 
						|
        .arg("remote")
 | 
						|
        .arg("list")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("no remotes configured"));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("server")
 | 
						|
        .arg("remote")
 | 
						|
        .arg("set")
 | 
						|
        .arg("1")
 | 
						|
        .arg("http://1.2.3.4:1234")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("server")
 | 
						|
        .arg("remote")
 | 
						|
        .arg("list")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("http://1.2.3.4:1234"));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("server")
 | 
						|
        .arg("remote")
 | 
						|
        .arg("remove")
 | 
						|
        .arg("1")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("server")
 | 
						|
        .arg("remote")
 | 
						|
        .arg("list")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("no remotes configured"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_list_partitions() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    create_readable_database(&db_name, server_fixture.grpc_channel()).await;
 | 
						|
 | 
						|
    let lp_data = vec![
 | 
						|
        "cpu,region=west user=23.2 100",
 | 
						|
        "mem,region=west free=100000 150",
 | 
						|
    ];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("list")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("cpu").and(predicate::str::contains("mem")));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_list_partitions_error() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("list")
 | 
						|
        .arg("non_existent_database")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains("Database not found"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_get_partition() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    create_readable_database(&db_name, server_fixture.grpc_channel()).await;
 | 
						|
 | 
						|
    let lp_data = vec![
 | 
						|
        "cpu,region=west user=23.2 100",
 | 
						|
        "mem,region=west free=100000 150",
 | 
						|
    ];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    let expected = r#""key": "cpu""#;
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("get")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains(expected));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_get_partition_error() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("get")
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("non_existent_database")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains("Database not found"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_list_partition_chunks() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    create_readable_database(&db_name, server_fixture.grpc_channel()).await;
 | 
						|
 | 
						|
    let lp_data = vec![
 | 
						|
        "cpu,region=west user=23.2 100",
 | 
						|
        "cpu2,region=west user=21.0 150",
 | 
						|
    ];
 | 
						|
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    let expected = r#"
 | 
						|
    "partition_key": "cpu",
 | 
						|
    "table_name": "cpu",
 | 
						|
    "id": 0,
 | 
						|
    "storage": "OpenMutableBuffer",
 | 
						|
"#;
 | 
						|
 | 
						|
    let partition_key = "cpu";
 | 
						|
    // should not contain anything related to cpu2 partition
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("list-chunks")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg(&partition_key)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains(expected).and(predicate::str::contains("cpu2").not()));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_list_partition_chunks_error() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    // note don't make the database, expect error
 | 
						|
 | 
						|
    // list the chunks
 | 
						|
    let partition_key = "cpu";
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("list-chunks")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg(&partition_key)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(
 | 
						|
            predicate::str::contains("Some requested entity was not found: Resource database")
 | 
						|
                .and(predicate::str::contains(&db_name)),
 | 
						|
        );
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_new_partition_chunk() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    create_readable_database(&db_name, server_fixture.grpc_channel()).await;
 | 
						|
 | 
						|
    let lp_data = vec!["cpu,region=west user=23.2 100"];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    let expected = "Ok";
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("new-chunk")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains(expected));
 | 
						|
 | 
						|
    wait_for_exact_chunk_states(
 | 
						|
        &server_fixture,
 | 
						|
        &db_name,
 | 
						|
        vec![ChunkStorage::ReadBuffer],
 | 
						|
        std::time::Duration::from_secs(5),
 | 
						|
    )
 | 
						|
    .await;
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("chunk")
 | 
						|
        .arg("list")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("ReadBuffer"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_new_partition_chunk_error() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("new-chunk")
 | 
						|
        .arg("non_existent_database")
 | 
						|
        .arg("non_existent_partition")
 | 
						|
        .arg("non_existent_table")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains(
 | 
						|
            "Resource database/non_existent_database not found",
 | 
						|
        ));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_close_partition_chunk() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    create_readable_database(&db_name, server_fixture.grpc_channel()).await;
 | 
						|
 | 
						|
    let lp_data = vec!["cpu,region=west user=23.2 100"];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    let stdout: Operation = serde_json::from_slice(
 | 
						|
        &Command::cargo_bin("influxdb_iox")
 | 
						|
            .unwrap()
 | 
						|
            .arg("database")
 | 
						|
            .arg("partition")
 | 
						|
            .arg("close-chunk")
 | 
						|
            .arg(&db_name)
 | 
						|
            .arg("cpu")
 | 
						|
            .arg("cpu")
 | 
						|
            .arg("0")
 | 
						|
            .arg("--host")
 | 
						|
            .arg(addr)
 | 
						|
            .assert()
 | 
						|
            .success()
 | 
						|
            .get_output()
 | 
						|
            .stdout,
 | 
						|
    )
 | 
						|
    .expect("Expected JSON output");
 | 
						|
 | 
						|
    let expected_job = Job::CompactChunk {
 | 
						|
        chunk: ChunkAddr {
 | 
						|
            db_name: Arc::from(db_name.as_str()),
 | 
						|
            table_name: Arc::from("cpu"),
 | 
						|
            partition_key: Arc::from("cpu"),
 | 
						|
            chunk_id: 0,
 | 
						|
        },
 | 
						|
    };
 | 
						|
 | 
						|
    assert_eq!(
 | 
						|
        Some(expected_job),
 | 
						|
        stdout.job,
 | 
						|
        "operation was {:#?}",
 | 
						|
        stdout
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_close_partition_chunk_error() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("close-chunk")
 | 
						|
        .arg("non_existent_database")
 | 
						|
        .arg("non_existent_partition")
 | 
						|
        .arg("non_existent_table")
 | 
						|
        .arg("0")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains("Database not found"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_wipe_persisted_catalog() {
 | 
						|
    let db_name = rand_name();
 | 
						|
    let server_fixture = fixture_broken_catalog(&db_name).await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
 | 
						|
    let stdout: Operation = serde_json::from_slice(
 | 
						|
        &Command::cargo_bin("influxdb_iox")
 | 
						|
            .unwrap()
 | 
						|
            .arg("database")
 | 
						|
            .arg("recover")
 | 
						|
            .arg("wipe")
 | 
						|
            .arg(&db_name)
 | 
						|
            .arg("--host")
 | 
						|
            .arg(addr)
 | 
						|
            .arg("--force")
 | 
						|
            .assert()
 | 
						|
            .success()
 | 
						|
            .get_output()
 | 
						|
            .stdout,
 | 
						|
    )
 | 
						|
    .expect("Expected JSON output");
 | 
						|
 | 
						|
    let expected_job = Job::WipePreservedCatalog {
 | 
						|
        db_name: Arc::from(db_name.as_str()),
 | 
						|
    };
 | 
						|
 | 
						|
    assert_eq!(
 | 
						|
        Some(expected_job),
 | 
						|
        stdout.job,
 | 
						|
        "operation was {:#?}",
 | 
						|
        stdout
 | 
						|
    );
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_wipe_persisted_catalog_error_force() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("recover")
 | 
						|
        .arg("wipe")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains("Need to pass `--force`"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_wipe_persisted_catalog_error_db_exists() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    create_readable_database(&db_name, server_fixture.grpc_channel()).await;
 | 
						|
 | 
						|
    let expected_err = format!("Failed precondition: database ({}) in invalid state (Initialized) for transition (WipePreservedCatalog)", db_name);
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("recover")
 | 
						|
        .arg("wipe")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .arg("--force")
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains(&expected_err));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_skip_replay() {
 | 
						|
    let kafka_connection = maybe_skip_kafka_integration!();
 | 
						|
    let db_name = rand_name();
 | 
						|
    let server_fixture = fixture_replay_broken(&db_name, &kafka_connection).await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("recover")
 | 
						|
        .arg("skip-replay")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_skip_replay_error_db_exists() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    create_readable_database(&db_name, server_fixture.grpc_channel()).await;
 | 
						|
 | 
						|
    let expected_err = format!("Failed precondition: database ({}) in invalid state (Initialized) for transition (SkipReplay)", db_name);
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("recover")
 | 
						|
        .arg("skip-replay")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains(&expected_err));
 | 
						|
}
 | 
						|
 | 
						|
/// Loads the specified lines into the named database
 | 
						|
fn load_lp(addr: &str, db_name: &str, lp_data: Vec<&str>) {
 | 
						|
    let lp_data_file = make_temp_file(lp_data.join("\n"));
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("write")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg(lp_data_file.as_ref())
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Lines OK"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_unload_partition_chunk() {
 | 
						|
    let fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    DatabaseBuilder::new(db_name.clone())
 | 
						|
        .persist(true)
 | 
						|
        .persist_age_threshold_seconds(1)
 | 
						|
        .late_arrive_window_seconds(1)
 | 
						|
        .build(fixture.grpc_channel())
 | 
						|
        .await;
 | 
						|
 | 
						|
    let lp_data = vec!["cpu,region=west user=23.2 10"];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    let mut chunks = wait_for_exact_chunk_states(
 | 
						|
        &fixture,
 | 
						|
        &db_name,
 | 
						|
        vec![ChunkStorage::ReadBufferAndObjectStore],
 | 
						|
        std::time::Duration::from_secs(5),
 | 
						|
    )
 | 
						|
    .await;
 | 
						|
    let chunk = chunks.pop().unwrap();
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("unload-chunk")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("cpu")
 | 
						|
        .arg(chunk.id.to_string())
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_unload_partition_chunk_error() {
 | 
						|
    let server_fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = server_fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    create_readable_database(&db_name, server_fixture.grpc_channel()).await;
 | 
						|
 | 
						|
    let lp_data = vec!["cpu,region=west user=23.2 100"];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("unload-chunk")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("0")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains("wrong chunk lifecycle"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_drop_partition() {
 | 
						|
    let fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    DatabaseBuilder::new(db_name.clone())
 | 
						|
        .persist(true)
 | 
						|
        .persist_age_threshold_seconds(1)
 | 
						|
        .late_arrive_window_seconds(1)
 | 
						|
        .build(fixture.grpc_channel())
 | 
						|
        .await;
 | 
						|
 | 
						|
    let lp_data = vec!["cpu,region=west user=23.2 10"];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    wait_for_exact_chunk_states(
 | 
						|
        &fixture,
 | 
						|
        &db_name,
 | 
						|
        vec![ChunkStorage::ReadBufferAndObjectStore],
 | 
						|
        std::time::Duration::from_secs(5),
 | 
						|
    )
 | 
						|
    .await;
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("drop")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_drop_partition_error() {
 | 
						|
    let fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    DatabaseBuilder::new(db_name.clone())
 | 
						|
        .persist(true)
 | 
						|
        .persist_age_threshold_seconds(1_000)
 | 
						|
        .late_arrive_window_seconds(1_000)
 | 
						|
        .build(fixture.grpc_channel())
 | 
						|
        .await;
 | 
						|
 | 
						|
    let lp_data = vec!["cpu,region=west user=23.2 10"];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    wait_for_exact_chunk_states(
 | 
						|
        &fixture,
 | 
						|
        &db_name,
 | 
						|
        vec![ChunkStorage::OpenMutableBuffer],
 | 
						|
        std::time::Duration::from_secs(5),
 | 
						|
    )
 | 
						|
    .await;
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("drop")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains("Cannot drop unpersisted chunk"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_persist_partition() {
 | 
						|
    let fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    DatabaseBuilder::new(db_name.clone())
 | 
						|
        .persist(true)
 | 
						|
        .persist_age_threshold_seconds(1_000)
 | 
						|
        .late_arrive_window_seconds(1)
 | 
						|
        .build(fixture.grpc_channel())
 | 
						|
        .await;
 | 
						|
 | 
						|
    let lp_data = vec!["cpu,region=west user=23.2 10"];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    wait_for_exact_chunk_states(
 | 
						|
        &fixture,
 | 
						|
        &db_name,
 | 
						|
        vec![ChunkStorage::OpenMutableBuffer],
 | 
						|
        std::time::Duration::from_secs(5),
 | 
						|
    )
 | 
						|
    .await;
 | 
						|
 | 
						|
    tokio::time::sleep(Duration::from_millis(1500)).await;
 | 
						|
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("persist")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .success()
 | 
						|
        .stdout(predicate::str::contains("Ok"));
 | 
						|
}
 | 
						|
 | 
						|
#[tokio::test]
 | 
						|
async fn test_persist_partition_error() {
 | 
						|
    let fixture = ServerFixture::create_shared().await;
 | 
						|
    let addr = fixture.grpc_base();
 | 
						|
    let db_name = rand_name();
 | 
						|
 | 
						|
    DatabaseBuilder::new(db_name.clone())
 | 
						|
        .persist(true)
 | 
						|
        .persist_age_threshold_seconds(1_000)
 | 
						|
        .late_arrive_window_seconds(1_000)
 | 
						|
        .build(fixture.grpc_channel())
 | 
						|
        .await;
 | 
						|
 | 
						|
    let lp_data = vec!["cpu,region=west user=23.2 10"];
 | 
						|
    load_lp(addr, &db_name, lp_data);
 | 
						|
 | 
						|
    wait_for_exact_chunk_states(
 | 
						|
        &fixture,
 | 
						|
        &db_name,
 | 
						|
        vec![ChunkStorage::OpenMutableBuffer],
 | 
						|
        std::time::Duration::from_secs(5),
 | 
						|
    )
 | 
						|
    .await;
 | 
						|
 | 
						|
    // there is no old data (late arrival window is 1000s) that can be persisted
 | 
						|
    Command::cargo_bin("influxdb_iox")
 | 
						|
        .unwrap()
 | 
						|
        .arg("database")
 | 
						|
        .arg("partition")
 | 
						|
        .arg("persist")
 | 
						|
        .arg(&db_name)
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("cpu")
 | 
						|
        .arg("--host")
 | 
						|
        .arg(addr)
 | 
						|
        .assert()
 | 
						|
        .failure()
 | 
						|
        .stderr(predicate::str::contains("Error persisting partition:").and(
 | 
						|
            predicate::str::contains(
 | 
						|
                "Cannot persist partition because it cannot be flushed at the moment",
 | 
						|
            ),
 | 
						|
        ));
 | 
						|
}
 |