<commit_before>// Copyright 2016 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate grin_grin as grin;
extern crate grin_core as core;
extern crate grin_p2p as p2p;
extern crate grin_chain as chain;
extern crate grin_api as api;
extern crate grin_wallet as wallet;
extern crate grin_pow as pow;
extern crate grin_util as util;
extern crate secp256k1zkp as secp;

extern crate futures;
extern crate tokio_core;
extern crate tokio_timer;

mod framework;

use std::thread;
use std::time;
use std::default::Default;

use futures::{Future, Poll, Async};
use futures::task::current;
use tokio_core::reactor;
use tokio_timer::Timer;

use core::consensus;
use core::global;
use core::global::{MiningParameterMode, MINING_PARAMETER_MODE};
use wallet::WalletConfig;

use framework::{LocalServerContainer, LocalServerContainerConfig, LocalServerContainerPoolConfig,
                LocalServerContainerPool};

/// Testing the frameworks by starting a fresh server, creating a genesis
/// Block and mining into a wallet for a bit
#[test]
fn basic_genesis_mine() {
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "genesis_mine";
	framework::clean_all_output(test_name_dir);

	// Create a server pool
	let mut pool_config = LocalServerContainerPoolConfig::default();
	pool_config.base_name = String::from(test_name_dir);
	pool_config.run_length_in_seconds = 5;

	pool_config.base_api_port = 30000;
	pool_config.base_p2p_port = 31000;
	pool_config.base_wallet_port = 32000;

	let mut pool = LocalServerContainerPool::new(pool_config);

	// Create a server to add into the pool
	let mut server_config = LocalServerContainerConfig::default();
	server_config.start_miner = true;
	server_config.start_wallet = true;

	pool.create_server(&mut server_config);
	pool.run_all_servers();

}

/// Creates 5 servers, first being a seed and check that through peer address
/// messages they all end up connected.
#[test]
fn simulate_seeding() {
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "simulate_seeding";
	framework::clean_all_output(test_name_dir);

	// Create a server pool
	let mut pool_config = LocalServerContainerPoolConfig::default();
	pool_config.base_name = String::from(test_name_dir);
	pool_config.run_length_in_seconds = 30;

	// have to select different ports because of tests being run in parallel
	pool_config.base_api_port = 30020;
	pool_config.base_p2p_port = 31020;
	pool_config.base_wallet_port = 32020;

	let mut pool = LocalServerContainerPool::new(pool_config);

	// Create a first seed server to add into the pool
	let mut server_config = LocalServerContainerConfig::default();
	// server_config.start_miner = true;
	server_config.start_wallet = true;
	server_config.is_seeding = true;

	pool.create_server(&mut server_config);

	// point next servers at first seed
	server_config.is_seeding = false;
	server_config.seed_addr = String::from(format!(
		"{}:{}",
		server_config.base_addr,
		server_config.p2p_server_port
	));

	for _ in 0..4 {
		pool.create_server(&mut server_config);
	}

	pool.connect_all_peers();

	let _ = pool.run_all_servers();
}

/// Create 1 server, start it mining, then connect 4 other peers mining and
/// using the first
/// as a seed. Meant to test the evolution of mining difficulty with miners
/// running at
/// different rates
// Just going to comment this out as an automatically run test for the time
// being,
// As it's more for actively testing and hurts CI a lot
//#[test]
#[allow(dead_code)]
fn simulate_parallel_mining() {
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "simulate_parallel_mining";
	// framework::clean_all_output(test_name_dir);

	// Create a server pool
	let mut pool_config = LocalServerContainerPoolConfig::default();
	pool_config.base_name = String::from(test_name_dir);
	pool_config.run_length_in_seconds = 60;
	// have to select different ports because of tests being run in parallel
	pool_config.base_api_port = 30040;
	pool_config.base_p2p_port = 31040;
	pool_config.base_wallet_port = 32040;

	let mut pool = LocalServerContainerPool::new(pool_config);

	// Create a first seed server to add into the pool
	let mut server_config = LocalServerContainerConfig::default();
	server_config.start_miner = true;
	server_config.start_wallet = true;
	server_config.is_seeding = true;

	pool.create_server(&mut server_config);

	// point next servers at first seed
	server_config.is_seeding = false;
	server_config.seed_addr = String::from(format!(
		"{}:{}",
		server_config.base_addr,
		server_config.p2p_server_port
	));

	// And create 4 more, then let them run for a while
	for i in 1..4 {
		// fudge in some slowdown
		server_config.miner_slowdown_in_millis = i * 2;
		pool.create_server(&mut server_config);
	}

	pool.connect_all_peers();

	let _ = pool.run_all_servers();

	// Check mining difficulty here?, though I'd think it's more valuable
	// to simply output it. Can at least see the evolution of the difficulty target
	// in the debug log output for now

}

// TODO: Convert these tests to newer framework format
/// Create a network of 5 servers and mine a block, verifying that the block
/// gets propagated to all.
#[test]
fn a_simulate_block_propagation() {
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "grin-prop";
	framework::clean_all_output(test_name_dir);

	let mut evtlp = reactor::Core::new().unwrap();
	let handle = evtlp.handle();

	let mut plugin_config = pow::types::CuckooMinerPluginConfig::default();
	let mut plugin_config_vec: Vec<pow::types::CuckooMinerPluginConfig> = Vec::new();
	plugin_config.type_filter = String::from("mean_cpu");
	plugin_config_vec.push(plugin_config);

	let miner_config = pow::types::MinerConfig {
		enable_mining: true,
		burn_reward: true,
		use_cuckoo_miner: false,
		cuckoo_miner_async_mode: None,
		cuckoo_miner_plugin_dir: Some(String::from("../target/debug/deps")),
		cuckoo_miner_plugin_config: Some(plugin_config_vec),
		..Default::default()
	};

	// instantiates 5 servers on different ports
	let mut servers = vec![];
	for n in 0..5 {
		let s = grin::Server::future(
			grin::ServerConfig {
				api_http_addr: format!("127.0.0.1:{}", 19000 + n),
				db_root: format!("target/{}/grin-prop-{}", test_name_dir, n),
				p2p_config: Some(p2p::P2PConfig {
					port: 18000 + n,
					..p2p::P2PConfig::default()
				}),
				..Default::default()
			},
			&handle,
		).unwrap();
		servers.push(s);
	}

	// everyone connects to everyone else
	for n in 0..5 {
		for m in 0..5 {
			if m == n {
				continue;
			}
			let addr = format!("{}:{}", "127.0.0.1", 18000 + m);
			servers[n].connect_peer(addr.parse().unwrap()).unwrap();
		}
	}

	// start mining
	servers[0].start_miner(miner_config);
	let original_height = servers[0].head().height;

	// monitor for a change of head on a different server and check whether
	// chain height has changed
	evtlp.run(change(&servers[4]).and_then(|tip| {
		assert!(tip.height == original_height + 1);
		Ok(())
	}));
}

/// Creates 2 different disconnected servers, mine a few blocks on one, connect
/// them and check that the 2nd gets all the blocks
#[test]
fn simulate_full_sync() {
	util::init_test_logger();
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "grin-sync";
	framework::clean_all_output(test_name_dir);

	let mut evtlp = reactor::Core::new().unwrap();
	let handle = evtlp.handle();

	let mut plugin_config = pow::types::CuckooMinerPluginConfig::default();
	let mut plugin_config_vec: Vec<pow::types::CuckooMinerPluginConfig> = Vec::new();
	plugin_config.type_filter = String::from("mean_cpu");
	plugin_config_vec.push(plugin_config);

	let miner_config = pow::types::MinerConfig {
		enable_mining: true,
		burn_reward: true,
		use_cuckoo_miner: false,
		cuckoo_miner_async_mode: Some(false),
		cuckoo_miner_plugin_dir: Some(String::from("../target/debug/deps")),
		cuckoo_miner_plugin_config: Some(plugin_config_vec),
		..Default::default()
	};

	// instantiates 2 servers on different ports
	let mut servers = vec![];
	for n in 0..2 {
		let config = grin::ServerConfig {
			db_root: format!("target/{}/grin-sync-{}", test_name_dir, n),
			p2p_config: Some(p2p::P2PConfig {
				port: 11000 + n,
				..p2p::P2PConfig::default()
			}),
			..Default::default()
		};
		if n == 1 {
			config.seeding_type = grin::Seeding::Programmatic;
		}
		let s = grin::Server::future(config, &handle).unwrap();
		servers.push(s);
	}

	// mine a few blocks on server 1
	servers[0].start_miner(miner_config);
	thread::sleep(time::Duration::from_secs(5));

	// connect 1 and 2
	let addr = format!("{}:{}", "127.0.0.1", 11001);
	servers[0].connect_peer(addr.parse().unwrap()).unwrap();

	// 2 should get blocks
	evtlp.run(change(&servers[1]));
}

// Builds the change future, monitoring for a change of head on the provided
// server
fn change<'a>(s: &'a grin::Server) -> HeadChange<'a> {
	let start_head = s.head();
	HeadChange {
		server: s,
		original: start_head,
	}
}

/// Future that monitors when a server has had its head updated. Current
/// implementation isn't optimized, only use for tests.
struct HeadChange<'a> {
	server: &'a grin::Server,
	original: chain::Tip,
}

impl<'a> Future for HeadChange<'a> {
	type Item = chain::Tip;
	type Error = ();

	fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
		let new_head = self.server.head();
		if new_head.last_block_h != self.original.last_block_h {
			Ok(Async::Ready(new_head))
		} else {
			// egregious polling, asking the task to schedule us every iteration
			current().notify();
			Ok(Async::NotReady)
		}
	}
}
<commit_msg>Missing mut for test config<commit_after>// Copyright 2016 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate grin_grin as grin;
extern crate grin_core as core;
extern crate grin_p2p as p2p;
extern crate grin_chain as chain;
extern crate grin_api as api;
extern crate grin_wallet as wallet;
extern crate grin_pow as pow;
extern crate grin_util as util;
extern crate secp256k1zkp as secp;

extern crate futures;
extern crate tokio_core;
extern crate tokio_timer;

mod framework;

use std::thread;
use std::time;
use std::default::Default;

use futures::{Future, Poll, Async};
use futures::task::current;
use tokio_core::reactor;
use tokio_timer::Timer;

use core::consensus;
use core::global;
use core::global::{MiningParameterMode, MINING_PARAMETER_MODE};
use wallet::WalletConfig;

