<commit_before>use std::sync::Arc;
use std::error::Error as StdError;

use nickel::{Request, Response, Middleware, Continue, MiddlewareResult};
use postgres::{SslMode};
use r2d2_postgres::{PostgresConnectionManager};
use r2d2::{Pool, HandleError, Config, PooledConnection};
use typemap::Key;
use plugin::{Pluggable, Extensible};

pub struct PostgresMiddleware {
    pub pool: Arc<Pool<PostgresConnectionManager>>
}

impl PostgresMiddleware {
    pub fn new(connect_str: &str,
               ssl_mode: SslMode,
               num_connections: u32,
               error_handler: Box<HandleError<::r2d2_postgres::Error>>)
                    -> Result<PostgresMiddleware, Box<StdError>> {
        let manager = try!(PostgresConnectionManager::new(connect_str, ssl_mode));

        let config = Config::builder()
          .pool_size(num_connections)
          .error_handler(error_handler)
          .build();

        let pool = try!(Pool::new(config, manager));

        Ok(PostgresMiddleware { pool: Arc::new(pool) })
    }
}

impl Key for PostgresMiddleware { type Value = Arc<Pool<PostgresConnectionManager>>; }

impl<D> Middleware<D> for PostgresMiddleware {
    fn invoke<'mw, 'conn>(&self, req: &mut Request<'mw, 'conn, D>, res: Response<'mw, D>) -> MiddlewareResult<'mw, D> {
        req.extensions_mut().insert::<PostgresMiddleware>(self.pool.clone());
        Ok(Continue(res))
    }
}

pub trait PostgresRequestExtensions {
    fn db_conn(&self) -> PooledConnection<PostgresConnectionManager>;
}

impl<'a, 'b> PostgresRequestExtensions for Request<'a, 'b> {
    fn db_conn(&self) -> PooledConnection<PostgresConnectionManager> {
        self.extensions().get::<PostgresMiddleware>().unwrap().get().unwrap()
    }
}
<commit_msg>feat: allow usage with generic Request<commit_after>use std::sync::Arc;
use std::error::Error as StdError;

use nickel::{Request, Response, Middleware, Continue, MiddlewareResult};
use postgres::{SslMode};
use r2d2_postgres::{PostgresConnectionManager};
use r2d2::{Pool, HandleError, Config, PooledConnection};
use typemap::Key;
use plugin::{Pluggable, Extensible};

pub struct PostgresMiddleware {
    pub pool: Arc<Pool<PostgresConnectionManager>>
}

impl PostgresMiddleware {
    pub fn new(connect_str: &str,
               ssl_mode: SslMode,
               num_connections: u32,
               error_handler: Box<HandleError<::r2d2_postgres::Error>>)
                    -> Result<PostgresMiddleware, Box<StdError>> {
        let manager = try!(PostgresConnectionManager::new(connect_str, ssl_mode));

        let config = Config::builder()
          .pool_size(num_connections)
          .error_handler(error_handler)
          .build();

        let pool = try!(Pool::new(config, manager));

        Ok(PostgresMiddleware { pool: Arc::new(pool) })
    }
}

impl Key for PostgresMiddleware { type Value = Arc<Pool<PostgresConnectionManager>>; }

impl<D> Middleware<D> for PostgresMiddleware {
    fn invoke<'mw, 'conn>(&self, req: &mut Request<'mw, 'conn, D>, res: Response<'mw, D>) -> MiddlewareResult<'mw, D> {
        req.extensions_mut().insert::<PostgresMiddleware>(self.pool.clone());
        Ok(Continue(res))
    }
}

pub trait PostgresRequestExtensions {
    fn db_conn(&self) -> PooledConnection<PostgresConnectionManager>;
}

impl<'a, 'b, D> PostgresRequestExtensions for Request<'a, 'b, D> {
    fn db_conn(&self) -> PooledConnection<PostgresConnectionManager> {
        self.extensions().get::<PostgresMiddleware>().unwrap().get().unwrap()
    }
}
<|endoftext|>


<commit_before>use metric::{Measured, Line, Grapheme, Metric};
use super::{NodeLink, LeafRepr };

use self::Value::*;

use std::cell::Cell;
use std::convert;
use std::default::Default;
use std::fmt;
use std::ops;

/// A lazily-evaluated field
#[derive(Clone)]
struct Lazy<T: Copy>(Cell<Option<T>>);

impl<T> Lazy<T>
where T: Copy {

    #[inline]
    pub fn get_or_else<F>(&self, f: F) -> T
    where F: FnOnce() -> T {
        if let Some(value) = self.0.get() {
            value
        } else {
            let value = f();
            self.0.set(Some(value));
            value
        }
    }

    #[inline]
    pub fn new() -> Self {
        Lazy(Cell::new(None))
    }

}

impl<T> Default for Lazy<T>
where T: Copy {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> fmt::Debug for Lazy<T>
where T: fmt::Debug
    , T: Copy {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0.get() { Some(value) => value.fmt(f)
                           , None => write!(f, "?")

        }
    }
}
macro_rules! lazy_field {
    ($method: ident, $field: ident, $ty:ty) => {
        #[inline] fn $method(&self) -> $ty {
            self.$field.get_or_else(|| { self.value.$method() })
        }

    }
}

/// A `Node`.
#[derive(Clone, Debug, Default)]
pub struct Node { len: Lazy<usize>
                , weight: Lazy<usize>
                , line_count: Lazy<Line>
                , line_weight: Lazy<Line>
                , grapheme_count: Lazy<Grapheme>
                , grapheme_weight: Lazy<Grapheme>
                , pub value: Value
                }

impl Node {
    pub fn new(value: Value) -> Self {
        Node { value: value, ..Default::default() }
    }

    pub fn spanning(&self, i: usize, span_len: usize) -> (&Node, usize)
    where Node: Measured<usize> {
        assert!(self.len() >= span_len);
        match **self {
            Branch { ref right, ref left } if <Node as Measured<usize>>::measure_weight(self) < i => {
                // if this node is a branch, and the weight is less than the
                // index, where the span begins, then the first index of the
                // span is on the right side
                let span_i = or_zero!(i, left.len());
                assert!(or_zero!(right.len(), span_i) >= span_len);
                right.spanning(span_i, span_len)
            }
          , Branch { ref left, .. }
            // if the left child is long enough to contain the entire span,
            // walk to the left child
            if or_zero!(left.len(), i) >= span_len => left.spanning(i, span_len)
         ,  Leaf(_) | Branch {..} =>
            // if this function has walked as far as a leaf node,
            // then that leaf must be the spanning node. return it;
            //
            // otherwise, if the node is a branch node and the span is longer
            // than the left child, then this node must be the minimum
            // spanning node
            (self, i)
        }
    }
}

impl fmt::Display for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.strings()
            .fold(Ok(()), |r, string| r.and_then(|_| write!(f, "{}", string)))
    }
}

impl convert::Into<NodeLink> for Node {
    #[inline] fn into(self) -> NodeLink {
        NodeLink::new(self)
    }
}

impl ops::Deref for Node {
    type Target = Value;
    fn deref(&self) -> &Value { &self.value }
}

impl Measured<usize> for Node {

        #[inline] fn to_byte_index(&self, index: usize) -> Option<usize>  {
             Some(index)
        }

        lazy_field!(measure, len, usize);
        lazy_field!(measure_weight, weight, usize);

}

impl Measured<Grapheme> for Node {

        #[inline] fn to_byte_index(&self, index: Grapheme) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, grapheme_count, Grapheme);
        lazy_field!(measure_weight, grapheme_weight, Grapheme);

}

impl Measured<Line> for Node {

        #[inline] fn to_byte_index(&self, index: Line) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, line_count, Line);
        lazy_field!(measure_weight, line_weight, Line);

}

impl<M> ops::Index<M> for Node
where M: Metric
    , Node: Measured<M>
    , LeafRepr: Measured<M>
    {
    type Output = str;

    fn index(&self, i: M) -> &str {
        let len = self.measure();
        assert!( i < len
               , "Node::index: index {:?} out of bounds (length {:?})", i, len);
        match **self {
            Leaf(ref string) => {
                let idx = string.to_byte_index(i)
                                .expect("index out of bounds!");
                &string[idx..idx+1]
            }
          , Branch { ref right, .. } if len < i =>
                &right[i - len]
          , Branch { ref left, .. } => &left[i]
        }
    }
}

/// A `Node` in the `Rope`'s tree.
///
/// A `Node` is either a `Leaf` holding a `String`, or a
/// a `Branch` concatenating together two `Node`s.
#[derive(Clone, Debug)]
pub enum Value {
    /// A leaf node
    Leaf(LeafRepr)
  , /// A branch concatenating together `l`eft and `r`ight nodes.
    Branch { /// The left branch node
             left: NodeLink
           , /// The right branch node
             right: NodeLink }
}

impl Value {
    #[inline]
    pub fn new_branch(left: NodeLink, right: NodeLink) -> Self {
        Branch { left: left, right: right }
    }
}

impl<M> Measured<M> for Value
where M: Metric
    , LeafRepr: Measured<M>
    , Node: Measured<M>
{
    fn to_byte_index(&self, index: M) -> Option<usize> {
        unimplemented!()
    }

    fn measure(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure()
          , Branch { ref left, ref right } =>
                left.measure() + right.measure()
        }
    }

    fn measure_weight(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure_weight()
          , Branch { ref left, ref right } =>
                left.measure()
        }
    }

}

impl convert::Into<Node> for Value {
    #[inline] fn into(self) -> Node {
        Node::new(self)
    }
}

impl Default for Value {
    fn default() -> Self {
        Leaf(LeafRepr::default())
    }
}
<commit_msg>feat(node): lazy fields can be gotten optionally<commit_after>use metric::{Measured, Line, Grapheme, Metric};
use super::{NodeLink, LeafRepr };

use self::Value::*;

use std::cell::Cell;
use std::convert;
use std::default::Default;
use std::fmt;
use std::ops;

/// A lazily-evaluated field
#[derive(Clone)]
struct Lazy<T: Copy>(Cell<Option<T>>);

impl<T> Lazy<T>
where T: Copy {

    #[inline]
    pub fn get(&self) -> Option<T> { self.0.get() }

    #[inline]
    pub fn get_or_else<F>(&self, f: F) -> T
    where F: FnOnce() -> T {
        if let Some(value) = self.0.get() {
            value
        } else {
            let value = f();
            self.0.set(Some(value));
            value
        }
    }

    #[inline]
    pub fn new() -> Self {
        Lazy(Cell::new(None))
    }

}

impl<T> Default for Lazy<T>
where T: Copy {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> fmt::Debug for Lazy<T>
where T: fmt::Debug
    , T: Copy {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0.get() { Some(value) => value.fmt(f)
                           , None => write!(f, "?")

        }
    }
}

macro_rules! lazy_field {
    ($method: ident, $field: ident, $ty:ty) => {
        #[inline] fn $method(&self) -> $ty {
            self.$field.get_or_else(|| { self.value.$method() })
        }

    }
}

/// A `Node`.
#[derive(Clone, Debug, Default)]
pub struct Node { len: Lazy<usize>
                , weight: Lazy<usize>
                , line_count: Lazy<Line>
                , line_weight: Lazy<Line>
                , grapheme_count: Lazy<Grapheme>
                , grapheme_weight: Lazy<Grapheme>
                , pub value: Value
                }

impl Node {
    pub fn new(value: Value) -> Self {
        Node { value: value, ..Default::default() }
    }

    pub fn spanning(&self, i: usize, span_len: usize) -> (&Node, usize)
    where Node: Measured<usize> {
        assert!(self.len() >= span_len);
        match **self {
            Branch { ref right, ref left } if <Node as Measured<usize>>::measure_weight(self) < i => {
                // if this node is a branch, and the weight is less than the
                // index, where the span begins, then the first index of the
                // span is on the right side
                let span_i = or_zero!(i, left.len());
                assert!(or_zero!(right.len(), span_i) >= span_len);
                right.spanning(span_i, span_len)
            }
          , Branch { ref left, .. }
            // if the left child is long enough to contain the entire span,
            // walk to the left child
            if or_zero!(left.len(), i) >= span_len => left.spanning(i, span_len)
         ,  Leaf(_) | Branch {..} =>
            // if this function has walked as far as a leaf node,
            // then that leaf must be the spanning node. return it;
            //
            // otherwise, if the node is a branch node and the span is longer
            // than the left child, then this node must be the minimum
            // spanning node
            (self, i)
        }
    }
}

impl fmt::Display for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.strings()
            .fold(Ok(()), |r, string| r.and_then(|_| write!(f, "{}", string)))
    }
}

impl convert::Into<NodeLink> for Node {
    #[inline] fn into(self) -> NodeLink {
        NodeLink::new(self)
    }
}

impl ops::Deref for Node {
    type Target = Value;
    fn deref(&self) -> &Value { &self.value }
}

impl Measured<usize> for Node {

        #[inline] fn to_byte_index(&self, index: usize) -> Option<usize>  {
             Some(index)
        }

        lazy_field!(measure, len, usize);
        lazy_field!(measure_weight, weight, usize);

}

impl Measured<Grapheme> for Node {

        #[inline] fn to_byte_index(&self, index: Grapheme) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, grapheme_count, Grapheme);
        lazy_field!(measure_weight, grapheme_weight, Grapheme);

}

impl Measured<Line> for Node {

        #[inline] fn to_byte_index(&self, index: Line) -> Option<usize>  {
            self.value.to_byte_index(index)
        }

        lazy_field!(measure, line_count, Line);
        lazy_field!(measure_weight, line_weight, Line);

}

impl<M> ops::Index<M> for Node
where M: Metric
    , Node: Measured<M>
    , LeafRepr: Measured<M>
    {
    type Output = str;

    fn index(&self, i: M) -> &str {
        let len = self.measure();
        assert!( i < len
               , "Node::index: index {:?} out of bounds (length {:?})", i, len);
        match **self {
            Leaf(ref string) => {
                let idx = string.to_byte_index(i)
                                .expect("index out of bounds!");
                &string[idx..idx+1]
            }
          , Branch { ref right, .. } if len < i =>
                &right[i - len]
          , Branch { ref left, .. } => &left[i]
        }
    }
}

/// A `Node` in the `Rope`'s tree.
///
/// A `Node` is either a `Leaf` holding a `String`, or a
/// a `Branch` concatenating together two `Node`s.
#[derive(Clone, Debug)]
pub enum Value {
    /// A leaf node
    Leaf(LeafRepr)
  , /// A branch concatenating together `l`eft and `r`ight nodes.
    Branch { /// The left branch node
             left: NodeLink
           , /// The right branch node
             right: NodeLink }
}

impl Value {
    #[inline]
    pub fn new_branch(left: NodeLink, right: NodeLink) -> Self {
        Branch { left: left, right: right }
    }
}

impl<M> Measured<M> for Value
where M: Metric
    , LeafRepr: Measured<M>
    , Node: Measured<M>
{
    fn to_byte_index(&self, index: M) -> Option<usize> {
        unimplemented!()
    }

    fn measure(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure()
          , Branch { ref left, ref right } =>
                left.measure() + right.measure()
        }
    }

    fn measure_weight(&self) -> M {
        match *self {
            Leaf(ref r) => r.measure_weight()
          , Branch { ref left, ref right } =>
                left.measure()
        }
    }

}

impl convert::Into<Node> for Value {
    #[inline] fn into(self) -> Node {
        Node::new(self)
    }
}

impl Default for Value {
    fn default() -> Self {
        Leaf(LeafRepr::default())
    }
}
<|endoftext|>


<commit_before>
use server::{Request, Response};
use server_backend::status;
use errors::{Error, ErrorRefExt, NotMatchError, NotFoundError};

pub type HandleError = Box<Error>;
pub type HandleResult<T> = Result<T, HandleError>;
pub type HandleSuccessResult = HandleResult<()>;

pub trait BeforeMiddleware: Send + Sync {
    fn before(&self, &mut Request) -> HandleResult<Option<Response>>;
}

pub trait AfterMiddleware: Send + Sync {
    fn after(&self, &mut Request, &mut Response) -> HandleResult<Option<Response>>;
}

pub trait CatchMiddleware: Send + Sync {
    fn rescue(&self, &mut Request, err: &HandleError) -> HandleResult<Option<Response>>;
}

pub trait Handler: Send + Sync {
    fn call(&self, &str, &mut Request) -> HandleResult<Response>;
}

#[deriving(Send)]
pub struct Application {
    before: Vec<Box<BeforeMiddleware + Send + Sync>>,
    after: Vec<Box<AfterMiddleware + Send + Sync>>,
    catch: Vec<Box<CatchMiddleware + Send + Sync>>,
    handlers: Vec<Box<Handler + Send + Sync>>
}

impl Application {

    pub fn new() -> Application {
        Application {
            before: vec![],
            after: vec![],
            catch: vec![],
            handlers: vec![]
        }
    }

    pub fn call(&self, req: &mut Request) -> HandleResult<Response> {

        for mdw in self.before.iter() {
            match mdw.before(req) {
                Err(err) => {
                    match self.handle_error(req, err) {
                        Some(response) => return Ok(response),
                        None => ()
                    }
                },
                Ok(Some(response)) => return Ok(response),
                Ok(None) => ()
            }
        }

        let mut response: Option<Response> = None;
        let path = req.url().serialize_path().unwrap_or(String::new());

        for handler in self.handlers.iter() {
            match handler.call(path.as_slice(), req) {
                Ok(resp) => response = Some(resp),
                Err(err) => match err.downcast::<NotMatchError>() {
                    Some(_) => (),
                    None => match self.handle_error(req, err) {
                        Some(response) => return Ok(response),
                        None => ()
                    }
                }
            }
        }

        let mut exact_response = match response {
            Some(resp) => resp,
            None => return Ok(self.handle_error(req, NotFoundError.erase()).unwrap())
        };

        for mdw in self.after.iter() {
            match mdw.after(req, &mut exact_response) {
                Err(err) => match self.handle_error(req, err) {
                    Some(response) => return Ok(response),
                    None => ()
                },
                Ok(Some(response)) => return Ok(response),
                Ok(None) => ()
            }
        }

        Ok(exact_response)

    }

    pub fn handle_error(&self, req: &mut Request, err: HandleError) -> Option<Response> {
        for catcher in self.catch.iter() {
            match catcher.rescue(req, &err) {
                Ok(maybe_response) => {
                    match maybe_response {
                        Some(resp) => return Some(resp),
                        None => return None
                    }
                },
                Err(some) => ()
            }
        }

        if err.downcast::<NotFoundError>().is_some() {
            Some(Response::from_string(status::NotFound, "".to_string()))
        } else {
            Some(Response::from_string(status::InternalServerError, format!("{}", err)))
        }
    }

    pub fn mount(&mut self, handler: Box<Handler + Send + Sync>) {
        self.handlers.push(handler);
    }
}

trait AfterMiddlewareSupport {
    fn using(&mut self, middleware: Box<AfterMiddleware + Send + Sync>);
}

trait BeforeMiddlewareSupport {
    fn using(&mut self, middleware: Box<BeforeMiddleware + Send + Sync>);
}

impl AfterMiddlewareSupport for Application {
    fn using(&mut self, middleware: Box<AfterMiddleware + Send + Sync>) {
        self.after.push(middleware);
    }
}

impl BeforeMiddlewareSupport for Application {
    fn using(&mut self, middleware: Box<BeforeMiddleware + Send + Sync>) {
        self.before.push(middleware);
    }
}

<commit_msg>refactor: fix new unused variable error with new rustc<commit_after>
use server::{Request, Response};
use server_backend::status;
use errors::{Error, ErrorRefExt, NotMatchError, NotFoundError};

pub type HandleError = Box<Error>;
pub type HandleResult<T> = Result<T, HandleError>;
pub type HandleSuccessResult = HandleResult<()>;

pub trait BeforeMiddleware: Send + Sync {
    fn before(&self, &mut Request) -> HandleResult<Option<Response>>;
}

