mongodb 0.3.10

A native MongoDB driver developed under MongoDB labs.
Documentation
use mongodb::{Client, ThreadedClient};
use mongodb::Error::OperationError;
use mongodb::connstring::{self, ConnectionString};
use mongodb::topology::{Topology, TopologyDescription, TopologyType};
use mongodb::stream::StreamConnector;
use mongodb::topology::monitor::IsMasterResult;
use mongodb::topology::server::Server;

use json::sdam::reader::SuiteContainer;
use serde_json::Value;

use std::collections::HashMap;

pub fn run_suite(file: &str, description: Option<TopologyDescription>) {
    let json = Value::from_file(file).unwrap();
    let suite = json.get_suite().unwrap();

    let dummy_config = ConnectionString::new("i-dont-exist", 27017);
    let dummy_client = Client::with_config(dummy_config, None, None).unwrap();
    let connection_string = connstring::parse(&suite.uri).unwrap();

    // For a standalone topology with multiple startup servers, the user
    // should pass in an unknown topology. For a base standalone topology,
    // the user should note that they expect a standalone by providing TopologyType::Single.
    let should_ignore_description = if let Some(ref inner) = description {
        inner.topology_type == TopologyType::Single && connection_string.hosts.len() != 1
    } else {
        false
    };

    let topology = if should_ignore_description {
        Topology::new(connection_string.clone(), None, StreamConnector::default()).unwrap()
    } else {
        Topology::new(
            connection_string.clone(),
            description,
            StreamConnector::default(),
        ).unwrap()
    };

    let top_description_arc = topology.description.clone();

    let mut servers = HashMap::new();

    // Fill servers array
    for host in &connection_string.hosts {
        let mut topology_description = topology.description.write().unwrap();
        let server = Server::new(
            dummy_client.clone(),
            host.clone(),
            top_description_arc.clone(),
            false,
            StreamConnector::default(),
        );
        topology_description.servers.insert(host.clone(), server);
    }

    for phase in suite.phases {
        for (host, response) in phase.operation.data {
            {
                // Save each seen server to replicate monitors for servers
                // that have been removed from the topology.
                let topology_description = topology.description.read().unwrap();
                for (host, server) in &topology_description.servers {
                    servers.insert(host.clone(), server.clone());
                }
            }

            let mut topology_description = topology.description.write().unwrap();

            if response.is_empty() {
                let server = servers.get(&host).expect("Host not found.");
                let mut server_description = server.description.write().unwrap();
                server_description.set_err(OperationError("Simulated network error.".to_owned()));
            } else {
                match IsMasterResult::new(response) {
                    Ok(ismaster) => {
                        let server = servers.get(&host).expect("Host not found.");
                        let mut server_description = server.description.write().unwrap();
                        server_description.update(ismaster, 0)
                    }
                    Err(err) => panic!(err),
                }
            }

            let server = servers.get(&host).expect("Host not found.");

            topology_description.update_without_monitor(
                host.clone(),
                server.description.clone(),
                dummy_client.clone(),
                top_description_arc.clone(),
            );
        }

        // Check server and topology descriptions.
        let topology_description = topology.description.read().unwrap();

        assert_eq!(
            phase.outcome.servers.len(),
            topology_description.servers.len()
        );
        for (host, server) in &phase.outcome.servers {
            match topology_description.servers.get(host) {
                Some(top_server) => {
                    let top_server_description = top_server.description.read().unwrap();
                    assert_eq!(server.set_name, top_server_description.set_name);
                    assert_eq!(server.stype, top_server_description.server_type);
                }
                None => panic!("Missing host in outcome."),
            }
        }

        assert_eq!(phase.outcome.set_name, topology_description.set_name);
        assert_eq!(phase.outcome.ttype, topology_description.topology_type);
    }
}