use framework::{LocalServerContainer, LocalServerContainerConfig, LocalServerContainerPoolConfig,
                LocalServerContainerPool};

/// Testing the frameworks by starting a fresh server, creating a genesis
/// Block and mining into a wallet for a bit
#[test]
fn basic_genesis_mine() {
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "genesis_mine";
	framework::clean_all_output(test_name_dir);

	// Create a server pool
	let mut pool_config = LocalServerContainerPoolConfig::default();
	pool_config.base_name = String::from(test_name_dir);
	pool_config.run_length_in_seconds = 5;

	pool_config.base_api_port = 30000;
	pool_config.base_p2p_port = 31000;
	pool_config.base_wallet_port = 32000;

	let mut pool = LocalServerContainerPool::new(pool_config);

	// Create a server to add into the pool
	let mut server_config = LocalServerContainerConfig::default();
	server_config.start_miner = true;
	server_config.start_wallet = true;

	pool.create_server(&mut server_config);
	pool.run_all_servers();

}

/// Creates 5 servers, first being a seed and check that through peer address
/// messages they all end up connected.
#[test]
fn simulate_seeding() {
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "simulate_seeding";
	framework::clean_all_output(test_name_dir);

	// Create a server pool
	let mut pool_config = LocalServerContainerPoolConfig::default();
	pool_config.base_name = String::from(test_name_dir);
	pool_config.run_length_in_seconds = 30;

	// have to select different ports because of tests being run in parallel
	pool_config.base_api_port = 30020;
	pool_config.base_p2p_port = 31020;
	pool_config.base_wallet_port = 32020;

	let mut pool = LocalServerContainerPool::new(pool_config);

	// Create a first seed server to add into the pool
	let mut server_config = LocalServerContainerConfig::default();
	// server_config.start_miner = true;
	server_config.start_wallet = true;
	server_config.is_seeding = true;

	pool.create_server(&mut server_config);

	// point next servers at first seed
	server_config.is_seeding = false;
	server_config.seed_addr = String::from(format!(
		"{}:{}",
		server_config.base_addr,
		server_config.p2p_server_port
	));

	for _ in 0..4 {
		pool.create_server(&mut server_config);
	}

	pool.connect_all_peers();

	let _ = pool.run_all_servers();
}

/// Create 1 server, start it mining, then connect 4 other peers mining and
/// using the first
/// as a seed. Meant to test the evolution of mining difficulty with miners
/// running at
/// different rates
// Just going to comment this out as an automatically run test for the time
// being,
// As it's more for actively testing and hurts CI a lot
//#[test]
#[allow(dead_code)]
fn simulate_parallel_mining() {
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "simulate_parallel_mining";
	// framework::clean_all_output(test_name_dir);

	// Create a server pool
	let mut pool_config = LocalServerContainerPoolConfig::default();
	pool_config.base_name = String::from(test_name_dir);
	pool_config.run_length_in_seconds = 60;
	// have to select different ports because of tests being run in parallel
	pool_config.base_api_port = 30040;
	pool_config.base_p2p_port = 31040;
	pool_config.base_wallet_port = 32040;

	let mut pool = LocalServerContainerPool::new(pool_config);

	// Create a first seed server to add into the pool
	let mut server_config = LocalServerContainerConfig::default();
	server_config.start_miner = true;
	server_config.start_wallet = true;
	server_config.is_seeding = true;

	pool.create_server(&mut server_config);

	// point next servers at first seed
	server_config.is_seeding = false;
	server_config.seed_addr = String::from(format!(
		"{}:{}",
		server_config.base_addr,
		server_config.p2p_server_port
	));

	// And create 4 more, then let them run for a while
	for i in 1..4 {
		// fudge in some slowdown
		server_config.miner_slowdown_in_millis = i * 2;
		pool.create_server(&mut server_config);
	}

	pool.connect_all_peers();

	let _ = pool.run_all_servers();

	// Check mining difficulty here?, though I'd think it's more valuable
	// to simply output it. Can at least see the evolution of the difficulty target
	// in the debug log output for now

}

// TODO: Convert these tests to newer framework format
/// Create a network of 5 servers and mine a block, verifying that the block
/// gets propagated to all.
#[test]
fn a_simulate_block_propagation() {
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "grin-prop";
	framework::clean_all_output(test_name_dir);

	let mut evtlp = reactor::Core::new().unwrap();
	let handle = evtlp.handle();

	let mut plugin_config = pow::types::CuckooMinerPluginConfig::default();
	let mut plugin_config_vec: Vec<pow::types::CuckooMinerPluginConfig> = Vec::new();
	plugin_config.type_filter = String::from("mean_cpu");
	plugin_config_vec.push(plugin_config);

	let miner_config = pow::types::MinerConfig {
		enable_mining: true,
		burn_reward: true,
		use_cuckoo_miner: false,
		cuckoo_miner_async_mode: None,
		cuckoo_miner_plugin_dir: Some(String::from("../target/debug/deps")),
		cuckoo_miner_plugin_config: Some(plugin_config_vec),
		..Default::default()
	};

	// instantiates 5 servers on different ports
	let mut servers = vec![];
	for n in 0..5 {
		let s = grin::Server::future(
			grin::ServerConfig {
				api_http_addr: format!("127.0.0.1:{}", 19000 + n),
				db_root: format!("target/{}/grin-prop-{}", test_name_dir, n),
				p2p_config: Some(p2p::P2PConfig {
					port: 18000 + n,
					..p2p::P2PConfig::default()
				}),
				..Default::default()
			},
			&handle,
		).unwrap();
		servers.push(s);
	}

	// everyone connects to everyone else
	for n in 0..5 {
		for m in 0..5 {
			if m == n {
				continue;
			}
			let addr = format!("{}:{}", "127.0.0.1", 18000 + m);
			servers[n].connect_peer(addr.parse().unwrap()).unwrap();
		}
	}

	// start mining
	servers[0].start_miner(miner_config);
	let original_height = servers[0].head().height;

	// monitor for a change of head on a different server and check whether
	// chain height has changed
	evtlp.run(change(&servers[4]).and_then(|tip| {
		assert!(tip.height == original_height + 1);
		Ok(())
	}));
}

/// Creates 2 different disconnected servers, mine a few blocks on one, connect
/// them and check that the 2nd gets all the blocks
#[test]
fn simulate_full_sync() {
	util::init_test_logger();
	global::set_mining_mode(MiningParameterMode::AutomatedTesting);

	let test_name_dir = "grin-sync";
	framework::clean_all_output(test_name_dir);

	let mut evtlp = reactor::Core::new().unwrap();
	let handle = evtlp.handle();

	let mut plugin_config = pow::types::CuckooMinerPluginConfig::default();
	let mut plugin_config_vec: Vec<pow::types::CuckooMinerPluginConfig> = Vec::new();
	plugin_config.type_filter = String::from("mean_cpu");
	plugin_config_vec.push(plugin_config);

	let miner_config = pow::types::MinerConfig {
		enable_mining: true,
		burn_reward: true,
		use_cuckoo_miner: false,
		cuckoo_miner_async_mode: Some(false),
		cuckoo_miner_plugin_dir: Some(String::from("../target/debug/deps")),
		cuckoo_miner_plugin_config: Some(plugin_config_vec),
		..Default::default()
	};

	// instantiates 2 servers on different ports
	let mut servers = vec![];
	for n in 0..2 {
		let mut config = grin::ServerConfig {
			db_root: format!("target/{}/grin-sync-{}", test_name_dir, n),
			p2p_config: Some(p2p::P2PConfig {
				port: 11000 + n,
				..p2p::P2PConfig::default()
			}),
			..Default::default()
		};
		if n == 1 {
			config.seeding_type = grin::Seeding::Programmatic;
		}
		let s = grin::Server::future(config, &handle).unwrap();
		servers.push(s);
	}

	// mine a few blocks on server 1
	servers[0].start_miner(miner_config);
	thread::sleep(time::Duration::from_secs(5));

	// connect 1 and 2
	let addr = format!("{}:{}", "127.0.0.1", 11001);
	servers[0].connect_peer(addr.parse().unwrap()).unwrap();

	// 2 should get blocks
	evtlp.run(change(&servers[1]));
}

// Builds the change future, monitoring for a change of head on the provided
// server
fn change<'a>(s: &'a grin::Server) -> HeadChange<'a> {
	let start_head = s.head();
	HeadChange {
		server: s,
		original: start_head,
	}
}

/// Future that monitors when a server has had its head updated. Current
/// implementation isn't optimized, only use for tests.
struct HeadChange<'a> {
	server: &'a grin::Server,
	original: chain::Tip,
}

impl<'a> Future for HeadChange<'a> {
	type Item = chain::Tip;
	type Error = ();

	fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
		let new_head = self.server.head();
		if new_head.last_block_h != self.original.last_block_h {
			Ok(Async::Ready(new_head))
		} else {
			// egregious polling, asking the task to schedule us every iteration
			current().notify();
			Ok(Async::NotReady)
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate grin_grin as grin;
extern crate grin_core as core;
extern crate grin_p2p as p2p;
extern crate grin_chain as chain;

extern crate env_logger;
extern crate futures;
extern crate tokio_core;
extern crate tokio_timer;

use std::io;
use std::thread;
use std::time;
use std::default::Default;

use futures::{Future, Poll, Async};
use futures::task::park;
use tokio_core::reactor;
use tokio_timer::Timer;

/// Create a network of 5 servers and mine a block, verifying that the block
/// gets propagated to all.
#[test]
fn simulate_block_propagation() {
  env_logger::init();

  let mut evtlp = reactor::Core::new().unwrap();
  let handle = evtlp.handle();

  // instantiates 5 servers on different ports
  let mut servers = vec![];
  for n in 0..5 {
      let s = grin::Server::future(
          grin::ServerConfig{
            db_root: format!("target/grin-prop-{}", n),
            cuckoo_size: 12,
            p2p_config: p2p::P2PConfig{port: 10000+n, ..p2p::P2PConfig::default()},
            ..Default::default()
          }, &handle).unwrap();
      servers.push(s);
  }

  // everyone connects to everyone else
  for n in 0..5 {
    for m in 0..5 {
      if m == n { continue }
      let addr = format!("{}:{}", "127.0.0.1", 10000+m);
      servers[n].connect_peer(addr.parse().unwrap()).unwrap();
    }
  }

  // start mining
  servers[0].start_miner();
  let original_height = servers[0].head().height;

  // monitor for a change of head on a different server and check whether
  // chain height has changed
  evtlp.run(change(&servers[4]).and_then(|tip| {
    assert!(tip.height == original_height+1);
    Ok(())
  }));
}

/// Creates 2 different disconnected servers, mine a few blocks on one, connect
/// them and check that the 2nd gets all the blocks
#[test]
fn simulate_full_sync() {
  env_logger::init();

  let mut evtlp = reactor::Core::new().unwrap();
  let handle = evtlp.handle();

  // instantiates 2 servers on different ports
  let mut servers = vec![];
  for n in 0..2 {
      let s = grin::Server::future(
          grin::ServerConfig{
            db_root: format!("target/grin-sync-{}", n),
            cuckoo_size: 12,
            p2p_config: p2p::P2PConfig{port: 11000+n, ..p2p::P2PConfig::default()},
            ..Default::default()
          }, &handle).unwrap();
      servers.push(s);
  }

  // mine a few blocks on server 1
  servers[0].start_miner();
  thread::sleep(time::Duration::from_secs(15));

  // connect 1 and 2
  let addr = format!("{}:{}", "127.0.0.1", 11001);
  servers[0].connect_peer(addr.parse().unwrap()).unwrap();

  // 2 should get blocks
  evtlp.run(change(&servers[1]));
}

/// Creates 5 servers, one being a seed and check that through peer address
/// messages they all end up connected.
#[test]
fn simulate_seeding() {
  env_logger::init();

  let mut evtlp = reactor::Core::new().unwrap();
  let handle = evtlp.handle();

  // instantiates 5 servers on different ports, with 0 as a seed
  let mut servers = vec![];
  for n in 0..5 {
      let s = grin::Server::future(
          grin::ServerConfig{
            db_root: format!("target/grin-seed-{}", n),
            cuckoo_size: 12,
            p2p_config: p2p::P2PConfig{port: 12000+n, ..p2p::P2PConfig::default()},
            seeding_type: grin::Seeding::List(vec!["127.0.0.1:10000".to_string()]),
            ..Default::default()
          }, &handle).unwrap();
      servers.push(s);
  }

  // wait a bit and check all servers are now connected
  evtlp.run(Timer::default().sleep(time::Duration::from_secs(30)).and_then(|_| {
    for s in servers {
      // occasionally 2 peers will connect to each other at the same time
      assert!(s.peer_count() >= 4);
    }
    Ok(())
  }));
}

// Builds the change future, monitoring for a change of head on the provided server
fn change<'a>(s: &'a grin::Server) -> HeadChange<'a> {
  let start_head = s.head();
  HeadChange {
    server: s,
    original: start_head,
  }
}

/// Future that monitors when a server has had its head updated. Current
/// implementation isn't optimized, only use for tests.
struct HeadChange<'a> {
  server: &'a grin::Server,
  original:  chain::Tip,
}

impl<'a> Future for HeadChange<'a> {
  type Item = chain::Tip;
  type Error = ();

  fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
    let new_head = self.server.head();
    if new_head.last_block_h != self.original.last_block_h {
      Ok(Async::Ready(new_head))
    } else {
      // egregious polling, asking the task to schedule us every iteration
      park().unpark();
      Ok(Async::NotReady)
    }
  }
}
<commit_msg>Forgot to update seed address as well.<commit_after>// Copyright 2016 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate grin_grin as grin;
extern crate grin_core as core;
extern crate grin_p2p as p2p;
extern crate grin_chain as chain;

extern crate env_logger;
extern crate futures;
extern crate tokio_core;
extern crate tokio_timer;

use std::io;
use std::thread;
use std::time;
use std::default::Default;

use futures::{Future, Poll, Async};
use futures::task::park;
use tokio_core::reactor;
use tokio_timer::Timer;

/// Create a network of 5 servers and mine a block, verifying that the block
/// gets propagated to all.
#[test]
fn simulate_block_propagation() {
  env_logger::init();

  let mut evtlp = reactor::Core::new().unwrap();
  let handle = evtlp.handle();

  // instantiates 5 servers on different ports
  let mut servers = vec![];
  for n in 0..5 {
      let s = grin::Server::future(
          grin::ServerConfig{
            db_root: format!("target/grin-prop-{}", n),
            cuckoo_size: 12,
            p2p_config: p2p::P2PConfig{port: 10000+n, ..p2p::P2PConfig::default()},
            ..Default::default()
          }, &handle).unwrap();
      servers.push(s);
  }

  // everyone connects to everyone else
  for n in 0..5 {
    for m in 0..5 {
      if m == n { continue }
      let addr = format!("{}:{}", "127.0.0.1", 10000+m);
      servers[n].connect_peer(addr.parse().unwrap()).unwrap();
    }
  }

  // start mining
  servers[0].start_miner();
  let original_height = servers[0].head().height;

  // monitor for a change of head on a different server and check whether
  // chain height has changed
  evtlp.run(change(&servers[4]).and_then(|tip| {
    assert!(tip.height == original_height+1);
    Ok(())
  }));
}

/// Creates 2 different disconnected servers, mine a few blocks on one, connect
/// them and check that the 2nd gets all the blocks
#[test]
fn simulate_full_sync() {
  env_logger::init();

  let mut evtlp = reactor::Core::new().unwrap();
  let handle = evtlp.handle();

  // instantiates 2 servers on different ports
  let mut servers = vec![];
  for n in 0..2 {
      let s = grin::Server::future(
          grin::ServerConfig{
            db_root: format!("target/grin-sync-{}", n),
            cuckoo_size: 12,
            p2p_config: p2p::P2PConfig{port: 11000+n, ..p2p::P2PConfig::default()},
            ..Default::default()
          }, &handle).unwrap();
      servers.push(s);
  }

  // mine a few blocks on server 1
  servers[0].start_miner();
  thread::sleep(time::Duration::from_secs(15));

  // connect 1 and 2
  let addr = format!("{}:{}", "127.0.0.1", 11001);
  servers[0].connect_peer(addr.parse().unwrap()).unwrap();

  // 2 should get blocks
  evtlp.run(change(&servers[1]));
}

/// Creates 5 servers, one being a seed and check that through peer address
/// messages they all end up connected.
#[test]
fn simulate_seeding() {
  env_logger::init();

  let mut evtlp = reactor::Core::new().unwrap();
  let handle = evtlp.handle();

  // instantiates 5 servers on different ports, with 0 as a seed
  let mut servers = vec![];
  for n in 0..5 {
      let s = grin::Server::future(
          grin::ServerConfig{
            db_root: format!("target/grin-seed-{}", n),
            cuckoo_size: 12,
            p2p_config: p2p::P2PConfig{port: 12000+n, ..p2p::P2PConfig::default()},
            seeding_type: grin::Seeding::List(vec!["127.0.0.1:12000".to_string()]),
            ..Default::default()
          }, &handle).unwrap();
      servers.push(s);
  }

  // wait a bit and check all servers are now connected
  evtlp.run(Timer::default().sleep(time::Duration::from_secs(30)).and_then(|_| {
    for s in servers {
      // occasionally 2 peers will connect to each other at the same time
      assert!(s.peer_count() >= 4);
    }
    Ok(())
  }));
}

// Builds the change future, monitoring for a change of head on the provided server
fn change<'a>(s: &'a grin::Server) -> HeadChange<'a> {
  let start_head = s.head();
  HeadChange {
    server: s,
    original: start_head,
  }
}

/// Future that monitors when a server has had its head updated. Current
/// implementation isn't optimized, only use for tests.
struct HeadChange<'a> {
  server: &'a grin::Server,
  original:  chain::Tip,
}

impl<'a> Future for HeadChange<'a> {
  type Item = chain::Tip;
  type Error = ();

  fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
    let new_head = self.server.head();
    if new_head.last_block_h != self.original.last_block_h {
      Ok(Async::Ready(new_head))
    } else {
      // egregious polling, asking the task to schedule us every iteration
      park().unpark();
      Ok(Async::NotReady)
    }
  }
}
<|endoftext|>


<commit_before>// vim: tw=80
use super::*;

use quote::ToTokens;

use crate::{
    mock_function::MockFunction,
    mock_trait::MockTrait
};