pub trait AfterMiddleware: Send + Sync {
    fn after(&self, &mut Request, &mut Response) -> HandleResult<Option<Response>>;
}

pub trait CatchMiddleware: Send + Sync {
    fn rescue(&self, &mut Request, err: &HandleError) -> HandleResult<Option<Response>>;
}

pub trait Handler: Send + Sync {
    fn call(&self, &str, &mut Request) -> HandleResult<Response>;
}

#[deriving(Send)]
pub struct Application {
    before: Vec<Box<BeforeMiddleware + Send + Sync>>,
    after: Vec<Box<AfterMiddleware + Send + Sync>>,
    catch: Vec<Box<CatchMiddleware + Send + Sync>>,
    handlers: Vec<Box<Handler + Send + Sync>>
}

impl Application {

    pub fn new() -> Application {
        Application {
            before: vec![],
            after: vec![],
            catch: vec![],
            handlers: vec![]
        }
    }

    pub fn call(&self, req: &mut Request) -> HandleResult<Response> {

        for mdw in self.before.iter() {
            match mdw.before(req) {
                Err(err) => {
                    match self.handle_error(req, err) {
                        Some(response) => return Ok(response),
                        None => ()
                    }
                },
                Ok(Some(response)) => return Ok(response),
                Ok(None) => ()
            }
        }

        let mut response: Option<Response> = None;
        let path = req.url().serialize_path().unwrap_or(String::new());

        for handler in self.handlers.iter() {
            match handler.call(path.as_slice(), req) {
                Ok(resp) => response = Some(resp),
                Err(err) => match err.downcast::<NotMatchError>() {
                    Some(_) => (),
                    None => match self.handle_error(req, err) {
                        Some(response) => return Ok(response),
                        None => ()
                    }
                }
            }
        }

        let mut exact_response = match response {
            Some(resp) => resp,
            None => return Ok(self.handle_error(req, NotFoundError.erase()).unwrap())
        };

        for mdw in self.after.iter() {
            match mdw.after(req, &mut exact_response) {
                Err(err) => match self.handle_error(req, err) {
                    Some(response) => return Ok(response),
                    None => ()
                },
                Ok(Some(response)) => return Ok(response),
                Ok(None) => ()
            }
        }

        Ok(exact_response)

    }

    pub fn handle_error(&self, req: &mut Request, err: HandleError) -> Option<Response> {
        for catcher in self.catch.iter() {
            match catcher.rescue(req, &err) {
                Ok(maybe_response) => {
                    match maybe_response {
                        Some(resp) => return Some(resp),
                        None => return None
                    }
                },
                Err(_) => ()
            }
        }

        if err.downcast::<NotFoundError>().is_some() {
            Some(Response::from_string(status::NotFound, "".to_string()))
        } else {
            Some(Response::from_string(status::InternalServerError, format!("{}", err)))
        }
    }

    pub fn mount(&mut self, handler: Box<Handler + Send + Sync>) {
        self.handlers.push(handler);
    }
}

trait AfterMiddlewareSupport {
    fn using(&mut self, middleware: Box<AfterMiddleware + Send + Sync>);
}

trait BeforeMiddlewareSupport {
    fn using(&mut self, middleware: Box<BeforeMiddleware + Send + Sync>);
}

impl AfterMiddlewareSupport for Application {
    fn using(&mut self, middleware: Box<AfterMiddleware + Send + Sync>) {
        self.after.push(middleware);
    }
}

impl BeforeMiddlewareSupport for Application {
    fn using(&mut self, middleware: Box<BeforeMiddleware + Send + Sync>) {
        self.before.push(middleware);
    }
}

<|endoftext|>


<commit_before>use std::str::FromStr;
use std::old_io::{File};
use std::env;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap};
use iron::modifier::Modifier;
use plugin::Phantom;
use plugin::Plugin as PluginFor;
use iron::headers;

use glob::glob;

use hyper::header::ContentType;

use handlebars::Handlebars;
use serialize::json::{ToJson, Json};

pub struct HandlebarsEngine {
    registry: Handlebars
}

#[derive(Clone)]
pub struct Template {
    name: String,
    value: Json
}

impl Template {
    pub fn new<T: ToJson>(name: &str, value: T) -> Template {
        Template {
            name: name.to_string(),
            value: value.to_json()
        }
    }
}

impl typemap::Key for HandlebarsEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<HandlebarsEngine>(self);
    }
}

impl PluginFor<Response> for HandlebarsEngine {
    fn eval(resp: &mut Response, _: Phantom<HandlebarsEngine>) -> Option<Template> {
        resp.extensions.get::<HandlebarsEngine>().cloned()
    }
}

impl HandlebarsEngine {
    pub fn new(prefix: &str, suffix: &str) -> HandlebarsEngine {
        let mut r = Handlebars::new();

        let prefix_path = Path::new(prefix);
        let current_dir = env::current_dir();
        if !current_dir.is_ok() {
            panic!("failed to get current working directory");
        }
        let abs_prefix_path = current_dir.ok().unwrap().join(prefix_path);
        let prefix_path_str = abs_prefix_path.as_str().unwrap();

        let mut pattern = String::new();
        pattern.push_str(prefix_path_str);
        pattern.push_str("/**/*");
        pattern.push_str(suffix);

        for entry in glob(pattern.as_slice()).unwrap() {
            match entry {
                Ok(path) => {
                    let disp = path.as_str().unwrap();
                    let t = r.register_template_string(
                        &disp[prefix_path_str.len()+1 .. disp.len()-suffix.len()],
                        File::open(&path).ok()
                            .expect(format!("Failed to open file {}", disp).as_slice())
                            .read_to_string().unwrap());

                    if t.is_err() {
                        panic!("Failed to create template.");
                    }
                },
                Err(_) => {}
            }
        }

        HandlebarsEngine {
            registry: r
        }
    }
}

impl AfterMiddleware for HandlebarsEngine {
    fn after(&self, _: &mut Request, r: Response) -> IronResult<Response> {
        let mut resp = r;
        // internally we still extensions.get to avoid clone
        let page = match resp.extensions.get::<HandlebarsEngine>() {
            Some(h) => {
                let name = &h.name;
                let value = &h.value;
                let rendered = self.registry.render(name.as_slice(), value);
                match rendered {
                    Ok(r) => Some(r),
                    Err(_) => None
                }
            },
            None => {
                None
            }
        };

        if page.is_some() {
            if !resp.headers.has::<ContentType>() {
                resp.headers.set(headers::ContentType(FromStr::from_str("text/html;charset=utf-8").unwrap()));
            }
            resp.set_mut(page.unwrap());
        }

        Ok(resp)
    }
}

#[cfg(test)]
mod test {
    use serialize::json::ToJson;
    use std::collections::BTreeMap;
    use iron::prelude::*;
    use middleware::*;

    fn hello_world() -> IronResult<Response> {
        let resp = Response::new();

        let mut data = BTreeMap::new();
        data.insert("title".to_string(), "Handlebars on Iron".to_json());

        Ok(resp.set(Template::new("index", data)))
    }

    #[test]
    fn test_resp_set() {
        let mut resp = hello_world().ok().expect("response expected");

        // use response plugin to retrieve a cloned template for testing
        match resp.get::<HandlebarsEngine>() {
            Some(h) => {
                assert_eq!(h.name, "index".to_string());
                assert_eq!(h.value.as_object().unwrap()
                           .get(&"title".to_string()).unwrap()
                           .as_string().unwrap(),
                           "Handlebars on Iron");
            },
            None => panic!("template expected")
        }
    }
}
<commit_msg>(feat) moved handlebars to heap<commit_after>use std::str::FromStr;
use std::old_io::{File};
use std::env;

use iron::prelude::*;
use iron::{AfterMiddleware, typemap};
use iron::modifier::Modifier;
use plugin::Phantom;
use plugin::Plugin as PluginFor;
use iron::headers;

use glob::glob;

use hyper::header::ContentType;

use handlebars::Handlebars;
use serialize::json::{ToJson, Json};

pub struct HandlebarsEngine {
    registry: Box<Handlebars>
}

#[derive(Clone)]
pub struct Template {
    name: String,
    value: Json
}

impl Template {
    pub fn new<T: ToJson>(name: &str, value: T) -> Template {
        Template {
            name: name.to_string(),
            value: value.to_json()
        }
    }
}

impl typemap::Key for HandlebarsEngine {
    type Value = Template;
}

impl Modifier<Response> for Template {
    fn modify(self, resp: &mut Response) {
        resp.extensions.insert::<HandlebarsEngine>(self);
    }
}

impl PluginFor<Response> for HandlebarsEngine {
    fn eval(resp: &mut Response, _: Phantom<HandlebarsEngine>) -> Option<Template> {
        resp.extensions.get::<HandlebarsEngine>().cloned()
    }
}

impl HandlebarsEngine {
    pub fn new(prefix: &str, suffix: &str) -> HandlebarsEngine {
        let mut r = Handlebars::new();

        let prefix_path = Path::new(prefix);
        let current_dir = env::current_dir();
        if !current_dir.is_ok() {
            panic!("failed to get current working directory");
        }
        let abs_prefix_path = current_dir.ok().unwrap().join(prefix_path);
        let prefix_path_str = abs_prefix_path.as_str().unwrap();

        let mut pattern = String::new();
        pattern.push_str(prefix_path_str);
        pattern.push_str("/**/*");
        pattern.push_str(suffix);

        for entry in glob(pattern.as_slice()).unwrap() {
            match entry {
                Ok(path) => {
                    let disp = path.as_str().unwrap();
                    let t = r.register_template_string(
                        &disp[prefix_path_str.len()+1 .. disp.len()-suffix.len()],
                        File::open(&path).ok()
                            .expect(format!("Failed to open file {}", disp).as_slice())
                            .read_to_string().unwrap());

                    if t.is_err() {
                        panic!("Failed to create template.");
                    }
                },
                Err(_) => {}
            }
        }

        HandlebarsEngine {
            registry: Box::new(r)
        }
    }
}

impl AfterMiddleware for HandlebarsEngine {
    fn after(&self, _: &mut Request, r: Response) -> IronResult<Response> {
        let mut resp = r;
        // internally we still extensions.get to avoid clone
        let page = match resp.extensions.get::<HandlebarsEngine>() {
            Some(h) => {
                let name = &h.name;
                let value = &h.value;
                let rendered = self.registry.render(name.as_slice(), value);
                match rendered {
                    Ok(r) => Some(r),
                    Err(_) => None
                }
            },
            None => {
                None
            }
        };

        if page.is_some() {
            if !resp.headers.has::<ContentType>() {
                resp.headers.set(headers::ContentType(FromStr::from_str("text/html;charset=utf-8").unwrap()));
            }
            resp.set_mut(page.unwrap());
        }

        Ok(resp)
    }
}

#[cfg(test)]
mod test {
    use serialize::json::ToJson;
    use std::collections::BTreeMap;
    use iron::prelude::*;
    use middleware::*;

    fn hello_world() -> IronResult<Response> {
        let resp = Response::new();

        let mut data = BTreeMap::new();
        data.insert("title".to_string(), "Handlebars on Iron".to_json());

        Ok(resp.set(Template::new("index", data)))
    }

    #[test]
    fn test_resp_set() {
        let mut resp = hello_world().ok().expect("response expected");

        // use response plugin to retrieve a cloned template for testing
        match resp.get::<HandlebarsEngine>() {
            Some(h) => {
                assert_eq!(h.name, "index".to_string());
                assert_eq!(h.value.as_object().unwrap()
                           .get(&"title".to_string()).unwrap()
                           .as_string().unwrap(),
                           "Handlebars on Iron");
            },
            None => panic!("template expected")
        }
    }
}
<|endoftext|>


<commit_before>use crate::comment::CommentStyle;
use std::fmt::{self, Display};
use syntax_pos::symbol::Symbol;

pub(super) struct DocCommentFormatter<'a> {
    literal: &'a Symbol,
    style: CommentStyle<'a>,
}

impl<'a> DocCommentFormatter<'a> {
    pub(super) fn new(literal: &'a Symbol, style: CommentStyle<'a>) -> Self {
        Self { literal, style }
    }
}

impl Display for DocCommentFormatter<'_> {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        let opener = self.style.opener().trim_end();

        let literal_as_str = self.literal.as_str().get();
        let line_count = literal_as_str.lines().count();
        let last_line_index = line_count - 1;
        let lines = literal_as_str.lines().enumerate();

        for (index, line) in lines {
            if index == last_line_index {
                write!(formatter, "{}{}", opener, line)?;
            } else {
                writeln!(formatter, "{}{}", opener, line)?;
            }
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use syntax_pos::{Globals, GLOBALS};

    #[test]
    fn literal_controls_leading_spaces() {
        test_doc_comment_is_formatted_correctly(
            "    Lorem ipsum",
            "///    Lorem ipsum",
            CommentStyle::TripleSlash,
        );
    }

    #[test]
    fn single_line_doc_comment_is_formatted_correctly() {
        test_doc_comment_is_formatted_correctly(
            "Lorem ipsum",
            "///Lorem ipsum",
            CommentStyle::TripleSlash,
        );
    }

    #[test]
    fn multi_line_doc_comment_is_formatted_correctly() {
        test_doc_comment_is_formatted_correctly(
            "Lorem ipsum\nDolor sit amet",
            "///Lorem ipsum\n///Dolor sit amet",
            CommentStyle::TripleSlash,
        );
    }

    #[test]
    fn whitespace_within_lines_is_preserved() {
        test_doc_comment_is_formatted_correctly(
            " Lorem ipsum \n Dolor sit amet ",
            "/// Lorem ipsum \n/// Dolor sit amet ",
            CommentStyle::TripleSlash,
        );
    }

    fn test_doc_comment_is_formatted_correctly(
        literal: &str,
        expected_comment: &str,
        style: CommentStyle<'_>,
    ) {
        GLOBALS.set(&Globals::new(), || {
            let literal = Symbol::gensym(literal);

            assert_eq!(
                expected_comment,
                format!("{}", DocCommentFormatter::new(&literal, style))
            );
        });
    }
}
<commit_msg>Use peek() instead of checking indexes<commit_after>use crate::comment::CommentStyle;
use std::fmt::{self, Display};
use syntax_pos::symbol::Symbol;

pub(super) struct DocCommentFormatter<'a> {
    literal: &'a Symbol,
    style: CommentStyle<'a>,
}

impl<'a> DocCommentFormatter<'a> {
    pub(super) fn new(literal: &'a Symbol, style: CommentStyle<'a>) -> Self {
        Self { literal, style }
    }
}

impl Display for DocCommentFormatter<'_> {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        let opener = self.style.opener().trim_end();
        let literal_as_str = self.literal.as_str().get();

        let mut lines = literal_as_str.lines().peekable();
        while let Some(line) = lines.next() {
            let is_last_line = lines.peek().is_none();
            if is_last_line {
                write!(formatter, "{}{}", opener, line)?;
            } else {
                writeln!(formatter, "{}{}", opener, line)?;
            }
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use syntax_pos::{Globals, GLOBALS};

    #[test]
    fn literal_controls_leading_spaces() {
        test_doc_comment_is_formatted_correctly(
            "    Lorem ipsum",
            "///    Lorem ipsum",
            CommentStyle::TripleSlash,
        );
    }

    #[test]
    fn single_line_doc_comment_is_formatted_correctly() {
        test_doc_comment_is_formatted_correctly(
            "Lorem ipsum",
            "///Lorem ipsum",
            CommentStyle::TripleSlash,
        );
    }

    #[test]
    fn multi_line_doc_comment_is_formatted_correctly() {
        test_doc_comment_is_formatted_correctly(
            "Lorem ipsum\nDolor sit amet",
            "///Lorem ipsum\n///Dolor sit amet",
            CommentStyle::TripleSlash,
        );
    }

    #[test]
    fn whitespace_within_lines_is_preserved() {
        test_doc_comment_is_formatted_correctly(
            " Lorem ipsum \n Dolor sit amet ",
            "/// Lorem ipsum \n/// Dolor sit amet ",
            CommentStyle::TripleSlash,
        );
    }

    fn test_doc_comment_is_formatted_correctly(
        literal: &str,
        expected_comment: &str,
        style: CommentStyle<'_>,
    ) {
        GLOBALS.set(&Globals::new(), || {
            let literal = Symbol::gensym(literal);

            assert_eq!(
                expected_comment,
                format!("{}", DocCommentFormatter::new(&literal, style))
            );
        });
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 Alexander Reece
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::slice;
use {Class, ClassField, ClassMethod, ClassMethodField};

impl Class {
    pub fn name(&self) -> &'static str {
        self.name
    }

    pub fn fields(&self) -> ClassFields {
        ClassFields(self.fields.iter())
    }

    pub fn index(&self) -> u16 {
        self.index
    }

    pub fn methods(&self) -> ClassMethods {
        ClassMethods(self.methods.iter())
    }
}

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum ClassMethodFieldAssertion {
    Null,
    NotNull,
    ChannelMax,
    NotZero,
    Enum(&'static [&'static str]),
    Length(usize),
    Regexp(&'static str),
    Syntax(&'static str),
}

pub struct ClassFields(slice::Iter<'static, ClassField>);
pub struct ClassMethods(slice::Iter<'static, ClassMethod>);
pub struct ClassMethodFields(slice::Iter<'static, ClassMethodField>);
pub struct ClassMethodFieldAssertions(slice::Iter<'static, ClassMethodFieldAssertion>);

impl ClassField {
    pub fn name(&self) -> &'static str {
        self.name
    }

    pub fn domain(&self) -> &'static str {
        self.domain
    }
}

impl ClassMethod {
    pub fn index(&self) -> u16 {
        self.index
    }
    pub fn name(&self) -> &str {
        self.name
    }
    pub fn fields(&self) -> ClassMethodFields {
        ClassMethodFields(self.fields.iter())
    }
    pub fn has_content(&self) -> bool {
        self.has_content
    }
}

impl ClassMethodField {
    pub fn name(&self) -> &'static str {
        self.name
    }

    pub fn domain(&self) -> &'static str {
        self.domain
    }

    pub fn assertions(&self) -> ClassMethodFieldAssertions {
        ClassMethodFieldAssertions(self.assertions.iter())
    }

    pub fn is_reserved(&self) -> bool {
        self.is_reserved
    }
}

impl Iterator for ClassFields {
    type Item = &'static ClassField;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

impl Iterator for ClassMethods {
    type Item = &'static ClassMethod;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}<commit_msg>[specs] Add `Iterator` implementation for `class:C:lassMethodFields`<commit_after>// Copyright 2017 Alexander Reece
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::slice;
use {Class, ClassField, ClassMethod, ClassMethodField};

impl Class {
    pub fn name(&self) -> &'static str {
        self.name
    }

    pub fn fields(&self) -> ClassFields {
        ClassFields(self.fields.iter())
    }

    pub fn index(&self) -> u16 {
        self.index
    }

    pub fn methods(&self) -> ClassMethods {
        ClassMethods(self.methods.iter())
    }
}

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum ClassMethodFieldAssertion {
    Null,
    NotNull,
    ChannelMax,
    NotZero,
    Enum(&'static [&'static str]),
    Length(usize),
    Regexp(&'static str),
    Syntax(&'static str),
}

pub struct ClassFields(slice::Iter<'static, ClassField>);
pub struct ClassMethods(slice::Iter<'static, ClassMethod>);
pub struct ClassMethodFields(slice::Iter<'static, ClassMethodField>);
pub struct ClassMethodFieldAssertions(slice::Iter<'static, ClassMethodFieldAssertion>);

impl ClassField {
    pub fn name(&self) -> &'static str {
        self.name
    }

    pub fn domain(&self) -> &'static str {
        self.domain
    }
}

impl ClassMethod {
    pub fn index(&self) -> u16 {
        self.index
    }
    pub fn name(&self) -> &str {
        self.name
    }
    pub fn fields(&self) -> ClassMethodFields {
        ClassMethodFields(self.fields.iter())
    }
    pub fn has_content(&self) -> bool {
        self.has_content
    }
}

impl ClassMethodField {
    pub fn name(&self) -> &'static str {
        self.name
    }

    pub fn domain(&self) -> &'static str {
        self.domain
    }

    pub fn assertions(&self) -> ClassMethodFieldAssertions {
        ClassMethodFieldAssertions(self.assertions.iter())
    }

    pub fn is_reserved(&self) -> bool {
        self.is_reserved
    }
}

impl Iterator for ClassFields {
    type Item = &'static ClassField;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

impl Iterator for ClassMethods {
    type Item = &'static ClassMethod;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

impl Iterator for ClassMethodFields {
    type Item = &'static ClassMethodField;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate env_logger;
mod json;

use core_executor::engines::NullEngine;
use core_executor::libexecutor::economical_model::EconomicalModel;
use core_executor::libexecutor::sys_config::BlockSysConfig;
use core_executor::state::ApplyResult;
use core_executor::types::transaction::Transaction;
use evm::cita_types::U256;
use evm::env_info::EnvInfo;
use libproto::blockchain::Transaction as ProtoTransaction;
use std::fs;
use test_helper::{get_temp_state, secret_2_address, string_2_bytes, string_2_h256, string_2_u256};

fn test_json_file(p: &str) {
    let f = fs::File::open(p).unwrap();
    let tests = json::Test::load(f).unwrap();
    for (_name, test) in tests.into_iter() {
        let data_post_byzantium = test.post.unwrap().byzantium;
        if data_post_byzantium.is_none() {
            continue;
        }

        for (_i, postdata) in data_post_byzantium.unwrap().into_iter().enumerate() {
            // Init state
            let mut state = get_temp_state();
            for (address, account) in test.pre.clone().unwrap() {
                let balance = string_2_u256(account.balance);
                let code = string_2_bytes(account.code);
                let nonce = string_2_u256(account.nonce);
                if code.is_empty() {
                    state.new_contract(&address, balance, nonce);
                } else {
                    state.new_contract(&address, balance, nonce);
                    let _ = state.init_code(&address, code);
                }

                for (k, v) in account.storage {
                    let kk = string_2_h256(k);
                    let vv = string_2_h256(v);
                    let _ = state.set_storage(&address, kk, vv);
                }
            }
            state.commit().unwrap();

            // Set envionment
            let mut env_info = EnvInfo::default();
            env_info.difficulty = string_2_u256(test.env.current_difficulty.clone());
            env_info.number = string_2_u256(test.env.current_number.clone()).low_u64();
            env_info.timestamp = string_2_u256(test.env.current_timestamp.clone()).low_u64();
            env_info.gas_limit = string_2_u256(test.env.current_gas_limit.clone());
            env_info.author = test.env.current_coinbase;

            let engine = NullEngine::cita();
            let mut config = BlockSysConfig::default();
            config.quota_price = string_2_u256(test.transaction.gas_price.clone());
            config.economical_model = EconomicalModel::Charge;
            config.quota_price = U256::from(1);

            let idx_gas = &postdata.indexes[&String::from("gas")];
            let idx_value = &postdata.indexes[&String::from("value")];
            let idx_data = &postdata.indexes[&String::from("data")];
            let str_gas = test.transaction.gas_limit.clone()[*idx_gas].clone();
            let str_value = test.transaction.value.clone()[*idx_value].clone();
            let str_data = test.transaction.data.clone()[*idx_data].clone();

            let mut proto_tx = ProtoTransaction::new();
            proto_tx.set_data(string_2_bytes(str_data));
            proto_tx.set_value(string_2_bytes(str_value));
            proto_tx.set_nonce(test.transaction.nonce.clone());
            proto_tx.set_quota(string_2_u256(str_gas).low_u64());
            if !test.transaction.to.is_empty() {
                proto_tx.set_to(test.transaction.to.clone());
            }

            let tx = Transaction::create(&proto_tx).unwrap();
            let sender = secret_2_address(&test.transaction.secret_key);
            let signed_transaction = tx.fake_sign(sender);

            // Execute transactions
            let result: ApplyResult =
                state.apply(&env_info, &engine, &signed_transaction, true, &config);
            match result {
                Ok(outcome) => {
                    debug!("lalalal receipt error: {:?}", outcome.receipt.error);
                }
                _ => panic!("apply_transaction: There must be something wrong!"),
            }

            // check root hash
            state.commit().unwrap();
            let root = state.root();
            debug!("state.root {}", root);
            assert_eq!(*root, string_2_h256(postdata.hash));
        }
    }
}

fn test_json_path(p: &str) {
    let info = fs::metadata(p).unwrap();
    if info.is_dir() {
        for entry in fs::read_dir(p).unwrap() {
            let entry = entry.unwrap();
            let p = entry.path();
            test_json_path(p.to_str().unwrap());
        }
    } else {
        test_json_file(p);
    }
}

fn skip_path(_reason: &str, _name: &str) {}

fn main() {
    env_logger::init();

    test_json_path(r"./tests/jsondata/GeneralStateTests/stRefundTest");
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCodeCopyTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stMemExpandingEIP150Calls",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCallDelegateCodesCallCodeHomestead",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stRevertTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stArgsZeroOneBalance",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stMemoryStressTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stTransactionTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stReturnDataTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stPreCompiledContracts",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCodeSizeLimit",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stHomesteadSpecific",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stEIP158Specific",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stZeroKnowledge2",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCreateTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stSStoreTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stTransitionTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stZeroCallsTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stBadOpcode",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stLogTests",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stNonZeroCallsTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCallDelegateCodesHomestead",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stBugs",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stShift",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stWalletTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stRandom2",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stEWASMTests",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stStaticCall",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stAttackTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stStackTests",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stPreCompiledContracts2",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stInitCodeTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stZeroKnowledge",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stEIP150singleCodeGasPrices",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stChangedEIP150",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stExample",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stSolidityTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stEIP150Specific",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stQuadraticComplexityTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stSystemOperationsTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stZeroCallsRevert",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stRecursiveCreate",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stRandom",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stDelegatecallTestHomestead",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stMemoryTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCreate2",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stSpecialTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCallCodes",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCallCreateCallCodeTest",
    );
    skip_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stExtCodeHash",
    );
}
<commit_msg>Rename skip_path to skip_json_path. [skip travis]<commit_after>#[macro_use]
extern crate log;
extern crate env_logger;
mod json;

use core_executor::engines::NullEngine;
use core_executor::libexecutor::economical_model::EconomicalModel;
use core_executor::libexecutor::sys_config::BlockSysConfig;
use core_executor::state::ApplyResult;
use core_executor::types::transaction::Transaction;
use evm::cita_types::U256;
use evm::env_info::EnvInfo;
use libproto::blockchain::Transaction as ProtoTransaction;
use std::fs;
use test_helper::{get_temp_state, secret_2_address, string_2_bytes, string_2_h256, string_2_u256};

fn test_json_file(p: &str) {
    let f = fs::File::open(p).unwrap();
    let tests = json::Test::load(f).unwrap();
    for (_name, test) in tests.into_iter() {
        let data_post_byzantium = test.post.unwrap().byzantium;
        if data_post_byzantium.is_none() {
            continue;
        }

        for (_i, postdata) in data_post_byzantium.unwrap().into_iter().enumerate() {
            // Init state
            let mut state = get_temp_state();
            for (address, account) in test.pre.clone().unwrap() {
                let balance = string_2_u256(account.balance);
                let code = string_2_bytes(account.code);
                let nonce = string_2_u256(account.nonce);
                if code.is_empty() {
                    state.new_contract(&address, balance, nonce);
                } else {
                    state.new_contract(&address, balance, nonce);
                    let _ = state.init_code(&address, code);
                }

                for (k, v) in account.storage {
                    let kk = string_2_h256(k);
                    let vv = string_2_h256(v);
                    let _ = state.set_storage(&address, kk, vv);
                }
            }
            state.commit().unwrap();

            // Set envionment
            let mut env_info = EnvInfo::default();
            env_info.difficulty = string_2_u256(test.env.current_difficulty.clone());
            env_info.number = string_2_u256(test.env.current_number.clone()).low_u64();
            env_info.timestamp = string_2_u256(test.env.current_timestamp.clone()).low_u64();
            env_info.gas_limit = string_2_u256(test.env.current_gas_limit.clone());
            env_info.author = test.env.current_coinbase;

            let engine = NullEngine::cita();
            let mut config = BlockSysConfig::default();
            config.quota_price = string_2_u256(test.transaction.gas_price.clone());
            config.economical_model = EconomicalModel::Charge;
            config.quota_price = U256::from(1);

            let idx_gas = &postdata.indexes[&String::from("gas")];
            let idx_value = &postdata.indexes[&String::from("value")];
            let idx_data = &postdata.indexes[&String::from("data")];
            let str_gas = test.transaction.gas_limit.clone()[*idx_gas].clone();
            let str_value = test.transaction.value.clone()[*idx_value].clone();
            let str_data = test.transaction.data.clone()[*idx_data].clone();

            let mut proto_tx = ProtoTransaction::new();
            proto_tx.set_data(string_2_bytes(str_data));
            proto_tx.set_value(string_2_bytes(str_value));
            proto_tx.set_nonce(test.transaction.nonce.clone());
            proto_tx.set_quota(string_2_u256(str_gas).low_u64());
            if !test.transaction.to.is_empty() {
                proto_tx.set_to(test.transaction.to.clone());
            }

            let tx = Transaction::create(&proto_tx).unwrap();
            let sender = secret_2_address(&test.transaction.secret_key);
            let signed_transaction = tx.fake_sign(sender);

            // Execute transactions
            let result: ApplyResult =
                state.apply(&env_info, &engine, &signed_transaction, true, &config);
            match result {
                Ok(outcome) => {
                    debug!("lalalal receipt error: {:?}", outcome.receipt.error);
                }
                _ => panic!("apply_transaction: There must be something wrong!"),
            }

            // check root hash
            state.commit().unwrap();
            let root = state.root();
            debug!("state.root {}", root);
            assert_eq!(*root, string_2_h256(postdata.hash));
        }
    }
}

fn test_json_path(p: &str) {
    let info = fs::metadata(p).unwrap();
    if info.is_dir() {
        for entry in fs::read_dir(p).unwrap() {
            let entry = entry.unwrap();
            let p = entry.path();
            test_json_path(p.to_str().unwrap());
        }
    } else {
        test_json_file(p);
    }
}

fn skip_json_path(_reason: &str, _name: &str) {}

fn main() {
    env_logger::init();

    test_json_path(r"./tests/jsondata/GeneralStateTests/stRefundTest");
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCodeCopyTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stMemExpandingEIP150Calls",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCallDelegateCodesCallCodeHomestead",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stRevertTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stArgsZeroOneBalance",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stMemoryStressTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stTransactionTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stReturnDataTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stPreCompiledContracts",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCodeSizeLimit",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stHomesteadSpecific",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stEIP158Specific",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stZeroKnowledge2",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCreateTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stSStoreTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stTransitionTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stZeroCallsTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stBadOpcode",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stLogTests",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stNonZeroCallsTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCallDelegateCodesHomestead",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stBugs",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stShift",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stWalletTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stRandom2",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stEWASMTests",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stStaticCall",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stAttackTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stStackTests",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stPreCompiledContracts2",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stInitCodeTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stZeroKnowledge",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stEIP150singleCodeGasPrices",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stChangedEIP150",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stExample",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stSolidityTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stEIP150Specific",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stQuadraticComplexityTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stSystemOperationsTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stZeroCallsRevert",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stRecursiveCreate",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stRandom",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stDelegatecallTestHomestead",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stMemoryTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCreate2",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stSpecialTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCallCodes",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stCallCreateCallCodeTest",
    );
    skip_json_path(
        "run tests integration",
        r"./tests/jsondata/GeneralStateTests/stExtCodeHash",
    );
}
<|endoftext|>


<commit_before>// Modified from the `peeking_take_while` crate. Copyright 2017 Nick Fitzgerald. License MIT OR
// Apache-2.

use std::iter::Peekable;

pub(crate) struct PeekingTakeWhile<'a, I: Iterator, P> {
    iter: &'a mut Peekable<I>,
    pred: P,
}

impl<I: Iterator, P: Fn(&I::Item) -> bool> Iterator for PeekingTakeWhile<'_, I, P> {
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        let pred = &self.pred;
        if self.iter.peek().map_or(false, |v| !(pred)(v)) {
            None
        } else {
            self.iter.next()
        }
    }
}

pub(crate) trait PeekableExt<'a, I: Iterator>: Iterator {
    fn peeking_take_while<P: Fn(&Self::Item) -> bool>(
        &'a mut self,
        pred: P,
    ) -> PeekingTakeWhile<'a, I, P>;
}

impl<'a, I: Iterator> PeekableExt<'a, I> for Peekable<I> {
    fn peeking_take_while<P: Fn(&Self::Item) -> bool>(
        &'a mut self,
        pred: P,
    ) -> PeekingTakeWhile<'_, I, P> {
        PeekingTakeWhile { iter: self, pred }
    }
}
<commit_msg>Simplify shim in macro code<commit_after>use std::iter::Peekable;

#[allow(unused_imports)]
use standback::prelude::*;

pub(crate) struct PeekingTakeWhile<'a, I: Iterator, P> {
    iter: &'a mut Peekable<I>,
    pred: P,
}

impl<I: Iterator, P: Fn(&I::Item) -> bool> Iterator for PeekingTakeWhile<'_, I, P> {
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next_if(&self.pred)
    }
}

pub(crate) trait PeekableExt<'a, I: Iterator>: Iterator {
    fn peeking_take_while<P: Fn(&Self::Item) -> bool>(
        &'a mut self,
        pred: P,
    ) -> PeekingTakeWhile<'a, I, P>;
}

impl<'a, I: Iterator> PeekableExt<'a, I> for Peekable<I> {
    fn peeking_take_while<P: Fn(&Self::Item) -> bool>(
        &'a mut self,
        pred: P,
    ) -> PeekingTakeWhile<'_, I, P> {
        PeekingTakeWhile { iter: self, pred }
    }
}
<|endoftext|>


<commit_before>#![cfg(feature = "dnssec")]

extern crate futures;
extern crate log;
extern crate tokio_core;
extern crate trust_dns;
extern crate trust_dns_proto;

mod server_harness;

use std::env;
use std::fs::File;
use std::path::Path;
use std::io::*;
use std::net::*;

use tokio_core::reactor::Core;

use trust_dns::client::*;
use trust_dns::tcp::TcpClientStream;
use trust_dns::rr::dnssec::*;

use server_harness::*;

#[cfg(all(not(feature = "dnssec-ring"), feature = "dnssec-openssl"))]
fn confg_toml() -> &'static str {
    "openssl_dnssec.toml"
}

#[cfg(all(feature = "dnssec-ring", not(feature = "dnssec-openssl")))]
fn confg_toml() -> &'static str {
    "ring_dnssec.toml"
}

#[cfg(all(feature = "dnssec-ring", feature = "dnssec-openssl"))]
fn confg_toml() -> &'static str {
    "all_supported_dnssec.toml"
}

fn trust_anchor(public_key_path: &Path, format: KeyFormat, algorithm: Algorithm) -> TrustAnchor {
    let mut file = File::open(public_key_path).expect("key not found");
    let mut buf = Vec::<u8>::new();

    file.read_to_end(&mut buf).expect("could not read key");
    let key_pair = format.decode_key(&buf, Some("123456"), algorithm).expect(
        "could not decode key",
    );

    let public_key = key_pair.to_public_key().unwrap();
    let mut trust_anchor = TrustAnchor::new();

    trust_anchor.insert_trust_anchor(public_key);
    trust_anchor
}

fn standard_conn(port: u16, io_loop: &Core) -> BasicClientHandle {
    let addr: SocketAddr = ("127.0.0.1", port)
        .to_socket_addrs()
        .unwrap()
        .next()
        .unwrap();
    let (stream, sender) = TcpClientStream::new(addr, &io_loop.handle());
    ClientFuture::new(stream, sender, &io_loop.handle(), None)
}

fn generic_test(config_toml: &str, key_path: &str, key_format: KeyFormat, algorithm: Algorithm) {
    // use trust_dns::logger;
    // use log::LogLevel;
    // logger::TrustDnsLogger::enable_logging(LogLevel::Debug);

    let server_path = env::var("TDNS_SERVER_SRC_ROOT").unwrap_or(".".to_owned());
    let server_path = Path::new(&server_path);

    named_test_harness(config_toml, |port, _| {
        let mut io_loop = Core::new().unwrap();

        // verify all records are present
        let client = standard_conn(port, &io_loop);
        query_all_dnssec_with_rfc6975(&mut io_loop, client, algorithm);
        let client = standard_conn(port, &io_loop);
        query_all_dnssec_wo_rfc6975(&mut io_loop, client, algorithm);

        // test that request with Secure client is successful, i.e. validates chain
        let trust_anchor = trust_anchor(&server_path.join(key_path), key_format, algorithm);
        let client = standard_conn(port, &io_loop);
        let mut client = SecureClientHandle::with_trust_anchor(client, trust_anchor);

        query_a(&mut io_loop, &mut client);
    });
}

#[test]
#[cfg(feature = "dnssec-openssl")]
fn test_rsa_sha256() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA256,
    );
}

#[test]
#[cfg(feature = "dnssec-openssl")]
fn test_rsa_sha512() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA512,
    );
}

#[test]
#[cfg(feature = "dnssec-openssl")]
fn test_ecdsa_p256() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/ecdsa_p256.pem",
        KeyFormat::Pem,
        Algorithm::ECDSAP256SHA256,
    );
}

#[test]
#[cfg(feature = "dnssec-openssl")]
fn test_ecdsa_p384() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/ecdsa_p384.pem",
        KeyFormat::Pem,
        Algorithm::ECDSAP384SHA384,
    );
}

#[test]
#[cfg(feature = "dnssec-ring")]
fn test_ed25519() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/ed25519.pk8",
        KeyFormat::Pkcs8,
        Algorithm::ED25519,
    );
}

#[test]
#[should_panic]
fn test_rsa_sha1_fails() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA1,
    );
}

#[cfg(feature = "dnssec-openssl")]
#[cfg(not(windows))]
#[test]
fn test_dnssec_restart_with_update_journal() {
    // TODO: make journal path configurable, it should be in target/tests/...
    let server_path = env::var("TDNS_SERVER_SRC_ROOT").unwrap_or(".".to_owned());
    let server_path = Path::new(&server_path);
    let journal = server_path.join("tests/named_test_configs/example.com.jrnl");
    std::fs::remove_file(&journal).ok();

    generic_test(
        "dnssec_with_update.toml",
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA256,
    );

    // after running the above test, the journal file should exist
    assert!(journal.exists());

    // and all dnssec tests should still pass
    generic_test(
        "dnssec_with_update.toml",
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA256,
    );

    // and journal should still exist
    assert!(journal.exists());

    // cleanup...
    // TODO: fix journal path so that it doesn't leave the dir dirty... this might make windows an option after that
    std::fs::remove_file(&journal).expect("failed to cleanup after test");
}
<commit_msg>disable rsa named tests on windows<commit_after>#![cfg(feature = "dnssec")]
#![cfg(not(windows))]

extern crate futures;
extern crate log;
extern crate tokio_core;
extern crate trust_dns;
extern crate trust_dns_proto;

mod server_harness;

use std::env;
use std::fs::File;
use std::path::Path;
use std::io::*;
use std::net::*;

use tokio_core::reactor::Core;

use trust_dns::client::*;
use trust_dns::tcp::TcpClientStream;
use trust_dns::rr::dnssec::*;

use server_harness::*;

#[cfg(all(not(feature = "dnssec-ring"), feature = "dnssec-openssl"))]
fn confg_toml() -> &'static str {
    "openssl_dnssec.toml"
}

#[cfg(all(feature = "dnssec-ring", not(feature = "dnssec-openssl")))]
fn confg_toml() -> &'static str {
    "ring_dnssec.toml"
}

#[cfg(all(feature = "dnssec-ring", feature = "dnssec-openssl"))]
fn confg_toml() -> &'static str {
    "all_supported_dnssec.toml"
}

fn trust_anchor(public_key_path: &Path, format: KeyFormat, algorithm: Algorithm) -> TrustAnchor {
    let mut file = File::open(public_key_path).expect("key not found");
    let mut buf = Vec::<u8>::new();

    file.read_to_end(&mut buf).expect("could not read key");
    let key_pair = format.decode_key(&buf, Some("123456"), algorithm).expect(
        "could not decode key",
    );

    let public_key = key_pair.to_public_key().unwrap();
    let mut trust_anchor = TrustAnchor::new();

    trust_anchor.insert_trust_anchor(public_key);
    trust_anchor
}

fn standard_conn(port: u16, io_loop: &Core) -> BasicClientHandle {
    let addr: SocketAddr = ("127.0.0.1", port)
        .to_socket_addrs()
        .unwrap()
        .next()
        .unwrap();
    let (stream, sender) = TcpClientStream::new(addr, &io_loop.handle());
    ClientFuture::new(stream, sender, &io_loop.handle(), None)
}

fn generic_test(config_toml: &str, key_path: &str, key_format: KeyFormat, algorithm: Algorithm) {
    // use trust_dns::logger;
    // use log::LogLevel;
    // logger::TrustDnsLogger::enable_logging(LogLevel::Debug);

    let server_path = env::var("TDNS_SERVER_SRC_ROOT").unwrap_or(".".to_owned());
    let server_path = Path::new(&server_path);

    named_test_harness(config_toml, |port, _| {
        let mut io_loop = Core::new().unwrap();

        // verify all records are present
        let client = standard_conn(port, &io_loop);
        query_all_dnssec_with_rfc6975(&mut io_loop, client, algorithm);
        let client = standard_conn(port, &io_loop);
        query_all_dnssec_wo_rfc6975(&mut io_loop, client, algorithm);

        // test that request with Secure client is successful, i.e. validates chain
        let trust_anchor = trust_anchor(&server_path.join(key_path), key_format, algorithm);
        let client = standard_conn(port, &io_loop);
        let mut client = SecureClientHandle::with_trust_anchor(client, trust_anchor);

        query_a(&mut io_loop, &mut client);
    });
}

#[test]
#[cfg(feature = "dnssec-openssl")]
fn test_rsa_sha256() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA256,
    );
}

#[test]
#[cfg(feature = "dnssec-openssl")]
fn test_rsa_sha512() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA512,
    );
}

#[test]
#[cfg(feature = "dnssec-openssl")]
fn test_ecdsa_p256() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/ecdsa_p256.pem",
        KeyFormat::Pem,
        Algorithm::ECDSAP256SHA256,
    );
}

#[test]
#[cfg(feature = "dnssec-openssl")]
fn test_ecdsa_p384() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/ecdsa_p384.pem",
        KeyFormat::Pem,
        Algorithm::ECDSAP384SHA384,
    );
}

#[test]
#[cfg(feature = "dnssec-ring")]
fn test_ed25519() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/ed25519.pk8",
        KeyFormat::Pkcs8,
        Algorithm::ED25519,
    );
}

#[test]
#[should_panic]
fn test_rsa_sha1_fails() {
    generic_test(
        confg_toml(),
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA1,
    );
}

#[cfg(feature = "dnssec-openssl")]
#[test]
fn test_dnssec_restart_with_update_journal() {
    // TODO: make journal path configurable, it should be in target/tests/...
    let server_path = env::var("TDNS_SERVER_SRC_ROOT").unwrap_or(".".to_owned());
    let server_path = Path::new(&server_path);
    let journal = server_path.join("tests/named_test_configs/example.com.jrnl");
    std::fs::remove_file(&journal).ok();

    generic_test(
        "dnssec_with_update.toml",
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA256,
    );

    // after running the above test, the journal file should exist
    assert!(journal.exists());

    // and all dnssec tests should still pass
    generic_test(
        "dnssec_with_update.toml",
        "tests/named_test_configs/dnssec/rsa_2048.pem",
        KeyFormat::Pem,
        Algorithm::RSASHA256,
    );

    // and journal should still exist
    assert!(journal.exists());

    // cleanup...
    // TODO: fix journal path so that it doesn't leave the dir dirty... this might make windows an option after that
    std::fs::remove_file(&journal).expect("failed to cleanup after test");
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use core::fmt;
use core::cell::UnsafeCell;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering::{Acquire, Release, AcqRel};

use task::Waker;

/// A synchronization primitive for task wakeup.
///
/// Sometimes the task interested in a given event will change over time.
/// An `AtomicWaker` can coordinate concurrent notifications with the consumer
/// potentially "updating" the underlying task to wake up. This is useful in
/// scenarios where a computation completes in another thread and wants to
/// notify the consumer, but the consumer is in the process of being migrated to
/// a new logical task.
///
/// Consumers should call `register` before checking the result of a computation
/// and producers should call `wake` after producing the computation (this
/// differs from the usual `thread::park` pattern). It is also permitted for
/// `wake` to be called **before** `register`. This results in a no-op.
///
/// A single `AtomicWaker` may be reused for any number of calls to `register` or
/// `wake`.
///
/// `AtomicWaker` does not provide any memory ordering guarantees, as such the
/// user should use caution and use other synchronization primitives to guard
/// the result of the underlying computation.
pub struct AtomicWaker {
    state: AtomicUsize,
    waker: UnsafeCell<Option<Waker>>,
}

/// Initial state, the `AtomicWaker` is currently not being used.
///
/// The value `2` is picked specifically because it between the write lock &
/// read lock values. Since the read lock is represented by an incrementing
/// counter, this enables an atomic fetch_sub operation to be used for releasing
/// a lock.
const WAITING: usize = 2;

/// The `register` function has determined that the task is no longer current.
/// This implies that `AtomicWaker::register` is being called from a different
/// task than is represented by the currently stored task. The write lock is
/// obtained to update the task cell.
const LOCKED_WRITE: usize = 0;

/// At least one call to `wake` happened concurrently to `register` updating
/// the task cell. This state is detected when `register` exits the mutation
/// code and signals to `register` that it is responsible for notifying its own
/// task.
const LOCKED_WRITE_NOTIFIED: usize = 1;

/// The `wake` function has locked access to the task cell for notification.
///
/// The constant is left here mostly for documentation reasons.
#[allow(dead_code)]
const LOCKED_READ: usize = 3;

impl AtomicWaker {
    /// Create an `AtomicWaker` with no initial `Waker`
    pub fn new() -> AtomicWaker {
        // Make sure that task is Sync
        trait AssertSync: Sync {}
        impl AssertSync for Waker {}

        AtomicWaker {
            state: AtomicUsize::new(WAITING),
            waker: UnsafeCell::new(None),
        }
    }

    /// Registers the waker to be notified on calls to `wake`.
    ///
    /// The new task will take place of any previous tasks that were registered
    /// by previous calls to `register`. Any calls to `wake` that happen after
    /// a call to `register` (as defined by the memory ordering rules), will
    /// notify the `register` caller's task and deregister the waker from future
    /// notifications. Because of this, callers should ensure `register` gets
    /// invoked with a new `Waker` **each** time they require a wakeup.
    ///
    /// It is safe to call `register` with multiple other threads concurrently
    /// calling `wake`. This will result in the `register` caller's current
    /// task being notified once.
    ///
    /// This function is safe to call concurrently, but this is generally a bad
    /// idea. Concurrent calls to `register` will attempt to register different
    /// tasks to be notified. One of the callers will win and have its task set,
    /// but there is no guarantee as to which caller will succeed.
    ///
    /// # Examples
    ///
    /// Here is how `register` is used when implementing a flag.
    ///
    /// ```
    /// # use futures_core::{Future, Poll, Never};
    /// # use futures_core::Async::*;
    /// # use futures_core::task::{self, AtomicWaker};
    /// # use std::sync::atomic::AtomicBool;
    /// # use std::sync::atomic::Ordering::SeqCst;
    /// struct Flag {
    ///     waker: AtomicWaker,
    ///     set: AtomicBool,
    /// }
    ///
    /// impl Future for Flag {
    ///     type Item = ();
    ///     type Error = Never;
    ///
    ///     fn poll(&mut self, cx: &mut task::Context) -> Poll<(), Never> {
    ///         // Register **before** checkin `set` to avoid a race condition
    ///         // that would result in lost notifications.
    ///         self.waker.register(cx.waker());
    ///
    ///         if self.set.load(SeqCst) {
    ///             Ok(Ready(()))
    ///         } else {
    ///             Ok(Pending)
    ///         }
    ///     }
    /// }
    /// ```
    pub fn register(&self, waker: &Waker) {
        match self.state.compare_and_swap(WAITING, LOCKED_WRITE, Acquire) {
            WAITING => {
                unsafe {
                    // Locked acquired, update the waker cell
                    *self.waker.get() = Some(waker.clone());

                    // Release the lock. If the state transitioned to
                    // `LOCKED_NOTIFIED`, this means that an notify has been
                    // signaled, so notify the task.
                    //
                    // Start by assuming that the state is LOCKED_WRITE as this
                    // is what we jut set it to.
                    let mut curr = LOCKED_WRITE;

                    loop {
                        let res = self.state.compare_exchange(
                            curr, WAITING, AcqRel, Acquire);

                        match res {
                            Ok(_) => return,
                            Err(actual) => {
                                // Update `curr` for the next iteration of the
                                // loop
                                curr = actual;
                            }
                        }

                        // Since we aren't using the weak variant of the atomic
                        // operation, the only possible option for `curr` is
                        // `LOCKED_WRITE_NOTIFIED`.
                        assert_eq!(curr, LOCKED_WRITE_NOTIFIED);

                        if let Some(waker) = (*self.waker.get()).take() {
                            waker.wake();
                        }
                    }
                }
            }
            LOCKED_WRITE | LOCKED_WRITE_NOTIFIED => {
                // A thread is concurrently calling `register`. This shouldn't
                // happen as it doesn't really make much sense, but it isn't
                // unsafe per se. Since two threads are concurrently trying to
                // update the task, it's undefined which one "wins" (no ordering
                // guarantees), so we can just do nothing.
            }
            state => {
                debug_assert!(state != LOCKED_WRITE, "unexpected state LOCKED_WRITE");
                debug_assert!(state != LOCKED_WRITE_NOTIFIED, "unexpected state LOCKED_WRITE_NOTIFIED");

                // Currently in a read locked state, this implies that `wake`
                // is currently being called on the old task handle. So, we call
                // `wake` on the new task handle
                waker.wake();
            }
        }
    }

    /// Calls `wake` on the last `Waker` passed to `register`.
    ///
    /// If `register` has not been called yet, then this does nothing.
    pub fn wake(&self) {
        let mut curr = WAITING;

        loop {
            if curr == LOCKED_WRITE {
                // Transition the state to LOCKED_NOTIFIED
                let actual = self.state.compare_and_swap(LOCKED_WRITE, LOCKED_WRITE_NOTIFIED, Release);

                if curr == actual {
                    // Success, return
                    return;
                }

                // update current state variable and try again
                curr = actual;

            } else if curr == LOCKED_WRITE_NOTIFIED {
                // Currently in `LOCKED_WRITE_NOTIFIED` state, nothing else to do.
                return;

            } else {
                // Currently in a LOCKED_READ state, so attempt to increment the
                // lock count.
                let actual = self.state.compare_and_swap(curr, curr + 1, Acquire);

                // Locked acquired
                if actual == curr {
                    // Notify the task
                    unsafe {
                        if let Some(waker) = (*self.waker.get()).take() {
                            waker.wake();
                        }
                    }

                    // Release the lock
                    self.state.fetch_sub(1, Release);

                    // Done
                    return;
                }

                // update current state variable and try again
                curr = actual;

            }
        }
    }
}

impl Default for AtomicWaker {
    fn default() -> Self {
        AtomicWaker::new()
    }
}

impl fmt::Debug for AtomicWaker {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "AtomicWaker")
    }
}

