Skip to content

Commit ac7d1be

Browse files
committed
add coverage on config include logic
Signed-off-by: onur-ozkan <[email protected]>
1 parent 8270478 commit ac7d1be

File tree

1 file changed

+209
-2
lines changed

1 file changed

+209
-2
lines changed

src/bootstrap/src/core/config/tests.rs

+209-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::collections::BTreeSet;
2-
use std::env;
32
use std::fs::{File, remove_file};
43
use std::io::Write;
5-
use std::path::Path;
4+
use std::path::{Path, PathBuf};
5+
use std::{env, fs};
66

77
use build_helper::ci::CiEnv;
88
use clap::CommandFactory;
@@ -23,6 +23,27 @@ pub(crate) fn parse(config: &str) -> Config {
2323
)
2424
}
2525

26+
fn get_toml(file: &Path) -> Result<TomlConfig, toml::de::Error> {
27+
let contents = std::fs::read_to_string(file).unwrap();
28+
toml::from_str(&contents).and_then(|table: toml::Value| TomlConfig::deserialize(table))
29+
}
30+
31+
/// Helps with debugging by using consistent test-specific directories instead of
32+
/// random temporary directories.
33+
fn prepare_test_specific_dir() -> PathBuf {
34+
let current = std::thread::current();
35+
// Replace "::" with "_" to make it safe for directory names on Windows systems
36+
let test_path = current.name().unwrap().replace("::", "_");
37+
38+
let testdir = parse("").tempdir().join(test_path);
39+
40+
// clean up any old test files
41+
let _ = fs::remove_dir_all(&testdir);
42+
let _ = fs::create_dir_all(&testdir);
43+
44+
testdir
45+
}
46+
2647
#[test]
2748
fn download_ci_llvm() {
2849
let config = parse("llvm.download-ci-llvm = false");
@@ -539,3 +560,189 @@ fn test_ci_flag() {
539560
let config = Config::parse_inner(Flags::parse(&["check".into()]), |&_| toml::from_str(""));
540561
assert_eq!(config.is_running_on_ci, CiEnv::is_ci());
541562
}
563+
564+
#[test]
565+
fn test_precedence_of_includes() {
566+
let testdir = prepare_test_specific_dir();
567+
568+
let root_config = testdir.join("config.toml");
569+
let root_config_content = br#"
570+
include = ["./extension.toml"]
571+
572+
[llvm]
573+
link-jobs = 2
574+
"#;
575+
File::create(&root_config).unwrap().write_all(root_config_content).unwrap();
576+
577+
let extension = testdir.join("extension.toml");
578+
let extension_content = br#"
579+
change-id=543
580+
include = ["./extension2.toml"]
581+
"#;
582+
File::create(extension).unwrap().write_all(extension_content).unwrap();
583+
584+
let extension = testdir.join("extension2.toml");
585+
let extension_content = br#"
586+
change-id=742
587+
588+
[llvm]
589+
link-jobs = 10
590+
591+
[build]
592+
description = "Some creative description"
593+
"#;
594+
File::create(extension).unwrap().write_all(extension_content).unwrap();
595+
596+
let config = Config::parse_inner(
597+
Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]),
598+
get_toml,
599+
);
600+
601+
assert_eq!(config.change_id.unwrap(), ChangeId::Id(543));
602+
assert_eq!(config.llvm_link_jobs.unwrap(), 2);
603+
assert_eq!(config.description.unwrap(), "Some creative description");
604+
}
605+
606+
#[test]
607+
#[should_panic(expected = "Cyclic inclusion detected")]
608+
fn test_cyclic_include_direct() {
609+
let testdir = prepare_test_specific_dir();
610+
611+
let root_config = testdir.join("config.toml");
612+
let root_config_content = br#"
613+
include = ["./extension.toml"]
614+
"#;
615+
File::create(&root_config).unwrap().write_all(root_config_content).unwrap();
616+
617+
let extension = testdir.join("extension.toml");
618+
let extension_content = br#"
619+
include = ["./config.toml"]
620+
"#;
621+
File::create(extension).unwrap().write_all(extension_content).unwrap();
622+
623+
let config = Config::parse_inner(
624+
Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]),
625+
get_toml,
626+
);
627+
}
628+
629+
#[test]
630+
#[should_panic(expected = "Cyclic inclusion detected")]
631+
fn test_cyclic_include_indirect() {
632+
let testdir = prepare_test_specific_dir();
633+
634+
let root_config = testdir.join("config.toml");
635+
let root_config_content = br#"
636+
include = ["./extension.toml"]
637+
"#;
638+
File::create(&root_config).unwrap().write_all(root_config_content).unwrap();
639+
640+
let extension = testdir.join("extension.toml");
641+
let extension_content = br#"
642+
include = ["./extension2.toml"]
643+
"#;
644+
File::create(extension).unwrap().write_all(extension_content).unwrap();
645+
646+
let extension = testdir.join("extension2.toml");
647+
let extension_content = br#"
648+
include = ["./extension3.toml"]
649+
"#;
650+
File::create(extension).unwrap().write_all(extension_content).unwrap();
651+
652+
let extension = testdir.join("extension3.toml");
653+
let extension_content = br#"
654+
include = ["./extension.toml"]
655+
"#;
656+
File::create(extension).unwrap().write_all(extension_content).unwrap();
657+
658+
let config = Config::parse_inner(
659+
Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]),
660+
get_toml,
661+
);
662+
}
663+
664+
#[test]
665+
fn test_include_absolute_paths() {
666+
let testdir = prepare_test_specific_dir();
667+
668+
let extension = testdir.join("extension.toml");
669+
File::create(&extension).unwrap().write_all(&[]).unwrap();
670+
671+
let root_config = testdir.join("config.toml");
672+
let extension_absolute_path =
673+
extension.canonicalize().unwrap().to_str().unwrap().replace('\\', r"\\");
674+
let root_config_content = format!(r#"include = ["{}"]"#, extension_absolute_path);
675+
File::create(&root_config).unwrap().write_all(root_config_content.as_bytes()).unwrap();
676+
677+
let config = Config::parse_inner(
678+
Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]),
679+
get_toml,
680+
);
681+
}
682+
683+
#[test]
684+
fn test_include_relative_paths() {
685+
let testdir = prepare_test_specific_dir();
686+
687+
let _ = fs::create_dir_all(&testdir.join("subdir/another_subdir"));
688+
689+
let root_config = testdir.join("config.toml");
690+
let root_config_content = br#"
691+
include = ["./subdir/extension.toml"]
692+
"#;
693+
File::create(&root_config).unwrap().write_all(root_config_content).unwrap();
694+
695+
let extension = testdir.join("subdir/extension.toml");
696+
let extension_content = br#"
697+
include = ["../extension2.toml"]
698+
"#;
699+
File::create(extension).unwrap().write_all(extension_content).unwrap();
700+
701+
let extension = testdir.join("extension2.toml");
702+
let extension_content = br#"
703+
include = ["./subdir/another_subdir/extension3.toml"]
704+
"#;
705+
File::create(extension).unwrap().write_all(extension_content).unwrap();
706+
707+
let extension = testdir.join("subdir/another_subdir/extension3.toml");
708+
let extension_content = br#"
709+
include = ["../../extension4.toml"]
710+
"#;
711+
File::create(extension).unwrap().write_all(extension_content).unwrap();
712+
713+
let extension = testdir.join("extension4.toml");
714+
File::create(extension).unwrap().write_all(&[]).unwrap();
715+
716+
let config = Config::parse_inner(
717+
Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]),
718+
get_toml,
719+
);
720+
}
721+
722+
#[test]
723+
fn test_include_precedence_over_profile() {
724+
let testdir = prepare_test_specific_dir();
725+
726+
let root_config = testdir.join("config.toml");
727+
let root_config_content = br#"
728+
profile = "dist"
729+
include = ["./extension.toml"]
730+
"#;
731+
File::create(&root_config).unwrap().write_all(root_config_content).unwrap();
732+
733+
let extension = testdir.join("extension.toml");
734+
let extension_content = br#"
735+
[rust]
736+
channel = "dev"
737+
"#;
738+
File::create(extension).unwrap().write_all(extension_content).unwrap();
739+
740+
let config = Config::parse_inner(
741+
Flags::parse(&["check".to_owned(), format!("--config={}", root_config.to_str().unwrap())]),
742+
get_toml,
743+
);
744+
745+
// "dist" profile would normally set the channel to "auto-detect", but includes should
746+
// override profile settings, so we expect this to be "dev" here.
747+
assert_eq!(config.channel, "dev");
748+
}

0 commit comments

Comments
 (0)