<commit_before>#[macro_use]
extern crate bencher;
extern crate rav1e;
extern crate rand;
extern crate libc;

use bencher::Bencher;
use rand::{ChaChaRng, Rng};
use rav1e::predict::*;

extern {
    fn highbd_dc_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_dc_left_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_dc_top_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_h_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_v_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
        bh: libc::c_int, above: *const u16,
        left: *const u16, bd: libc::c_int);
}

#[inline(always)]
fn pred_dc_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_dc_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

#[inline(always)]
fn pred_h_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_h_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

#[inline(always)]
fn pred_v_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_v_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

const MAX_ITER: usize = 50000;

fn setup_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>, Vec<u16>) {
    let o1 = vec![0u16; 32 * 32];
    let above: Vec<u16> = (0..32).map(|_| ra.gen()).collect();
    let left: Vec<u16> = (0..32).map(|_| ra.gen()).collect();

    (above, left, o1)
}

fn native(b: &mut Bencher) {
    let mut ra = ChaChaRng::new_unseeded();
    let (above, left, mut o2) = setup_pred(&mut ra);

    b.iter(|| {
        for _ in 0..MAX_ITER {
        pred_dc::<Block4x4>(&mut o2, 32, &above[..4], &left[..4]);
        }
    })
}

fn aom(b: &mut Bencher) {
    let mut ra = ChaChaRng::new_unseeded();
    let (above, left, mut o2) = setup_pred(&mut ra);

    b.iter(|| {
        for _ in 0..MAX_ITER {
            pred_dc_4x4(&mut o2, 32, &above[..4], &left[..4]);
        }
    })
}

use rav1e::*;
use rav1e::context::*;
use rav1e::predict::*;
use rav1e::partition::*;
use rav1e::ec;

fn write_b_bench(b: &mut Bencher) {
    let mut fi = FrameInvariants::new(1024, 1024);
    let w = ec::Writer::new();
    let fc = CDFContext::new();
    let bc = BlockContext::new(fi.sb_width * 16, fi.sb_height * 16);
    let mut fs = FrameState::new(&fi);
    let mut cw = ContextWriter {
        w: w,
        fc: fc,
        bc: bc,
    };

    let mode = PredictionMode::DC_PRED;
    let tx_type = TxType::DCT_DCT;

    let sbx = 0;
    let sby = 0;

    b.iter(|| {
        for &mode in RAV1E_INTRA_MODES {
            let sbo = SuperBlockOffset { x: sbx, y: sby };
            for p in 1..3 {
                for by in 0..8 {
                    for bx in 0..8 {
                        let bo = sbo.block_offset(bx, by);
                            write_b(&mut cw, &mut fi, &mut fs, p, &bo, mode, tx_type);
                    }
                }
            }
        }
    });
}

benchmark_group!(predict, aom, native, write_b_bench);
benchmark_main!(predict);
<commit_msg>Add benchmarks for h_pred and v_pred<commit_after>#[macro_use]
extern crate bencher;
extern crate rav1e;
extern crate rand;
extern crate libc;

use bencher::Bencher;
use rand::{ChaChaRng, Rng};
use rav1e::predict::*;

extern {
    fn highbd_dc_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_h_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
                           bh: libc::c_int, above: *const u16,
                           left: *const u16, bd: libc::c_int);
    fn highbd_v_predictor(dst: *mut u16, stride: libc::ptrdiff_t, bw: libc::c_int,
        bh: libc::c_int, above: *const u16,
        left: *const u16, bd: libc::c_int);
}

#[inline(always)]
fn pred_dc_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_dc_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

#[inline(always)]
fn pred_h_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_h_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

#[inline(always)]
fn pred_v_4x4(output: &mut [u16], stride: usize, above: &[u16], left: &[u16]) {
    unsafe {
        highbd_v_predictor(output.as_mut_ptr(), stride as libc::ptrdiff_t, 4, 4, above.as_ptr(), left.as_ptr(), 8);
    }
}

const MAX_ITER: usize = 50000;

fn setup_pred(ra: &mut ChaChaRng) -> (Vec<u16>, Vec<u16>, Vec<u16>) {
    let o1 = vec![0u16; 32 * 32];
    let above: Vec<u16> = (0..32).map(|_| ra.gen()).collect();
    let left: Vec<u16> = (0..32).map(|_| ra.gen()).collect();

    (above, left, o1)
}

fn intra_dc_pred_native(b: &mut Bencher) {
    let mut ra = ChaChaRng::new_unseeded();
    let (above, left, mut o2) = setup_pred(&mut ra);

    b.iter(|| {
        for _ in 0..MAX_ITER {
        pred_dc::<Block4x4>(&mut o2, 32, &above[..4], &left[..4]);
        }
    })
}

fn intra_dc_pred_aom(b: &mut Bencher) {
    let mut ra = ChaChaRng::new_unseeded();
    let (above, left, mut o2) = setup_pred(&mut ra);

    b.iter(|| {
        for _ in 0..MAX_ITER {
            pred_dc_4x4(&mut o2, 32, &above[..4], &left[..4]);
        }
    })
}

fn intra_h_pred_native(b: &mut Bencher) {
    let mut ra = ChaChaRng::new_unseeded();
    let (_above, left, mut o2) = setup_pred(&mut ra);

    b.iter(|| {
        for _ in 0..MAX_ITER {
            pred_h::<Block4x4>(&mut o2, 32, &left[..4]);
        }
    })
}

fn intra_h_pred_aom(b: &mut Bencher) {
    let mut ra = ChaChaRng::new_unseeded();
    let (above, left, mut o2) = setup_pred(&mut ra);

    b.iter(|| {
        for _ in 0..MAX_ITER {
            pred_h_4x4(&mut o2, 32, &above[..4], &left[..4]);
        }
    })
}

fn intra_v_pred_native(b: &mut Bencher) {
    let mut ra = ChaChaRng::new_unseeded();
    let (above, _left, mut o2) = setup_pred(&mut ra);

    b.iter(|| {
        for _ in 0..MAX_ITER {
            pred_v::<Block4x4>(&mut o2, 32, &above[..4]);
        }
    })
}

fn intra_v_pred_aom(b: &mut Bencher) {
    let mut ra = ChaChaRng::new_unseeded();
    let (above, left, mut o2) = setup_pred(&mut ra);

    b.iter(|| {
        for _ in 0..MAX_ITER {
            pred_v_4x4(&mut o2, 32, &above[..4], &left[..4]);
        }
    })
}

use rav1e::*;
use rav1e::context::*;
use rav1e::partition::*;
use rav1e::ec;

fn write_b_bench(b: &mut Bencher) {
    let mut fi = FrameInvariants::new(1024, 1024);
    let w = ec::Writer::new();
    let fc = CDFContext::new();
    let bc = BlockContext::new(fi.sb_width * 16, fi.sb_height * 16);
    let mut fs = FrameState::new(&fi);
    let mut cw = ContextWriter {
        w: w,
        fc: fc,
        bc: bc,
    };

    let mode = PredictionMode::DC_PRED;
    let tx_type = TxType::DCT_DCT;

    let sbx = 0;
    let sby = 0;

    b.iter(|| {
        for &mode in RAV1E_INTRA_MODES {
            let sbo = SuperBlockOffset { x: sbx, y: sby };
            for p in 1..3 {
                for by in 0..8 {
                    for bx in 0..8 {
                        let bo = sbo.block_offset(bx, by);
                            write_b(&mut cw, &mut fi, &mut fs, p, &bo, mode, tx_type);
                    }
                }
            }
        }
    });
}

benchmark_group!(intra, intra_dc_pred_native, intra_dc_pred_aom,
    intra_h_pred_native, intra_h_pred_aom, intra_v_pred_native,
    intra_v_pred_aom);
benchmark_group!(ec, write_b_bench);
benchmark_main!(intra, ec);
<|endoftext|>


<commit_before>// Copyright (c) 2017-2018, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

mod dist;
mod mc;
mod plane;
mod predict;
mod rdo;
mod transform;

use rav1e::bench::api::*;
use rav1e::bench::cdef::*;
use rav1e::bench::context::*;
use rav1e::bench::ec::*;
use rav1e::bench::encoder::*;
use rav1e::bench::partition::*;
use rav1e::bench::predict::*;
use rav1e::bench::rdo::*;
use rav1e::bench::transform::*;

use crate::plane::plane;
use crate::rdo::rdo;
use crate::transform::{forward_transforms, inverse_transforms};

use criterion::*;
use std::time::Duration;

fn write_b(c: &mut Criterion) {
  for &tx_size in &[TxSize::TX_4X4, TxSize::TX_8X8] {
    for &qi in &[20, 55] {
      let n = format!("write_b_bench({:?}, {})", tx_size, qi);
      c.bench_function(&n, move |b| write_b_bench(b, tx_size, qi));
    }
  }
}

fn write_b_bench(b: &mut Bencher, tx_size: TxSize, qindex: usize) {
  let config = EncoderConfig {
    width: 1024,
    height: 1024,
    quantizer: qindex,
    speed_settings: SpeedSettings::from_preset(10),
    ..Default::default()
  };
  let sequence = Sequence::new(&Default::default());
  let fi = FrameInvariants::<u16>::new(config, sequence);
  let mut w = WriterEncoder::new();
  let mut fc = CDFContext::new(fi.base_q_idx);
  let mut fb = FrameBlocks::new(fi.sb_width * 16, fi.sb_height * 16);
  let mut tb = fb.as_tile_blocks_mut();
  let bc = BlockContext::new(&mut tb);
  let mut fs = FrameState::new(&fi);
  let mut ts = fs.as_tile_state_mut();
  // For now, restoration unit size is locked to superblock size.
  let mut cw = ContextWriter::new(&mut fc, bc);

  let tx_type = TxType::DCT_DCT;

  let sbx = 0;
  let sby = 0;
  let ac = &[0i16; 32 * 32];

  b.iter(|| {
    for &mode in RAV1E_INTRA_MODES {
      let sbo = TileSuperBlockOffset(SuperBlockOffset { x: sbx, y: sby });
      for p in 1..3 {
        ts.qc.update(
          fi.base_q_idx,
          tx_size,
          mode.is_intra(),
          8,
          fi.dc_delta_q[p],
          fi.ac_delta_q[p],
        );
        for by in 0..8 {
          for bx in 0..8 {
            // For ex, 8x8 tx should be applied to even numbered (bx,by)
            if (tx_size.width_mi() >> 1) & bx != 0
              || (tx_size.height_mi() >> 1) & by != 0
            {
              continue;
            };
            let bo = sbo.block_offset(bx, by);
            let tx_bo =
              TileBlockOffset(BlockOffset { x: bo.0.x + bx, y: bo.0.y + by });
            let po = tx_bo.plane_offset(&ts.input.planes[p].cfg);
            encode_tx_block(
              &fi,
              &mut ts,
              &mut cw,
              &mut w,
              p,
              bo,
              0,
              0,
              tx_bo,
              mode,
              tx_size,
              tx_type,
              tx_size.block_size(),
              po,
              false,
              qindex as u8,
              ac,
              IntraParam::None,
              RDOType::PixelDistRealRate,
              true,
            );
          }
        }
      }
    }
  });
}

fn cdef_frame(c: &mut Criterion) {
  let w = 128;
  let h = 128;
  let n = format!("cdef_frame({}, {})", w, h);
  c.bench_function(&n, move |b| cdef_frame_bench(b, w, h));
}

fn cdef_frame_bench(b: &mut Bencher, width: usize, height: usize) {
  let config = EncoderConfig {
    width,
    height,
    quantizer: 100,
    speed_settings: SpeedSettings::from_preset(10),
    ..Default::default()
  };
  let sequence = Sequence::new(&Default::default());
  let fi = FrameInvariants::<u16>::new(config, sequence);
  let fb = FrameBlocks::new(fi.sb_width * 16, fi.sb_height * 16);
  let mut fs = FrameState::new(&fi);
  let in_frame = fs.rec.clone();
  let mut ts = fs.as_tile_state_mut();

  b.iter(|| {
    cdef_filter_tile(&fi, &mut ts.rec, &fb.as_tile_blocks(), &in_frame)
  });
}

fn cfl_rdo(c: &mut Criterion) {
  for &bsize in &[
    BlockSize::BLOCK_4X4,
    BlockSize::BLOCK_8X8,
    BlockSize::BLOCK_16X16,
    BlockSize::BLOCK_32X32,
  ] {
    let n = format!("cfl_rdo({:?})", bsize);
    c.bench_function(&n, move |b| cfl_rdo_bench(b, bsize));
  }
}

fn cfl_rdo_bench(b: &mut Bencher, bsize: BlockSize) {
  let config = EncoderConfig {
    width: 1024,
    height: 1024,
    quantizer: 100,
    speed_settings: SpeedSettings::from_preset(10),
    ..Default::default()
  };
  let sequence = Sequence::new(&Default::default());
  let fi = FrameInvariants::<u16>::new(config, sequence);
  let mut fs = FrameState::new(&fi);
  let mut ts = fs.as_tile_state_mut();
  let offset = TileBlockOffset(BlockOffset { x: 1, y: 1 });
  b.iter(|| rdo_cfl_alpha(&mut ts, offset, bsize, bsize.tx_size(), &fi))
}

fn ec_bench(c: &mut Criterion) {
  c.bench_function("update_cdf_4", update_cdf_4);
}

fn update_cdf_4(b: &mut Bencher) {
  let mut cdf = [7296, 3819, 1616, 0, 0];
  b.iter(|| {
    for i in 0..1000 {
      update_cdf(&mut cdf, i & 3);
      black_box(cdf);
    }
  });
}

criterion_group!(intra_prediction, predict::pred_bench,);

criterion_group!(cfl, cfl_rdo);
criterion_group!(cdef, cdef_frame);
criterion_group!(write_block, write_b);
criterion_group! {
  name = dist;
  config = Criterion::default().warm_up_time(Duration::new(1,0));
  targets = dist::get_sad, dist::get_satd
}

criterion_group!(ec, ec_bench);

criterion_main!(
  write_block,
  intra_prediction,
  cdef,
  cfl,
  dist,
  forward_transforms,
  inverse_transforms,
  ec,
  rdo,
  plane,
  mc::mc
);
<commit_msg>Update benchmark for lf_assembly_reenable<commit_after>// Copyright (c) 2017-2018, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

mod dist;
mod mc;
mod plane;
mod predict;
mod rdo;
mod transform;

use rav1e::bench::api::*;
use rav1e::bench::cdef::*;
use rav1e::bench::context::*;
use rav1e::bench::ec::*;
use rav1e::bench::encoder::*;
use rav1e::bench::partition::*;
use rav1e::bench::predict::*;
use rav1e::bench::rdo::*;
use rav1e::bench::transform::*;

use crate::plane::plane;
use crate::rdo::rdo;
use crate::transform::{forward_transforms, inverse_transforms};

use criterion::*;
use std::time::Duration;

fn write_b(c: &mut Criterion) {
  for &tx_size in &[TxSize::TX_4X4, TxSize::TX_8X8] {
    for &qi in &[20, 55] {
      let n = format!("write_b_bench({:?}, {})", tx_size, qi);
      c.bench_function(&n, move |b| write_b_bench(b, tx_size, qi));
    }
  }
}

fn write_b_bench(b: &mut Bencher, tx_size: TxSize, qindex: usize) {
  let config = EncoderConfig {
    width: 1024,
    height: 1024,
    quantizer: qindex,
    speed_settings: SpeedSettings::from_preset(10),
    ..Default::default()
  };
  let sequence = Sequence::new(&Default::default());
  let fi = FrameInvariants::<u16>::new(config, sequence);
  let mut w = WriterEncoder::new();
  let mut fc = CDFContext::new(fi.base_q_idx);
  let mut fb = FrameBlocks::new(fi.sb_width * 16, fi.sb_height * 16);
  let mut tb = fb.as_tile_blocks_mut();
  let bc = BlockContext::new(&mut tb);
  let mut fs = FrameState::new(&fi);
  let mut ts = fs.as_tile_state_mut();
  // For now, restoration unit size is locked to superblock size.
  let mut cw = ContextWriter::new(&mut fc, bc);

  let tx_type = TxType::DCT_DCT;

  let sbx = 0;
  let sby = 0;
  let ac = &[0i16; 32 * 32];

  b.iter(|| {
    for &mode in RAV1E_INTRA_MODES {
      let sbo = TileSuperBlockOffset(SuperBlockOffset { x: sbx, y: sby });
      for p in 1..3 {
        ts.qc.update(
          fi.base_q_idx,
          tx_size,
          mode.is_intra(),
          8,
          fi.dc_delta_q[p],
          fi.ac_delta_q[p],
        );
        for by in 0..8 {
          for bx in 0..8 {
            // For ex, 8x8 tx should be applied to even numbered (bx,by)
            if (tx_size.width_mi() >> 1) & bx != 0
              || (tx_size.height_mi() >> 1) & by != 0
            {
              continue;
            };
            let bo = sbo.block_offset(bx, by);
            let tx_bo =
              TileBlockOffset(BlockOffset { x: bo.0.x + bx, y: bo.0.y + by });
            let po = tx_bo.plane_offset(&ts.input.planes[p].cfg);
            encode_tx_block(
              &fi,
              &mut ts,
              &mut cw,
              &mut w,
              p,
              bo,
              0,
              0,
              tx_bo,
              mode,
              tx_size,
              tx_type,
              tx_size.block_size(),
              po,
              false,
              qindex as u8,
              ac,
              IntraParam::None,
              RDOType::PixelDistRealRate,
              true,
            );
          }
        }
      }
    }
  });
}

fn cdef_frame(c: &mut Criterion) {
  let w = 128;
  let h = 128;
  let n = format!("cdef_frame({}, {})", w, h);
  c.bench_function(&n, move |b| cdef_frame_bench(b, w, h));
}

fn cdef_frame_bench(b: &mut Bencher, width: usize, height: usize) {
  let config = EncoderConfig {
    width,
    height,
    quantizer: 100,
    speed_settings: SpeedSettings::from_preset(10),
    ..Default::default()
  };
  let sequence = Sequence::new(&Default::default());
  let fi = FrameInvariants::<u16>::new(config, sequence);
  let fb = FrameBlocks::new(fi.sb_width * 16, fi.sb_height * 16);
  let mut fs = FrameState::new(&fi);
  let in_frame = fs.rec.clone();
  let mut ts = fs.as_tile_state_mut();

  b.iter(|| {
    cdef_filter_tile(&fi, &in_frame, &fb.as_tile_blocks(), &mut ts.rec)
  });
}

fn cfl_rdo(c: &mut Criterion) {
  for &bsize in &[
    BlockSize::BLOCK_4X4,
    BlockSize::BLOCK_8X8,
    BlockSize::BLOCK_16X16,
    BlockSize::BLOCK_32X32,
  ] {
    let n = format!("cfl_rdo({:?})", bsize);
    c.bench_function(&n, move |b| cfl_rdo_bench(b, bsize));
  }
}

