Adding upstream version 0.0.22.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
2f814b513a
commit
b06d3acde8
190 changed files with 61565 additions and 0 deletions
3
icann-rdap-cli/tests/integration/main.rs
Normal file
3
icann-rdap-cli/tests/integration/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
mod rdap_cmd;
|
||||
mod rdap_test_cmd;
|
||||
mod test_jig;
|
50
icann-rdap-cli/tests/integration/rdap_cmd/cache.rs
Normal file
50
icann-rdap-cli/tests/integration/rdap_cmd/cache.rs
Normal file
|
@ -0,0 +1,50 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use {
|
||||
icann_rdap_client::rdap::RequestResponseOwned,
|
||||
icann_rdap_common::response::{Domain, Entity, RdapResponse},
|
||||
icann_rdap_srv::storage::StoreOps,
|
||||
};
|
||||
|
||||
use crate::test_jig::TestJig;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_domain_with_entity_WHEN_retreived_from_cache_THEN_is_domain() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_domain(
|
||||
&Domain::builder()
|
||||
.ldh_name("foo.example")
|
||||
.entity(Entity::builder().handle("bob").build())
|
||||
.build(),
|
||||
)
|
||||
.await
|
||||
.expect("add domain in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
test_jig.cmd.arg("foo.example");
|
||||
let output = test_jig.cmd.output().expect("executing domain query");
|
||||
let responses: Vec<RequestResponseOwned> =
|
||||
serde_json::from_slice(&output.stdout).expect("parsing stdout");
|
||||
let rdap = &responses.first().expect("response is empty").res_data.rdap;
|
||||
println!("response type is {rdap}");
|
||||
|
||||
// WHEN
|
||||
let mut test_jig = test_jig.new_cmd();
|
||||
test_jig.cmd.arg("foo.example");
|
||||
|
||||
// THEN
|
||||
let output = test_jig.cmd.output().expect("executing domain query");
|
||||
let responses: Vec<RequestResponseOwned> =
|
||||
serde_json::from_slice(&output.stdout).expect("parsing stdout");
|
||||
let rdap = &responses.first().expect("response is empty").res_data.rdap;
|
||||
println!("response type is {rdap}");
|
||||
assert!(matches!(rdap, RdapResponse::Domain(_)));
|
||||
let rdap_type = &responses
|
||||
.first()
|
||||
.expect("response is empty")
|
||||
.res_data
|
||||
.rdap_type;
|
||||
assert_eq!(rdap_type, "Domain");
|
||||
}
|
23
icann-rdap-cli/tests/integration/rdap_cmd/check.rs
Normal file
23
icann-rdap-cli/tests/integration/rdap_cmd/check.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use {icann_rdap_common::response::Domain, icann_rdap_srv::storage::StoreOps};
|
||||
|
||||
use crate::test_jig::TestJig;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_domain_with_check_WHEN_query_THEN_failure() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_domain(&Domain::builder().ldh_name("foo.example").build())
|
||||
.await
|
||||
.expect("add domain in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg("--error-on-check").arg("foo.example");
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.failure();
|
||||
}
|
5
icann-rdap-cli/tests/integration/rdap_cmd/mod.rs
Normal file
5
icann-rdap-cli/tests/integration/rdap_cmd/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
mod cache;
|
||||
mod check;
|
||||
mod queries;
|
||||
mod source;
|
||||
mod url;
|
214
icann-rdap-cli/tests/integration/rdap_cmd/queries.rs
Normal file
214
icann-rdap-cli/tests/integration/rdap_cmd/queries.rs
Normal file
|
@ -0,0 +1,214 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use {
|
||||
icann_rdap_common::response::{Autnum, Domain, Entity, Nameserver, Network},
|
||||
icann_rdap_srv::storage::StoreOps,
|
||||
rstest::rstest,
|
||||
};
|
||||
|
||||
use crate::test_jig::TestJig;
|
||||
|
||||
#[rstest]
|
||||
#[case("foo.example", "foo.example")]
|
||||
#[case("foo.example", "foo.example.")]
|
||||
#[case("foo.example", "FOO.EXAMPLE")]
|
||||
#[case("foó.example", "foó.example")] // unicode
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_domain_WHEN_query_THEN_success(#[case] db_domain: &str, #[case] q_domain: &str) {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_domain(&Domain::builder().ldh_name(db_domain).build())
|
||||
.await
|
||||
.expect("add domain in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg(q_domain);
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_tld_WHEN_query_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_domain(&Domain::builder().ldh_name("example").build())
|
||||
.await
|
||||
.expect("add domain in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
// without "--tld-lookup=none" then this attempts to query IANA instead of the test server
|
||||
test_jig.cmd.arg("--tld-lookup=none").arg(".example");
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_entity_WHEN_query_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_entity(&Entity::builder().handle("foo").build())
|
||||
.await
|
||||
.expect("add entity in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg("foo");
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_nameserver_WHEN_query_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_nameserver(
|
||||
&Nameserver::builder()
|
||||
.ldh_name("ns.foo.example")
|
||||
.build()
|
||||
.unwrap(),
|
||||
)
|
||||
.await
|
||||
.expect("add nameserver in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg("ns.foo.example");
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_autnum_WHEN_query_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_autnum(&Autnum::builder().autnum_range(700..710).build())
|
||||
.await
|
||||
.expect("add autnum in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg("700");
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_network_ip_WHEN_query_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_network(
|
||||
&Network::builder()
|
||||
.cidr("10.0.0.0/24")
|
||||
.build()
|
||||
.expect("cidr parsing"),
|
||||
)
|
||||
.await
|
||||
.expect("add network in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg("10.0.0.1");
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case("10.0.0.0/24", "10.0.0.0/24")]
|
||||
#[case("10.0.0.0/24", "10.0.0/24")]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_network_cidr_WHEN_query_THEN_success(#[case] db_cidr: &str, #[case] q_cidr: &str) {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_network(
|
||||
&Network::builder()
|
||||
.cidr(db_cidr)
|
||||
.build()
|
||||
.expect("cidr parsing"),
|
||||
)
|
||||
.await
|
||||
.expect("add network in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg(q_cidr);
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_url_WHEN_query_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_domain(&Domain::builder().ldh_name("foo.example").build())
|
||||
.await
|
||||
.expect("add domain in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
let url = format!("{}/domain/foo.example", test_jig.rdap_base);
|
||||
test_jig.cmd.arg(url);
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_idn_WHEN_query_a_label_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_domain(&Domain::builder().ldh_name("xn--caf-dma.example").build())
|
||||
.await
|
||||
.expect("add domain in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg("-t").arg("a-label").arg("café.example");
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_domain_WHEN_search_domain_names_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap_with_dn_search().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_domain(&Domain::builder().ldh_name("foo.example").build())
|
||||
.await
|
||||
.expect("add domain in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg("-t").arg("domain-name").arg("foo.*");
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
46
icann-rdap-cli/tests/integration/rdap_cmd/source.rs
Normal file
46
icann-rdap-cli/tests/integration/rdap_cmd/source.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use {
|
||||
icann_rdap_client::rdap::{RequestResponseOwned, SourceType},
|
||||
icann_rdap_common::response::Network,
|
||||
icann_rdap_srv::storage::StoreOps,
|
||||
rstest::rstest,
|
||||
};
|
||||
|
||||
use crate::test_jig::TestJig;
|
||||
|
||||
#[rstest]
|
||||
#[case("10.0.0.0/24", "10.0.0.0/24")]
|
||||
#[case("10.0.0.0/24", "10.0.0.1")]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_inr_query_WHEN_query_THEN_source_is_rir(
|
||||
#[case] db_cidr: &str,
|
||||
#[case] q_cidr: &str,
|
||||
) {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_network(
|
||||
&Network::builder()
|
||||
.cidr(db_cidr)
|
||||
.build()
|
||||
.expect("cidr parsing"),
|
||||
)
|
||||
.await
|
||||
.expect("add network in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
test_jig.cmd.arg(q_cidr);
|
||||
|
||||
// THEN
|
||||
let output = test_jig.cmd.output().expect("executing inr query");
|
||||
let responses: Vec<RequestResponseOwned> =
|
||||
serde_json::from_slice(&output.stdout).expect("parsing stdout");
|
||||
let source_type = responses
|
||||
.first()
|
||||
.expect("respons is empty")
|
||||
.req_data
|
||||
.source_type;
|
||||
assert!(matches!(source_type, SourceType::RegionalInternetRegistry));
|
||||
}
|
54
icann-rdap-cli/tests/integration/rdap_cmd/url.rs
Normal file
54
icann-rdap-cli/tests/integration/rdap_cmd/url.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use {icann_rdap_common::response::Network, icann_rdap_srv::storage::StoreOps};
|
||||
|
||||
use crate::test_jig::TestJig;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_url_used_with_base_url_WHEN_query_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_network(
|
||||
&Network::builder()
|
||||
.cidr("10.0.0.0/24")
|
||||
.build()
|
||||
.expect("cidr parsing"),
|
||||
)
|
||||
.await
|
||||
.expect("add network in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
let url = format!("{}/ip/10.0.0.1", test_jig.rdap_base);
|
||||
test_jig.cmd.arg(url);
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_url_used_with_no_base_url_WHEN_query_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap().await;
|
||||
test_jig.cmd.env_remove("RDAP_BASE_URL");
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_network(
|
||||
&Network::builder()
|
||||
.cidr("10.0.0.0/24")
|
||||
.build()
|
||||
.expect("cidr parsing"),
|
||||
)
|
||||
.await
|
||||
.expect("add network in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
let url = format!("{}/ip/10.0.0.1", test_jig.rdap_base);
|
||||
test_jig.cmd.arg(url);
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
1
icann-rdap-cli/tests/integration/rdap_test_cmd/mod.rs
Normal file
1
icann-rdap-cli/tests/integration/rdap_test_cmd/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
mod url;
|
30
icann-rdap-cli/tests/integration/rdap_test_cmd/url.rs
Normal file
30
icann-rdap-cli/tests/integration/rdap_test_cmd/url.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use {icann_rdap_common::response::Network, icann_rdap_srv::storage::StoreOps};
|
||||
|
||||
use crate::test_jig::TestJig;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn GIVEN_url_WHEN_test_THEN_success() {
|
||||
// GIVEN
|
||||
let mut test_jig = TestJig::new_rdap_test().await;
|
||||
test_jig.cmd.env_remove("RDAP_BASE_URL");
|
||||
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
|
||||
tx.add_network(
|
||||
&Network::builder()
|
||||
.cidr("10.0.0.0/24")
|
||||
.build()
|
||||
.expect("cidr parsing"),
|
||||
)
|
||||
.await
|
||||
.expect("add network in tx");
|
||||
tx.commit().await.expect("tx commit");
|
||||
|
||||
// WHEN
|
||||
let url = format!("{}/ip/10.0.0.1", test_jig.rdap_base);
|
||||
test_jig.cmd.arg(url);
|
||||
|
||||
// THEN
|
||||
let assert = test_jig.cmd.assert();
|
||||
assert.success();
|
||||
}
|
109
icann-rdap-cli/tests/integration/test_jig.rs
Normal file
109
icann-rdap-cli/tests/integration/test_jig.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
use {
|
||||
assert_cmd::Command,
|
||||
icann_rdap_srv::{
|
||||
config::ListenConfig,
|
||||
server::{AppState, Listener},
|
||||
storage::{
|
||||
mem::{config::MemConfig, ops::Mem},
|
||||
CommonConfig,
|
||||
},
|
||||
},
|
||||
std::time::Duration,
|
||||
test_dir::{DirBuilder, FileType, TestDir},
|
||||
};
|
||||
|
||||
pub enum CommandType {
|
||||
Rdap,
|
||||
RdapTest,
|
||||
}
|
||||
|
||||
pub struct TestJig {
|
||||
pub mem: Mem,
|
||||
pub cmd: Command,
|
||||
pub cmd_type: CommandType,
|
||||
pub rdap_base: String,
|
||||
// pass ownership to the test so the directories are dropped when the test is done.
|
||||
test_dir: TestDir,
|
||||
}
|
||||
|
||||
impl TestJig {
|
||||
pub async fn new_rdap() -> Self {
|
||||
let common_config = CommonConfig::default();
|
||||
Self::new_common_config(common_config, CommandType::Rdap).await
|
||||
}
|
||||
|
||||
pub async fn new_rdap_with_dn_search() -> Self {
|
||||
let common_config = CommonConfig::builder()
|
||||
.domain_search_by_name_enable(true)
|
||||
.build();
|
||||
Self::new_common_config(common_config, CommandType::Rdap).await
|
||||
}
|
||||
|
||||
pub async fn new_rdap_test() -> Self {
|
||||
let common_config = CommonConfig::default();
|
||||
Self::new_common_config(common_config, CommandType::RdapTest).await
|
||||
}
|
||||
|
||||
pub async fn new_common_config(common_config: CommonConfig, cmd_type: CommandType) -> Self {
|
||||
let mem = Mem::new(MemConfig::builder().common_config(common_config).build());
|
||||
let app_state = AppState {
|
||||
storage: mem.clone(),
|
||||
bootstrap: false,
|
||||
};
|
||||
let _ = tracing_subscriber::fmt().try_init();
|
||||
let listener = Listener::listen(&ListenConfig::default())
|
||||
.await
|
||||
.expect("listening on interface");
|
||||
let rdap_base = listener.rdap_base();
|
||||
tokio::spawn(async move {
|
||||
listener
|
||||
.start_with_state(app_state)
|
||||
.await
|
||||
.expect("starting server");
|
||||
});
|
||||
let test_dir = TestDir::temp()
|
||||
.create("cache", FileType::Dir)
|
||||
.create("config", FileType::Dir);
|
||||
let cmd = Command::new("sh"); //throw away
|
||||
Self {
|
||||
mem,
|
||||
cmd,
|
||||
cmd_type,
|
||||
rdap_base,
|
||||
test_dir,
|
||||
}
|
||||
.new_cmd()
|
||||
}
|
||||
|
||||
/// Creates a new command from an existing one but resetting necessary environment variables.
|
||||
///
|
||||
/// Using the function allows the test jig to stay up but a new command to be executed.
|
||||
pub fn new_cmd(self) -> Self {
|
||||
let cmd = match self.cmd_type {
|
||||
CommandType::Rdap => {
|
||||
let mut cmd = Command::cargo_bin("rdap").expect("cannot find rdap cmd");
|
||||
cmd.env_clear()
|
||||
.timeout(Duration::from_secs(2))
|
||||
.env("RDAP_BASE_URL", self.rdap_base.clone())
|
||||
.env("RDAP_PAGING", "none")
|
||||
.env("RDAP_OUTPUT", "json-extra")
|
||||
.env("RDAP_LOG", "debug")
|
||||
.env("RDAP_ALLOW_HTTP", "true")
|
||||
.env("XDG_CACHE_HOME", self.test_dir.path("cache"))
|
||||
.env("XDG_CONFIG_HOME", self.test_dir.path("config"));
|
||||
cmd
|
||||
}
|
||||
CommandType::RdapTest => {
|
||||
let mut cmd = Command::cargo_bin("rdap-test").expect("cannot find rdap-test cmd");
|
||||
cmd.env_clear()
|
||||
.timeout(Duration::from_secs(2))
|
||||
.env("RDAP_TEST_LOG", "debug")
|
||||
.env("RDAP_TEST_ALLOW_HTTP", "true")
|
||||
.env("XDG_CACHE_HOME", self.test_dir.path("cache"))
|
||||
.env("XDG_CONFIG_HOME", self.test_dir.path("config"));
|
||||
cmd
|
||||
}
|
||||
};
|
||||
Self { cmd, ..self }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue