<commit_before>extern crate r2d2;

use std::sync::Mutex;
use std::default::Default;

mod config;

#[deriving(Show, PartialEq)]
struct FakeConnection;

#[deriving(Default)]
struct OkManager;

impl r2d2::PoolManager<FakeConnection, ()> for OkManager {
    fn connect(&self) -> Result<FakeConnection, ()> {
        Ok(FakeConnection)
    }

    fn is_valid(&self, _: &FakeConnection) -> bool {
        true
    }
}

struct NthConnectFailManager {
    n: Mutex<uint>,
}

impl r2d2::PoolManager<FakeConnection, ()> for NthConnectFailManager {
    fn connect(&self) -> Result<FakeConnection, ()> {
        let mut n = self.n.lock();
        if *n > 0 {
            *n -= 1;
            Ok(FakeConnection)
        } else {
            Err(())
        }
    }

    fn is_valid(&self, _: &FakeConnection) -> bool {
        true
    }
}

#[test]
fn test_pool_size_ok() {
    let config = r2d2::Config {
        pool_size: 5,
        ..Default::default()
    };
    let manager = NthConnectFailManager { n: Mutex::new(5) };
    assert!(r2d2::Pool::new(config, manager, r2d2::NoopErrorHandler).is_ok());
}

#[test]
fn test_pool_size_err() {
    let config = r2d2::Config {
        pool_size: 5,
        ..Default::default()
    };
    let manager = NthConnectFailManager { n: Mutex::new(4) };
    assert_eq!(r2d2::Pool::new(config, manager, r2d2::NoopErrorHandler).err().unwrap(),
               r2d2::ConnectionError(()));
}

#[test]
fn test_acquire_release() {
    let config = r2d2::Config {
        pool_size: 2,
        ..Default::default()
    };
    let pool = r2d2::Pool::new(config, OkManager, r2d2::NoopErrorHandler).unwrap();

    let conn1 = pool.get().unwrap();
    let conn2 = pool.get().unwrap();
    drop(conn1);
    let conn3 = pool.get().unwrap();
    drop(conn2);
    drop(conn3);
}

#[test]
fn test_is_send_sync() {
    fn is_send_sync<T: Send+Sync>() {}
    is_send_sync::<r2d2::Pool<FakeConnection, (), OkManager, r2d2::NoopErrorHandler>>();
}
<commit_msg>Add a test for #2<commit_after>extern crate r2d2;

use std::comm;
use std::sync::{Mutex, Arc};
use std::sync::atomic::{AtomicBool, SeqCst};
use std::default::Default;

mod config;

#[deriving(Show, PartialEq)]
struct FakeConnection;

#[deriving(Default)]
struct OkManager;

impl r2d2::PoolManager<FakeConnection, ()> for OkManager {
    fn connect(&self) -> Result<FakeConnection, ()> {
        Ok(FakeConnection)
    }

    fn is_valid(&self, _: &FakeConnection) -> bool {
        true
    }
}

struct NthConnectFailManager {
    n: Mutex<uint>,
}

impl r2d2::PoolManager<FakeConnection, ()> for NthConnectFailManager {
    fn connect(&self) -> Result<FakeConnection, ()> {
        let mut n = self.n.lock();
        if *n > 0 {
            *n -= 1;
            Ok(FakeConnection)
        } else {
            Err(())
        }
    }

    fn is_valid(&self, _: &FakeConnection) -> bool {
        true
    }
}

#[test]
fn test_pool_size_ok() {
    let config = r2d2::Config {
        pool_size: 5,
        ..Default::default()
    };
    let manager = NthConnectFailManager { n: Mutex::new(5) };
    assert!(r2d2::Pool::new(config, manager, r2d2::NoopErrorHandler).is_ok());
}

#[test]
fn test_pool_size_err() {
    let config = r2d2::Config {
        pool_size: 5,
        ..Default::default()
    };
    let manager = NthConnectFailManager { n: Mutex::new(4) };
    assert_eq!(r2d2::Pool::new(config, manager, r2d2::NoopErrorHandler).err().unwrap(),
               r2d2::ConnectionError(()));
}

#[test]
fn test_acquire_release() {
    let config = r2d2::Config {
        pool_size: 2,
        ..Default::default()
    };
    let pool = r2d2::Pool::new(config, OkManager, r2d2::NoopErrorHandler).unwrap();

    let conn1 = pool.get().unwrap();
    let conn2 = pool.get().unwrap();
    drop(conn1);
    let conn3 = pool.get().unwrap();
    drop(conn2);
    drop(conn3);
}

#[test]
fn test_is_send_sync() {
    fn is_send_sync<T: Send+Sync>() {}
    is_send_sync::<r2d2::Pool<FakeConnection, (), OkManager, r2d2::NoopErrorHandler>>();
}

#[test]
fn test_issue_2_unlocked_during_is_valid() {
    struct BlockingChecker {
        first: AtomicBool,
        s: Mutex<SyncSender<()>>,
        r: Mutex<Receiver<()>>,
    }

    impl r2d2::PoolManager<FakeConnection, ()> for BlockingChecker {
        fn connect(&self) -> Result<FakeConnection, ()> {
            Ok(FakeConnection)
        }

        fn is_valid(&self, _: &FakeConnection) -> bool {
            if self.first.compare_and_swap(true, false, SeqCst) {
                self.s.lock().send(());
                self.r.lock().recv();
            }
            true
        }
    }

    let (s1, r1) = comm::sync_channel(0);
    let (s2, r2) = comm::sync_channel(0);

    let config = r2d2::Config {
        test_on_check_out: true,
        pool_size: 2,
        ..Default::default()
    };
    let manager = BlockingChecker {
        first: AtomicBool::new(true),
        s: Mutex::new(s1),
        r: Mutex::new(r2),
    };
    let pool = Arc::new(r2d2::Pool::new(config, manager, r2d2::NoopErrorHandler).unwrap());

    let p2 = pool.clone();
    spawn(proc() {
        p2.get().unwrap();
    });

    r1.recv();
    // get call by other task has triggered the health check
    pool.get().unwrap();
    s2.send(());
}
<|endoftext|>


<commit_before>#![feature(globs,macro_rules,phase)]

#[phase(plugin,link)]
extern crate nom;

use nom::{IResult,Producer,FileProducer,ProducerState,FlatMapper,Mapper,Mapper2,line_ending,not_line_ending, space, alphanumeric, is_alphanumeric};
use nom::IResult::*;

use std::str;
use std::fmt::Show;

fn empty_result(i:&[u8]) -> IResult<&[u8], ()> { Done(i,()) }
tag!(semicolon ";".as_bytes());
o!(comment_body<&[u8],&[u8]> semicolon ~ not_line_ending ~ );
o!(comment<&[u8], ()> comment_body line_ending ~ empty_result ~);
opt!(opt_comment<&[u8],&[u8]> comment_body);

tag!(lsb "[".as_bytes());
tag!(rsb "]".as_bytes());
fn category_name(input:&[u8]) -> IResult<&[u8], &str> {
  for idx in range(0, input.len()) {
    if input[idx] == ']' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx)).map_res(str::from_utf8)
    }
  }
  Done("".as_bytes(), input).map_res(str::from_utf8)
}
o!(category<&[u8], &str> lsb ~ category_name ~ rsb line_ending);

tag!(equal "=".as_bytes());
fn not_equal(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == '=' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}

fn value_parser(input:&[u8]) -> IResult<&[u8], &str> {
  for idx in range(0, input.len()) {
    if input[idx] == '\n' as u8 || input[idx] == ';' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx)).map_res(str::from_utf8)
    }
  }
  Done("".as_bytes(), input).map_res(str::from_utf8)
}

fn parameter_parser(input: &[u8]) -> IResult<&[u8], &str> {
  alphanumeric(input).map_res(str::from_utf8)
}

opt!(opt_line_ending<&[u8],&[u8]> line_ending);
o!(value<&[u8],&str> space equal space ~ value_parser ~ space opt_comment opt_line_ending);
chain!(key_value<&[u8],(&str,&str)>, ||{(key, val)},  key: parameter_parser, val: value,);

#[test]
fn parse_comment_test() {
  let ini_file = ";comment
[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let ini_without_comment = "[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let res = Done((), ini_file.as_bytes()).flat_map(comment);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_comment.as_bytes(), ()));
}

#[test]
fn parse_category_test() {
  let ini_file = "[category]
parameter=value
key = value2";

  let ini_without_category = "parameter=value
key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(category);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_category.as_bytes(), "category"));
}

#[test]
fn parse_key_value_test() {
  let ini_file = "parameter=value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_key_value_with_space_test() {
  let ini_file = "parameter = value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_key_value_with_comment_test() {
  let ini_file = "parameter=value;abc
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}
<commit_msg>parse multiple keys and values<commit_after>#![feature(globs,macro_rules,phase)]

#[phase(plugin,link)]
extern crate nom;

use nom::{IResult,Producer,FileProducer,ProducerState,FlatMapper,Mapper,Mapper2,line_ending,not_line_ending, space, alphanumeric, is_alphanumeric};
use nom::IResult::*;

use std::str;
use std::fmt::Show;

fn empty_result(i:&[u8]) -> IResult<&[u8], ()> { Done(i,()) }
tag!(semicolon ";".as_bytes());
o!(comment_body<&[u8],&[u8]> semicolon ~ not_line_ending ~ );
o!(comment<&[u8], ()> comment_body line_ending ~ empty_result ~);
opt!(opt_comment<&[u8],&[u8]> comment_body);

tag!(lsb "[".as_bytes());
tag!(rsb "]".as_bytes());
fn category_name(input:&[u8]) -> IResult<&[u8], &str> {
  for idx in range(0, input.len()) {
    if input[idx] == ']' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx)).map_res(str::from_utf8)
    }
  }
  Done("".as_bytes(), input).map_res(str::from_utf8)
}
o!(category<&[u8], &str> lsb ~ category_name ~ rsb line_ending);

tag!(equal "=".as_bytes());
fn not_equal(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == '=' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}

fn value_parser(input:&[u8]) -> IResult<&[u8], &str> {
  for idx in range(0, input.len()) {
    if input[idx] == '\n' as u8 || input[idx] == ';' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx)).map_res(str::from_utf8)
    }
  }
  Done("".as_bytes(), input).map_res(str::from_utf8)
}

fn parameter_parser(input: &[u8]) -> IResult<&[u8], &str> {
  alphanumeric(input).map_res(str::from_utf8)
}

opt!(opt_line_ending<&[u8],&[u8]> line_ending);
o!(value<&[u8],&str> space equal space ~ value_parser ~ space opt_comment opt_line_ending);
chain!(key_value<&[u8],(&str,&str)>, ||{(key, val)},  key: parameter_parser, val: value,);

many0!(keys_and_values<&[u8], (&str, &str) > key_value);

#[test]
fn parse_comment_test() {
  let ini_file = ";comment
[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let ini_without_comment = "[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let res = Done((), ini_file.as_bytes()).flat_map(comment);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_comment.as_bytes(), ()));
}

#[test]
fn parse_category_test() {
  let ini_file = "[category]
parameter=value
key = value2";

  let ini_without_category = "parameter=value
key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(category);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_category.as_bytes(), "category"));
}

#[test]
fn parse_key_value_test() {
  let ini_file = "parameter=value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_key_value_with_space_test() {
  let ini_file = "parameter = value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_key_value_with_comment_test() {
  let ini_file = "parameter=value;abc
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_multiple_keys_and_values_test() {
  let ini_file = "parameter=value;abc
key = value2

[category]";

  let ini_without_key_value = "
[category]";

  let res = Done((), ini_file.as_bytes()).flat_map(keys_and_values);
  println!("{}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), vec![("parameter", "value"), ("key", "value2")]));
}
<|endoftext|>


<commit_before>#![feature(globs,macro_rules,phase)]

#[phase(plugin,link)]
extern crate nom;

use nom::{IResult,Producer,FileProducer,ProducerState,FlatMapper,Mapper,Mapper2,line_ending,not_line_ending, space, alphanumeric, is_alphanumeric, multispace};
use nom::IResult::*;

use std::str;
use std::collections::HashMap;
use std::fmt::Show;

fn empty_result(i:&[u8]) -> IResult<&[u8], ()> { Done(i,()) }
tag!(semicolon ";".as_bytes());
o!(comment_body<&[u8],&[u8]> semicolon ~ not_line_ending ~ );
o!(comment<&[u8], ()> comment_body line_ending ~ empty_result ~);
opt!(opt_comment<&[u8],&[u8]> comment_body);

tag!(lsb "[".as_bytes());
tag!(rsb "]".as_bytes());
fn category_name(input:&[u8]) -> IResult<&[u8], &str> {
  for idx in range(0, input.len()) {
    if input[idx] == ']' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx)).map_res(str::from_utf8)
    }
  }
  Done("".as_bytes(), input).map_res(str::from_utf8)
}
o!(category<&[u8], &str> lsb ~ category_name ~ rsb line_ending);

tag!(equal "=".as_bytes());
fn not_equal(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == '=' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}

fn value_parser(input:&[u8]) -> IResult<&[u8], &str> {
  for idx in range(0, input.len()) {
    if input[idx] == '\n' as u8 || input[idx] == ';' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx)).map_res(str::from_utf8)
    }
  }
  Done("".as_bytes(), input).map_res(str::from_utf8)
}

fn parameter_parser(input: &[u8]) -> IResult<&[u8], &str> {
  alphanumeric(input).map_res(str::from_utf8)
}

opt!(opt_multispace<&[u8],&[u8]> multispace);
o!(value<&[u8],&str> space equal space ~ value_parser ~ space opt_comment opt_multispace);
chain!(key_value<&[u8],(&str,&str)>, ||{(key, val)},  key: parameter_parser, val: value,);

fn keys_and_values<'a>(input: &'a[u8], mut z: HashMap<&'a str, &'a str>) -> IResult<&'a[u8], HashMap<&'a str, &'a str> > {
  fold0_impl!(<&[u8], HashMap<&str, &str> >, |mut h:HashMap<&'a str, &'a str>, (k, v)| {
    h.insert(k,v);
    h
  }, key_value, input, z);
}

fn keys_and_values_wrapper<'a>(input:&'a[u8]) -> IResult<&'a[u8], HashMap<&'a str, &'a str> > {
  let h: HashMap<&str, &str> = HashMap::new();
  let res = keys_and_values(input, h);
  //println!("{}", res);
  res
}

chain!(category_and_keys<&[u8],(&str,HashMap<&str,&str>)>, move |:|{(category, keys)},  category: category, keys: keys_and_values_wrapper,);

#[test]
fn parse_comment_test() {
  let ini_file = ";comment
[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let ini_without_comment = "[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let res = Done((), ini_file.as_bytes()).flat_map(comment);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_comment.as_bytes(), ()));
}

#[test]
fn parse_category_test() {
  let ini_file = "[category]
parameter=value
key = value2";

  let ini_without_category = "parameter=value
key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(category);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_category.as_bytes(), "category"));
}

#[test]
fn parse_key_value_test() {
  let ini_file = "parameter=value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_key_value_with_space_test() {
  let ini_file = "parameter = value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_key_value_with_comment_test() {
  let ini_file = "parameter=value;abc
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_multiple_keys_and_values_test() {
  let ini_file = "parameter=value;abc

key = value2

[category]";

  let ini_without_key_value = "[category]";

  let mut h: HashMap<&str, &str> = HashMap::new();
  let res = keys_and_values(ini_file.as_bytes(), h);
  println!("{}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected: HashMap<&str, &str> = HashMap::new();
  expected.insert("parameter", "value");
  expected.insert("key", "value2");
  assert_eq!(res, Done(ini_without_key_value.as_bytes(), expected));
}

#[test]
fn parse_category_then_multiple_keys_and_values_test() {
  //FIXME: there can be an empty line or a comment line after a category
  let ini_file = "[abcd]
parameter=value;abc

key = value2

[category]";

  let ini_after_parser = "[category]";

  let res = category_and_keys(ini_file.as_bytes());
  println!("{}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected_h: HashMap<&str, &str> = HashMap::new();
  expected_h.insert("parameter", "value");
  expected_h.insert("key", "value2");
  assert_eq!(res, Done(ini_after_parser.as_bytes(), ("abcd", expected_h)));
}
<commit_msg>parse multiple categories<commit_after>#![feature(globs,macro_rules,phase)]

#[phase(plugin,link)]
extern crate nom;

use nom::{IResult,Producer,FileProducer,ProducerState,FlatMapper,Mapper,Mapper2,line_ending,not_line_ending, space, alphanumeric, is_alphanumeric, multispace};
use nom::IResult::*;

use std::str;
use std::collections::HashMap;
use std::fmt::Show;

fn empty_result(i:&[u8]) -> IResult<&[u8], ()> { Done(i,()) }
tag!(semicolon ";".as_bytes());
o!(comment_body<&[u8],&[u8]> semicolon ~ not_line_ending ~ );
o!(comment<&[u8], ()> comment_body line_ending ~ empty_result ~);
opt!(opt_comment<&[u8],&[u8]> comment_body);

tag!(lsb "[".as_bytes());
tag!(rsb "]".as_bytes());
fn category_name(input:&[u8]) -> IResult<&[u8], &str> {
  for idx in range(0, input.len()) {
    if input[idx] == ']' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx)).map_res(str::from_utf8)
    }
  }
  Done("".as_bytes(), input).map_res(str::from_utf8)
}
o!(category<&[u8], &str> lsb ~ category_name ~ rsb line_ending);

tag!(equal "=".as_bytes());
fn not_equal(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == '=' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}

fn value_parser(input:&[u8]) -> IResult<&[u8], &str> {
  for idx in range(0, input.len()) {
    if input[idx] == '\n' as u8 || input[idx] == ';' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx)).map_res(str::from_utf8)
    }
  }
  Done("".as_bytes(), input).map_res(str::from_utf8)
}

fn parameter_parser(input: &[u8]) -> IResult<&[u8], &str> {
  alphanumeric(input).map_res(str::from_utf8)
}

opt!(opt_multispace<&[u8],&[u8]> multispace);
o!(value<&[u8],&str> space equal space ~ value_parser ~ space opt_comment opt_multispace);
chain!(key_value<&[u8],(&str,&str)>, ||{(key, val)},  key: parameter_parser, val: value,);

fn keys_and_values<'a>(input: &'a[u8], mut z: HashMap<&'a str, &'a str>) -> IResult<&'a[u8], HashMap<&'a str, &'a str> > {
  fold0_impl!(<&[u8], HashMap<&str, &str> >, |mut h:HashMap<&'a str, &'a str>, (k, v)| {
    h.insert(k,v);
    h
  }, key_value, input, z);
}

fn keys_and_values_wrapper<'a>(input:&'a[u8]) -> IResult<&'a[u8], HashMap<&'a str, &'a str> > {
  let h: HashMap<&str, &str> = HashMap::new();
  let res = keys_and_values(input, h);
  //println!("{}", res);
  res
}

chain!(category_and_keys<&[u8],(&str,HashMap<&str,&str>)>,move |:|{(category, keys)},  category: category, keys: keys_and_values_wrapper,);

fn categories<'a>(input: &'a[u8]) -> IResult<&'a[u8], HashMap<&'a str, HashMap<&'a str, &'a str> > > {
  let mut z: HashMap<&str, HashMap<&str, &str>> = HashMap::new();
  fold0_impl!(<&[u8], HashMap<&str, HashMap<&str, &str> > >, |mut h:HashMap<&'a str, HashMap<&'a str, &'a str> >, (k, v)| {
    h.insert(k,v);
    h
  }, category_and_keys, input, z);
}

#[test]
fn parse_comment_test() {
  let ini_file = ";comment
[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let ini_without_comment = "[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let res = Done((), ini_file.as_bytes()).flat_map(comment);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_comment.as_bytes(), ()));
}

#[test]
fn parse_category_test() {
  let ini_file = "[category]
parameter=value
key = value2";

  let ini_without_category = "parameter=value
key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(category);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_category.as_bytes(), "category"));
}

#[test]
fn parse_key_value_test() {
  let ini_file = "parameter=value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_key_value_with_space_test() {
  let ini_file = "parameter = value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_key_value_with_comment_test() {
  let ini_file = "parameter=value;abc
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter", "value")));
}

#[test]
fn parse_multiple_keys_and_values_test() {
  let ini_file = "parameter=value;abc

key = value2

[category]";

  let ini_without_key_value = "[category]";

  let mut h: HashMap<&str, &str> = HashMap::new();
  let res = keys_and_values(ini_file.as_bytes(), h);
  println!("{}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected: HashMap<&str, &str> = HashMap::new();
  expected.insert("parameter", "value");
  expected.insert("key", "value2");
  assert_eq!(res, Done(ini_without_key_value.as_bytes(), expected));
}

#[test]
fn parse_category_then_multiple_keys_and_values_test() {
  //FIXME: there can be an empty line or a comment line after a category
  let ini_file = "[abcd]
parameter=value;abc

key = value2

[category]";

  let ini_after_parser = "[category]";

  let res = category_and_keys(ini_file.as_bytes());
  println!("{}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected_h: HashMap<&str, &str> = HashMap::new();
  expected_h.insert("parameter", "value");
  expected_h.insert("key", "value2");
  assert_eq!(res, Done(ini_after_parser.as_bytes(), ("abcd", expected_h)));
}

#[test]
fn parse_multiple_categories_test() {
  let ini_file = "[abcd]
parameter=value;abc

key = value2
[category]
parameter3=value3
key4 = value4
";

  let ini_after_parser = "";

  let res = categories(ini_file.as_bytes());
  println!("{}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected_1: HashMap<&str, &str> = HashMap::new();
  expected_1.insert("parameter", "value");
  expected_1.insert("key", "value2");
  let mut expected_2: HashMap<&str, &str> = HashMap::new();
  expected_2.insert("parameter3", "value3");
  expected_2.insert("key4", "value4");
  let mut expected_h: HashMap<&str, HashMap<&str, &str>> = HashMap::new();
  expected_h.insert("abcd",     expected_1);
  expected_h.insert("category", expected_2);
  assert_eq!(res, Done(ini_after_parser.as_bytes(), expected_h));
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate json;
extern crate requests;

// use requests::Codes;
use requests::{delete, get, head, post, put};
use requests::Request;

#[test]
fn simple_get() {
    const URL: &'static str = "http://httpbin.org/get";
    let res = get(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
    let data = res.json().unwrap();
    println!("{:?}", data);
    assert_eq!(data["url"], URL);
    assert_eq!(data["headers"]["Host"], "httpbin.org");
    assert_eq!(data["headers"]["User-Agent"],
               concat!("requests-rs/", env!("CARGO_PKG_VERSION")));
}

#[test]
fn simple_post() {
    const URL: &'static str = "http://httpbin.org/post";
    let res = post(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
}

#[test]
fn simple_put() {
    const URL: &'static str = "http://httpbin.org/put";
    let res = put(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
}

#[test]
fn simple_head() {
    const URL: &'static str = "http://httpbin.org/get";
    let res = head(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
}

#[test]
fn simple_delete() {
    const URL: &'static str = "http://httpbin.org/delete";
    let res = delete(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
}

#[test]
fn user_agent() {
    let useragent = concat!("{\n  \"user-agent\": \"requests-rs/",
                            env!("CARGO_PKG_VERSION"),
                            "\"\n}\n");
    const URL: &'static str = "http://httpbin.org/user-agent";
    let res = get(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
    assert_eq!(res.text(), Some(useragent));
}

#[test]
fn custom_user_agent() {
    const UA: &'static str = concat!("requests-rs-tests/", env!("CARGO_PKG_VERSION"));
    const URL: &'static str = "http://httpbin.org/user-agent";
    let mut request = Request::new();
    request.user_agent(UA);
    let res = request.get(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
    assert!(res.is_json());

    let ua = res.json().unwrap();
    assert_eq!(ua["user-agent"], UA);
}

#[test]
fn user_agent_json() {

    const URL: &'static str = "http://httpbin.org/user-agent";
    let res = get(URL).unwrap();
    assert!(res.is_json());

    let ua = res.json().unwrap();
    assert_eq!(ua["user-agent"],
               concat!("requests-rs/", env!("CARGO_PKG_VERSION")));
}

#[test]
fn content() {
    const URL: &'static str = "http://httpbin.org/headers";
    let res = get(URL).unwrap();
    let content = vec![123, 10, 32, 32, 34, 104, 101, 97, 100, 101, 114, 115, 34, 58, 32, 123, 10,
                       32, 32, 32, 32, 34, 72, 111, 115, 116, 34, 58, 32, 34, 104, 116, 116, 112,
                       98, 105, 110, 46, 111, 114, 103, 34, 44, 32, 10, 32, 32, 32, 32, 34, 85,
                       115, 101, 114, 45, 65, 103, 101, 110, 116, 34, 58, 32, 34, 114, 101, 113,
                       117, 101, 115, 116, 115, 45, 114, 115, 47, 48, 46, 48, 46, 50, 51, 34, 10,
                       32, 32, 125, 10, 125, 10];
    assert_eq!(res.content(), &content);
}

macro_rules! status_code_test {
    ($($name:ident: $numeric:expr,)+) => {
        $(#[test]
        fn $name() {
            let res = get(&format!("http://httpbin.org/status/{}", $numeric)).unwrap();
            println!("{}", res.text().unwrap());
            assert_eq!(res.status_code(), hyper::status::StatusCode::from_u16($numeric));
        })+
    }
}

status_code_test! {
    status_code_100: 100,
    status_code_101: 101,
    status_code_102: 102,
    status_code_200: 200,
    status_code_201: 201,
    status_code_202: 202,
    status_code_203: 203,
    status_code_400: 400,
    status_code_401: 401,
    status_code_402: 402,
    status_code_403: 403,
    status_code_404: 404,
    status_code_500: 500,
}
<commit_msg>Rework content() test<commit_after>extern crate hyper;
extern crate json;
extern crate requests;

// use requests::Codes;
use requests::{delete, get, head, post, put};
use requests::Request;

#[test]
fn simple_get() {
    const URL: &'static str = "http://httpbin.org/get";
    let res = get(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
    let data = res.json().unwrap();
    println!("{:?}", data);
    assert_eq!(data["url"], URL);
    assert_eq!(data["headers"]["Host"], "httpbin.org");
    assert_eq!(data["headers"]["User-Agent"],
               concat!("requests-rs/", env!("CARGO_PKG_VERSION")));
}

#[test]
fn simple_post() {
    const URL: &'static str = "http://httpbin.org/post";
    let res = post(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
}

#[test]
fn simple_put() {
    const URL: &'static str = "http://httpbin.org/put";
    let res = put(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
}

#[test]
fn simple_head() {
    const URL: &'static str = "http://httpbin.org/get";
    let res = head(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
}

#[test]
fn simple_delete() {
    const URL: &'static str = "http://httpbin.org/delete";
    let res = delete(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
}

#[test]
fn user_agent() {
    let useragent = concat!("{\n  \"user-agent\": \"requests-rs/",
                            env!("CARGO_PKG_VERSION"),
                            "\"\n}\n");
    const URL: &'static str = "http://httpbin.org/user-agent";
    let res = get(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
    assert_eq!(res.text(), Some(useragent));
}

#[test]
fn custom_user_agent() {
    const UA: &'static str = concat!("requests-rs-tests/", env!("CARGO_PKG_VERSION"));
    const URL: &'static str = "http://httpbin.org/user-agent";
    let mut request = Request::new();
    request.user_agent(UA);
    let res = request.get(URL).unwrap();
    assert_eq!(res.url(), URL);
    assert_eq!(res.status_code(), hyper::Ok);
    assert_eq!(res.reason(), "OK");
    assert!(res.is_json());

    let ua = res.json().unwrap();
    assert_eq!(ua["user-agent"], UA);
}

#[test]
fn user_agent_json() {

    const URL: &'static str = "http://httpbin.org/user-agent";
    let res = get(URL).unwrap();
    assert!(res.is_json());

    let ua = res.json().unwrap();
    assert_eq!(ua["user-agent"],
               concat!("requests-rs/", env!("CARGO_PKG_VERSION")));
}

#[test]
fn content() {
    const URL: &'static str = "http://httpbin.org/headers";
    let res = get(URL).unwrap();
    let content = concat!("{\n  \"headers\": {\n    \"Host\": \"httpbin.org\",",
                          " \n    \"User-Agent\": \"requests-rs/",
                          env!("CARGO_PKG_VERSION"),
                          "\"\n  }\n}\n");

    assert_eq!(res.content(), &content.as_bytes());
}

macro_rules! status_code_test {
    ($($name:ident: $numeric:expr,)+) => {
        $(#[test]
        fn $name() {
            let res = get(&format!("http://httpbin.org/status/{}", $numeric)).unwrap();
            println!("{}", res.text().unwrap());
            assert_eq!(res.status_code(), hyper::status::StatusCode::from_u16($numeric));
        })+
    }
}

status_code_test! {
    status_code_100: 100,
    status_code_101: 101,
    status_code_102: 102,
    status_code_200: 200,
    status_code_201: 201,
    status_code_202: 202,
    status_code_203: 203,
    status_code_400: 400,
    status_code_401: 401,
    status_code_402: 402,
    status_code_403: 403,
    status_code_404: 404,
    status_code_500: 500,
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate generator;

use generator::{Generator, FnGenerator};

#[test]
fn generator_is_done() {
    let mut g = generator!({
        _yield_!();
    });

    g.next();
    assert!(!g.is_done());
    g.next();
    assert!(g.is_done());
}

#[test]
fn test_yield() {
    let mut g = FnGenerator::new(|| {
        _yield_!(10);
        20
    });

    // the para type could be deduced here
    let i = g.send(());
    assert!(i == 10);

    let j = g.next();
    assert!(j.unwrap() == 20);
}

#[test]
fn test_scoped() {
    use std::rc::Rc;
    use std::cell::RefCell;
    let x = Rc::new(RefCell::new(10));

    let x1 = x.clone();
    let mut g = FnGenerator::<(), _>::new(move|| {
         *x1.borrow_mut() = 20;
         _yield_!();
         *x1.borrow_mut() = 5;
    });

    g.next();
    assert!(*x.borrow() == 20);

    g.next();
    assert!(*x.borrow() == 5);

    assert!(g.is_done());
}

#[test]
fn test_scoped_1() {
    let mut x = 10;
    {
        let mut g = FnGenerator::<(), _>::new( || {
           x = 5;
        });
        g.next();
    }

    assert!(x == 5);
}

#[test]
fn test_drop() {
    let mut x = 10;
    {
        FnGenerator::<(), _>::new( || {
           x = 1;
           _yield_!();
           x = 5;
        });
    }

    assert!(x == 5);
}

<commit_msg>add test_inner_ref<commit_after>#[macro_use]
extern crate generator;

use generator::*;

#[test]
fn generator_is_done() {
    let mut g = generator!({
        _yield_!();
    });

    g.next();
    assert!(!g.is_done());
    g.next();
    assert!(g.is_done());
}

#[test]
fn test_yield() {
    let mut g = FnGenerator::new(|| {
        _yield_!(10);
        20
    });

    // the para type could be deduced here
    let i = g.send(());
    assert!(i == 10);

    let j = g.next();
    assert!(j.unwrap() == 20);
}

#[test]
fn test_scoped() {
    use std::rc::Rc;
    use std::cell::RefCell;
    let x = Rc::new(RefCell::new(10));

    let x1 = x.clone();
    let mut g = FnGenerator::<(), _>::new(move|| {
         *x1.borrow_mut() = 20;
         _yield_!();
         *x1.borrow_mut() = 5;
    });

    g.next();
    assert!(*x.borrow() == 20);

    g.next();
    assert!(*x.borrow() == 5);

    assert!(g.is_done());
}

#[test]
fn test_scoped_1() {
    let mut x = 10;
    {
        let mut g = FnGenerator::<(), _>::new( || {
           x = 5;
        });
        g.next();
    }

    assert!(x == 5);
}

#[test]
fn test_inner_ref(){
    use std::mem;
    let mut g = FnGenerator::<(), &mut u32>::new(||{
        // setup something
        let mut x:u32 = 10;

        // the x memory remains on heap even returned!
        // the life time of x is assosiated with the generator
        // however modify this interal value is really unsafe
        // but this is useful pattern for setup and teardown
        // which can be put in the same place
        {
            // mut borrow block
            let y: &mut u32 = unsafe { mem::transmute(&mut x) };
            _yield_!(y);
        }
        // this was modified by the invoker
        assert!(x == 5);
        // teardown happened when the generator get dropped
        unsafe { mem::transmute(&mut x) }
    });

    // use the resource setup from generator
    let a = g.next().unwrap();
    assert!(*a == 10);
    *a = 5;
    // a keeps valid until the generator dropped
}

#[test]
fn test_drop() {
    let mut x = 10;
    {
        FnGenerator::<(), _>::new( || {
           x = 1;
           _yield_!();
           x = 5;
        });
    }

    assert!(x == 5);
}

<|endoftext|>


<commit_before>#![feature(iter_order)]
extern crate simple_parallel;
extern crate crossbeam;

use std::sync::Mutex;

// with this many elements, its (hopefully) likely that the
// threads won't execute sequentially.
const N: usize = 1000;
const M: usize = 100;

#[test]
fn unordered_map_probabilistic_out_of_ordering() {
    crossbeam::scope(|scope| {
        let iter = simple_parallel::unordered_map(scope, 0..N, |_| {});

        // see if there are any elements where the order they come out of
        // the original iterator is different to the order in which they
        // are yielded here.
        assert!(iter.enumerate().any(|(yield_order, (true_order, ()))| yield_order != true_order));
    });
}

#[test]
fn map_in_order() {
    crossbeam::scope(|scope| {
        let iter = simple_parallel::map(scope, 0..N, |i| i);

        assert!(iter.enumerate().all(|(yield_order, true_order)| yield_order == true_order));
    });
}

#[test]
fn unordered_map_delays() {
    let finished = Mutex::new(0);
    crossbeam::scope(|scope| {
        let iter = simple_parallel::unordered_map(scope, 0..M, |_| {
            *finished.lock().unwrap() += 1;
        });
        ::std::mem::forget(iter);
    });

    assert_eq!(*finished.lock().unwrap(), M);
}

#[test]
fn map_delays() {
    let finished = Mutex::new(0);
    crossbeam::scope(|scope| {
        let iter = simple_parallel::map(scope, 0..M, |_| {
            *finished.lock().unwrap() += 1;
        });
        ::std::mem::forget(iter);
    });

    assert_eq!(*finished.lock().unwrap(), M);
}

#[test]
fn pool_unordered() {
    crossbeam::scope(|scope| {
        let mut pool = simple_parallel::Pool::new(8);

        let iter = pool.unordered_map(scope, 0..N, |_| {});

        // see if there are any elements where the order they come out of
        // the original iterator is different to the order in which they
        // are yielded here.
        let v: Vec<_> = iter.enumerate().collect();
        assert_eq!(v.len(), N);
        assert!(v.into_iter().any(|(yield_order, (true_order, ()))| yield_order != true_order));
    });
}

#[test]
fn pool_map_in_order() {
    crossbeam::scope(|scope| {
        let mut pool = simple_parallel::Pool::new(8);

        let iter = pool.map(scope, 0..N, |i| i);

        assert!(iter.eq(0..N));
    });
}

#[test]
fn pool_unordered_map_delays() {
    let mut pool = simple_parallel::Pool::new(8);
    let finished = Mutex::new(0);
    crossbeam::scope(|scope| {
        let iter = pool.unordered_map(scope, 0..M, |_| {
            *finished.lock().unwrap() += 1;
        });
        ::std::mem::forget(iter);
    });

    assert_eq!(*finished.lock().unwrap(), M);
}

#[test]
fn pool_map_delays() {
    let mut pool = simple_parallel::Pool::new(8);
    let finished = Mutex::new(0);
    crossbeam::scope(|scope| {
        let iter = pool.map(scope, 0..M, |_| {
            *finished.lock().unwrap() += 1;
        });
        ::std::mem::forget(iter);
    });

    assert_eq!(*finished.lock().unwrap(), M);
}
<commit_msg>Make tests run on stable too.<commit_after>extern crate simple_parallel;
extern crate crossbeam;

use std::sync::Mutex;

fn eq<I, J>(mut x: I, mut y: J) -> bool
    where I: Iterator, J: Iterator<Item = I::Item>, I::Item: PartialEq
{
    loop {
        match (x.next(), y.next()) {
            (None, None) => return true,
            (Some(ref x), Some(ref y)) if x == y => continue,
            _ => return false
        }
    }
}

// with this many elements, its (hopefully) likely that the
// threads won't execute sequentially.
const N: usize = 1000;
const M: usize = 100;

#[test]
fn unordered_map_probabilistic_out_of_ordering() {
    crossbeam::scope(|scope| {
        let iter = simple_parallel::unordered_map(scope, 0..N, |_| {});

        // see if there are any elements where the order they come out of
        // the original iterator is different to the order in which they
        // are yielded here.
        assert!(!eq(iter.map(|t| t.0), 0..N));
    });
}

#[test]
fn map_in_order() {
    crossbeam::scope(|scope| {
        let iter = simple_parallel::map(scope, 0..N, |i| i);

        assert!(eq(iter, 0..N));
    });
}

#[test]
fn unordered_map_delays() {
    let finished = Mutex::new(0);
    crossbeam::scope(|scope| {
        let iter = simple_parallel::unordered_map(scope, 0..M, |_| {
            *finished.lock().unwrap() += 1;
        });
        ::std::mem::forget(iter);
    });

    assert_eq!(*finished.lock().unwrap(), M);
}

#[test]
fn map_delays() {
    let finished = Mutex::new(0);
    crossbeam::scope(|scope| {
        let iter = simple_parallel::map(scope, 0..M, |_| {
            *finished.lock().unwrap() += 1;
        });
        ::std::mem::forget(iter);
    });

    assert_eq!(*finished.lock().unwrap(), M);
}

#[test]
fn pool_unordered() {
    crossbeam::scope(|scope| {
        let mut pool = simple_parallel::Pool::new(8);

        let iter = pool.unordered_map(scope, 0..N, |_| {});

        // see if there are any elements where the order they come out of
        // the original iterator is different to the order in which they
        // are yielded here.
        assert!(!eq(iter.map(|t| t.0), 0..N));
    });
}

#[test]
fn pool_map_in_order() {
    crossbeam::scope(|scope| {
        let mut pool = simple_parallel::Pool::new(8);

        let iter = pool.map(scope, 0..N, |i| i);

        assert!(eq(iter, 0..N));
    });
}

#[test]
fn pool_unordered_map_delays() {
    let mut pool = simple_parallel::Pool::new(8);
    let finished = Mutex::new(0);
    crossbeam::scope(|scope| {
        let iter = pool.unordered_map(scope, 0..M, |_| {
            *finished.lock().unwrap() += 1;
        });
        ::std::mem::forget(iter);
    });

    assert_eq!(*finished.lock().unwrap(), M);
}

#[test]
fn pool_map_delays() {
    let mut pool = simple_parallel::Pool::new(8);
    let finished = Mutex::new(0);
    crossbeam::scope(|scope| {
        let iter = pool.map(scope, 0..M, |_| {
            *finished.lock().unwrap() += 1;
        });
        ::std::mem::forget(iter);
    });

    assert_eq!(*finished.lock().unwrap(), M);
}
<|endoftext|>


<commit_before>#[macro_use]
mod common;

use common::util::*;

static UTIL_NAME: &'static str = "sum";

#[test]
fn test_bsd_single_file() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let result = ucmd.arg("lorem_ipsum.txt").run();

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("bsd_single_file.expected"));
}

#[test]
fn test_bsd_multiple_files() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let result = ucmd.arg("lorem_ipsum.txt")
                     .arg("alice_in_wonderland.txt")
                     .run();

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("bsd_multiple_files.expected"));
}

#[test]
fn test_bsd_stdin() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let input = at.read("lorem_ipsum.txt");
    let result = ucmd.run_piped_stdin(input);

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("bsd_stdin.expected"));
}

#[test]
fn test_sysv_single_file() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let result = ucmd.arg("-s").arg("lorem_ipsum.txt").run();

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("sysv_single_file.expected"));
}

#[test]
fn test_sysv_multiple_files() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let result = ucmd.arg("-s")
                     .arg("lorem_ipsum.txt")
                     .arg("alice_in_wonderland.txt")
                     .run();

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("sysv_multiple_files.expected"));
}

#[test]
fn test_sysv_stdin() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let input = at.read("lorem_ipsum.txt");
    let result = ucmd.run_piped_stdin(input);

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("sysv_stdin.expected"));
}
<commit_msg>sum: fix sysv_stdin testcase<commit_after>#[macro_use]
mod common;

use common::util::*;

static UTIL_NAME: &'static str = "sum";

#[test]
fn test_bsd_single_file() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let result = ucmd.arg("lorem_ipsum.txt").run();

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("bsd_single_file.expected"));
}

#[test]
fn test_bsd_multiple_files() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let result = ucmd.arg("lorem_ipsum.txt")
                     .arg("alice_in_wonderland.txt")
                     .run();

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("bsd_multiple_files.expected"));
}

#[test]
fn test_bsd_stdin() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let input = at.read("lorem_ipsum.txt");
    let result = ucmd.run_piped_stdin(input);

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("bsd_stdin.expected"));
}

#[test]
fn test_sysv_single_file() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let result = ucmd.arg("-s").arg("lorem_ipsum.txt").run();

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("sysv_single_file.expected"));
}

#[test]
fn test_sysv_multiple_files() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let result = ucmd.arg("-s")
                     .arg("lorem_ipsum.txt")
                     .arg("alice_in_wonderland.txt")
                     .run();

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("sysv_multiple_files.expected"));
}

#[test]
fn test_sysv_stdin() {
    let (at, mut ucmd) = testing(UTIL_NAME);
    let input = at.read("lorem_ipsum.txt");
    let result = ucmd.arg("-s").run_piped_stdin(input);

    assert_empty_stderr!(result);
    assert!(result.success);
    assert_eq!(result.stdout, at.read("sysv_stdin.expected"));
}
<|endoftext|>


<commit_before>extern crate bytes;
#[cfg(any(target_os = "android", target_os = "linux"))]
extern crate caps;
#[macro_use]
extern crate cfg_if;
#[macro_use]
extern crate nix;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate rand;
#[cfg(target_os = "freebsd")]
extern crate sysctl;
extern crate tempfile;
extern crate semver;

cfg_if! {
    if #[cfg(any(target_os = "android", target_os = "linux"))] {
        macro_rules! require_capability {
            ($capname:ident) => {
                use ::caps::{Capability, CapSet, has_cap};
                use ::std::io::{self, Write};

                if !has_cap(None, CapSet::Effective, Capability::$capname)
                    .unwrap()
                {
                    let stderr = io::stderr();
                    let mut handle = stderr.lock();
                    writeln!(handle,
                        "Insufficient capabilities. Skipping test.")
                        .unwrap();
                    return;
                }
            }
        }
    } else {
        macro_rules! require_capability {
            ($capname:ident) => {}
        }
    }
}

#[cfg(target_os = "freebsd")]
macro_rules! skip_if_jailed {
    ($name:expr) => {
        use ::sysctl::CtlValue;

        if let CtlValue::Int(1) = ::sysctl::value("security.jail.jailed")
            .unwrap()
        {
            use ::std::io::Write;
            let stderr = ::std::io::stderr();
            let mut handle = stderr.lock();
            writeln!(handle, "{} cannot run in a jail. Skipping test.", $name)
                .unwrap();
            return;
        }
    }
}

macro_rules! skip_if_not_root {
    ($name:expr) => {
        use nix::unistd::Uid;

        if !Uid::current().is_root() {
            use ::std::io::Write;
            let stderr = ::std::io::stderr();
            let mut handle = stderr.lock();
            writeln!(handle, "{} requires root privileges. Skipping test.", $name).unwrap();
            return;
        }
    };
}

cfg_if! {
    if #[cfg(any(target_os = "android", target_os = "linux"))] {
        macro_rules! skip_if_seccomp {
            ($name:expr) => {
                if let Ok(s) = std::fs::read_to_string("/proc/self/status") {
                    for l in s.lines() {
                        let mut fields = l.split_whitespace();
                        if fields.next() == Some("Seccomp:") &&
                            fields.next() != Some("0")
                        {
                            use ::std::io::Write;
                            let stderr = ::std::io::stderr();
                            let mut handle = stderr.lock();
                            writeln!(handle,
                                "{} cannot be run in Seccomp mode.  Skipping test.",
                                stringify!($name)).unwrap();
                            return;
                        }
                    }
                }
            }
        }
    } else {
        macro_rules! skip_if_seccomp {
            ($name:expr) => {}
        }
    }
}

cfg_if! {
    if #[cfg(any(target_os = "android", target_os = "linux"))] {
        macro_rules! require_kernel_version {
            ($name:expr, $version_requirement:expr) => {
                use ::std::io::Write;
                use semver::{Version, VersionReq};

                let version_requirement = VersionReq::parse($version_requirement)
                        .expect("Bad match_version provided");

                let uname = nix::sys::utsname::uname();

                let mut version = Version::parse(uname.release()).unwrap();

                //Keep only numeric parts
                version.pre.clear();
                version.build.clear();

                if !version_requirement.matches(&version) {
                    let stderr = ::std::io::stderr();
                    let mut handle = stderr.lock();

                    writeln!(handle,
                        "Skip {} because kernel version `{}` doesn't match the requirement `{}`",
                        stringify!($name), version, version_requirement).unwrap();
                    return;
                }
            }
        }
    } else {
        macro_rules! require_kernel_version {
            ($name:expr) => {}
        }
    }
}

mod sys;
mod test_dir;
mod test_fcntl;
#[cfg(any(target_os = "android",
          target_os = "linux"))]
mod test_kmod;
#[cfg(any(target_os = "dragonfly",
          target_os = "freebsd",
          target_os = "fushsia",
          target_os = "linux",
          target_os = "netbsd"))]
mod test_mq;
mod test_net;
mod test_nix_path;
mod test_poll;
mod test_pty;
#[cfg(any(target_os = "android",
          target_os = "linux"))]
mod test_sched;
#[cfg(any(target_os = "android",
          target_os = "freebsd",
          target_os = "ios",
          target_os = "linux",
          target_os = "macos"))]
mod test_sendfile;
mod test_stat;
mod test_unistd;

use std::os::unix::io::RawFd;
use std::path::PathBuf;
use std::sync::{Mutex, RwLock, RwLockWriteGuard};
use nix::unistd::{chdir, getcwd, read};

/// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s
fn read_exact(f: RawFd, buf: &mut  [u8]) {
    let mut len = 0;
    while len < buf.len() {
        // get_mut would be better than split_at_mut, but it requires nightly
        let (_, remaining) = buf.split_at_mut(len);
        len += read(f, remaining).unwrap();
    }
}

lazy_static! {
    /// Any test that changes the process's current working directory must grab
    /// the RwLock exclusively.  Any process that cares about the current
    /// working directory must grab it shared.
    pub static ref CWD_LOCK: RwLock<()> = RwLock::new(());
    /// Any test that creates child processes must grab this mutex, regardless
    /// of what it does with those children.
    pub static ref FORK_MTX: Mutex<()> = Mutex::new(());
    /// Any test that changes the process's supplementary groups must grab this
    /// mutex
    pub static ref GROUPS_MTX: Mutex<()> = Mutex::new(());
    /// Any tests that loads or unloads kernel modules must grab this mutex
    pub static ref KMOD_MTX: Mutex<()> = Mutex::new(());
    /// Any test that calls ptsname(3) must grab this mutex.
    pub static ref PTSNAME_MTX: Mutex<()> = Mutex::new(());
    /// Any test that alters signal handling must grab this mutex.
    pub static ref SIGNAL_MTX: Mutex<()> = Mutex::new(());
}

/// RAII object that restores a test's original directory on drop
struct DirRestore<'a> {
    d: PathBuf,
    _g: RwLockWriteGuard<'a, ()>
}

impl<'a> DirRestore<'a> {
    fn new() -> Self {
        let guard = ::CWD_LOCK.write()
            .expect("Lock got poisoned by another test");
        DirRestore{
            _g: guard,
            d: getcwd().unwrap(),
        }
    }
}

impl<'a> Drop for DirRestore<'a> {
    fn drop(&mut self) {
        let r = chdir(&self.d);
        if std::thread::panicking() {
            r.unwrap();
        }
    }
}
<commit_msg>Fix an "unused macro" warning on non-Linux platforms<commit_after>extern crate bytes;
#[cfg(any(target_os = "android", target_os = "linux"))]
extern crate caps;
#[macro_use]
extern crate cfg_if;
#[macro_use]
extern crate nix;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate rand;
#[cfg(target_os = "freebsd")]
extern crate sysctl;
extern crate tempfile;
extern crate semver;

cfg_if! {
    if #[cfg(any(target_os = "android", target_os = "linux"))] {
        macro_rules! require_capability {
            ($capname:ident) => {
                use ::caps::{Capability, CapSet, has_cap};
                use ::std::io::{self, Write};

                if !has_cap(None, CapSet::Effective, Capability::$capname)
                    .unwrap()
                {
                    let stderr = io::stderr();
                    let mut handle = stderr.lock();
                    writeln!(handle,
                        "Insufficient capabilities. Skipping test.")
                        .unwrap();
                    return;
                }
            }
        }
    } else {
        macro_rules! require_capability {
            ($capname:ident) => {}
        }
    }
}

#[cfg(target_os = "freebsd")]
macro_rules! skip_if_jailed {
    ($name:expr) => {
        use ::sysctl::CtlValue;

        if let CtlValue::Int(1) = ::sysctl::value("security.jail.jailed")
            .unwrap()
        {
            use ::std::io::Write;
            let stderr = ::std::io::stderr();
            let mut handle = stderr.lock();
            writeln!(handle, "{} cannot run in a jail. Skipping test.", $name)
                .unwrap();
            return;
        }
    }
}

macro_rules! skip_if_not_root {
    ($name:expr) => {
        use nix::unistd::Uid;

        if !Uid::current().is_root() {
            use ::std::io::Write;
            let stderr = ::std::io::stderr();
            let mut handle = stderr.lock();
            writeln!(handle, "{} requires root privileges. Skipping test.", $name).unwrap();
            return;
        }
    };
}

cfg_if! {
    if #[cfg(any(target_os = "android", target_os = "linux"))] {
        macro_rules! skip_if_seccomp {
            ($name:expr) => {
                if let Ok(s) = std::fs::read_to_string("/proc/self/status") {
                    for l in s.lines() {
                        let mut fields = l.split_whitespace();
                        if fields.next() == Some("Seccomp:") &&
                            fields.next() != Some("0")
                        {
                            use ::std::io::Write;
                            let stderr = ::std::io::stderr();
                            let mut handle = stderr.lock();
                            writeln!(handle,
                                "{} cannot be run in Seccomp mode.  Skipping test.",
                                stringify!($name)).unwrap();
                            return;
                        }
                    }
                }
            }
        }
    } else {
        macro_rules! skip_if_seccomp {
            ($name:expr) => {}
        }
    }
}

cfg_if! {
    if #[cfg(target_os = "linux")] {
        macro_rules! require_kernel_version {
            ($name:expr, $version_requirement:expr) => {
                use ::std::io::Write;
                use semver::{Version, VersionReq};

                let version_requirement = VersionReq::parse($version_requirement)
                        .expect("Bad match_version provided");

                let uname = nix::sys::utsname::uname();

                let mut version = Version::parse(uname.release()).unwrap();

                //Keep only numeric parts
                version.pre.clear();
                version.build.clear();

                if !version_requirement.matches(&version) {
                    let stderr = ::std::io::stderr();
                    let mut handle = stderr.lock();

                    writeln!(handle,
                        "Skip {} because kernel version `{}` doesn't match the requirement `{}`",
                        stringify!($name), version, version_requirement).unwrap();
                    return;
                }
            }
        }
    }
}

mod sys;
mod test_dir;
mod test_fcntl;
#[cfg(any(target_os = "android",
          target_os = "linux"))]
mod test_kmod;
#[cfg(any(target_os = "dragonfly",
          target_os = "freebsd",
          target_os = "fushsia",
          target_os = "linux",
          target_os = "netbsd"))]
mod test_mq;
mod test_net;
mod test_nix_path;
mod test_poll;
mod test_pty;
#[cfg(any(target_os = "android",
          target_os = "linux"))]
mod test_sched;
#[cfg(any(target_os = "android",
          target_os = "freebsd",
          target_os = "ios",
          target_os = "linux",
          target_os = "macos"))]
mod test_sendfile;
mod test_stat;
mod test_unistd;

use std::os::unix::io::RawFd;
use std::path::PathBuf;
use std::sync::{Mutex, RwLock, RwLockWriteGuard};
use nix::unistd::{chdir, getcwd, read};

/// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s
fn read_exact(f: RawFd, buf: &mut  [u8]) {
    let mut len = 0;
    while len < buf.len() {
        // get_mut would be better than split_at_mut, but it requires nightly
        let (_, remaining) = buf.split_at_mut(len);
        len += read(f, remaining).unwrap();
    }
}

lazy_static! {
    /// Any test that changes the process's current working directory must grab
    /// the RwLock exclusively.  Any process that cares about the current
    /// working directory must grab it shared.
    pub static ref CWD_LOCK: RwLock<()> = RwLock::new(());
    /// Any test that creates child processes must grab this mutex, regardless
    /// of what it does with those children.
    pub static ref FORK_MTX: Mutex<()> = Mutex::new(());
    /// Any test that changes the process's supplementary groups must grab this
    /// mutex
    pub static ref GROUPS_MTX: Mutex<()> = Mutex::new(());
    /// Any tests that loads or unloads kernel modules must grab this mutex
    pub static ref KMOD_MTX: Mutex<()> = Mutex::new(());
    /// Any test that calls ptsname(3) must grab this mutex.
    pub static ref PTSNAME_MTX: Mutex<()> = Mutex::new(());
    /// Any test that alters signal handling must grab this mutex.
    pub static ref SIGNAL_MTX: Mutex<()> = Mutex::new(());
}

/// RAII object that restores a test's original directory on drop
struct DirRestore<'a> {
    d: PathBuf,
    _g: RwLockWriteGuard<'a, ()>
}

impl<'a> DirRestore<'a> {
    fn new() -> Self {
        let guard = ::CWD_LOCK.write()
            .expect("Lock got poisoned by another test");
        DirRestore{
            _g: guard,
            d: getcwd().unwrap(),
        }
    }
}

impl<'a> Drop for DirRestore<'a> {
    fn drop(&mut self) {
        let r = chdir(&self.d);
        if std::thread::panicking() {
            r.unwrap();
        }
    }
}
<|endoftext|>


<commit_before>#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]

#[miri_run]
fn make_vec() -> Vec<i32> {
    let v = Vec::with_capacity(4);
    v.push(1);
    v.push(2);
    v
}

// #[miri_run]
// fn make_vec_macro() -> Vec<i32> {
//     vec![1, 2]
// }
<commit_msg>Fix vec test compile error.<commit_after>#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]

#[miri_run]
fn make_vec() -> Vec<i32> {
    let mut v = Vec::with_capacity(4);
    v.push(1);
    v.push(2);
    v
}

// #[miri_run]
// fn make_vec_macro() -> Vec<i32> {
//     vec![1, 2]
// }
<|endoftext|>


<commit_before>use assert_cmd::prelude::*;
use copy_dir::copy_dir;
use predicates::prelude::*;
use predicates::str::similar;
use std::error::Error;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use std::process::Command;
use tempfile::{tempdir, TempDir};

// helpers

pub struct TempRepo {
    dir: TempDir,
}

impl TempRepo {
    pub fn new() -> io::Result<TempRepo> {
        let dir = tempdir()?;
        copy_dir("tests/repo", dir.path().join("repo"))?;
        Ok(TempRepo { dir })
    }

    pub fn path(&self) -> PathBuf {
        self.dir.path().join("repo")
    }

    pub fn path_string(&self) -> String {
        self.path().to_string_lossy().to_string()
    }
}

fn run_test<T>(test_fn: T) -> Result<(), Box<Error>>
where
    T: FnOnce(&mut Command, &Path, &TempRepo) -> Result<(), Box<Error>>,
{
    let empty_dir = tempdir()?;
    let repo = TempRepo::new()?;
    let mut cmd = Command::cargo_bin("sala")?;
    cmd.env("HOME", empty_dir.path());
    test_fn(&mut cmd, &empty_dir.path(), &repo)
}

const DIRECTORY: &str = "foo";
const EXISTING_SECRET: &str = "foo/@bar";
const NON_EXISTING_SECRET: &str = "foo/@new";
const INVALID_SECRET_PATH_DEEP: &str = "foo/@bar/@baz";
const NON_EXISTING_SECRET_DEEP: &str = "foo/bar/baz/@new";

// get

#[test]
fn get_no_repo() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        fs::write(dir.join("foo"), "".as_bytes())?;

        cmd.current_dir(&dir)
            .args(&["get", "foo"])
            .assert()
            .failure()
            .stderr(similar("No repository. Run `sala init' first\n"));

        Ok(())
    })
}

#[test]
fn get_wrong_passphrase() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["get", EXISTING_SECRET])
            .with_stdin()
            .buffer("this is wrong\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(
                "\
Enter the master passphrase:
Error: Unable to unlock the encryption key
",
            ));

        Ok(())
    })
}

#[test]
fn get_not_found() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["get", NON_EXISTING_SECRET])
            .assert()
            .failure()
            .stderr(similar(format!(
                "\
Error: File does not exist or invalid: {}
",
                NON_EXISTING_SECRET
            )));

        Ok(())
    })
}

#[test]
fn get_directory() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["get", DIRECTORY])
            .assert()
            .failure()
            .stderr(similar(format!(
                "\
Error: File does not exist or invalid: {}
",
                DIRECTORY
            )));

        Ok(())
    })
}

#[test]
fn get_success() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar(
                "
foo/@bar: baz

",
            ));

        Ok(())
    })
}

#[test]
fn get_raw() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["-r", "get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar("baz\n"));

        Ok(())
    })
}

#[test]
fn implicit_get() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .arg(EXISTING_SECRET)
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar(
                "
foo/@bar: baz

",
            ));

        Ok(())
    })
}

#[test]
fn get_in_dir_does_not_exist() -> Result<(), Box<Error>> {
    run_test(|cmd, tmpdir, _| {
        let dir = tmpdir.join("foo");
        cmd.args(&["-C", &dir.to_string_lossy(), "get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(format!(
                "\
Error: File does not exist or invalid: {}
",
                EXISTING_SECRET
            )));

        Ok(())
    })
}

#[test]
fn get_in_dir_success() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.args(&["-C", &repo.path_string(), "get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar(
                "
foo/@bar: baz

",
            ));

        Ok(())
    })
}

#[test]
fn get_saladir_env() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.env("SALADIR", repo.path_string())
            .args(&["get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar(
                "
foo/@bar: baz

",
            ));

        Ok(())
    })
}

// set

#[test]
fn set_no_repo() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        cmd.current_dir(&dir)
            .args(&["set", "foobar"])
            .assert()
            .failure()
            .stderr(similar("No repository. Run `sala init' first").trim());

        Ok(())
    })
}

#[test]
fn set_wrong_passphrase() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", NON_EXISTING_SECRET])
            .with_stdin()
            .buffer("this is wrong\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(
                "\
Enter the master passphrase:
Error: Unable to unlock the encryption key
",
            ));

        Ok(())
    })
}

#[test]
fn set_target_is_directory() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", DIRECTORY])
            .assert()
            .failure()
            .stderr(similar(
                "\
Error: Target is a directory: foo
",
            ));

        Ok(())
    })
}

#[test]
fn set_secrets_dont_match() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", NON_EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\nfoo\nother\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(
                "\
Enter the master passphrase: Type a new secret for foo/@new: Confirm:
Inputs did not match.
",
            ));

        assert_eq!(repo.path().join(NON_EXISTING_SECRET).exists(), false);
        Ok(())
    })
}

#[test]
fn set_new_success() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", NON_EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\nfoo\nfoo\n")
            .output()?
            .assert()
            .success()
            .stderr(similar(
                "Enter the master passphrase: Type a new secret for foo/@new: Confirm: ",
            ));

        let secret_path = repo.path().join(NON_EXISTING_SECRET);
        assert_eq!(secret_path.is_file(), true);
        assert_eq!(secret_path.metadata()?.len() > 0, true);
        Ok(())
    })
}

#[test]
fn set_new_cannot_create_parent_dirs() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", INVALID_SECRET_PATH_DEEP])
            .with_stdin()
            .buffer("qwerty\nfoo\nfoo\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar("Error: Cannot create directory: foo/@bar\n"));

        Ok(())
    })
}

#[test]
fn set_new_creates_parent_dirs() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", NON_EXISTING_SECRET_DEEP])
            .with_stdin()
            .buffer("qwerty\nfoo\nfoo\n")
            .output()?
            .assert()
            .success()
            .stderr(similar(
                "Enter the master passphrase: Type a new secret for foo/bar/baz/@new: Confirm: ",
            ));

        let secret_path = repo.path().join(NON_EXISTING_SECRET_DEEP);
        assert_eq!(secret_path.is_file(), true);
        assert_eq!(secret_path.metadata()?.len() > 0, true);
        Ok(())
    })
}

#[test]
fn set_replace_existing_success() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\nquux\nquux\n")
            .output()?
            .assert()
            .success()
            .stderr(similar(
                "Enter the master passphrase: Type a new secret for foo/@bar: Confirm: ",
            ));

        let secret_path = repo.path().join(EXISTING_SECRET);
        assert_eq!(secret_path.is_file(), true);
        assert_eq!(secret_path.metadata()?.len() > 0, true);
        Ok(())
    })
}

#[test]
fn implicit_set() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .arg(NON_EXISTING_SECRET)
            .with_stdin()
            .buffer("qwerty\nfoo\nfoo\n")
            .output()?
            .assert()
            .success()
            .stderr(similar(
                "Enter the master passphrase: Type a new secret for foo/@new: Confirm: ",
            ));

        let secret_path = repo.path().join(NON_EXISTING_SECRET);
        assert_eq!(secret_path.is_file(), true);
        assert_eq!(secret_path.metadata()?.len() > 0, true);
        Ok(())
    })
}

// init

#[test]
fn init_already_initialized() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .arg("init")
            .output()?
            .assert()
            .failure()
            .stderr(similar("Error: The master key already exists\n"));

        Ok(())
    })
}

#[test]
fn init_passphrases_dont_match() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        cmd.current_dir(dir)
            .arg("init")
            .with_stdin()
            .buffer("foobar\nquux\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(
                "\
Enter a master passphrase: Confirm:
Inputs did not match.
",
            ));

        assert_eq!(dir.join(".sala/key").exists(), false);
        Ok(())
    })
}

#[test]
fn init_success() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        cmd.current_dir(dir)
            .arg("init")
            .with_stdin()
            .buffer("foobar\nfoobar\n")
            .output()?
            .assert()
            .success()
            .stdout(similar(
                "\
Please pick a master passphrase. It is used to encrypt a very long
random key, which in turn is used to encrypt all the private data in
this directory.

Make sure you remember the master passphrase and that it's strong
enough for your privacy needs.

Generating a master key (512 bits)... done
",
            ))
            .stderr(similar("Enter a master passphrase: Confirm: "));

        assert_eq!(dir.join(".sala/key").metadata()?.len() > 0, true);
        Ok(())
    })
}

// misc

#[test]
fn no_args() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        cmd.current_dir(dir)
            .assert()
            .failure()
            .stderr(similar("Try `sala --help'\n"));

        Ok(())
    })
}
<commit_msg>Add a test for password suggestions (Rust)<commit_after>use assert_cmd::prelude::*;
use copy_dir::copy_dir;
use predicates::prelude::*;
use predicates::str::similar;
use std::error::Error;
use std::fs;
use std::io;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
use tempfile::{tempdir, TempDir};

// helpers

pub struct TempRepo {
    dir: TempDir,
}

impl TempRepo {
    pub fn new() -> io::Result<TempRepo> {
        let dir = tempdir()?;
        copy_dir("tests/repo", dir.path().join("repo"))?;
        Ok(TempRepo { dir })
    }

    pub fn path(&self) -> PathBuf {
        self.dir.path().join("repo")
    }

    pub fn path_string(&self) -> String {
        self.path().to_string_lossy().to_string()
    }
}

fn run_test<T>(test_fn: T) -> Result<(), Box<Error>>
where
    T: FnOnce(&mut Command, &Path, &TempRepo) -> Result<(), Box<Error>>,
{
    let empty_dir = tempdir()?;
    let repo = TempRepo::new()?;
    let mut cmd = Command::cargo_bin("sala")?;
    cmd.env("HOME", empty_dir.path());
    test_fn(&mut cmd, &empty_dir.path(), &repo)
}

const DIRECTORY: &str = "foo";
const EXISTING_SECRET: &str = "foo/@bar";
const NON_EXISTING_SECRET: &str = "foo/@new";
const INVALID_SECRET_PATH_DEEP: &str = "foo/@bar/@baz";
const NON_EXISTING_SECRET_DEEP: &str = "foo/bar/baz/@new";

// get

#[test]
fn get_no_repo() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        fs::write(dir.join("foo"), "".as_bytes())?;

        cmd.current_dir(&dir)
            .args(&["get", "foo"])
            .assert()
            .failure()
            .stderr(similar("No repository. Run `sala init' first\n"));

        Ok(())
    })
}

#[test]
fn get_wrong_passphrase() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["get", EXISTING_SECRET])
            .with_stdin()
            .buffer("this is wrong\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(
                "\
Enter the master passphrase:
Error: Unable to unlock the encryption key
",
            ));

        Ok(())
    })
}

#[test]
fn get_not_found() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["get", NON_EXISTING_SECRET])
            .assert()
            .failure()
            .stderr(similar(format!(
                "\
Error: File does not exist or invalid: {}
",
                NON_EXISTING_SECRET
            )));

        Ok(())
    })
}

#[test]
fn get_directory() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["get", DIRECTORY])
            .assert()
            .failure()
            .stderr(similar(format!(
                "\
Error: File does not exist or invalid: {}
",
                DIRECTORY
            )));

        Ok(())
    })
}

#[test]
fn get_success() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar(
                "
foo/@bar: baz

",
            ));

        Ok(())
    })
}

#[test]
fn get_raw() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["-r", "get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar("baz\n"));

        Ok(())
    })
}

#[test]
fn implicit_get() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .arg(EXISTING_SECRET)
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar(
                "
foo/@bar: baz

",
            ));

        Ok(())
    })
}

#[test]
fn get_in_dir_does_not_exist() -> Result<(), Box<Error>> {
    run_test(|cmd, tmpdir, _| {
        let dir = tmpdir.join("foo");
        cmd.args(&["-C", &dir.to_string_lossy(), "get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(format!(
                "\
Error: File does not exist or invalid: {}
",
                EXISTING_SECRET
            )));

        Ok(())
    })
}