fn cfl_rdo_bench(b: &mut Bencher, bsize: BlockSize) {
  let config = EncoderConfig {
    width: 1024,
    height: 1024,
    quantizer: 100,
    speed_settings: SpeedSettings::from_preset(10),
    ..Default::default()
  };
  let sequence = Sequence::new(&Default::default());
  let fi = FrameInvariants::<u16>::new(config, sequence);
  let mut fs = FrameState::new(&fi);
  let mut ts = fs.as_tile_state_mut();
  let offset = TileBlockOffset(BlockOffset { x: 1, y: 1 });
  b.iter(|| rdo_cfl_alpha(&mut ts, offset, bsize, bsize.tx_size(), &fi))
}

fn ec_bench(c: &mut Criterion) {
  c.bench_function("update_cdf_4", update_cdf_4);
}

fn update_cdf_4(b: &mut Bencher) {
  let mut cdf = [7296, 3819, 1616, 0, 0];
  b.iter(|| {
    for i in 0..1000 {
      update_cdf(&mut cdf, i & 3);
      black_box(cdf);
    }
  });
}

criterion_group!(intra_prediction, predict::pred_bench,);

criterion_group!(cfl, cfl_rdo);
criterion_group!(cdef, cdef_frame);
criterion_group!(write_block, write_b);
criterion_group! {
  name = dist;
  config = Criterion::default().warm_up_time(Duration::new(1,0));
  targets = dist::get_sad, dist::get_satd
}

criterion_group!(ec, ec_bench);

criterion_main!(
  write_block,
  intra_prediction,
  cdef,
  cfl,
  dist,
  forward_transforms,
  inverse_transforms,
  ec,
  rdo,
  plane,
  mc::mc
);
<|endoftext|>


<commit_before>/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Sahid Orentino Ferdjaoui <sahid.ferdjaoui@redhat.com>
 */

extern crate virt;

mod common;

use virt::domain::Domain;

fn tdom(exec_test: fn(dom: Domain)) {
    let c = common::conn();
    match Domain::lookup_by_name(&c, "test") {
        Ok(dom) => {
            exec_test(dom);
            common::close(c);
        }
        Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
    }
}

#[test]
fn test_name() {
    fn t(dom: Domain) {
        assert_eq!("test", dom.get_name().unwrap_or(String::new()));
    }
    tdom(t);
}

#[test]
fn test_uuid_string() {
    fn t(dom: Domain) {
        assert_eq!("6695eb01-f6a4-8304-79aa-97f2502e193f",
                   dom.get_uuid_string().unwrap_or(String::new()));
    }
    tdom(t);
}

#[test]
fn test_id() {
    fn t(dom: Domain) {
        assert_eq!(1, dom.get_id().unwrap_or(0));
    }
    tdom(t);
}

#[test]
fn test_get_xml_desc() {
    fn t(dom: Domain) {
        assert!("" != dom.get_xml_desc(0).unwrap_or(String::new()),
                "Should not be empty");
    }
    tdom(t);
}

#[test]
fn test_get_info() {
    fn t(dom: Domain) {
        match dom.get_info() {
            Ok(info) => assert_eq!(1, info.state),
            Err(_) => panic!("should have a node info"),
        }
    }
    tdom(t);
}

#[test]
fn test_get_vcpus_flags() {
    fn t(dom: Domain) {
        assert_eq!(2, dom.get_vcpus_flags(0).unwrap_or(0));
    }
    tdom(t);
}

#[test]
fn test_lookup_domain_by_id() {
    let c = common::conn();
    let v = c.list_domains().unwrap_or(vec![]);
    assert!(0 < v.len(), "At least one domain should exist");
    for domid in v {
        match Domain::lookup_by_id(&c, domid) {
            Ok(mut dom) => dom.free().unwrap_or(()),
            Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
        }
    }
    common::close(c);
}

#[test]
fn test_lookup_domain_by_name() {
    let c = common::conn();
    match Domain::lookup_by_name(&c, "test") {
        Ok(mut r) => r.free().unwrap_or(()),
        Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
    }
    common::close(c);
}

#[test]
fn test_create_with_flags() {
    let c = common::conn();
    let d = common::build_test_domain(&c, "create", false);
    assert_eq!(Ok(0), d.create_with_flags(0));
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_RUNNING, 1)), d.get_state());
    assert_eq!(Ok(String::from("libvirt-rs-test-create")), d.get_name());
    common::clean(d);
    common::close(c);
}

#[test]
fn test_shutdown() {
    let c = common::conn();
    let d = common::build_test_domain(&c, "shutdown", false);
    assert_eq!(Ok(0), d.create_with_flags(0));
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_RUNNING, 1)), d.get_state());
    assert_eq!(Ok(0), d.shutdown());
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_SHUTOFF, 1)), d.get_state());
    common::clean(d);
    common::close(c);
}

#[test]
fn test_pause_resume() {
    let c = common::conn();
    let d = common::build_test_domain(&c, "pause_resume", false);
    assert_eq!(Ok(0), d.create_with_flags(0));
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_RUNNING, 1)), d.get_state());
    assert_eq!(Ok(0), d.suspend());
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_PAUSED, 1)), d.get_state());
    assert_eq!(Ok(0), d.resume());
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_RUNNING, 5)), d.get_state());
    common::clean(d);
    common::close(c);
}
<commit_msg>make lookup_by_id() test more robust<commit_after>/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Sahid Orentino Ferdjaoui <sahid.ferdjaoui@redhat.com>
 */

extern crate virt;

mod common;

use virt::domain::Domain;

fn tdom(exec_test: fn(dom: Domain)) {
    let c = common::conn();
    match Domain::lookup_by_name(&c, "test") {
        Ok(dom) => {
            exec_test(dom);
            common::close(c);
        }
        Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
    }
}

#[test]
fn test_name() {
    fn t(dom: Domain) {
        assert_eq!("test", dom.get_name().unwrap_or(String::new()));
    }
    tdom(t);
}

#[test]
fn test_uuid_string() {
    fn t(dom: Domain) {
        assert_eq!("6695eb01-f6a4-8304-79aa-97f2502e193f",
                   dom.get_uuid_string().unwrap_or(String::new()));
    }
    tdom(t);
}

#[test]
fn test_id() {
    fn t(dom: Domain) {
        assert_eq!(1, dom.get_id().unwrap_or(0));
    }
    tdom(t);
}

#[test]
fn test_get_xml_desc() {
    fn t(dom: Domain) {
        assert!("" != dom.get_xml_desc(0).unwrap_or(String::new()),
                "Should not be empty");
    }
    tdom(t);
}

#[test]
fn test_get_info() {
    fn t(dom: Domain) {
        match dom.get_info() {
            Ok(info) => assert_eq!(1, info.state),
            Err(_) => panic!("should have a node info"),
        }
    }
    tdom(t);
}

#[test]
fn test_get_vcpus_flags() {
    fn t(dom: Domain) {
        assert_eq!(2, dom.get_vcpus_flags(0).unwrap_or(0));
    }
    tdom(t);
}

#[test]
fn test_lookup_domain_by_id() {
    let c = common::conn();
    let d = common::build_test_domain(&c, "by_id", true);
    let id = d.get_id().unwrap_or(0);
    match Domain::lookup_by_id(&c, id) {
        Ok(mut r) => r.free().unwrap_or(()),
        Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
    }
    common::clean(d);
    common::close(c);
}

#[test]
fn test_lookup_domain_by_name() {
    let c = common::conn();
    match Domain::lookup_by_name(&c, "test") {
        Ok(mut r) => r.free().unwrap_or(()),
        Err(e) => panic!("failed with code {}, message: {}", e.code, e.message),
    }
    common::close(c);
}

#[test]
fn test_create_with_flags() {
    let c = common::conn();
    let d = common::build_test_domain(&c, "create", false);
    assert_eq!(Ok(0), d.create_with_flags(0));
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_RUNNING, 1)), d.get_state());
    assert_eq!(Ok(String::from("libvirt-rs-test-create")), d.get_name());
    common::clean(d);
    common::close(c);
}

#[test]
fn test_shutdown() {
    let c = common::conn();
    let d = common::build_test_domain(&c, "shutdown", false);
    assert_eq!(Ok(0), d.create_with_flags(0));
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_RUNNING, 1)), d.get_state());
    assert_eq!(Ok(0), d.shutdown());
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_SHUTOFF, 1)), d.get_state());
    common::clean(d);
    common::close(c);
}

#[test]
fn test_pause_resume() {
    let c = common::conn();
    let d = common::build_test_domain(&c, "pause_resume", false);
    assert_eq!(Ok(0), d.create_with_flags(0));
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_RUNNING, 1)), d.get_state());
    assert_eq!(Ok(0), d.suspend());
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_PAUSED, 1)), d.get_state());
    assert_eq!(Ok(0), d.resume());
    assert_eq!(Ok((::virt::domain::VIR_DOMAIN_RUNNING, 5)), d.get_state());
    common::clean(d);
    common::close(c);
}
<|endoftext|>


<commit_before>#[cfg(not(lib_build))]
#[macro_use]
extern crate log;

macro_rules! all_log_macros {
    ($($arg:tt)*) => ({
        trace!($($arg)*);
        debug!($($arg)*);
        info!($($arg)*);
        warn!($($arg)*);
        error!($($arg)*);
    });
}

#[test]
fn no_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello");
        log!(lvl, "hello",);

        log!(target: "my_target", lvl, "hello");
        log!(target: "my_target", lvl, "hello",);

        log!(lvl; "hello");
        log!(lvl; "hello",);

        log!(target = "my_target", lvl; "hello");
        log!(target = "my_target", lvl; "hello",);
    }

    all_log_macros!("hello");
    all_log_macros!("hello",);

    all_log_macros!(target = "my_target"; "hello");
    all_log_macros!(target = "my_target"; "hello",);

    all_log_macros!(target: "my_target", "hello");
    all_log_macros!(target: "my_target", "hello",);
}

#[test]
fn anonymous_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello {}", "world");
        log!(lvl, "hello {}", "world",);

        log!(target: "my_target", lvl, "hello {}", "world");
        log!(target: "my_target", lvl, "hello {}", "world",);

        log!(lvl; "hello {}", "world");
        log!(lvl; "hello {}", "world",);

        log!(target = "my_target", lvl; "hello {}", "world");
        log!(target = "my_target", lvl; "hello {}", "world",);
    }

    all_log_macros!("hello {}", "world");
    all_log_macros!("hello {}", "world",);

    all_log_macros!(target = "my_target"; "hello {}", "world");
    all_log_macros!(target = "my_target"; "hello {}", "world",);

    all_log_macros!(target: "my_target", "hello {}", "world");
    all_log_macros!(target: "my_target", "hello {}", "world",);
}

#[test]
fn named_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello {world}", world = "world");
        log!(lvl, "hello {world}", world = "world",);

        log!(target: "my_target", lvl, "hello {world}", world = "world");
        log!(target: "my_target", lvl, "hello {world}", world = "world",);

        log!(lvl; "hello {world}", world = "world");
        log!(lvl; "hello {world}", world = "world",);

        log!(target = "my_target", lvl; "hello {world}", world = "world");
        log!(target = "my_target", lvl; "hello {world}", world = "world",);
    }

    all_log_macros!("hello {world}", world = "world");
    all_log_macros!("hello {world}", world = "world",);

    all_log_macros!(target = "my_target"; "hello {world}", world = "world");
    all_log_macros!(target = "my_target"; "hello {world}", world = "world",);

    all_log_macros!(target: "my_target", "hello {world}", world = "world");
    all_log_macros!(target: "my_target", "hello {world}", world = "world",);
}

#[test]
fn enabled() {
    for lvl in log::Level::iter() {
        let _enabled = if log_enabled!(target: "my_target", lvl) {
            true
        } else {
            false
        };

        let _enabled = if log_enabled!(target = "my_target", lvl) {
            true
        } else {
            false
        };
    }
}

#[test]
fn expr() {
    for lvl in log::Level::iter() {
        let _ = log!(lvl; "hello");
    }
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_no_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_anonymous_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_named_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_expr_context() {
    match "chashu" {
        cat_1 => {
            info!(target = "target"; cat_1 = cat_1, cat_2 = "nori"; "hello {}", "cats")
        }
    };
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_shadow_target() {
    all_log_macros!(target = "kv_target"; "hello {}", "world");
    all_log_macros!(target = "kv_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
}

#[rustversion::since(1.58)]
mod implicit_args {
    use super::*;

    #[test]
    fn implicit_named_args() {
        let world = "world";

        for lvl in log::Level::iter() {
            log!(lvl, "hello {world}");
            log!(lvl, "hello {world}",);

            log!(target: "my_target", lvl, "hello {world}");
            log!(target: "my_target", lvl, "hello {world}",);

            log!(lvl; "hello {world}");
            log!(lvl; "hello {world}",);

            log!(target = "my_target", lvl; "hello {world}");
            log!(target = "my_target", lvl; "hello {world}",);
        }

        all_log_macros!("hello {world}");
        all_log_macros!("hello {world}",);

        all_log_macros!(target = "my_target"; "hello {world}");
        all_log_macros!(target = "my_target"; "hello {world}",);

        all_log_macros!(target: "my_target", "hello {world}");
        all_log_macros!(target: "my_target", "hello {world}",);
    }

    #[test]
    #[cfg(feature = "kv_unstable")]
    fn kv_implicit_named_args() {
        let world = "world";

        for lvl in log::Level::iter() {
            log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}");

            log!(lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}");
        }

        all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}");
        all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}");
    }
}
<commit_msg>add an expr test to macros<commit_after>#[cfg(not(lib_build))]
#[macro_use]
extern crate log;

macro_rules! all_log_macros {
    ($($arg:tt)*) => ({
        trace!($($arg)*);
        debug!($($arg)*);
        info!($($arg)*);
        warn!($($arg)*);
        error!($($arg)*);
    });
}

#[test]
fn no_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello");
        log!(lvl, "hello",);

        log!(target: "my_target", lvl, "hello");
        log!(target: "my_target", lvl, "hello",);

        log!(lvl; "hello");
        log!(lvl; "hello",);

        log!(target = "my_target", lvl; "hello");
        log!(target = "my_target", lvl; "hello",);
    }

    all_log_macros!("hello");
    all_log_macros!("hello",);

    all_log_macros!(target = "my_target"; "hello");
    all_log_macros!(target = "my_target"; "hello",);

    all_log_macros!(target: "my_target", "hello");
    all_log_macros!(target: "my_target", "hello",);
}

#[test]
fn anonymous_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello {}", "world");
        log!(lvl, "hello {}", "world",);

        log!(target: "my_target", lvl, "hello {}", "world");
        log!(target: "my_target", lvl, "hello {}", "world",);

        log!(lvl; "hello {}", "world");
        log!(lvl; "hello {}", "world",);

        log!(target = "my_target", lvl; "hello {}", "world");
        log!(target = "my_target", lvl; "hello {}", "world",);
    }

    all_log_macros!("hello {}", "world");
    all_log_macros!("hello {}", "world",);

    all_log_macros!(target = "my_target"; "hello {}", "world");
    all_log_macros!(target = "my_target"; "hello {}", "world",);

    all_log_macros!(target: "my_target", "hello {}", "world");
    all_log_macros!(target: "my_target", "hello {}", "world",);
}

#[test]
fn named_args() {
    for lvl in log::Level::iter() {
        log!(lvl, "hello {world}", world = "world");
        log!(lvl, "hello {world}", world = "world",);

        log!(target: "my_target", lvl, "hello {world}", world = "world");
        log!(target: "my_target", lvl, "hello {world}", world = "world",);

        log!(lvl; "hello {world}", world = "world");
        log!(lvl; "hello {world}", world = "world",);

        log!(target = "my_target", lvl; "hello {world}", world = "world");
        log!(target = "my_target", lvl; "hello {world}", world = "world",);
    }

    all_log_macros!("hello {world}", world = "world");
    all_log_macros!("hello {world}", world = "world",);

    all_log_macros!(target = "my_target"; "hello {world}", world = "world");
    all_log_macros!(target = "my_target"; "hello {world}", world = "world",);

    all_log_macros!(target: "my_target", "hello {world}", world = "world");
    all_log_macros!(target: "my_target", "hello {world}", world = "world",);
}

#[test]
fn enabled() {
    for lvl in log::Level::iter() {
        let _enabled = if log_enabled!(target: "my_target", lvl) {
            true
        } else {
            false
        };

        let _enabled = if log_enabled!(target = "my_target", lvl) {
            true
        } else {
            false
        };
    }
}

#[test]
fn expr() {
    for lvl in log::Level::iter() {
        let _ = log!(lvl; "hello");
    }
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_no_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_expr_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");

        log!(lvl; cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
    }

    all_log_macros!(target = "my_target"; cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
    all_log_macros!(cat_math = { let mut x = 0; x += 1; x + 1 }; "hello");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_anonymous_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_named_args() {
    for lvl in log::Level::iter() {
        log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");

        log!(lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
    }

    all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
    all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}", world = "world");
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_expr_context() {
    match "chashu" {
        cat_1 => {
            info!(target = "target"; cat_1 = cat_1, cat_2 = "nori"; "hello {}", "cats")
        }
    };
}

#[test]
#[cfg(feature = "kv_unstable")]
fn kv_shadow_target() {
    all_log_macros!(target = "kv_target"; "hello {}", "world");
    all_log_macros!(target = "kv_target", cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {}", "world");
}

#[rustversion::since(1.58)]
mod implicit_args {
    use super::*;

    #[test]
    fn implicit_named_args() {
        let world = "world";

        for lvl in log::Level::iter() {
            log!(lvl, "hello {world}");
            log!(lvl, "hello {world}",);

            log!(target: "my_target", lvl, "hello {world}");
            log!(target: "my_target", lvl, "hello {world}",);

            log!(lvl; "hello {world}");
            log!(lvl; "hello {world}",);

            log!(target = "my_target", lvl; "hello {world}");
            log!(target = "my_target", lvl; "hello {world}",);
        }

        all_log_macros!("hello {world}");
        all_log_macros!("hello {world}",);

        all_log_macros!(target = "my_target"; "hello {world}");
        all_log_macros!(target = "my_target"; "hello {world}",);

        all_log_macros!(target: "my_target", "hello {world}");
        all_log_macros!(target: "my_target", "hello {world}",);
    }

    #[test]
    #[cfg(feature = "kv_unstable")]
    fn kv_implicit_named_args() {
        let world = "world";

        for lvl in log::Level::iter() {
            log!(target = "my_target", lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}");

            log!(lvl; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}");
        }

        all_log_macros!(target = "my_target"; cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}");
        all_log_macros!(cat_1 = "chashu", cat_2 = "nori", cat_count = 2; "hello {world}");
    }
}
<|endoftext|>


<commit_before>use rust_embed::RustEmbed;

#[derive(RustEmbed)]
#[folder = "examples/public/"]
#[prefix = "prefix/"]
struct Asset;

#[test]
fn get_with_prefix() {
    assert!(Asset::get("prefix/index.html").is_some());
}

#[test]
fn get_without_prefix() {
    assert!(Asset::get("index.html").is_none());
}

#[test]
fn iter_values_have_prefix() {
    for file in Asset::iter() {
        assert!(file.starts_with("prefix/"));
        assert!(Asset::get(file.as_ref()).is_some());
    }
}
<commit_msg>Format prefix tests<commit_after>use rust_embed::RustEmbed;

#[derive(RustEmbed)]
#[folder = "examples/public/"]
#[prefix = "prefix/"]
struct Asset;

#[test]
fn get_with_prefix() {
  assert!(Asset::get("prefix/index.html").is_some());
}

#[test]
fn get_without_prefix() {
  assert!(Asset::get("index.html").is_none());
}

#[test]
fn iter_values_have_prefix() {
  for file in Asset::iter() {
    assert!(file.starts_with("prefix/"));
    assert!(Asset::get(file.as_ref()).is_some());
  }
}
<|endoftext|>


<commit_before>extern crate rsoundio;

use std::f32::consts;
use std::thread;
use std::time::Duration;

#[test]
fn test_outstream() {
    println!("test: OutStream");
    let sio = rsoundio::SoundIo::new();
    sio.connect_backend(rsoundio::ffi::SioBackend::Dummy).unwrap();
    println!("current backend: {}", sio.current_backend().unwrap());
    sio.flush_events();
    let fmt;
    let dev_idx = sio.default_output_device_index().unwrap();
    let mut frames: Vec<Vec<f32>> = vec![vec![], vec![]];
    let dev = sio.get_output_device(dev_idx).unwrap();
    println!("device: {}, ref_count: {}", dev, dev.ref_count());
    let mut stream = dev.create_outstream().unwrap();
    stream.open().unwrap();
    fmt = stream.current_format().unwrap();
    println!("current format: {}", fmt);
    let f = 4400f32;
    let sr = stream.get_sample_rate();
    let layout = stream.get_layout();
    let channels = layout.channel_count();
    let phi = 2.0 * f * consts::PI / (sr as f32);
    let l: Vec<f32> = (0..4096).map(|i| f32::sin(i as f32 * phi)).collect();
    let r = l.clone();
    frames = vec![l, r];
    let cb = |out: rsoundio::OutStream, min_frame_count: i32, max_frame_count: i32| {
        let frames_written = out.write_stream_f32(min_frame_count, &frames).unwrap();
        assert!(frames_written > 0);
        out.get_latency().map(|latency| assert!(latency >= 0.0));
    };
    stream.register_write_callback(Box::new(cb));
    let ucb = |out: rsoundio::OutStream| println!("Underflow!");
    stream.register_underflow_callback(Box::new(ucb));
    let ecb = |out: rsoundio::OutStream, err: rsoundio::ffi::SioError| println!("Error: {}", err);
    stream.register_error_callback(Box::new(ecb));
    assert!(stream.start().is_none());
    //sio.wait_events();
    thread::sleep(Duration::new(1,0));
    assert!(stream.pause(true).is_none());
    thread::sleep(Duration::new(1,0));
    assert!(stream.pause(false).is_none());
    assert!(stream.clear_buffer().is_none());
    thread::sleep(Duration::new(1,0));
    stream.destroy();
    dev.dec_ref();
}
<commit_msg>Remove `println!` from stream test<commit_after>extern crate rsoundio;

use std::f32::consts;
use std::thread;
use std::time::Duration;

#[test]
fn test_outstream() {
    let sio = rsoundio::SoundIo::new();
    sio.connect_backend(rsoundio::ffi::SioBackend::Dummy).unwrap();
    sio.flush_events();
    let fmt;
    let dev_idx = sio.default_output_device_index().unwrap();
    let mut frames: Vec<Vec<f32>> = vec![vec![], vec![]];
    let dev = sio.get_output_device(dev_idx).unwrap();
    let mut stream = dev.create_outstream().unwrap();
    stream.open().unwrap();
    fmt = stream.current_format().unwrap();
    let f = 4400f32;
    let sr = stream.get_sample_rate();
    let layout = stream.get_layout();
    let channels = layout.channel_count();
    let phi = 2.0 * f * consts::PI / (sr as f32);
    let l: Vec<f32> = (0..4096).map(|i| f32::sin(i as f32 * phi)).collect();
    let r = l.clone();
    frames = vec![l, r];
    let cb = |out: rsoundio::OutStream, min_frame_count: i32, max_frame_count: i32| {
        let frames_written = out.write_stream_f32(min_frame_count, &frames).unwrap();
        assert!(frames_written > 0);
        out.get_latency().map(|latency| assert!(latency >= 0.0));
    };
    stream.register_write_callback(Box::new(cb));
    let ucb = |out: rsoundio::OutStream| println!("Underflow!");
    stream.register_underflow_callback(Box::new(ucb));
    let ecb = |out: rsoundio::OutStream, err: rsoundio::ffi::SioError| println!("Error: {}", err);
    stream.register_error_callback(Box::new(ecb));
    assert!(stream.start().is_none());
    //sio.wait_events();
    thread::sleep(Duration::new(1,0));
    assert!(stream.pause(true).is_none());
    thread::sleep(Duration::new(1,0));
    assert!(stream.pause(false).is_none());
    assert!(stream.clear_buffer().is_none());
    thread::sleep(Duration::new(1,0));
    stream.destroy();
    dev.dec_ref();
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![cfg(test)]

extern crate capnp;
extern crate capnp_rpc;

#[macro_use]
extern crate gj;

use gj::{EventLoop, Promise};
use gj::io::unix;
use capnp::Error;
use capnp_rpc::{RpcSystem, rpc_twoparty_capnp, twoparty};

pub mod test_capnp {
  include!(concat!(env!("OUT_DIR"), "/test_capnp.rs"));
}

pub mod impls;
pub mod test_util;

#[test]
fn drop_rpc_system() {
    EventLoop::top_level(|wait_scope| {
        let (instream, _outstream) = try!(unix::Stream::new_pair());
        let (reader, writer) = instream.split();
        let network =
            Box::new(twoparty::VatNetwork::new(reader, writer,
                                               rpc_twoparty_capnp::Side::Client,
                                               Default::default()));
        let rpc_system = RpcSystem::new(network, None);
        drop(rpc_system);
        try!(Promise::<(),Error>::ok(()).wait(wait_scope));
        Ok(())
    }).expect("top level error");
}

fn set_up_rpc<F>(main: F)
    where F: FnOnce(test_capnp::bootstrap::Client) -> Promise<(), Error>,
          F: Send + 'static
{
    EventLoop::top_level(|wait_scope| {
        let (join_handle, stream) = try!(unix::spawn(|stream, wait_scope| {

            let (reader, writer) = stream.split();
            let mut network =
                Box::new(twoparty::VatNetwork::new(reader, writer,
                                                   rpc_twoparty_capnp::Side::Server,
                                                   Default::default()));
            let disconnect_promise = network.on_disconnect();
            let bootstrap =
                test_capnp::bootstrap::ToClient::new(impls::Bootstrap).from_server::<::capnp_rpc::Server>();

            let _rpc_system = RpcSystem::new(network, Some(bootstrap.client));
            try!(disconnect_promise.wait(wait_scope));
            Ok(())
        }));

        let (reader, writer) = stream.split();
        let network =
            Box::new(twoparty::VatNetwork::new(reader, writer,
                                               rpc_twoparty_capnp::Side::Client,
                                               Default::default()));

        let mut rpc_system = RpcSystem::new(network, None);
        let client: test_capnp::bootstrap::Client = rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server);

        try!(main(client).wait(wait_scope));
        drop(rpc_system);
        join_handle.join().expect("thread exited unsuccessfully");
        Ok(())
    }).expect("top level error");
}

#[test]
fn do_nothing() {
    set_up_rpc(|_client| {
        Promise::ok(())
    });
}

#[test]
fn basic() {
    set_up_rpc(|client| {
        client.test_interface_request().send().promise.then(|response| {

            let client = pry!(pry!(response.get()).get_cap());
            let mut request1 = client.foo_request();
            request1.get().set_i(123);
            request1.get().set_j(true);
            let promise1 = request1.send().promise.then(|response| {
                if "foo" == pry!(pry!(response.get()).get_x()) {
                    Promise::ok(())
                } else {
                    Promise::err(Error::failed("expected X to equal 'foo'".to_string()))
                }
            });

            let request3 = client.bar_request();
            let promise3 = request3.send().promise.then_else(|result| {
                // We expect this call to fail.
                match result {
                    Ok(_) => {
                        Promise::err(Error::failed("expected bar() to fail".to_string()))
                    }
                    Err(_) => {
                        Promise::ok(())
                    }
                }
            });

            let mut request2 = client.baz_request();
            ::test_util::init_test_message(pry!(request2.get().get_s()));
            let promise2 = request2.send().promise.map(|_| Ok(()));

            Promise::all(vec![promise1, promise2, promise3].into_iter()).map(|_| Ok(()))
        })
    });
}

#[test]
fn pipelining() {
    set_up_rpc(|client| {
        client.test_pipeline_request().send().promise.then(|response| {
            let client = pry!(pry!(response.get()).get_cap());
            let mut request = client.get_cap_request();
            request.get().set_n(234);
            let server = impls::TestInterface::new();
            let chained_call_count = server.get_call_count();
            request.get().set_in_cap(
                ::test_capnp::test_interface::ToClient::new(server).from_server::<::capnp_rpc::Server>());

            let promise = request.send();

            let mut pipeline_request = promise.pipeline.get_out_box().get_cap().foo_request();
            pipeline_request.get().set_i(321);
            let pipeline_promise = pipeline_request.send();

            let pipeline_request2 = {
                let extends_client =
                    ::test_capnp::test_extends::Client { client: promise.pipeline.get_out_box().get_cap().client };
                extends_client.grault_request()
            };
            let pipeline_promise2 = pipeline_request2.send();

            drop(promise); // Just to be annoying, drop the original promise.

            if chained_call_count.get() != 0 {
                return Promise::err(Error::failed("expeced chained_call_count to equal 0".to_string()));
            }

            pipeline_promise.promise.then(move |response| {
                if pry!(pry!(response.get()).get_x()) != "bar" {
                    return Promise::err(Error::failed("expected x to equal 'bar'".to_string()));
                }
                pipeline_promise2.promise.then(move |response| {
                    ::test_util::CheckTestMessage::check_test_message(pry!(response.get()));
                    assert_eq!(chained_call_count.get(), 1);
                    Promise::ok(())
                })
            })
        })
    });
}

#[test]
fn null_capability() {
    let mut message = ::capnp::message::Builder::new_default();
    let root: ::test_capnp::test_all_types::Builder = message.get_root().unwrap();

    // In capnproto-c++, this would return a BrokenCap. Here, it returns a decode error.
    // Would it be worthwhile to try to match the C++ behavior here? We would need something
    // like the BrokenCapFactory singleton.
    assert!(root.get_interface_field().is_err());
}

#[test]
fn release_simple() {
    set_up_rpc(|client| {
        client.test_more_stuff_request().send().promise.then(|response| {
            let client = pry!(pry!(response.get()).get_cap());

            Promise::all(vec![
                client.get_handle_request().send().promise,
                client.get_handle_request().send().promise].into_iter()).then(move |responses| {
                let handle1 = pry!(pry!(responses[0].get()).get_handle());
                let handle2 = pry!(pry!(responses[1].get()).get_handle());

                let client1 = client.clone();
                let client2 = client.clone();
                client.get_handle_count_request().send().promise.map(|response| {
                    if try!(response.get()).get_count() != 2 {
                        Err(Error::failed("expected handle count to equal 2".to_string()))
                    } else {
                        Ok(())
                    }
                }).then(move |()| {
                    drop(handle1);
                    client1.get_handle_count_request().send().promise.map(|response| {
                        if try!(response.get()).get_count() != 1 {
                            Err(Error::failed("expected handle count to equal 1".to_string()))
                        } else {
                            Ok(())
                        }
                    })
                }).then(move |()| {
                    drop(handle2);
                    client2.get_handle_count_request().send().promise.map(|response| {
                        if try!(response.get()).get_count() != 0 {
                            Err(Error::failed("expected handle count to equal 0".to_string()))
                        } else {
                            Ok(())
                        }
                    })
                })
            })
        })
    });
}

#[test]
fn promise_resolve() {
    set_up_rpc(|client| {
        client.test_more_stuff_request().send().promise.then(|response| {
            let client = pry!(pry!(response.get()).get_cap());

            let mut request = client.call_foo_request();
            let mut request2 = client.call_foo_when_resolved_request();

            let (paf_promise, paf_fulfiller) =
                Promise::<::test_capnp::test_interface::Client, Error>::and_fulfiller();

            {
                let mut fork = paf_promise.fork();
                let cap1 = ::capnp_rpc::new_promise_client(fork.add_branch().map(|c| Ok(c.client)));
                let cap2 = ::capnp_rpc::new_promise_client(fork.add_branch().map(|c| Ok(c.client)));
                request.get().set_cap(cap1);
                request2.get().set_cap(cap2);
            }

            let promise = request.send().promise;
            let promise2 = request2.send().promise;

            // Make sure getCap() has been called on the server side by sending another call and waiting
            // for it.
            let client2 = ::test_capnp::test_call_order::Client { client: client.clone().client };
            client2.get_call_sequence_request().send().promise.then(move |_response| {
                let server = impls::TestInterface::new();

                paf_fulfiller.fulfill(
                    ::test_capnp::test_interface::ToClient::new(server).from_server::<::capnp_rpc::Server>());

                promise.then(move |response| {
                    if pry!(pry!(response.get()).get_s()) != "bar" {
                        return Promise::err(Error::failed("expected s to equal 'bar'".to_string()));
                    }
                    promise2.then(move |response| {
                        if pry!(pry!(response.get()).get_s()) != "bar" {
                            return Promise::err(Error::failed("expected s to equal 'bar'".to_string()));
                        }

                        Promise::ok(())
                    })
                })
            })
        })
    });
}

fn get_call_sequence(client: &::test_capnp::test_call_order::Client, expected: u32)
                     -> ::capnp::capability::RemotePromise<::test_capnp::test_call_order::get_call_sequence_results::Owned>
{
    let mut req = client.get_call_sequence_request();
    req.get().set_expected(expected);
    req.send()
}

#[test]
fn embargo() {
    set_up_rpc(|client| {
        client.test_more_stuff_request().send().promise.then(|response| {
            let client = pry!(pry!(response.get()).get_cap());

            let server = ::impls::TestCallOrder::new();

            // ugh, we need upcasting.
            let client2 = ::test_capnp::test_call_order::Client { client: client.clone().client };
            let early_call = client2.get_call_sequence_request().send();
            drop(client2);

            let mut echo_request = client.echo_request();
            echo_request.get().set_cap(
                ::test_capnp::test_call_order::ToClient::new(server).from_server::<::capnp_rpc::Server>());
            let echo = echo_request.send();

            let pipeline = echo.pipeline.get_cap();

            let call0 = get_call_sequence(&pipeline, 0);

            let call1 = get_call_sequence(&pipeline, 1);

            early_call.promise.then(move |_early_call_response| {
                let call2 = get_call_sequence(&pipeline, 2);
                echo.promise.then(move |_echo_response| {
                    let call3 = get_call_sequence(&pipeline, 3);
                    let call4 = get_call_sequence(&pipeline, 4);
                    let call5 = get_call_sequence(&pipeline, 5);

                    Promise::all(vec![call0.promise,
                                      call1.promise,
                                      call2.promise,
                                      call3.promise,
                                      call4.promise,
                                      call5.promise].into_iter()).map(|responses| {
                        let mut counter = 0;
                        for r in responses.into_iter() {
                            if counter != try!(r.get()).get_n() {
                                return Err(Error::failed(
                                    "calls arrived out of order".to_string()))
                            }
                            counter += 1;
                        }
                        Ok(())
                    })
                })
            })
        })
    });
}
<commit_msg>add as-yet-incomplete embargo_error() test case<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![cfg(test)]

extern crate capnp;
extern crate capnp_rpc;

#[macro_use]
extern crate gj;

use gj::{EventLoop, Promise};
use gj::io::unix;
use capnp::Error;
use capnp_rpc::{RpcSystem, rpc_twoparty_capnp, twoparty};

pub mod test_capnp {
  include!(concat!(env!("OUT_DIR"), "/test_capnp.rs"));
}

pub mod impls;
pub mod test_util;

#[test]
fn drop_rpc_system() {
    EventLoop::top_level(|wait_scope| {
        let (instream, _outstream) = try!(unix::Stream::new_pair());
        let (reader, writer) = instream.split();
        let network =
            Box::new(twoparty::VatNetwork::new(reader, writer,
                                               rpc_twoparty_capnp::Side::Client,
                                               Default::default()));
        let rpc_system = RpcSystem::new(network, None);
        drop(rpc_system);
        try!(Promise::<(),Error>::ok(()).wait(wait_scope));
        Ok(())
    }).expect("top level error");
}

fn set_up_rpc<F>(main: F)
    where F: FnOnce(test_capnp::bootstrap::Client) -> Promise<(), Error>,
          F: Send + 'static
{
    EventLoop::top_level(|wait_scope| {
        let (join_handle, stream) = try!(unix::spawn(|stream, wait_scope| {

            let (reader, writer) = stream.split();
            let mut network =
                Box::new(twoparty::VatNetwork::new(reader, writer,
                                                   rpc_twoparty_capnp::Side::Server,
                                                   Default::default()));
            let disconnect_promise = network.on_disconnect();
            let bootstrap =
                test_capnp::bootstrap::ToClient::new(impls::Bootstrap).from_server::<::capnp_rpc::Server>();

            let _rpc_system = RpcSystem::new(network, Some(bootstrap.client));
            try!(disconnect_promise.wait(wait_scope));
            Ok(())
        }));

        let (reader, writer) = stream.split();
        let network =
            Box::new(twoparty::VatNetwork::new(reader, writer,
                                               rpc_twoparty_capnp::Side::Client,
                                               Default::default()));

        let mut rpc_system = RpcSystem::new(network, None);
        let client: test_capnp::bootstrap::Client = rpc_system.bootstrap(rpc_twoparty_capnp::Side::Server);

        try!(main(client).wait(wait_scope));
        drop(rpc_system);
        join_handle.join().expect("thread exited unsuccessfully");
        Ok(())
    }).expect("top level error");
}

#[test]
fn do_nothing() {
    set_up_rpc(|_client| {
        Promise::ok(())
    });
}

#[test]
fn basic() {
    set_up_rpc(|client| {
        client.test_interface_request().send().promise.then(|response| {

            let client = pry!(pry!(response.get()).get_cap());
            let mut request1 = client.foo_request();
            request1.get().set_i(123);
            request1.get().set_j(true);
            let promise1 = request1.send().promise.then(|response| {
                if "foo" == pry!(pry!(response.get()).get_x()) {
                    Promise::ok(())
                } else {
                    Promise::err(Error::failed("expected X to equal 'foo'".to_string()))
                }
            });

            let request3 = client.bar_request();
            let promise3 = request3.send().promise.then_else(|result| {
                // We expect this call to fail.
                match result {
                    Ok(_) => {
                        Promise::err(Error::failed("expected bar() to fail".to_string()))
                    }
                    Err(_) => {
                        Promise::ok(())
                    }
                }
            });

            let mut request2 = client.baz_request();
            ::test_util::init_test_message(pry!(request2.get().get_s()));
            let promise2 = request2.send().promise.map(|_| Ok(()));

            Promise::all(vec![promise1, promise2, promise3].into_iter()).map(|_| Ok(()))
        })
    });
}

#[test]
fn pipelining() {
    set_up_rpc(|client| {
        client.test_pipeline_request().send().promise.then(|response| {
            let client = pry!(pry!(response.get()).get_cap());
            let mut request = client.get_cap_request();
            request.get().set_n(234);
            let server = impls::TestInterface::new();
            let chained_call_count = server.get_call_count();
            request.get().set_in_cap(
                ::test_capnp::test_interface::ToClient::new(server).from_server::<::capnp_rpc::Server>());

            let promise = request.send();

            let mut pipeline_request = promise.pipeline.get_out_box().get_cap().foo_request();
            pipeline_request.get().set_i(321);
            let pipeline_promise = pipeline_request.send();

            let pipeline_request2 = {
                let extends_client =
                    ::test_capnp::test_extends::Client { client: promise.pipeline.get_out_box().get_cap().client };
                extends_client.grault_request()
            };
            let pipeline_promise2 = pipeline_request2.send();

            drop(promise); // Just to be annoying, drop the original promise.

            if chained_call_count.get() != 0 {
                return Promise::err(Error::failed("expeced chained_call_count to equal 0".to_string()));
            }

            pipeline_promise.promise.then(move |response| {
                if pry!(pry!(response.get()).get_x()) != "bar" {
                    return Promise::err(Error::failed("expected x to equal 'bar'".to_string()));
                }
                pipeline_promise2.promise.then(move |response| {
                    ::test_util::CheckTestMessage::check_test_message(pry!(response.get()));
                    assert_eq!(chained_call_count.get(), 1);
                    Promise::ok(())
                })
            })
        })
    });
}

#[test]
fn null_capability() {
    let mut message = ::capnp::message::Builder::new_default();
    let root: ::test_capnp::test_all_types::Builder = message.get_root().unwrap();

    // In capnproto-c++, this would return a BrokenCap. Here, it returns a decode error.
    // Would it be worthwhile to try to match the C++ behavior here? We would need something
    // like the BrokenCapFactory singleton.
    assert!(root.get_interface_field().is_err());
}

#[test]
fn release_simple() {
    set_up_rpc(|client| {
        client.test_more_stuff_request().send().promise.then(|response| {
            let client = pry!(pry!(response.get()).get_cap());

            Promise::all(vec![
                client.get_handle_request().send().promise,
                client.get_handle_request().send().promise].into_iter()).then(move |responses| {
                let handle1 = pry!(pry!(responses[0].get()).get_handle());
                let handle2 = pry!(pry!(responses[1].get()).get_handle());

                let client1 = client.clone();
                let client2 = client.clone();
                client.get_handle_count_request().send().promise.map(|response| {
                    if try!(response.get()).get_count() != 2 {
                        Err(Error::failed("expected handle count to equal 2".to_string()))
                    } else {
                        Ok(())
                    }
                }).then(move |()| {
                    drop(handle1);
                    client1.get_handle_count_request().send().promise.map(|response| {
                        if try!(response.get()).get_count() != 1 {
                            Err(Error::failed("expected handle count to equal 1".to_string()))
                        } else {
                            Ok(())
                        }
                    })
                }).then(move |()| {
                    drop(handle2);
                    client2.get_handle_count_request().send().promise.map(|response| {
                        if try!(response.get()).get_count() != 0 {
                            Err(Error::failed("expected handle count to equal 0".to_string()))
                        } else {
                            Ok(())
                        }
                    })
                })
            })
        })
    });
}

#[test]
fn promise_resolve() {
    set_up_rpc(|client| {
        client.test_more_stuff_request().send().promise.then(|response| {
            let client = pry!(pry!(response.get()).get_cap());

            let mut request = client.call_foo_request();
            let mut request2 = client.call_foo_when_resolved_request();

            let (paf_promise, paf_fulfiller) =
                Promise::<::test_capnp::test_interface::Client, Error>::and_fulfiller();

            {
                let mut fork = paf_promise.fork();
                let cap1 = ::capnp_rpc::new_promise_client(fork.add_branch().map(|c| Ok(c.client)));
                let cap2 = ::capnp_rpc::new_promise_client(fork.add_branch().map(|c| Ok(c.client)));
                request.get().set_cap(cap1);
                request2.get().set_cap(cap2);
            }

            let promise = request.send().promise;
            let promise2 = request2.send().promise;

            // Make sure getCap() has been called on the server side by sending another call and waiting
            // for it.
            let client2 = ::test_capnp::test_call_order::Client { client: client.clone().client };
            client2.get_call_sequence_request().send().promise.then(move |_response| {
                let server = impls::TestInterface::new();

                paf_fulfiller.fulfill(
                    ::test_capnp::test_interface::ToClient::new(server).from_server::<::capnp_rpc::Server>());

                promise.then(move |response| {
                    if pry!(pry!(response.get()).get_s()) != "bar" {
                        return Promise::err(Error::failed("expected s to equal 'bar'".to_string()));
                    }
                    promise2.then(move |response| {
                        if pry!(pry!(response.get()).get_s()) != "bar" {
                            return Promise::err(Error::failed("expected s to equal 'bar'".to_string()));
                        }

                        Promise::ok(())
                    })
                })
            })
        })
    });
}

fn get_call_sequence(client: &::test_capnp::test_call_order::Client, expected: u32)
                     -> ::capnp::capability::RemotePromise<::test_capnp::test_call_order::get_call_sequence_results::Owned>
{
    let mut req = client.get_call_sequence_request();
    req.get().set_expected(expected);
    req.send()
}

#[test]
fn embargo() {
    set_up_rpc(|client| {
        client.test_more_stuff_request().send().promise.then(|response| {
            let client = pry!(pry!(response.get()).get_cap());

            let server = ::impls::TestCallOrder::new();

            // ugh, we need upcasting.
            let client2 = ::test_capnp::test_call_order::Client { client: client.clone().client };
            let early_call = client2.get_call_sequence_request().send();
            drop(client2);

            let mut echo_request = client.echo_request();
            echo_request.get().set_cap(
                ::test_capnp::test_call_order::ToClient::new(server).from_server::<::capnp_rpc::Server>());
            let echo = echo_request.send();

            let pipeline = echo.pipeline.get_cap();

            let call0 = get_call_sequence(&pipeline, 0);
            let call1 = get_call_sequence(&pipeline, 1);

            early_call.promise.then(move |_early_call_response| {
                let call2 = get_call_sequence(&pipeline, 2);
                echo.promise.then(move |_echo_response| {
                    let call3 = get_call_sequence(&pipeline, 3);
                    let call4 = get_call_sequence(&pipeline, 4);
                    let call5 = get_call_sequence(&pipeline, 5);

                    Promise::all(vec![call0.promise,
                                      call1.promise,
                                      call2.promise,
                                      call3.promise,
                                      call4.promise,
                                      call5.promise].into_iter()).map(|responses| {
                        let mut counter = 0;
                        for r in responses.into_iter() {
                            if counter != try!(r.get()).get_n() {
                                return Err(Error::failed(
                                    "calls arrived out of order".to_string()))
                            }
                            counter += 1;
                        }
                        Ok(())
                    })
                })
            })
        })
    });
}

#[test]
fn embargo_error() {
    set_up_rpc(|client| {
        client.test_more_stuff_request().send().promise.then(|response| {
            let client = pry!(pry!(response.get()).get_cap());

            let (promise, fulfiller) =
                Promise::<::test_capnp::test_call_order::Client, Error>::and_fulfiller();

            let cap = ::capnp_rpc::new_promise_client(promise.map(|c| Ok(c.client)));

            // ugh, we need upcasting.
            let client2 = ::test_capnp::test_call_order::Client { client: client.clone().client };
            let early_call = client2.get_call_sequence_request().send();
            drop(client2);

            let mut echo_request = client.echo_request();
            echo_request.get().set_cap(cap);
            let echo = echo_request.send();

            let pipeline = echo.pipeline.get_cap();

            let call0 = get_call_sequence(&pipeline, 0);
            let call1 = get_call_sequence(&pipeline, 1);

            early_call.promise.then(move |_early_call_response| {
                let call2 = get_call_sequence(&pipeline, 2);
                Promise::ok(())
/*
                echo.promise.then(move |_echo_response| {
                    let call3 = get_call_sequence(&pipeline, 3);
                    let call4 = get_call_sequence(&pipeline, 4);
                    let call5 = get_call_sequence(&pipeline, 5);

                    fulfiller.reject(Error::failed("foo".to_string()));
                    Promise::ok(())
                })*/
            })
        })
    });
}
<|endoftext|>


<commit_before>//! The condition expression used in `#[cfg(..)]` attributes.
//!
//! See: https://doc.rust-lang.org/reference/conditional-compilation.html#conditional-compilation

use std::slice::Iter as SliceIter;

use tt::SmolStr;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CfgExpr {
    Invalid,
    Atom(SmolStr),
    KeyValue { key: SmolStr, value: SmolStr },
    All(Vec<CfgExpr>),
    Any(Vec<CfgExpr>),
    Not(Box<CfgExpr>),
}

impl CfgExpr {
    pub fn parse(tt: &tt::Subtree) -> CfgExpr {
        next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid)
    }
    /// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates.
    pub fn fold(&self, query: &dyn Fn(&SmolStr, Option<&SmolStr>) -> bool) -> Option<bool> {
        match self {
            CfgExpr::Invalid => None,
            CfgExpr::Atom(name) => Some(query(name, None)),
            CfgExpr::KeyValue { key, value } => Some(query(key, Some(value))),
            CfgExpr::All(preds) => {
                preds.iter().try_fold(true, |s, pred| Some(s && pred.fold(query)?))
            }
            CfgExpr::Any(preds) => {
                preds.iter().try_fold(false, |s, pred| Some(s || pred.fold(query)?))
            }
            CfgExpr::Not(pred) => pred.fold(query).map(|s| !s),
        }
    }
}

fn next_cfg_expr(it: &mut SliceIter<tt::TokenTree>) -> Option<CfgExpr> {
    let name = match it.next() {
        None => return None,
        Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.text.clone(),
        Some(_) => return Some(CfgExpr::Invalid),
    };

    // Peek
    let ret = match it.as_slice().first() {
        Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) if punct.char == '=' => {
            match it.as_slice().get(1) {
                Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => {
                    it.next();
                    it.next();
                    // FIXME: escape? raw string?
                    let value =
                        SmolStr::new(literal.text.trim_start_matches('"').trim_end_matches('"'));
                    CfgExpr::KeyValue { key: name, value }
                }
                _ => return Some(CfgExpr::Invalid),
            }
        }
        Some(tt::TokenTree::Subtree(subtree)) => {
            it.next();
            let mut sub_it = subtree.token_trees.iter();
            let mut subs = std::iter::from_fn(|| next_cfg_expr(&mut sub_it)).collect();
            match name.as_str() {
                "all" => CfgExpr::All(subs),
                "any" => CfgExpr::Any(subs),
                "not" => CfgExpr::Not(Box::new(subs.pop().unwrap_or(CfgExpr::Invalid))),
                _ => CfgExpr::Invalid,
            }
        }
        _ => CfgExpr::Atom(name),
    };

    // Eat comma separator
    if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = it.as_slice().first() {
        if punct.char == ',' {
            it.next();
        }
    }
    Some(ret)
}

#[cfg(test)]
mod tests {
    use super::*;

    use mbe::{ast_to_token_tree, TokenMap};
    use syntax::ast::{self, AstNode};

    fn get_token_tree_generated(input: &str) -> (tt::Subtree, TokenMap) {
        let source_file = ast::SourceFile::parse(input).ok().unwrap();
        let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
        ast_to_token_tree(&tt).unwrap()
    }

    fn assert_parse_result(input: &str, expected: CfgExpr) {
        let (tt, _) = get_token_tree_generated(input);
        let cfg = CfgExpr::parse(&tt);
        assert_eq!(cfg, expected);
    }

    #[test]
    fn test_cfg_expr_parser() {
        assert_parse_result("#![cfg(foo)]", CfgExpr::Atom("foo".into()));
        assert_parse_result("#![cfg(foo,)]", CfgExpr::Atom("foo".into()));
        assert_parse_result(
            "#![cfg(not(foo))]",
            CfgExpr::Not(Box::new(CfgExpr::Atom("foo".into()))),
        );
        assert_parse_result("#![cfg(foo(bar))]", CfgExpr::Invalid);

        // Only take the first
        assert_parse_result(r#"#![cfg(foo, bar = "baz")]"#, CfgExpr::Atom("foo".into()));

        assert_parse_result(
            r#"#![cfg(all(foo, bar = "baz"))]"#,
            CfgExpr::All(vec![
                CfgExpr::Atom("foo".into()),
                CfgExpr::KeyValue { key: "bar".into(), value: "baz".into() },
            ]),
        );

        assert_parse_result(
            r#"#![cfg(any(not(), all(), , bar = "baz",))]"#,
            CfgExpr::Any(vec![
                CfgExpr::Not(Box::new(CfgExpr::Invalid)),
                CfgExpr::All(vec![]),
                CfgExpr::Invalid,
                CfgExpr::KeyValue { key: "bar".into(), value: "baz".into() },
            ]),
        );
    }
}
<commit_msg>Simplify<commit_after>//! The condition expression used in `#[cfg(..)]` attributes.
//!
//! See: https://doc.rust-lang.org/reference/conditional-compilation.html#conditional-compilation

use std::slice::Iter as SliceIter;

use tt::SmolStr;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CfgExpr {
    Invalid,
    Atom(SmolStr),
    KeyValue { key: SmolStr, value: SmolStr },
    All(Vec<CfgExpr>),
    Any(Vec<CfgExpr>),
    Not(Box<CfgExpr>),
}

impl CfgExpr {
    pub fn parse(tt: &tt::Subtree) -> CfgExpr {
        next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid)
    }
    /// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates.
    pub fn fold(&self, query: &dyn Fn(&SmolStr, Option<&SmolStr>) -> bool) -> Option<bool> {
        match self {
            CfgExpr::Invalid => None,
            CfgExpr::Atom(name) => Some(query(name, None)),
            CfgExpr::KeyValue { key, value } => Some(query(key, Some(value))),
            CfgExpr::All(preds) => {
                preds.iter().try_fold(true, |s, pred| Some(s && pred.fold(query)?))
            }
            CfgExpr::Any(preds) => {
                preds.iter().try_fold(false, |s, pred| Some(s || pred.fold(query)?))
            }
            CfgExpr::Not(pred) => pred.fold(query).map(|s| !s),
        }
    }
}

fn next_cfg_expr(it: &mut SliceIter<tt::TokenTree>) -> Option<CfgExpr> {
    let name = match it.next() {
        None => return None,
        Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.text.clone(),
        Some(_) => return Some(CfgExpr::Invalid),
    };

    // Peek
    let ret = match it.as_slice().first() {
        Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) if punct.char == '=' => {
            match it.as_slice().get(1) {
                Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => {
                    it.next();
                    it.next();
                    // FIXME: escape? raw string?
                    let value =
                        SmolStr::new(literal.text.trim_start_matches('"').trim_end_matches('"'));
                    CfgExpr::KeyValue { key: name, value }
                }
                _ => return Some(CfgExpr::Invalid),
            }
        }
        Some(tt::TokenTree::Subtree(subtree)) => {
            it.next();
            let mut sub_it = subtree.token_trees.iter();
            let mut subs = std::iter::from_fn(|| next_cfg_expr(&mut sub_it)).collect();
            match name.as_str() {
                "all" => CfgExpr::All(subs),
                "any" => CfgExpr::Any(subs),
                "not" => CfgExpr::Not(Box::new(subs.pop().unwrap_or(CfgExpr::Invalid))),
                _ => CfgExpr::Invalid,
            }
        }
        _ => CfgExpr::Atom(name),
    };

    // Eat comma separator
    if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = it.as_slice().first() {
        if punct.char == ',' {
            it.next();
        }
    }
    Some(ret)
}

#[cfg(test)]
mod tests {
    use super::*;

    use mbe::ast_to_token_tree;
    use syntax::ast::{self, AstNode};

    fn assert_parse_result(input: &str, expected: CfgExpr) {
        let (tt, _) = {
            let source_file = ast::SourceFile::parse(input).ok().unwrap();
            let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
            ast_to_token_tree(&tt).unwrap()
        };
        let cfg = CfgExpr::parse(&tt);
        assert_eq!(cfg, expected);
    }

    #[test]
    fn test_cfg_expr_parser() {
        assert_parse_result("#![cfg(foo)]", CfgExpr::Atom("foo".into()));
        assert_parse_result("#![cfg(foo,)]", CfgExpr::Atom("foo".into()));
        assert_parse_result(
            "#![cfg(not(foo))]",
            CfgExpr::Not(Box::new(CfgExpr::Atom("foo".into()))),
        );
        assert_parse_result("#![cfg(foo(bar))]", CfgExpr::Invalid);

        // Only take the first
        assert_parse_result(r#"#![cfg(foo, bar = "baz")]"#, CfgExpr::Atom("foo".into()));

        assert_parse_result(
            r#"#![cfg(all(foo, bar = "baz"))]"#,
            CfgExpr::All(vec![
                CfgExpr::Atom("foo".into()),
                CfgExpr::KeyValue { key: "bar".into(), value: "baz".into() },
            ]),
        );

        assert_parse_result(
            r#"#![cfg(any(not(), all(), , bar = "baz",))]"#,
            CfgExpr::Any(vec![
                CfgExpr::Not(Box::new(CfgExpr::Invalid)),
                CfgExpr::All(vec![]),
                CfgExpr::Invalid,
                CfgExpr::KeyValue { key: "bar".into(), value: "baz".into() },
            ]),
        );
    }
}
<|endoftext|>