This commit is contained in:
Adrian Utrilla 2016-11-13 18:58:29 +01:00
Родитель 3415b92bff
Коммит 16f48eb2d2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 6BA64E6212CDEBE9
2 изменённых файлов: 128 добавлений и 21 удалений

Просмотреть файл

@ -7,3 +7,5 @@ authors = ["Adrian Utrilla <adrianutrilla@gmail.com>"]
tempdir = "0.3.5"
serde = "0.8"
serde_json = "0.8"
serde_yaml = "0.5"
lazy_static = "0.1.*"

Просмотреть файл

@ -1,41 +1,119 @@
extern crate tempdir;
extern crate serde_json;
extern crate serde_yaml;
#[macro_use]
extern crate lazy_static;
#[cfg(test)]
mod tests {
extern crate serde_json;
extern crate serde_yaml;
use std::fs::File;
use std::io::Write;
use tempdir::TempDir;
use std::process::Command;
use serde_json::Value;
use std::collections::BTreeMap;
const SOPS_BINARY_PATH: &'static str = "./sops";
macro_rules! assert_encrypted {
($object:expr, $key:expr) => {
assert!($object.get($key).is_some());
match *$object.get($key).unwrap() {
serde_json::Value::String(ref s) => {
assert!(s.starts_with("ENC["), "Value is not encrypted");
// Boring code to use a single value enum instead of one for each json and yaml
#[derive(PartialOrd, Ord, Eq, PartialEq, Debug)]
enum Value {
String(String),
Mapping(BTreeMap<Value, Value>),
Sequence(Vec<Value>),
Null,
}
impl From<serde_yaml::Value> for Value {
fn from(val: serde_yaml::Value) -> Value {
match val {
serde_yaml::Value::String(s) => Value::String(s),
serde_yaml::Value::Mapping(m) => {
let mut map: BTreeMap<Value, Value> = BTreeMap::new();
for (key, value) in m {
map.insert(key.into(), value.into());
}
Value::Mapping(map)
}
_ => panic!("Value under key {} is not a string", $key)
serde_yaml::Value::Null => Value::Null,
serde_yaml::Value::Sequence(in_vec) => {
let mut vec: Vec<Value> = Vec::new();
for v in in_vec {
vec.push(v.into());
}
Value::Sequence(vec)
}
_ => unreachable!("{:?}", val),
}
}
}
#[test]
fn encrypt_file() {
let tmp_dir = TempDir::new("sops-functional-tests")
impl From<serde_json::Value> for Value {
fn from(val: serde_json::Value) -> Value {
match val {
serde_json::Value::String(s) => Value::String(s),
serde_json::Value::Object(m) => {
let mut map: BTreeMap<Value, Value> = BTreeMap::new();
for (key, value) in m {
map.insert(key.as_str().into(), value.into());
}
Value::Mapping(map)
}
serde_json::Value::Null => Value::Null,
serde_json::Value::Array(in_vec) => {
let mut vec: Vec<Value> = Vec::new();
for v in in_vec {
vec.push(v.into());
}
Value::Sequence(vec)
}
_ => unreachable!("{:?}", val),
}
}
}
impl<'a> From<&'a str> for Value {
fn from(val: &'a str) -> Value {
Value::String(val.to_owned())
}
}
macro_rules! assert_encrypted {
($object:expr, $key:expr) => {
let key : Value = $key.into();
assert!($object.get(&key).is_some());
match *$object.get(&key).unwrap() {
Value::String(ref s) => {
assert!(s.starts_with("ENC["), "Value is not encrypted");
}
_ => panic!("Value under key was not a string"),
}
}
}
lazy_static! {
static ref TMP_DIR: TempDir = TempDir::new("sops-functional-tests")
.expect("Unable to create temporary directory");
let file_path = tmp_dir.path().join("test_encrypt.json");
}
fn prepare_temp_file(name: &str, contents: &[u8]) -> String {
let file_path = TMP_DIR.path().join(name);
let mut tmp_file = File::create(file_path.clone())
.expect("Unable to create temporary file");
tmp_file.write_all(b"{
tmp_file.write_all(&contents)
.expect("Error writing to temporary file");
file_path.to_string_lossy().into_owned()
}
#[test]
fn encrypt_json_file() {
let file_path = prepare_temp_file("test_encrypt.json",
b"{
\"foo\": 2,
\"bar\": \"baz\"
}")
.expect("Error writing to temporary file");
}");
let output = Command::new(SOPS_BINARY_PATH)
.arg("-e")
.arg(file_path.clone())
@ -43,14 +121,41 @@ mod tests {
.expect("Error running sops");
assert!(output.status.success(), "sops didn't exit successfully");
let json = &String::from_utf8_lossy(&output.stdout);
let data: Value = serde_json::from_str(json).expect("Error parsing sops's JSON output");
match data {
serde_json::Value::Object(o) => {
assert!(o.get("sops").is_some(), "sops metadata branch not found");
assert_encrypted!(o, "foo");
assert_encrypted!(o, "bar");
let data: serde_json::Value = serde_json::from_str(json)
.expect("Error parsing sops's JSON output");
match data.into() {
Value::Mapping(m) => {
assert!(m.get(&"sops".into()).is_some(),
"sops metadata branch not found");
assert_encrypted!(&m, "foo");
assert_encrypted!(&m, "bar");
}
_ => panic!("sops's JSON output is not an object"),
}
}
#[test]
fn encrypt_yaml_file() {
let file_path = prepare_temp_file("test_encrypt.yaml",
b"foo: 2
bar: baz");
let output = Command::new(SOPS_BINARY_PATH)
.arg("-e")
.arg(file_path.clone())
.output()
.expect("Error running sops");
assert!(output.status.success(), "sops didn't exit successfully");
let json = &String::from_utf8_lossy(&output.stdout);
let data: serde_yaml::Value = serde_yaml::from_str(&json)
.expect("Error parsing sops's JSON output");
match data.into() {
Value::Mapping(m) => {
assert!(m.get(&"sops".into()).is_some(),
"sops metadata branch not found");
assert_encrypted!(&m, "foo");
assert_encrypted!(&m, "bar");
}
_ => panic!("sops's YAML output is not a mapping"),
}
}
}