#[test]
fn get_in_dir_success() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.args(&["-C", &repo.path_string(), "get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar(
                "
foo/@bar: baz

",
            ));

        Ok(())
    })
}

#[test]
fn get_saladir_env() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.env("SALADIR", repo.path_string())
            .args(&["get", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\n")
            .output()?
            .assert()
            .success()
            .stderr(similar("Enter the master passphrase: "))
            .stdout(similar(
                "
foo/@bar: baz

",
            ));

        Ok(())
    })
}

// set

#[test]
fn set_no_repo() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        cmd.current_dir(&dir)
            .args(&["set", "foobar"])
            .assert()
            .failure()
            .stderr(similar("No repository. Run `sala init' first").trim());

        Ok(())
    })
}

#[test]
fn set_wrong_passphrase() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", NON_EXISTING_SECRET])
            .with_stdin()
            .buffer("this is wrong\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(
                "\
Enter the master passphrase:
Error: Unable to unlock the encryption key
",
            ));

        Ok(())
    })
}

#[test]
fn set_target_is_directory() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", DIRECTORY])
            .assert()
            .failure()
            .stderr(similar(
                "\
Error: Target is a directory: foo
",
            ));

        Ok(())
    })
}

#[test]
fn set_secrets_dont_match() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", NON_EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\nfoo\nother\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(
                "\
Enter the master passphrase: Type a new secret for foo/@new: Confirm:
Inputs did not match.
",
            ));

        assert_eq!(repo.path().join(NON_EXISTING_SECRET).exists(), false);
        Ok(())
    })
}

#[test]
fn set_new_success() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", NON_EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\nfoo\nfoo\n")
            .output()?
            .assert()
            .success()
            .stderr(similar(
                "Enter the master passphrase: Type a new secret for foo/@new: Confirm: ",
            ));

        let secret_path = repo.path().join(NON_EXISTING_SECRET);
        assert_eq!(secret_path.is_file(), true);
        assert_eq!(secret_path.metadata()?.len() > 0, true);
        Ok(())
    })
}

#[test]
fn set_new_cannot_create_parent_dirs() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", INVALID_SECRET_PATH_DEEP])
            .with_stdin()
            .buffer("qwerty\nfoo\nfoo\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar("Error: Cannot create directory: foo/@bar\n"));

        Ok(())
    })
}

#[test]
fn set_new_creates_parent_dirs() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", NON_EXISTING_SECRET_DEEP])
            .with_stdin()
            .buffer("qwerty\nfoo\nfoo\n")
            .output()?
            .assert()
            .success()
            .stderr(similar(
                "Enter the master passphrase: Type a new secret for foo/bar/baz/@new: Confirm: ",
            ));

        let secret_path = repo.path().join(NON_EXISTING_SECRET_DEEP);
        assert_eq!(secret_path.is_file(), true);
        assert_eq!(secret_path.metadata()?.len() > 0, true);
        Ok(())
    })
}

#[test]
fn set_replace_existing_success() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .args(&["set", EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\nquux\nquux\n")
            .output()?
            .assert()
            .success()
            .stderr(similar(
                "Enter the master passphrase: Type a new secret for foo/@bar: Confirm: ",
            ));

        let secret_path = repo.path().join(EXISTING_SECRET);
        assert_eq!(secret_path.is_file(), true);
        assert_eq!(secret_path.metadata()?.len() > 0, true);
        Ok(())
    })
}

#[test]
fn set_suggestions() -> Result<(), Box<Error>> {
    run_test(|cmd, home, repo| {
        write!(
            fs::File::create(home.join(".sala.toml"))?,
            "password-generator = \"sh -c 'echo foo; echo bar; echo baz'\"",
        )?;
        cmd.current_dir(repo.path())
            .args(&["set", NON_EXISTING_SECRET])
            .with_stdin()
            .buffer("qwerty\nquux\nquux\n")
            .output()?
            .assert()
            .success()
            .stdout(similar("
0. foo
1. bar
2. baz

"))
            .stderr(similar(
                "Enter the master passphrase: Select a number from the list or type a new secret for foo/@new: Confirm: ",
            ));

        let secret_path = repo.path().join(EXISTING_SECRET);
        assert_eq!(secret_path.is_file(), true);
        assert_eq!(secret_path.metadata()?.len() > 0, true);
        Ok(())
    })
}

#[test]
fn implicit_set() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .arg(NON_EXISTING_SECRET)
            .with_stdin()
            .buffer("qwerty\nfoo\nfoo\n")
            .output()?
            .assert()
            .success()
            .stderr(similar(
                "Enter the master passphrase: Type a new secret for foo/@new: Confirm: ",
            ));

        let secret_path = repo.path().join(NON_EXISTING_SECRET);
        assert_eq!(secret_path.is_file(), true);
        assert_eq!(secret_path.metadata()?.len() > 0, true);
        Ok(())
    })
}

// init

#[test]
fn init_already_initialized() -> Result<(), Box<Error>> {
    run_test(|cmd, _, repo| {
        cmd.current_dir(repo.path())
            .arg("init")
            .output()?
            .assert()
            .failure()
            .stderr(similar("Error: The master key already exists\n"));

        Ok(())
    })
}

#[test]
fn init_passphrases_dont_match() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        cmd.current_dir(dir)
            .arg("init")
            .with_stdin()
            .buffer("foobar\nquux\n")
            .output()?
            .assert()
            .failure()
            .stderr(similar(
                "\
Enter a master passphrase: Confirm:
Inputs did not match.
",
            ));

        assert_eq!(dir.join(".sala/key").exists(), false);
        Ok(())
    })
}

#[test]
fn init_success() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        cmd.current_dir(dir)
            .arg("init")
            .with_stdin()
            .buffer("foobar\nfoobar\n")
            .output()?
            .assert()
            .success()
            .stdout(similar(
                "\
Please pick a master passphrase. It is used to encrypt a very long
random key, which in turn is used to encrypt all the private data in
this directory.

Make sure you remember the master passphrase and that it's strong
enough for your privacy needs.

Generating a master key (512 bits)... done
",
            ))
            .stderr(similar("Enter a master passphrase: Confirm: "));

        assert_eq!(dir.join(".sala/key").metadata()?.len() > 0, true);
        Ok(())
    })
}

// misc

#[test]
fn no_args() -> Result<(), Box<Error>> {
    run_test(|cmd, dir, _| {
        cmd.current_dir(dir)
            .assert()
            .failure()
            .stderr(similar("Try `sala --help'\n"));

        Ok(())
    })
}
<|endoftext|>


<commit_before>#![feature(io)]

extern crate compiler;

use compiler::ir;
use std::error::Error;
use std::io::Read;

fn main() {
    let mut args = std::env::args().skip(1);

    let filename = match args.next() {
        Some(f) => f,
        None => abort("expected a filename to assemble"),
    };

    let module = parse_module(&filename);

    print_module(&module);
}

fn open_file(path: &str) -> std::fs::File {
    match std::fs::File::open(path) {
        Ok(f) => f,
        Err(e) => abort(format!("could not open {}: {}",
                                path, e.description())),
    }
}

fn parse_module(file_name: &str) -> ir::Module {
    let chars = open_file(file_name).chars().map(|c| c.unwrap());

    match ir::read::textual(chars) {
        Ok(module) => module,
        Err(e) => abort(format!("could not parse IR file: {}", e)),
    }
}

fn print_module(module: &ir::Module) {
    println!("{}", module);
}

fn abort<S>(msg: S) -> !
    where S: Into<String> {
    println!("failed: {}", msg.into());
    std::process::exit(1);
}
<commit_msg>Add --tokenize option to 'asm'<commit_after>#![feature(io)]

extern crate compiler;
extern crate argparse;

use compiler::ir;
use std::error::Error;
use std::io::Read;

use argparse::ArgumentParser;

fn main() {
    let mut files: Vec<String> = Vec::new();
    let mut tokenize = false;

    {
        let mut ap = ArgumentParser::new();
        ap.set_description("Assembles files");

        ap.refer(&mut files)
            .add_argument("files", argparse::List,
                          r#"Files to process"#);
        ap.refer(&mut tokenize)
            .add_option(&["--tokenize"], argparse::StoreTrue,
                        "Only tokenize the input");
        ap.parse_args_or_exit();
    }

    if files.is_empty() {
        abort("expected a filename to assemble");
    }

    for filename in files.iter() {
        if tokenize {
            tokenize_module(&filename)
        } else {
            assemble_module(&filename)
        }
    }
}

fn tokenize_module(file_name: &str) {
    let chars = open_file(file_name).chars().map(|c| c.unwrap());

    let tokenizer = ir::read::Tokenizer::new(chars).preserve_comments();

    for token in tokenizer {
        println!("{:?}", token);
    }
}

fn assemble_module(file_name: &str) {
    let module = parse_module(&file_name);

    print_module(&module);
}

fn open_file(path: &str) -> std::fs::File {
    match std::fs::File::open(path) {
        Ok(f) => f,
        Err(e) => abort(format!("could not open {}: {}",
                                path, e.description())),
    }
}

fn parse_module(file_name: &str) -> ir::Module {
    let chars = open_file(file_name).chars().map(|c| c.unwrap());

    match ir::read::textual(chars) {
        Ok(module) => module,
        Err(e) => abort(format!("could not parse IR file: {}", e)),
    }
}

fn print_module(module: &ir::Module) {
    println!("{}", module);
}

fn abort<S>(msg: S) -> !
    where S: Into<String> {
    println!("failed: {}", msg.into());
    std::process::exit(1);
}
<|endoftext|>