unsafe impl Send for AtomicWaker {}
unsafe impl Sync for AtomicWaker {}
<commit_msg>Add missing g<commit_after>#![allow(dead_code)]

use core::fmt;
use core::cell::UnsafeCell;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering::{Acquire, Release, AcqRel};

use task::Waker;

/// A synchronization primitive for task wakeup.
///
/// Sometimes the task interested in a given event will change over time.
/// An `AtomicWaker` can coordinate concurrent notifications with the consumer
/// potentially "updating" the underlying task to wake up. This is useful in
/// scenarios where a computation completes in another thread and wants to
/// notify the consumer, but the consumer is in the process of being migrated to
/// a new logical task.
///
/// Consumers should call `register` before checking the result of a computation
/// and producers should call `wake` after producing the computation (this
/// differs from the usual `thread::park` pattern). It is also permitted for
/// `wake` to be called **before** `register`. This results in a no-op.
///
/// A single `AtomicWaker` may be reused for any number of calls to `register` or
/// `wake`.
///
/// `AtomicWaker` does not provide any memory ordering guarantees, as such the
/// user should use caution and use other synchronization primitives to guard
/// the result of the underlying computation.
pub struct AtomicWaker {
    state: AtomicUsize,
    waker: UnsafeCell<Option<Waker>>,
}

/// Initial state, the `AtomicWaker` is currently not being used.
///
/// The value `2` is picked specifically because it between the write lock &
/// read lock values. Since the read lock is represented by an incrementing
/// counter, this enables an atomic fetch_sub operation to be used for releasing
/// a lock.
const WAITING: usize = 2;

/// The `register` function has determined that the task is no longer current.
/// This implies that `AtomicWaker::register` is being called from a different
/// task than is represented by the currently stored task. The write lock is
/// obtained to update the task cell.
const LOCKED_WRITE: usize = 0;

/// At least one call to `wake` happened concurrently to `register` updating
/// the task cell. This state is detected when `register` exits the mutation
/// code and signals to `register` that it is responsible for notifying its own
/// task.
const LOCKED_WRITE_NOTIFIED: usize = 1;

/// The `wake` function has locked access to the task cell for notification.
///
/// The constant is left here mostly for documentation reasons.
#[allow(dead_code)]
const LOCKED_READ: usize = 3;

impl AtomicWaker {
    /// Create an `AtomicWaker` with no initial `Waker`
    pub fn new() -> AtomicWaker {
        // Make sure that task is Sync
        trait AssertSync: Sync {}
        impl AssertSync for Waker {}

        AtomicWaker {
            state: AtomicUsize::new(WAITING),
            waker: UnsafeCell::new(None),
        }
    }

    /// Registers the waker to be notified on calls to `wake`.
    ///
    /// The new task will take place of any previous tasks that were registered
    /// by previous calls to `register`. Any calls to `wake` that happen after
    /// a call to `register` (as defined by the memory ordering rules), will
    /// notify the `register` caller's task and deregister the waker from future
    /// notifications. Because of this, callers should ensure `register` gets
    /// invoked with a new `Waker` **each** time they require a wakeup.
    ///
    /// It is safe to call `register` with multiple other threads concurrently
    /// calling `wake`. This will result in the `register` caller's current
    /// task being notified once.
    ///
    /// This function is safe to call concurrently, but this is generally a bad
    /// idea. Concurrent calls to `register` will attempt to register different
    /// tasks to be notified. One of the callers will win and have its task set,
    /// but there is no guarantee as to which caller will succeed.
    ///
    /// # Examples
    ///
    /// Here is how `register` is used when implementing a flag.
    ///
    /// ```
    /// # use futures_core::{Future, Poll, Never};
    /// # use futures_core::Async::*;
    /// # use futures_core::task::{self, AtomicWaker};
    /// # use std::sync::atomic::AtomicBool;
    /// # use std::sync::atomic::Ordering::SeqCst;
    /// struct Flag {
    ///     waker: AtomicWaker,
    ///     set: AtomicBool,
    /// }
    ///
    /// impl Future for Flag {
    ///     type Item = ();
    ///     type Error = Never;
    ///
    ///     fn poll(&mut self, cx: &mut task::Context) -> Poll<(), Never> {
    ///         // Register **before** checking `set` to avoid a race condition
    ///         // that would result in lost notifications.
    ///         self.waker.register(cx.waker());
    ///
    ///         if self.set.load(SeqCst) {
    ///             Ok(Ready(()))
    ///         } else {
    ///             Ok(Pending)
    ///         }
    ///     }
    /// }
    /// ```
    pub fn register(&self, waker: &Waker) {
        match self.state.compare_and_swap(WAITING, LOCKED_WRITE, Acquire) {
            WAITING => {
                unsafe {
                    // Locked acquired, update the waker cell
                    *self.waker.get() = Some(waker.clone());

                    // Release the lock. If the state transitioned to
                    // `LOCKED_NOTIFIED`, this means that an notify has been
                    // signaled, so notify the task.
                    //
                    // Start by assuming that the state is LOCKED_WRITE as this
                    // is what we jut set it to.
                    let mut curr = LOCKED_WRITE;

                    loop {
                        let res = self.state.compare_exchange(
                            curr, WAITING, AcqRel, Acquire);

                        match res {
                            Ok(_) => return,
                            Err(actual) => {
                                // Update `curr` for the next iteration of the
                                // loop
                                curr = actual;
                            }
                        }

                        // Since we aren't using the weak variant of the atomic
                        // operation, the only possible option for `curr` is
                        // `LOCKED_WRITE_NOTIFIED`.
                        assert_eq!(curr, LOCKED_WRITE_NOTIFIED);

                        if let Some(waker) = (*self.waker.get()).take() {
                            waker.wake();
                        }
                    }
                }
            }
            LOCKED_WRITE | LOCKED_WRITE_NOTIFIED => {
                // A thread is concurrently calling `register`. This shouldn't
                // happen as it doesn't really make much sense, but it isn't
                // unsafe per se. Since two threads are concurrently trying to
                // update the task, it's undefined which one "wins" (no ordering
                // guarantees), so we can just do nothing.
            }
            state => {
                debug_assert!(state != LOCKED_WRITE, "unexpected state LOCKED_WRITE");
                debug_assert!(state != LOCKED_WRITE_NOTIFIED, "unexpected state LOCKED_WRITE_NOTIFIED");

                // Currently in a read locked state, this implies that `wake`
                // is currently being called on the old task handle. So, we call
                // `wake` on the new task handle
                waker.wake();
            }
        }
    }

    /// Calls `wake` on the last `Waker` passed to `register`.
    ///
    /// If `register` has not been called yet, then this does nothing.
    pub fn wake(&self) {
        let mut curr = WAITING;

        loop {
            if curr == LOCKED_WRITE {
                // Transition the state to LOCKED_NOTIFIED
                let actual = self.state.compare_and_swap(LOCKED_WRITE, LOCKED_WRITE_NOTIFIED, Release);

                if curr == actual {
                    // Success, return
                    return;
                }

                // update current state variable and try again
                curr = actual;

            } else if curr == LOCKED_WRITE_NOTIFIED {
                // Currently in `LOCKED_WRITE_NOTIFIED` state, nothing else to do.
                return;

            } else {
                // Currently in a LOCKED_READ state, so attempt to increment the
                // lock count.
                let actual = self.state.compare_and_swap(curr, curr + 1, Acquire);

                // Locked acquired
                if actual == curr {
                    // Notify the task
                    unsafe {
                        if let Some(waker) = (*self.waker.get()).take() {
                            waker.wake();
                        }
                    }

                    // Release the lock
                    self.state.fetch_sub(1, Release);

                    // Done
                    return;
                }

                // update current state variable and try again
                curr = actual;

            }
        }
    }
}

impl Default for AtomicWaker {
    fn default() -> Self {
        AtomicWaker::new()
    }
}

impl fmt::Debug for AtomicWaker {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "AtomicWaker")
    }
}

unsafe impl Send for AtomicWaker {}
unsafe impl Sync for AtomicWaker {}
<|endoftext|>