Skip to content

Commit

Permalink
Add tests for loading user configuration
Browse files Browse the repository at this point in the history
Signed-off-by: Krzesimir Nowak <krzesimir@kinvolk.io>
  • Loading branch information
krnowak committed Oct 30, 2017
1 parent 322d460 commit 18e2baf
Showing 1 changed file with 181 additions and 0 deletions.
181 changes: 181 additions & 0 deletions components/sup/src/manager/service/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ mod test {

use super::*;
use error::Error;
use std::fs;
use std::fs::{File, OpenOptions};
use std::io::{Seek, SeekFrom};

fn toml_from_str(content: &str) -> toml::value::Table {
toml::from_str(content).expect(&format!("Content should parse as TOML: {}", content))
Expand Down Expand Up @@ -712,4 +715,182 @@ mod test {

assert_eq!(default_toml, toml::to_string(&cfg).unwrap());
}

struct TestPkg {
path: PathBuf,
user_config_path: PathBuf,
svc_path: PathBuf,
name: String,
}

impl TestPkg {
fn new(tmp: &TempDir) -> Self {
let path = tmp.path().join("root");
let user_config_path = tmp.path().join("user");
let svc_path = tmp.path().join("svc");

fs::create_dir_all(&path).expect("create package root dir");
fs::create_dir_all(&user_config_path).expect("create user config dir");
fs::create_dir_all(&svc_path).expect("create service dir");
Self {
path: path,
user_config_path: user_config_path,
svc_path: svc_path,
name: String::from("testing"),
}
}

fn deprecated_ucp(&self) -> UserConfigPath {
UserConfigPath::Deprecated(self.svc_path.join("user.toml"))
}

fn recommended_ucp(&self) -> UserConfigPath {
UserConfigPath::Recommended(self.user_config_path.join("user.toml"))
}
}

impl PackageForConfig for TestPkg {
fn path(&self) -> &PathBuf {
&self.path
}
fn user_config_path(&self) -> &PathBuf {
&self.user_config_path
}
fn svc_path(&self) -> &PathBuf {
&self.svc_path
}
fn name(&self) -> &String {
&self.name
}
}

struct TestToml {
raw: Vec<u8>,
value: toml::Value,
}

impl TestToml {
fn new(raw: &str) -> Self {
Self {
raw: raw.as_bytes().to_vec(),
value: raw.parse::<toml::Value>().expect("parse toml string"),
}
}

fn reset(&mut self, raw: &str) {
let value = raw.parse::<toml::Value>().expect("parse toml string");
self.raw = raw.as_bytes().to_vec();
self.value = value;
}

fn write(&self, file: &mut File) {
file.seek(SeekFrom::Start(0)).expect(
"seek in toml file to start",
);
file.set_len(0).expect("truncate toml file");
file.write_all(self.raw.as_slice()).expect(
"write raw toml value",
);
file.flush().expect("flush changes in toml file");

file.seek(SeekFrom::Start(0)).expect(
"seek in toml file to start for checking",
);
let mut buf = Vec::new();
file.read_to_end(&mut buf).expect(
"read value from toml file",
);
assert_eq!(buf, self.raw);
}
}

fn get_toml_file(ucp: &UserConfigPath) -> File {
OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(ucp.get_path())
.expect("create toml file")
}

#[test]
fn default_to_recommended_user_toml_if_missing() {
let tmp = TempDir::new("habitat_config_test").expect("create temp dir");
let pkg = TestPkg::new(&tmp);
let cfg = Cfg::new(&pkg, None).expect("create config");

assert_eq!(cfg.user_config_path, Some(pkg.recommended_ucp()));
assert!(cfg.user.is_none());
}

#[test]
fn load_deprecated_user_toml() {
let tmp = TempDir::new("habitat_config_test").expect("create temp dir");
let pkg = TestPkg::new(&tmp);
let ucp = pkg.deprecated_ucp();
let mut file = get_toml_file(&ucp);
let toml = TestToml::new("foo = 42");
toml.write(&mut file);
let cfg = Cfg::new(&pkg, None).expect("create config");

assert_eq!(cfg.user_config_path, Some(ucp));
assert_eq!(cfg.user, Some(toml.value));
}

#[test]
fn load_recommended_user_toml() {
let tmp = TempDir::new("habitat_config_test").expect("create temp dir");
let pkg = TestPkg::new(&tmp);
let ucp = pkg.recommended_ucp();
let mut file = get_toml_file(&ucp);
let toml = TestToml::new("foo = 42");
toml.write(&mut file);
let cfg = Cfg::new(&pkg, None).expect("create config");

assert_eq!(cfg.user_config_path, Some(ucp));
assert_eq!(cfg.user, Some(toml.value));
}

#[test]
fn prefer_recommended_to_deprecated() {
let tmp = TempDir::new("habitat_config_test").expect("create temp dir");
let pkg = TestPkg::new(&tmp);
let rucp = pkg.recommended_ucp();
let ducp = pkg.deprecated_ucp();
let mut r_file = get_toml_file(&rucp);
let r_toml = TestToml::new("foo = 42");
r_toml.write(&mut r_file);
let mut d_file = get_toml_file(&ducp);
let d_toml = TestToml::new("foo = 13");
d_toml.write(&mut d_file);
let cfg = Cfg::new(&pkg, None).expect("create config");

assert_eq!(cfg.user_config_path, Some(rucp));
assert_eq!(cfg.user, Some(r_toml.value));
}

#[test]
fn keep_loading_deprecated_after_initial_load() {
let tmp = TempDir::new("habitat_config_test").expect("create temp dir");
let pkg = TestPkg::new(&tmp);
let ducp = pkg.deprecated_ucp();
let mut d_file = get_toml_file(&ducp);
let mut d_toml = TestToml::new("foo = 13");
d_toml.write(&mut d_file);
let mut cfg = Cfg::new(&pkg, None).expect("create config");

assert_eq!(cfg.user_config_path, Some(ducp.clone()));
assert_eq!(cfg.user, Some(d_toml.value.clone()));

d_toml.reset("foo = 85");
d_toml.write(&mut d_file);
let rucp = pkg.recommended_ucp();
let mut r_file = get_toml_file(&rucp);
let r_toml = TestToml::new("foo = 42");
r_toml.write(&mut r_file);
cfg.load_user(&pkg).expect("reload user config");

assert_eq!(cfg.user_config_path, Some(ducp));
assert_eq!(cfg.user, Some(d_toml.value));
}
}

0 comments on commit 18e2baf

Please sign in to comment.