fn phantom_default_inits(generics: &Generics) -> Vec<TokenStream> {
    generics.params
    .iter()
    .enumerate()
    .map(|(count, _param)| {
        let phident = format_ident!("_t{}", count);
        quote!(#phident: ::std::marker::PhantomData)
    }).collect()
}

/// Generate any PhantomData field definitions
fn phantom_fields(generics: &Generics) -> Vec<TokenStream> {
    generics.params
    .iter()
    .enumerate()
    .filter_map(|(count, param)| {
        let phident = format_ident!("_t{}", count);
        match param {
            syn::GenericParam::Lifetime(l) => {
                if !l.bounds.is_empty() {
                    compile_error(l.bounds.span(),
                        "#automock does not yet support lifetime bounds on structs");
                }
                let lifetime = &l.lifetime;
                Some(
                quote!(#phident: ::std::marker::PhantomData<&#lifetime ()>)
                )
            },
            syn::GenericParam::Type(tp) => {
                let ty = &tp.ident;
                Some(
                quote!(#phident: ::std::marker::PhantomData<#ty>)
                )
            },
            syn::GenericParam::Const(_) => {
                compile_error(param.span(),
                    "#automock does not yet support generic constants");
                None
            }
        }
    }).collect()
}

/// A collection of methods defined in one spot
struct Methods(Vec<MockFunction>);

impl Methods {
    /// Are all of these methods static?
    fn all_static(&self) -> bool {
        self.0.iter()
            .all(|meth| meth.is_static())
    }

    fn checkpoints(&self) -> Vec<impl ToTokens> {
        self.0.iter()
            .filter(|meth| !meth.is_static())
            .map(|meth| meth.checkpoint())
            .collect::<Vec<_>>()
    }

    /// Return a fragment of code to initialize struct fields during default()
    fn default_inits(&self) -> Vec<TokenStream> {
        self.0.iter()
            .filter(|meth| !meth.is_static())
            .map(|meth| {
                let name = meth.name();
                let attrs = AttrFormatter::new(&meth.attrs)
                    .doc(false)
                    .format();
                quote!(#(#attrs)* #name: Default::default())
            }).collect::<Vec<_>>()
    }

    fn field_definitions(&self, modname: &Ident) -> Vec<TokenStream> {
        self.0.iter()
            .filter(|meth| !meth.is_static())
            .map(|meth| meth.field_definition(Some(modname)))
            .collect::<Vec<_>>()
    }

    fn priv_mods(&self) -> Vec<impl ToTokens> {
        self.0.iter()
            .map(|meth| meth.priv_module())
            .collect::<Vec<_>>()
    }
}

pub(crate) struct MockItemStruct {
    attrs: Vec<Attribute>,
    consts: Vec<ImplItemConst>,
    generics: Generics,
    /// Does the original struct have a `new` method?
    has_new: bool,
    /// Inherent methods of the mock struct
    methods: Methods,
    /// Name of the overall module that holds all of the mock stuff
    modname: Ident,
    name: Ident,
    /// Is this a whole MockStruct or just a substructure for a trait impl?
    traits: Vec<MockTrait>,
    vis: Visibility,
}

impl MockItemStruct {
    fn new_method(&self) -> impl ToTokens {
        if self.has_new {
            TokenStream::new()
        } else {
            quote!(
                /// Create a new mock object with no expectations.
                ///
                /// This method will not be generated if the real struct
                /// already has a `new` method.  However, it *will* be
                /// generated if the struct implements a trait with a `new`
                /// method.  The trait's `new` method can still be called
                /// like `<MockX as TraitY>::new`
                pub fn new() -> Self {
                    Self::default()
                }
            )
        }
    }

    fn phantom_default_inits(&self) -> Vec<TokenStream> {
        phantom_default_inits(&self.generics)
    }

    fn phantom_fields(&self) -> Vec<TokenStream> {
        phantom_fields(&self.generics)
    }
}

impl From<MockableStruct> for MockItemStruct {
    fn from(mockable: MockableStruct) -> MockItemStruct {
        let modname = gen_mod_ident(&mockable.name, None);
        let generics = mockable.generics.clone();
        let struct_name = &mockable.name;
        let vis = mockable.vis;
        let has_new = mockable.methods.iter()
            .any(|meth| meth.sig.ident == "new") ||
            mockable.impls.iter()
            .any(|impl_|
                impl_.items.iter()
                    .any(|ii| if let ImplItem::Method(iim) = ii {
                            iim.sig.ident == "new"
                        } else {
                            false
                        }
                    )
            );
        let methods = Methods(mockable.methods.into_iter()
            .map(|meth|
                mock_function::Builder::new(&meth.sig, &meth.vis)
                    .attrs(&meth.attrs)
                    .struct_(&struct_name)
                    .struct_generics(&generics)
                    .levels(2)
                    .call_levels(0)
                    .build()
            ).collect::<Vec<_>>());
        let structname = &mockable.name;
        let traits = mockable.impls.into_iter()
            .map(|i| MockTrait::new(structname, &generics, i, &vis))
            .collect();

        MockItemStruct {
            attrs: mockable.attrs,
            consts: mockable.consts,
            generics,
            has_new,
            methods,
            modname,
            name: mockable.name,
            traits,
            vis
        }
    }
}

impl ToTokens for MockItemStruct {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let attrs = AttrFormatter::new(&self.attrs)
            .async_trait(false)
            .format();
        let consts = &self.consts;
        let struct_name = &self.name;
        let (ig, tg, wc) = self.generics.split_for_impl();
        let modname = &self.modname;
        let calls = self.methods.0.iter()
            .map(|meth| meth.call(Some(modname)))
            .collect::<Vec<_>>();
        let contexts = self.methods.0.iter()
            .filter(|meth| meth.is_static())
            .map(|meth| meth.context_fn(Some(modname)))
            .collect::<Vec<_>>();
        let expects = self.methods.0.iter()
            .filter(|meth| !meth.is_static())
            .map(|meth| meth.expect(modname))
            .collect::<Vec<_>>();
        let method_checkpoints = self.methods.checkpoints();
        let new_method = self.new_method();
        let priv_mods = self.methods.priv_mods();
        let substructs = self.traits.iter()
            .map(|trait_| {
                MockItemTraitImpl {
                    attrs: trait_.attrs.clone(),
                    generics: self.generics.clone(),
                    fieldname: format_ident!("{}_expectations", trait_.name()),
                    methods: Methods(trait_.methods.clone()),
                    modname: format_ident!("{}_{}", &self.modname, trait_.name()),
                    name: format_ident!("{}_{}", &self.name, trait_.name()),
                }
            }).collect::<Vec<_>>();
        let substruct_expectations = substructs.iter()
            .filter(|ss| !ss.all_static())
            .map(|ss| ss.fieldname.clone())
            .collect::<Vec<_>>();
        let mut field_definitions = substructs.iter()
            .filter(|ss| !ss.all_static())
            .map(|ss| {
                let fieldname = &ss.fieldname;
                let tyname = &ss.name;
                quote!(#fieldname: #tyname #tg)
            }).collect::<Vec<_>>();
        field_definitions.extend(self.methods.field_definitions(&modname));
        field_definitions.extend(self.phantom_fields());
        let mut default_inits = substructs.iter()
            .filter(|ss| !ss.all_static())
            .map(|ss| {
                let fieldname = &ss.fieldname;
                quote!(#fieldname: Default::default())
            }).collect::<Vec<_>>();
        default_inits.extend(self.methods.default_inits());
        default_inits.extend(self.phantom_default_inits());
        let trait_impls = self.traits.iter()
            .map(|ss| {
                let modname = format_ident!("{}_{}", &self.modname, ss.name());
                ss.trait_impl(&modname)
            }).collect::<Vec<_>>();
        let vis = &self.vis;
        quote!(
            #[allow(non_snake_case)]
            #[allow(missing_docs)]
            pub mod #modname {
                use super::*;
                #(#priv_mods)*
            }
            #[allow(non_camel_case_types)]
            #[allow(non_snake_case)]
            #[allow(missing_docs)]
            #(#attrs)*
            #vis struct #struct_name #ig #wc
            {
                #(#field_definitions),*
            }
            impl #ig ::std::default::Default for #struct_name #tg #wc {
                fn default() -> Self {
                    Self {
                        #(#default_inits),*
                    }
                }
            }
            #(#substructs)*
            impl #ig #struct_name #tg #wc {
                #(#consts)*
                #(#calls)*
                #(#contexts)*
                #(#expects)*
                /// Validate that all current expectations for all methods have
                /// been satisfied, and discard them.
                pub fn checkpoint(&mut self) {
                    #(self.#substruct_expectations.checkpoint();)*
                    #(#method_checkpoints)*
                }
                #new_method
            }
            #(#trait_impls)*
        ).to_tokens(tokens);
    }
}

pub(crate) struct MockItemTraitImpl {
    attrs: Vec<Attribute>,
    generics: Generics,
    /// Inherent methods of the mock struct
    methods: Methods,
    /// Name of the overall module that holds all of the mock stuff
    modname: Ident,
    name: Ident,
    /// Name of the field of this type in the parent's structure
    fieldname: Ident,
}

impl MockItemTraitImpl {
    /// Are all of this traits's methods static?
    fn all_static(&self) -> bool {
        self.methods.all_static()
    }

    fn phantom_default_inits(&self) -> Vec<TokenStream> {
        phantom_default_inits(&self.generics)
    }

    fn phantom_fields(&self) -> Vec<TokenStream> {
        phantom_fields(&self.generics)
    }
}

impl ToTokens for MockItemTraitImpl {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let attrs = AttrFormatter::new(&self.attrs)
            .async_trait(false)
            .doc(false)
            .format();
        let struct_name = &self.name;
        let (ig, tg, wc) = self.generics.split_for_impl();
        let modname = &self.modname;
        let method_checkpoints = self.methods.checkpoints();
        let mut default_inits = self.methods.default_inits();
        default_inits.extend(self.phantom_default_inits());
        let mut field_definitions = self.methods.field_definitions(&modname);
        field_definitions.extend(self.phantom_fields());
        let priv_mods = self.methods.priv_mods();
        quote!(
            #[allow(non_snake_case)]
            #[allow(missing_docs)]
            pub mod #modname {
                use super::*;
                #(#priv_mods)*
            }
            #[allow(non_camel_case_types)]
            #[allow(non_snake_case)]
            #[allow(missing_docs)]
            #(#attrs)*
            struct #struct_name #ig #wc
            {
                #(#field_definitions),*
            }
            impl #ig ::std::default::Default for #struct_name #tg #wc {
                fn default() -> Self {
                    Self {
                        #(#default_inits),*
                    }
                }
            }
            impl #ig #struct_name #tg #wc {
                /// Validate that all current expectations for all methods have
                /// been satisfied, and discard them.
                pub fn checkpoint(&mut self) {
                    #(#method_checkpoints)*
                }
            }
        ).to_tokens(tokens);
    }
}
<commit_msg>allow clippy default_trait_access<commit_after>// vim: tw=80
use super::*;

use quote::ToTokens;

use crate::{
    mock_function::MockFunction,
    mock_trait::MockTrait
};

fn phantom_default_inits(generics: &Generics) -> Vec<TokenStream> {
    generics.params
    .iter()
    .enumerate()
    .map(|(count, _param)| {
        let phident = format_ident!("_t{}", count);
        quote!(#phident: ::std::marker::PhantomData)
    }).collect()
}

/// Generate any PhantomData field definitions
fn phantom_fields(generics: &Generics) -> Vec<TokenStream> {
    generics.params
    .iter()
    .enumerate()
    .filter_map(|(count, param)| {
        let phident = format_ident!("_t{}", count);
        match param {
            syn::GenericParam::Lifetime(l) => {
                if !l.bounds.is_empty() {
                    compile_error(l.bounds.span(),
                        "#automock does not yet support lifetime bounds on structs");
                }
                let lifetime = &l.lifetime;
                Some(
                quote!(#phident: ::std::marker::PhantomData<&#lifetime ()>)
                )
            },
            syn::GenericParam::Type(tp) => {
                let ty = &tp.ident;
                Some(
                quote!(#phident: ::std::marker::PhantomData<#ty>)
                )
            },
            syn::GenericParam::Const(_) => {
                compile_error(param.span(),
                    "#automock does not yet support generic constants");
                None
            }
        }
    }).collect()
}

/// A collection of methods defined in one spot
struct Methods(Vec<MockFunction>);

impl Methods {
    /// Are all of these methods static?
    fn all_static(&self) -> bool {
        self.0.iter()
            .all(|meth| meth.is_static())
    }

    fn checkpoints(&self) -> Vec<impl ToTokens> {
        self.0.iter()
            .filter(|meth| !meth.is_static())
            .map(|meth| meth.checkpoint())
            .collect::<Vec<_>>()
    }

    /// Return a fragment of code to initialize struct fields during default()
    fn default_inits(&self) -> Vec<TokenStream> {
        self.0.iter()
            .filter(|meth| !meth.is_static())
            .map(|meth| {
                let name = meth.name();
                let attrs = AttrFormatter::new(&meth.attrs)
                    .doc(false)
                    .format();
                quote!(#(#attrs)* #name: Default::default())
            }).collect::<Vec<_>>()
    }

    fn field_definitions(&self, modname: &Ident) -> Vec<TokenStream> {
        self.0.iter()
            .filter(|meth| !meth.is_static())
            .map(|meth| meth.field_definition(Some(modname)))
            .collect::<Vec<_>>()
    }

    fn priv_mods(&self) -> Vec<impl ToTokens> {
        self.0.iter()
            .map(|meth| meth.priv_module())
            .collect::<Vec<_>>()
    }
}

pub(crate) struct MockItemStruct {
    attrs: Vec<Attribute>,
    consts: Vec<ImplItemConst>,
    generics: Generics,
    /// Does the original struct have a `new` method?
    has_new: bool,
    /// Inherent methods of the mock struct
    methods: Methods,
    /// Name of the overall module that holds all of the mock stuff
    modname: Ident,
    name: Ident,
    /// Is this a whole MockStruct or just a substructure for a trait impl?
    traits: Vec<MockTrait>,
    vis: Visibility,
}

impl MockItemStruct {
    fn new_method(&self) -> impl ToTokens {
        if self.has_new {
            TokenStream::new()
        } else {
            quote!(
                /// Create a new mock object with no expectations.
                ///
                /// This method will not be generated if the real struct
                /// already has a `new` method.  However, it *will* be
                /// generated if the struct implements a trait with a `new`
                /// method.  The trait's `new` method can still be called
                /// like `<MockX as TraitY>::new`
                pub fn new() -> Self {
                    Self::default()
                }
            )
        }
    }

    fn phantom_default_inits(&self) -> Vec<TokenStream> {
        phantom_default_inits(&self.generics)
    }

    fn phantom_fields(&self) -> Vec<TokenStream> {
        phantom_fields(&self.generics)
    }
}

impl From<MockableStruct> for MockItemStruct {
    fn from(mockable: MockableStruct) -> MockItemStruct {
        let modname = gen_mod_ident(&mockable.name, None);
        let generics = mockable.generics.clone();
        let struct_name = &mockable.name;
        let vis = mockable.vis;
        let has_new = mockable.methods.iter()
            .any(|meth| meth.sig.ident == "new") ||
            mockable.impls.iter()
            .any(|impl_|
                impl_.items.iter()
                    .any(|ii| if let ImplItem::Method(iim) = ii {
                            iim.sig.ident == "new"
                        } else {
                            false
                        }
                    )
            );
        let methods = Methods(mockable.methods.into_iter()
            .map(|meth|
                mock_function::Builder::new(&meth.sig, &meth.vis)
                    .attrs(&meth.attrs)
                    .struct_(&struct_name)
                    .struct_generics(&generics)
                    .levels(2)
                    .call_levels(0)
                    .build()
            ).collect::<Vec<_>>());
        let structname = &mockable.name;
        let traits = mockable.impls.into_iter()
            .map(|i| MockTrait::new(structname, &generics, i, &vis))
            .collect();

        MockItemStruct {
            attrs: mockable.attrs,
            consts: mockable.consts,
            generics,
            has_new,
            methods,
            modname,
            name: mockable.name,
            traits,
            vis
        }
    }
}

impl ToTokens for MockItemStruct {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let attrs = AttrFormatter::new(&self.attrs)
            .async_trait(false)
            .format();
        let consts = &self.consts;
        let struct_name = &self.name;
        let (ig, tg, wc) = self.generics.split_for_impl();
        let modname = &self.modname;
        let calls = self.methods.0.iter()
            .map(|meth| meth.call(Some(modname)))
            .collect::<Vec<_>>();
        let contexts = self.methods.0.iter()
            .filter(|meth| meth.is_static())
            .map(|meth| meth.context_fn(Some(modname)))
            .collect::<Vec<_>>();
        let expects = self.methods.0.iter()
            .filter(|meth| !meth.is_static())
            .map(|meth| meth.expect(modname))
            .collect::<Vec<_>>();
        let method_checkpoints = self.methods.checkpoints();
        let new_method = self.new_method();
        let priv_mods = self.methods.priv_mods();
        let substructs = self.traits.iter()
            .map(|trait_| {
                MockItemTraitImpl {
                    attrs: trait_.attrs.clone(),
                    generics: self.generics.clone(),
                    fieldname: format_ident!("{}_expectations", trait_.name()),
                    methods: Methods(trait_.methods.clone()),
                    modname: format_ident!("{}_{}", &self.modname, trait_.name()),
                    name: format_ident!("{}_{}", &self.name, trait_.name()),
                }
            }).collect::<Vec<_>>();
        let substruct_expectations = substructs.iter()
            .filter(|ss| !ss.all_static())
            .map(|ss| ss.fieldname.clone())
            .collect::<Vec<_>>();
        let mut field_definitions = substructs.iter()
            .filter(|ss| !ss.all_static())
            .map(|ss| {
                let fieldname = &ss.fieldname;
                let tyname = &ss.name;
                quote!(#fieldname: #tyname #tg)
            }).collect::<Vec<_>>();
        field_definitions.extend(self.methods.field_definitions(&modname));
        field_definitions.extend(self.phantom_fields());
        let mut default_inits = substructs.iter()
            .filter(|ss| !ss.all_static())
            .map(|ss| {
                let fieldname = &ss.fieldname;
                quote!(#fieldname: Default::default())
            }).collect::<Vec<_>>();
        default_inits.extend(self.methods.default_inits());
        default_inits.extend(self.phantom_default_inits());
        let trait_impls = self.traits.iter()
            .map(|ss| {
                let modname = format_ident!("{}_{}", &self.modname, ss.name());
                ss.trait_impl(&modname)
            }).collect::<Vec<_>>();
        let vis = &self.vis;
        quote!(
            #[allow(non_snake_case)]
            #[allow(missing_docs)]
            pub mod #modname {
                use super::*;
                #(#priv_mods)*
            }
            #[allow(non_camel_case_types)]
            #[allow(non_snake_case)]
            #[allow(missing_docs)]
            #(#attrs)*
            #vis struct #struct_name #ig #wc
            {
                #(#field_definitions),*
            }
            impl #ig ::std::default::Default for #struct_name #tg #wc {
                #[allow(clippy::default_trait_access)]
                fn default() -> Self {
                    Self {
                        #(#default_inits),*
                    }
                }
            }
            #(#substructs)*
            impl #ig #struct_name #tg #wc {
                #(#consts)*
                #(#calls)*
                #(#contexts)*
                #(#expects)*
                /// Validate that all current expectations for all methods have
                /// been satisfied, and discard them.
                pub fn checkpoint(&mut self) {
                    #(self.#substruct_expectations.checkpoint();)*
                    #(#method_checkpoints)*
                }
                #new_method
            }
            #(#trait_impls)*
        ).to_tokens(tokens);
    }
}

pub(crate) struct MockItemTraitImpl {
    attrs: Vec<Attribute>,
    generics: Generics,
    /// Inherent methods of the mock struct
    methods: Methods,
    /// Name of the overall module that holds all of the mock stuff
    modname: Ident,
    name: Ident,
    /// Name of the field of this type in the parent's structure
    fieldname: Ident,
}

impl MockItemTraitImpl {
    /// Are all of this traits's methods static?
    fn all_static(&self) -> bool {
        self.methods.all_static()
    }

    fn phantom_default_inits(&self) -> Vec<TokenStream> {
        phantom_default_inits(&self.generics)
    }

    fn phantom_fields(&self) -> Vec<TokenStream> {
        phantom_fields(&self.generics)
    }
}

impl ToTokens for MockItemTraitImpl {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let attrs = AttrFormatter::new(&self.attrs)
            .async_trait(false)
            .doc(false)
            .format();
        let struct_name = &self.name;
        let (ig, tg, wc) = self.generics.split_for_impl();
        let modname = &self.modname;
        let method_checkpoints = self.methods.checkpoints();
        let mut default_inits = self.methods.default_inits();
        default_inits.extend(self.phantom_default_inits());
        let mut field_definitions = self.methods.field_definitions(&modname);
        field_definitions.extend(self.phantom_fields());
        let priv_mods = self.methods.priv_mods();
        quote!(
            #[allow(non_snake_case)]
            #[allow(missing_docs)]
            pub mod #modname {
                use super::*;
                #(#priv_mods)*
            }
            #[allow(non_camel_case_types)]
            #[allow(non_snake_case)]
            #[allow(missing_docs)]
            #(#attrs)*
            struct #struct_name #ig #wc
            {
                #(#field_definitions),*
            }
            impl #ig ::std::default::Default for #struct_name #tg #wc {
                fn default() -> Self {
                    Self {
                        #(#default_inits),*
                    }
                }
            }
            impl #ig #struct_name #tg #wc {
                /// Validate that all current expectations for all methods have
                /// been satisfied, and discard them.
                pub fn checkpoint(&mut self) {
                    #(#method_checkpoints)*
                }
            }
        ).to_tokens(tokens);
    }
}
<|endoftext|>


<commit_before>//! Functionality for downloading crates and maintaining download counts
//!
//! Crate level functionality is located in `krate::downloads`.

use super::{extract_crate_name_and_semver, version_and_crate};
use crate::controllers::prelude::*;
use crate::db::PoolError;
use crate::middleware::log_request::add_custom_metadata;
use crate::models::{Crate, VersionDownload};
use crate::schema::*;
use crate::views::EncodableVersionDownload;
use chrono::{Duration, NaiveDate, Utc};

/// Handles the `GET /crates/:crate_id/:version/download` route.
/// This returns a URL to the location where the crate is stored.
pub fn download(req: &mut dyn RequestExt) -> EndpointResult {
    let app = req.app().clone();

    let mut crate_name = req.params()["crate_id"].clone();
    let version = req.params()["version"].as_str();

    let mut log_metadata = None;

    let cache_key = (crate_name.to_string(), version.to_string());
    if let Some(version_id) = app.version_id_cacher.get(&cache_key) {
        app.instance_metrics.version_id_cache_hits.inc();

        // The increment does not happen instantly, but it's deferred to be executed in a batch
        // along with other downloads. See crate::downloads_counter for the implementation.
        app.downloads_counter.increment(version_id);
    } else {
        app.instance_metrics.version_id_cache_misses.inc();

        // When no database connection is ready unconditional redirects will be performed. This could
        // happen if the pool is not healthy or if an operator manually configured the application to
        // always perform unconditional redirects (for example as part of the mitigations for an
        // outage). See the comments below for a description of what unconditional redirects do.
        let conn = if app.config.force_unconditional_redirects {
            None
        } else {
            match req.db_read_prefer_primary() {
                Ok(conn) => Some(conn),
                Err(PoolError::UnhealthyPool) => None,
                Err(err) => return Err(err.into()),
            }
        };

        if let Some(conn) = &conn {
            use self::versions::dsl::*;

            // Returns the crate name as stored in the database, or an error if we could
            // not load the version ID from the database.
            let (version_id, canonical_crate_name) = app
                .instance_metrics
                .downloads_select_query_execution_time
                .observe_closure_duration(|| {
                    versions
                        .inner_join(crates::table)
                        .select((id, crates::name))
                        .filter(Crate::with_name(&crate_name))
                        .filter(num.eq(version))
                        .first::<(i32, String)>(&**conn)
                })?;

            if canonical_crate_name != crate_name {
                app.instance_metrics
                    .downloads_non_canonical_crate_name_total
                    .inc();
                log_metadata = Some(("bot", "dl"));
                crate_name = canonical_crate_name;
            } else {
                // The version_id is only cached if the provided crate name was canonical.
                // Non-canonical requests fallback to the "slow" path with a DB query, but
                // we typically only get a few hundred non-canonical requests in a day anyway.
                app.version_id_cacher.insert(cache_key, version_id);
            }

            // The increment does not happen instantly, but it's deferred to be executed in a batch
            // along with other downloads. See crate::downloads_counter for the implementation.
            app.downloads_counter.increment(version_id);
        } else {
            // The download endpoint is the most critical route in the whole crates.io application,
            // as it's relied upon by users and automations to download crates. Keeping it working
            // is the most important thing for us.
            //
            // The endpoint relies on the database to fetch the canonical crate name (with the
            // right capitalization and hyphenation), but that's only needed to serve clients who
            // don't call the endpoint with the crate's canonical name.
            //
            // Thankfully Cargo always uses the right name when calling the endpoint, and we can
            // keep it working during a full database outage by unconditionally redirecting without
            // checking whether the crate exists or the rigth name is used. Non-Cargo clients might
            // get a 404 response instead of a 500, but that's worth it.
            //
            // Without a working database we also can't count downloads, but that's also less
            // critical than keeping Cargo downloads operational.

            app.instance_metrics
                .downloads_unconditional_redirects_total
                .inc();
            log_metadata = Some(("unconditional_redirect", "true"));
        }
    };

    let redirect_url = req
        .app()
        .config
        .uploader()
        .crate_location(&crate_name, &*version);

    if let Some((key, value)) = log_metadata {
        add_custom_metadata(key, value);
    }

    if req.wants_json() {
        Ok(req.json(&json!({ "url": redirect_url })))
    } else {
        Ok(req.redirect(redirect_url))
    }
}

/// Handles the `GET /crates/:crate_id/:version/downloads` route.
pub fn downloads(req: &mut dyn RequestExt) -> EndpointResult {
    let (crate_name, semver) = extract_crate_name_and_semver(req)?;

    let conn = req.db_read()?;
    let (version, _) = version_and_crate(&conn, crate_name, semver)?;

    let cutoff_end_date = req
        .query()
        .get("before_date")
        .and_then(|d| NaiveDate::parse_from_str(d, "%F").ok())
        .unwrap_or_else(|| Utc::today().naive_utc());
    let cutoff_start_date = cutoff_end_date - Duration::days(89);

    let downloads = VersionDownload::belonging_to(&version)
        .filter(version_downloads::date.between(cutoff_start_date, cutoff_end_date))
        .order(version_downloads::date)
        .load(&*conn)?
        .into_iter()
        .map(VersionDownload::into)
        .collect::<Vec<EncodableVersionDownload>>();

    Ok(req.json(&json!({ "version_downloads": downloads })))
}
<commit_msg>version::downloads: Simplify `add_custom_metadata()` usage (#4921)<commit_after>//! Functionality for downloading crates and maintaining download counts
//!
//! Crate level functionality is located in `krate::downloads`.

use super::{extract_crate_name_and_semver, version_and_crate};
use crate::controllers::prelude::*;
use crate::db::PoolError;
use crate::middleware::log_request::add_custom_metadata;
use crate::models::{Crate, VersionDownload};
use crate::schema::*;
use crate::views::EncodableVersionDownload;
use chrono::{Duration, NaiveDate, Utc};

/// Handles the `GET /crates/:crate_id/:version/download` route.
/// This returns a URL to the location where the crate is stored.
pub fn download(req: &mut dyn RequestExt) -> EndpointResult {
    let app = req.app().clone();

    let mut crate_name = req.params()["crate_id"].clone();
    let version = req.params()["version"].as_str();

    let cache_key = (crate_name.to_string(), version.to_string());
    if let Some(version_id) = app.version_id_cacher.get(&cache_key) {
        app.instance_metrics.version_id_cache_hits.inc();

        // The increment does not happen instantly, but it's deferred to be executed in a batch
        // along with other downloads. See crate::downloads_counter for the implementation.
        app.downloads_counter.increment(version_id);
    } else {
        app.instance_metrics.version_id_cache_misses.inc();

        // When no database connection is ready unconditional redirects will be performed. This could
        // happen if the pool is not healthy or if an operator manually configured the application to
        // always perform unconditional redirects (for example as part of the mitigations for an
        // outage). See the comments below for a description of what unconditional redirects do.
        let conn = if app.config.force_unconditional_redirects {
            None
        } else {
            match req.db_read_prefer_primary() {
                Ok(conn) => Some(conn),
                Err(PoolError::UnhealthyPool) => None,
                Err(err) => return Err(err.into()),
            }
        };

        if let Some(conn) = &conn {
            use self::versions::dsl::*;

            // Returns the crate name as stored in the database, or an error if we could
            // not load the version ID from the database.
            let (version_id, canonical_crate_name) = app
                .instance_metrics
                .downloads_select_query_execution_time
                .observe_closure_duration(|| {
                    versions
                        .inner_join(crates::table)
                        .select((id, crates::name))
                        .filter(Crate::with_name(&crate_name))
                        .filter(num.eq(version))
                        .first::<(i32, String)>(&**conn)
                })?;

            if canonical_crate_name != crate_name {
                app.instance_metrics
                    .downloads_non_canonical_crate_name_total
                    .inc();

                add_custom_metadata("bot", "dl");

                crate_name = canonical_crate_name;
            } else {
                // The version_id is only cached if the provided crate name was canonical.
                // Non-canonical requests fallback to the "slow" path with a DB query, but
                // we typically only get a few hundred non-canonical requests in a day anyway.
                app.version_id_cacher.insert(cache_key, version_id);
            }

            // The increment does not happen instantly, but it's deferred to be executed in a batch
            // along with other downloads. See crate::downloads_counter for the implementation.
            app.downloads_counter.increment(version_id);
        } else {
            // The download endpoint is the most critical route in the whole crates.io application,
            // as it's relied upon by users and automations to download crates. Keeping it working
            // is the most important thing for us.
            //
            // The endpoint relies on the database to fetch the canonical crate name (with the
            // right capitalization and hyphenation), but that's only needed to serve clients who
            // don't call the endpoint with the crate's canonical name.
            //
            // Thankfully Cargo always uses the right name when calling the endpoint, and we can
            // keep it working during a full database outage by unconditionally redirecting without
            // checking whether the crate exists or the rigth name is used. Non-Cargo clients might
            // get a 404 response instead of a 500, but that's worth it.
            //
            // Without a working database we also can't count downloads, but that's also less
            // critical than keeping Cargo downloads operational.

            app.instance_metrics
                .downloads_unconditional_redirects_total
                .inc();

            add_custom_metadata("unconditional_redirect", "true");
        }
    };

    let redirect_url = req
        .app()
        .config
        .uploader()
        .crate_location(&crate_name, &*version);

    if req.wants_json() {
        Ok(req.json(&json!({ "url": redirect_url })))
    } else {
        Ok(req.redirect(redirect_url))
    }
}

/// Handles the `GET /crates/:crate_id/:version/downloads` route.
pub fn downloads(req: &mut dyn RequestExt) -> EndpointResult {
    let (crate_name, semver) = extract_crate_name_and_semver(req)?;

    let conn = req.db_read()?;
    let (version, _) = version_and_crate(&conn, crate_name, semver)?;

    let cutoff_end_date = req
        .query()
        .get("before_date")
        .and_then(|d| NaiveDate::parse_from_str(d, "%F").ok())
        .unwrap_or_else(|| Utc::today().naive_utc());
    let cutoff_start_date = cutoff_end_date - Duration::days(89);

    let downloads = VersionDownload::belonging_to(&version)
        .filter(version_downloads::date.between(cutoff_start_date, cutoff_end_date))
        .order(version_downloads::date)
        .load(&*conn)?
        .into_iter()
        .map(VersionDownload::into)
        .collect::<Vec<EncodableVersionDownload>>();

    Ok(req.json(&json!({ "version_downloads": downloads })))
}
<|endoftext|>


<commit_before>use serde::{ser, Serialize};

use error::Error;
use token::Token;

/// A `Serializer` that ensures that a value serializes to a given list of
/// tokens.
#[derive(Debug)]
pub struct Serializer<'a> {
    tokens: &'a [Token],
}

impl<'a> Serializer<'a> {
    /// Creates the serializer.
    pub fn new(tokens: &'a [Token]) -> Self {
        Serializer { tokens: tokens }
    }

    /// Pulls the next token off of the serializer, ignoring it.
    fn next_token(&mut self) -> Option<Token> {
        if let Some((&first, rest)) = self.tokens.split_first() {
            self.tokens = rest;
            Some(first)
        } else {
            None
        }
    }

    pub fn remaining(&self) -> usize {
        self.tokens.len()
    }
}

macro_rules! assert_next_token {
    ($ser:expr, $actual:ident) => {
        assert_next_token!($ser, stringify!($actual), Token::$actual, true);
    };
    ($ser:expr, $actual:ident($v:expr)) => {
        assert_next_token!(
            $ser,
            format_args!(concat!(stringify!($actual), "({:?})"), $v),
            Token::$actual(v),
            v == $v
        );
    };
    ($ser:expr, $actual:ident { $($k:ident),* }) => {
        let compare = ($($k,)*);
        let field_format = || {
            use std::fmt::Write;
            let mut buffer = String::new();
            $(
                write!(&mut buffer, concat!(stringify!($k), ": {:?}, "), $k).unwrap();
            )*
            buffer
        };
        assert_next_token!(
            $ser,
            format_args!(concat!(stringify!($actual), " {{ {}}}"), field_format()),
            Token::$actual { $($k),* },
            ($($k,)*) == compare
        );
    };
    ($ser:expr, $actual:expr, $pat:pat, $guard:expr) => {
        match $ser.next_token() {
            Some($pat) if $guard => {}
            Some(expected) => {
                panic!("expected Token::{} but serialized as {}",
                       expected, $actual);
            }
            None => {
                panic!("expected end of tokens, but {} was serialized",
                       $actual);
            }
        }
    };
}

impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Self;
    type SerializeTuple = Self;
    type SerializeTupleStruct = Self;
    type SerializeTupleVariant = Variant<'s, 'a>;
    type SerializeMap = Self;
    type SerializeStruct = Self;
    type SerializeStructVariant = Variant<'s, 'a>;

    fn serialize_bool(self, v: bool) -> Result<(), Error> {
        assert_next_token!(self, Bool(v));
        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<(), Error> {
        assert_next_token!(self, I8(v));
        Ok(())
    }

    fn serialize_i16(self, v: i16) -> Result<(), Error> {
        assert_next_token!(self, I16(v));
        Ok(())
    }

    fn serialize_i32(self, v: i32) -> Result<(), Error> {
        assert_next_token!(self, I32(v));
        Ok(())
    }

    fn serialize_i64(self, v: i64) -> Result<(), Error> {
        assert_next_token!(self, I64(v));
        Ok(())
    }

    fn serialize_u8(self, v: u8) -> Result<(), Error> {
        assert_next_token!(self, U8(v));
        Ok(())
    }

    fn serialize_u16(self, v: u16) -> Result<(), Error> {
        assert_next_token!(self, U16(v));
        Ok(())
    }

    fn serialize_u32(self, v: u32) -> Result<(), Error> {
        assert_next_token!(self, U32(v));
        Ok(())
    }

    fn serialize_u64(self, v: u64) -> Result<(), Error> {
        assert_next_token!(self, U64(v));
        Ok(())
    }

    fn serialize_f32(self, v: f32) -> Result<(), Error> {
        assert_next_token!(self, F32(v));
        Ok(())
    }

    fn serialize_f64(self, v: f64) -> Result<(), Error> {
        assert_next_token!(self, F64(v));
        Ok(())
    }

    fn serialize_char(self, v: char) -> Result<(), Error> {
        assert_next_token!(self, Char(v));
        Ok(())
    }

    fn serialize_str(self, v: &str) -> Result<(), Error> {
        match self.tokens.first() {
            Some(&Token::BorrowedStr(_)) => assert_next_token!(self, BorrowedStr(v)),
            Some(&Token::String(_)) => assert_next_token!(self, String(v)),
            _ => assert_next_token!(self, Str(v)),
        }
        Ok(())
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
        match self.tokens.first() {
            Some(&Token::BorrowedBytes(_)) => assert_next_token!(self, BorrowedBytes(v)),
            Some(&Token::ByteBuf(_)) => assert_next_token!(self, ByteBuf(v)),
            _ => assert_next_token!(self, Bytes(v)),
        }
        Ok(())
    }

    fn serialize_unit(self) -> Result<(), Error> {
        assert_next_token!(self, Unit);
        Ok(())
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<(), Error> {
        assert_next_token!(self, UnitStruct { name });
        Ok(())
    }

    fn serialize_unit_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
    ) -> Result<(), Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            assert_next_token!(self, Unit);
        } else {
            assert_next_token!(self, UnitVariant { name, variant });
        }
        Ok(())
    }

    fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        assert_next_token!(self, NewtypeStruct { name });
        value.serialize(self)
    }

    fn serialize_newtype_variant<T: ?Sized>(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        value: &T,
    ) -> Result<(), Error>
    where
        T: Serialize,
    {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
        } else {
            assert_next_token!(self, NewtypeVariant { name, variant });
        }
        value.serialize(self)
    }

    fn serialize_none(self) -> Result<(), Error> {
        assert_next_token!(self, None);
        Ok(())
    }

    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        assert_next_token!(self, Some);
        value.serialize(self)
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self, Error> {
        assert_next_token!(self, Seq { len });
        Ok(self)
    }

    fn serialize_tuple(self, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, Tuple { len });
        Ok(self)
    }

    fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, TupleStruct { name, len });
        Ok(self)
    }

    fn serialize_tuple_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleVariant, Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            let len = Some(len);
            assert_next_token!(self, Seq { len });
            Ok(Variant {
                ser: self,
                end: Token::SeqEnd,
            })
        } else {
            assert_next_token!(self, TupleVariant { name, variant, len });
            Ok(Variant {
                ser: self,
                end: Token::TupleVariantEnd,
            })
        }
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self, Error> {
        assert_next_token!(self, Map { len });
        Ok(self)
    }

    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, Struct { name, len });
        Ok(self)
    }

    fn serialize_struct_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeStructVariant, Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            let len = Some(len);
            assert_next_token!(self, Map { len });
            Ok(Variant {
                ser: self,
                end: Token::MapEnd,
            })
        } else {
            assert_next_token!(self, StructVariant { name, variant, len });
            Ok(Variant {
                ser: self,
                end: Token::StructVariantEnd,
            })
        }
    }

    fn is_human_readable(&self) -> bool {
        panic!(
            "Types which have different human-readable and compact representations \
             must explicitly mark their test cases with `serde_test::Configure`"
        );
    }
}

pub struct Variant<'s, 'a: 's> {
    ser: &'s mut Serializer<'a>,
    end: Token,
}

impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, SeqEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, TupleEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, TupleStructEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTupleVariant for Variant<'s, 'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut *self.ser)
    }

    fn end(self) -> Result<(), Error> {
        match self.end {
            Token::TupleVariantEnd => assert_next_token!(self.ser, TupleVariantEnd),
            Token::SeqEnd => assert_next_token!(self.ser, SeqEnd),
            _ => unreachable!(),
        }
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        key.serialize(&mut **self)
    }

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Self::Error> {
        assert_next_token!(self, MapEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(
        &mut self,
        key: &'static str,
        value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        key.serialize(&mut **self)?;
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Self::Error> {
        assert_next_token!(self, StructEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeStructVariant for Variant<'s, 'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(
        &mut self,
        key: &'static str,
        value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        key.serialize(&mut *self.ser)?;
        value.serialize(&mut *self.ser)
    }

    fn end(self) -> Result<(), Self::Error> {
        match self.end {
            Token::StructVariantEnd => assert_next_token!(self.ser, StructVariantEnd),
            Token::MapEnd => assert_next_token!(self.ser, MapEnd),
            _ => unreachable!(),
        }
        Ok(())
    }
}
<commit_msg>Resolve semicolon_in_expressions_from_macros warning in serde_test<commit_after>use serde::{ser, Serialize};

use error::Error;
use token::Token;

/// A `Serializer` that ensures that a value serializes to a given list of
/// tokens.
#[derive(Debug)]
pub struct Serializer<'a> {
    tokens: &'a [Token],
}

impl<'a> Serializer<'a> {
    /// Creates the serializer.
    pub fn new(tokens: &'a [Token]) -> Self {
        Serializer { tokens: tokens }
    }

    /// Pulls the next token off of the serializer, ignoring it.
    fn next_token(&mut self) -> Option<Token> {
        if let Some((&first, rest)) = self.tokens.split_first() {
            self.tokens = rest;
            Some(first)
        } else {
            None
        }
    }

    pub fn remaining(&self) -> usize {
        self.tokens.len()
    }
}

macro_rules! assert_next_token {
    ($ser:expr, $actual:ident) => {{
        assert_next_token!($ser, stringify!($actual), Token::$actual, true);
    }};
    ($ser:expr, $actual:ident($v:expr)) => {{
        assert_next_token!(
            $ser,
            format_args!(concat!(stringify!($actual), "({:?})"), $v),
            Token::$actual(v),
            v == $v
        );
    }};
    ($ser:expr, $actual:ident { $($k:ident),* }) => {{
        let compare = ($($k,)*);
        let field_format = || {
            use std::fmt::Write;
            let mut buffer = String::new();
            $(
                write!(&mut buffer, concat!(stringify!($k), ": {:?}, "), $k).unwrap();
            )*
            buffer
        };
        assert_next_token!(
            $ser,
            format_args!(concat!(stringify!($actual), " {{ {}}}"), field_format()),
            Token::$actual { $($k),* },
            ($($k,)*) == compare
        );
    }};
    ($ser:expr, $actual:expr, $pat:pat, $guard:expr) => {
        match $ser.next_token() {
            Some($pat) if $guard => {}
            Some(expected) => {
                panic!("expected Token::{} but serialized as {}",
                       expected, $actual);
            }
            None => {
                panic!("expected end of tokens, but {} was serialized",
                       $actual);
            }
        }
    };
}

impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Self;
    type SerializeTuple = Self;
    type SerializeTupleStruct = Self;
    type SerializeTupleVariant = Variant<'s, 'a>;
    type SerializeMap = Self;
    type SerializeStruct = Self;
    type SerializeStructVariant = Variant<'s, 'a>;

    fn serialize_bool(self, v: bool) -> Result<(), Error> {
        assert_next_token!(self, Bool(v));
        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<(), Error> {
        assert_next_token!(self, I8(v));
        Ok(())
    }

    fn serialize_i16(self, v: i16) -> Result<(), Error> {
        assert_next_token!(self, I16(v));
        Ok(())
    }

    fn serialize_i32(self, v: i32) -> Result<(), Error> {
        assert_next_token!(self, I32(v));
        Ok(())
    }

    fn serialize_i64(self, v: i64) -> Result<(), Error> {
        assert_next_token!(self, I64(v));
        Ok(())
    }

    fn serialize_u8(self, v: u8) -> Result<(), Error> {
        assert_next_token!(self, U8(v));
        Ok(())
    }

    fn serialize_u16(self, v: u16) -> Result<(), Error> {
        assert_next_token!(self, U16(v));
        Ok(())
    }

    fn serialize_u32(self, v: u32) -> Result<(), Error> {
        assert_next_token!(self, U32(v));
        Ok(())
    }

    fn serialize_u64(self, v: u64) -> Result<(), Error> {
        assert_next_token!(self, U64(v));
        Ok(())
    }

    fn serialize_f32(self, v: f32) -> Result<(), Error> {
        assert_next_token!(self, F32(v));
        Ok(())
    }

    fn serialize_f64(self, v: f64) -> Result<(), Error> {
        assert_next_token!(self, F64(v));
        Ok(())
    }

    fn serialize_char(self, v: char) -> Result<(), Error> {
        assert_next_token!(self, Char(v));
        Ok(())
    }

    fn serialize_str(self, v: &str) -> Result<(), Error> {
        match self.tokens.first() {
            Some(&Token::BorrowedStr(_)) => assert_next_token!(self, BorrowedStr(v)),
            Some(&Token::String(_)) => assert_next_token!(self, String(v)),
            _ => assert_next_token!(self, Str(v)),
        }
        Ok(())
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
        match self.tokens.first() {
            Some(&Token::BorrowedBytes(_)) => assert_next_token!(self, BorrowedBytes(v)),
            Some(&Token::ByteBuf(_)) => assert_next_token!(self, ByteBuf(v)),
            _ => assert_next_token!(self, Bytes(v)),
        }
        Ok(())
    }

    fn serialize_unit(self) -> Result<(), Error> {
        assert_next_token!(self, Unit);
        Ok(())
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<(), Error> {
        assert_next_token!(self, UnitStruct { name });
        Ok(())
    }

    fn serialize_unit_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
    ) -> Result<(), Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            assert_next_token!(self, Unit);
        } else {
            assert_next_token!(self, UnitVariant { name, variant });
        }
        Ok(())
    }

    fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        assert_next_token!(self, NewtypeStruct { name });
        value.serialize(self)
    }

    fn serialize_newtype_variant<T: ?Sized>(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        value: &T,
    ) -> Result<(), Error>
    where
        T: Serialize,
    {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
        } else {
            assert_next_token!(self, NewtypeVariant { name, variant });
        }
        value.serialize(self)
    }

    fn serialize_none(self) -> Result<(), Error> {
        assert_next_token!(self, None);
        Ok(())
    }

    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        assert_next_token!(self, Some);
        value.serialize(self)
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self, Error> {
        assert_next_token!(self, Seq { len });
        Ok(self)
    }

    fn serialize_tuple(self, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, Tuple { len });
        Ok(self)
    }

    fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, TupleStruct { name, len });
        Ok(self)
    }

    fn serialize_tuple_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeTupleVariant, Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            let len = Some(len);
            assert_next_token!(self, Seq { len });
            Ok(Variant {
                ser: self,
                end: Token::SeqEnd,
            })
        } else {
            assert_next_token!(self, TupleVariant { name, variant, len });
            Ok(Variant {
                ser: self,
                end: Token::TupleVariantEnd,
            })
        }
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self, Error> {
        assert_next_token!(self, Map { len });
        Ok(self)
    }

    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
        assert_next_token!(self, Struct { name, len });
        Ok(self)
    }

    fn serialize_struct_variant(
        self,
        name: &'static str,
        _variant_index: u32,
        variant: &'static str,
        len: usize,
    ) -> Result<Self::SerializeStructVariant, Error> {
        if self.tokens.first() == Some(&Token::Enum { name: name }) {
            self.next_token();
            assert_next_token!(self, Str(variant));
            let len = Some(len);
            assert_next_token!(self, Map { len });
            Ok(Variant {
                ser: self,
                end: Token::MapEnd,
            })
        } else {
            assert_next_token!(self, StructVariant { name, variant, len });
            Ok(Variant {
                ser: self,
                end: Token::StructVariantEnd,
            })
        }
    }

    fn is_human_readable(&self) -> bool {
        panic!(
            "Types which have different human-readable and compact representations \
             must explicitly mark their test cases with `serde_test::Configure`"
        );
    }
}

pub struct Variant<'s, 'a: 's> {
    ser: &'s mut Serializer<'a>,
    end: Token,
}

impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, SeqEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, TupleEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Error> {
        assert_next_token!(self, TupleStructEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeTupleVariant for Variant<'s, 'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
    where
        T: Serialize,
    {
        value.serialize(&mut *self.ser)
    }

    fn end(self) -> Result<(), Error> {
        match self.end {
            Token::TupleVariantEnd => assert_next_token!(self.ser, TupleVariantEnd),
            Token::SeqEnd => assert_next_token!(self.ser, SeqEnd),
            _ => unreachable!(),
        }
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        key.serialize(&mut **self)
    }

    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Self::Error> {
        assert_next_token!(self, MapEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(
        &mut self,
        key: &'static str,
        value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        key.serialize(&mut **self)?;
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<(), Self::Error> {
        assert_next_token!(self, StructEnd);
        Ok(())
    }
}

impl<'s, 'a> ser::SerializeStructVariant for Variant<'s, 'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized>(
        &mut self,
        key: &'static str,
        value: &T,
    ) -> Result<(), Self::Error>
    where
        T: Serialize,
    {
        key.serialize(&mut *self.ser)?;
        value.serialize(&mut *self.ser)
    }

    fn end(self) -> Result<(), Self::Error> {
        match self.end {
            Token::StructVariantEnd => assert_next_token!(self.ser, StructVariantEnd),
            Token::MapEnd => assert_next_token!(self.ser, MapEnd),
            _ => unreachable!(),
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use backend::Backend;
use expression::*;
use expression::operators::And;
use expression_methods::*;
use result::QueryResult;
use super::*;
use types::Bool;

pub trait WhereAnd<Predicate> {
    type Output;

    fn and(self, predicate: Predicate) -> Self::Output;
}

#[derive(Debug, Clone, Copy)]
pub struct NoWhereClause;

impl_query_id!(NoWhereClause);

impl<DB: Backend> QueryFragment<DB> for NoWhereClause {
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Predicate> WhereAnd<Predicate> for NoWhereClause
where
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<Predicate>;

    fn and(self, predicate: Predicate) -> Self::Output {
        WhereClause(predicate)
    }
}

impl<DB: Backend> Into<Option<Box<QueryFragment<DB>>>> for NoWhereClause {
    fn into(self) -> Option<Box<QueryFragment<DB>>> {
        None
    }
}

#[derive(Debug, Clone, Copy)]
pub struct WhereClause<Expr>(Expr);

impl<DB, Expr> QueryFragment<DB> for WhereClause<Expr>
where
    DB: Backend,
    Expr: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" WHERE ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl_query_id!(WhereClause<T>);

impl<Expr, Predicate> WhereAnd<Predicate> for WhereClause<Expr>
where
    Expr: Expression<SqlType = Bool>,
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<And<Expr, Predicate>>;

    fn and(self, predicate: Predicate) -> Self::Output {
        WhereClause(self.0.and(predicate))
    }
}

impl<'a, DB, Predicate> Into<Option<Box<QueryFragment<DB> + 'a>>> for WhereClause<Predicate>
where
    DB: Backend,
    Predicate: QueryFragment<DB> + 'a,
{
    fn into(self) -> Option<Box<QueryFragment<DB> + 'a>> {
        Some(Box::new(self.0))
    }
}

/// Marker trait indicating that a `WHERE` clause is valid for a given query
/// source.
pub trait ValidWhereClause<QS> {}

impl<QS> ValidWhereClause<QS> for NoWhereClause {}

impl<QS, Expr> ValidWhereClause<QS> for WhereClause<Expr>
where
    Expr: AppearsOnTable<QS>,
{
}
<commit_msg>Document all items in `query_builder::where_clause`<commit_after>use backend::Backend;
use expression::*;
use expression::operators::And;
use expression_methods::*;
use result::QueryResult;
use super::*;
use types::Bool;

/// Add `Predicate` to the current `WHERE` clause, joining with `AND` if
/// applicable.
pub trait WhereAnd<Predicate> {
    /// What is the type of the resulting `WHERE` clause?
    type Output;

    /// See the trait-level docs.
    fn and(self, predicate: Predicate) -> Self::Output;
}

/// Represents that a query has no `WHERE` clause.
#[derive(Debug, Clone, Copy)]
pub struct NoWhereClause;

impl_query_id!(NoWhereClause);

impl<DB: Backend> QueryFragment<DB> for NoWhereClause {
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

impl<Predicate> WhereAnd<Predicate> for NoWhereClause
where
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<Predicate>;

    fn and(self, predicate: Predicate) -> Self::Output {
        WhereClause(predicate)
    }
}

impl<DB: Backend> Into<Option<Box<QueryFragment<DB>>>> for NoWhereClause {
    fn into(self) -> Option<Box<QueryFragment<DB>>> {
        None
    }
}

/// The `WHERE` clause of a query.
#[derive(Debug, Clone, Copy)]
pub struct WhereClause<Expr>(Expr);

impl<DB, Expr> QueryFragment<DB> for WhereClause<Expr>
where
    DB: Backend,
    Expr: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql(" WHERE ");
        self.0.walk_ast(out.reborrow())?;
        Ok(())
    }
}

impl_query_id!(WhereClause<T>);

impl<Expr, Predicate> WhereAnd<Predicate> for WhereClause<Expr>
where
    Expr: Expression<SqlType = Bool>,
    Predicate: Expression<SqlType = Bool>,
{
    type Output = WhereClause<And<Expr, Predicate>>;

    fn and(self, predicate: Predicate) -> Self::Output {
        WhereClause(self.0.and(predicate))
    }
}

impl<'a, DB, Predicate> Into<Option<Box<QueryFragment<DB> + 'a>>> for WhereClause<Predicate>
where
    DB: Backend,
    Predicate: QueryFragment<DB> + 'a,
{
    fn into(self) -> Option<Box<QueryFragment<DB> + 'a>> {
        Some(Box::new(self.0))
    }
}

/// Marker trait indicating that a `WHERE` clause is valid for a given query
/// source.
pub trait ValidWhereClause<QS> {}

impl<QS> ValidWhereClause<QS> for NoWhereClause {}

impl<QS, Expr> ValidWhereClause<QS> for WhereClause<Expr>
where
    Expr: AppearsOnTable<QS>,
{
}
<|endoftext|>