<commit_before>use bson;
use bson::Bson;
use bson::Document;

use mongodb::client::MongoClient;

#[test]
fn find_and_insert() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("find_and_insert");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert document
    let doc = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    // let mut doc = bson::Document::new();
    // doc.insert("title".to_owned(), Bson::String("Jaws".to_owned()));
    coll.insert_one(doc, None).ok().expect("Failed to insert document");

    // Find document
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let result = cursor.next().unwrap();

    // Assert expected title of document
    match result.get("title") {
        Some(&Bson::String(ref title)) => assert_eq!("Jaws", title),
        _ => panic!("Expected Bson::String!"),
    };

    assert!(cursor.next().is_none());
}

#[test]
fn find_and_insert_one() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("find_and_insert");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert document
    let doc = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    // let mut doc = bson::Document::new();
    // doc.insert("title".to_owned(), Bson::String("Jaws".to_owned()));
    coll.insert_one(doc, None).ok().expect("Failed to insert document");

    // Find single document
    let result = coll.find_one(None, None).ok().expect("Failed to execute find command.");
    assert!(result.is_some());

    // Assert expected title of document
    match result.unwrap().get("title") {
        Some(&Bson::String(ref title)) => assert_eq!("Jaws", title),
        _ => panic!("Expected Bson::String!"),
    };
}

#[test]
fn list_collections() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");

    db.drop_database().ok().expect("Failed to drop database");

    // Build collections
    db.collection("list_collections1").insert_one(bson::Document::new(), None)
        .ok().expect("Failed to insert placeholder document into collection");
    db.collection("list_collections2").insert_one(bson::Document::new(), None)
        .ok().expect("Failed to insert placeholder document into collection");

    // Check for namespaces
    let result = db.list_collections().ok().expect("Failed to execute list_collections command.");;
    assert_eq!(3, result.len());

    let namespace = vec![
        "test.list_collections1",
        "test.list_collections2",
        "test.system.indexes",
    ];

    for i in 0..2 {
        assert_eq!(namespace[i], result[i].namespace);
    }
}

#[test]
fn insert_many() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("insert_many");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    // let mut doc = bson::Document::new();
    // let mut doc2 = bson::Document::new();
    // doc.insert("title".to_owned(), Bson::String("Jaws".to_owned()));
    // doc2.insert("title".to_owned(), Bson::String("Back to the Future".to_owned()));

    coll.insert_many(vec![doc1, doc2], false, None).ok().expect("Failed to insert documents.");

    // Find documents
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let results = cursor.next_n(2);
    assert_eq!(2, results.len());

    // Assert expected title of documents
    let expected_titles = vec!(
        "Jaws",
        "Back to the Future",
        );

    for i in 0..1 {
        let ref expected_title = expected_titles[i];
        match results[i].get("title") {
            Some(&Bson::String(ref title)) => assert_eq!(expected_title, title),
            _ => panic!("Expected Bson::String!"),
        };
    }
}

#[test]
fn delete_one() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("delete_one");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    // let mut doc = bson::Document::new();
    // let mut doc2 = bson::Document::new();
    // doc.insert("title".to_owned(), Bson::String("Jaws".to_owned()));
    // doc2.insert("title".to_owned(), Bson::String("Back to the Future".to_owned()));

    coll.insert_many(vec![doc1.clone(), doc2.clone()], false, None)
        .ok().expect("Failed to insert documents.");

    // Delete document
    coll.delete_one(doc2.clone(), None).ok().expect("Failed to delete document.");
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let result = cursor.next().unwrap();

    match result.get("title") {
        Some(&Bson::String(ref title)) => assert_eq!("Jaws", title),
        _ => panic!("Expected Bson::String!"),
    }

    assert!(cursor.next().is_none());
}

#[test]
fn delete_many() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("delete_many");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    // let mut doc = bson::Document::new();
    // let mut doc2 = bson::Document::new();
    // doc.insert("title".to_owned(), Bson::String("Jaws".to_owned()));
    // doc2.insert("title".to_owned(), Bson::String("Back to the Future".to_owned()));

    coll.insert_many(vec![doc1.clone(), doc2.clone(), doc2.clone()], false, None)
        .ok().expect("Failed to insert documents into collection.");

    // Delete document
    coll.delete_many(doc2.clone(), None).ok().expect("Failed to delete documents.");
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let result = cursor.next().unwrap();

    match result.get("title") {
        Some(&Bson::String(ref title)) => assert_eq!("Jaws", title),
        _ => panic!("Expected Bson::String!"),
    }

    assert!(cursor.next().is_none());
}

#[test]
fn replace_one() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("replace_one");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    let doc3 = doc! {
        "title" => Bson::String("12 Angry Men".to_owned())
    };

    // let mut doc = bson::Document::new();
    // let mut doc2 = bson::Document::new();
    // let mut doc3 = bson::Document::new();
    // doc.insert("title".to_owned(), Bson::String("Jaws".to_owned()));
    // doc2.insert("title".to_owned(), Bson::String("Back to the Future".to_owned()));
    // doc3.insert("title".to_owned(), Bson::String("12 Angry Men".to_owned()));

    coll.insert_many(vec![doc1.clone(), doc2.clone(), doc3.clone()], false, None)
        .ok().expect("Failed to insert documents into collection.");

    // Replace single document
    coll.replace_one(doc2.clone(), doc3.clone(), false, None).ok().expect("Failed to replace document.");
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let results = cursor.next_n(3);
    assert_eq!(3, results.len());

    // Assert expected title of documents
    let expected_titles = vec!(
        "Jaws",
        "12 Angry Men",
        "12 Angry Men",
        );

    for i in 0..1 {
        let ref expected_title = expected_titles[i];
        match results[i].get("title") {
            Some(&Bson::String(ref title)) => assert_eq!(expected_title, title),
            _ => panic!("Expected Bson::String!"),
        };
    }
}

#[test]
fn update_one() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("update_one");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    let doc3 = doc! {
        "title" => Bson::String("12 Angry Men".to_owned())
    };

    // let mut doc = bson::Document::new();
    // let mut doc2 = bson::Document::new();
    // let mut doc3 = bson::Document::new();
    // doc.insert("title".to_owned(), Bson::String("Jaws".to_owned()));
    // doc2.insert("title".to_owned(), Bson::String("Back to the Future".to_owned()));
    // doc3.insert("title".to_owned(), Bson::String("12 Angry Men".to_owned()));

    coll.insert_many(vec![doc1.clone(), doc2.clone(), doc3.clone()], false, None)
        .ok().expect("Failed to insert documents into collection.");

    // Update single document
    let update = doc! {
        "$set" => nested_doc! {
            "director" => Bson::String("Robert Zemeckis".to_owned())
        }
    };

    // let mut update = bson::Document::new();
    // let mut set = bson::Document::new();
    // set.insert("director".to_owned(), Bson::String("Robert Zemeckis".to_owned()));
    // update.insert("$set".to_owned(), Bson::Document(set));

    coll.update_one(doc2.clone(), update, false, None).ok().expect("Failed to update document.");

    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let results = cursor.next_n(3);
    assert_eq!(3, results.len());

    // Assert director attributes
    assert!(results[0].get("director").is_none());
    assert!(results[2].get("director").is_none());
    match results[1].get("director") {
        Some(&Bson::String(ref director)) => assert_eq!("Robert Zemeckis", director),
        _ => panic!("Expected Bson::String!"),
    }
}

#[test]
fn update_many() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("update_many");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    let doc3 = doc! {
        "title" => Bson::String("12 Angry Men".to_owned())
    };

    // let mut doc = bson::Document::new();
    // let mut doc2 = bson::Document::new();
    // let mut doc3 = bson::Document::new();
    // doc.insert("title".to_owned(), Bson::String("Jaws".to_owned()));
    // doc2.insert("title".to_owned(), Bson::String("Back to the Future".to_owned()));
    // doc3.insert("title".to_owned(), Bson::String("12 Angry Men".to_owned()));

    coll.insert_many(vec![doc1.clone(), doc2.clone(), doc3.clone(), doc2.clone()], false, None)
        .ok().expect("Failed to insert documents into collection.");

    // Update single document
    let update = doc! {
        "$set" => nested_doc! {
            "director" => Bson::String("Robert Zemeckis".to_owned())
        }
    };

    // let mut update = bson::Document::new();
    // let mut set = bson::Document::new();
    // set.insert("director".to_owned(), Bson::String("Robert Zemeckis".to_owned()));
    // update.insert("$set".to_owned(), Bson::Document(set));

    coll.update_many(doc2.clone(), update, false, None).ok().expect("Failed to update documents.");

    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let results = cursor.next_n(4);
    assert_eq!(4, results.len());

    // Assert director attributes
    for i in 0..3 {

        // Check title
        match results[i].get("title") {
            Some(&Bson::String(ref title)) => {
                let dir_opt = results[i].get("director");

                // Only doc2 models should have a director field
                if "Back to the Future" == title {
                    match dir_opt {
                        Some(&Bson::String(ref director)) => assert_eq!("Robert Zemeckis", director),
                        _ => panic!("Expected Bson::String!"),
                    }
                } else {
                    assert!(dir_opt.is_none());
                }
            },
            _ => panic!("Expected Bson::String!"),
        }
    }
}
<commit_msg>deleted commented out dead code<commit_after>use bson;
use bson::Bson;
use bson::Document;

use mongodb::client::MongoClient;

#[test]
fn find_and_insert() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("find_and_insert");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert document
    let doc = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    coll.insert_one(doc, None).ok().expect("Failed to insert document");

    // Find document
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let result = cursor.next().unwrap();

    // Assert expected title of document
    match result.get("title") {
        Some(&Bson::String(ref title)) => assert_eq!("Jaws", title),
        _ => panic!("Expected Bson::String!"),
    };

    assert!(cursor.next().is_none());
}

#[test]
fn find_and_insert_one() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("find_and_insert");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert document
    let doc = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    coll.insert_one(doc, None).ok().expect("Failed to insert document");

    // Find single document
    let result = coll.find_one(None, None).ok().expect("Failed to execute find command.");
    assert!(result.is_some());

    // Assert expected title of document
    match result.unwrap().get("title") {
        Some(&Bson::String(ref title)) => assert_eq!("Jaws", title),
        _ => panic!("Expected Bson::String!"),
    };
}

#[test]
fn list_collections() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");

    db.drop_database().ok().expect("Failed to drop database");

    // Build collections
    db.collection("list_collections1").insert_one(bson::Document::new(), None)
        .ok().expect("Failed to insert placeholder document into collection");
    db.collection("list_collections2").insert_one(bson::Document::new(), None)
        .ok().expect("Failed to insert placeholder document into collection");

    // Check for namespaces
    let result = db.list_collections().ok().expect("Failed to execute list_collections command.");;
    assert_eq!(3, result.len());

    let namespace = vec![
        "test.list_collections1",
        "test.list_collections2",
        "test.system.indexes",
    ];

    for i in 0..2 {
        assert_eq!(namespace[i], result[i].namespace);
    }
}

#[test]
fn insert_many() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("insert_many");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    coll.insert_many(vec![doc1, doc2], false, None).ok().expect("Failed to insert documents.");

    // Find documents
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let results = cursor.next_n(2);
    assert_eq!(2, results.len());

    // Assert expected title of documents
    let expected_titles = vec!(
        "Jaws",
        "Back to the Future",
        );

    for i in 0..1 {
        let ref expected_title = expected_titles[i];
        match results[i].get("title") {
            Some(&Bson::String(ref title)) => assert_eq!(expected_title, title),
            _ => panic!("Expected Bson::String!"),
        };
    }
}

#[test]
fn delete_one() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("delete_one");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    coll.insert_many(vec![doc1.clone(), doc2.clone()], false, None)
        .ok().expect("Failed to insert documents.");

    // Delete document
    coll.delete_one(doc2.clone(), None).ok().expect("Failed to delete document.");
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let result = cursor.next().unwrap();

    match result.get("title") {
        Some(&Bson::String(ref title)) => assert_eq!("Jaws", title),
        _ => panic!("Expected Bson::String!"),
    }

    assert!(cursor.next().is_none());
}

#[test]
fn delete_many() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("delete_many");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    coll.insert_many(vec![doc1.clone(), doc2.clone(), doc2.clone()], false, None)
        .ok().expect("Failed to insert documents into collection.");

    // Delete document
    coll.delete_many(doc2.clone(), None).ok().expect("Failed to delete documents.");
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let result = cursor.next().unwrap();

    match result.get("title") {
        Some(&Bson::String(ref title)) => assert_eq!("Jaws", title),
        _ => panic!("Expected Bson::String!"),
    }

    assert!(cursor.next().is_none());
}

#[test]
fn replace_one() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("replace_one");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    let doc3 = doc! {
        "title" => Bson::String("12 Angry Men".to_owned())
    };

    coll.insert_many(vec![doc1.clone(), doc2.clone(), doc3.clone()], false, None)
        .ok().expect("Failed to insert documents into collection.");

    // Replace single document
    coll.replace_one(doc2.clone(), doc3.clone(), false, None).ok().expect("Failed to replace document.");
    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let results = cursor.next_n(3);
    assert_eq!(3, results.len());

    // Assert expected title of documents
    let expected_titles = vec!(
        "Jaws",
        "12 Angry Men",
        "12 Angry Men",
        );

    for i in 0..1 {
        let ref expected_title = expected_titles[i];
        match results[i].get("title") {
            Some(&Bson::String(ref title)) => assert_eq!(expected_title, title),
            _ => panic!("Expected Bson::String!"),
        };
    }
}

#[test]
fn update_one() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("update_one");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    let doc3 = doc! {
        "title" => Bson::String("12 Angry Men".to_owned())
    };

    coll.insert_many(vec![doc1.clone(), doc2.clone(), doc3.clone()], false, None)
        .ok().expect("Failed to insert documents into collection.");

    // Update single document
    let update = doc! {
        "$set" => nested_doc! {
            "director" => Bson::String("Robert Zemeckis".to_owned())
        }
    };

    coll.update_one(doc2.clone(), update, false, None).ok().expect("Failed to update document.");

    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let results = cursor.next_n(3);
    assert_eq!(3, results.len());

    // Assert director attributes
    assert!(results[0].get("director").is_none());
    assert!(results[2].get("director").is_none());
    match results[1].get("director") {
        Some(&Bson::String(ref director)) => assert_eq!("Robert Zemeckis", director),
        _ => panic!("Expected Bson::String!"),
    }
}

#[test]
fn update_many() {
    let client = MongoClient::with_uri("mongodb://localhost:27017").unwrap();
    let db = client.db("test");
    let coll = db.collection("update_many");

    db.drop_database().ok().expect("Failed to drop database");

    // Insert documents
    let doc1 = doc! {
        "title" => Bson::String("Jaws".to_owned())
    };

    let doc2 = doc! {
        "title" => Bson::String("Back to the Future".to_owned())
    };

    let doc3 = doc! {
        "title" => Bson::String("12 Angry Men".to_owned())
    };

    coll.insert_many(vec![doc1.clone(), doc2.clone(), doc3.clone(), doc2.clone()], false, None)
        .ok().expect("Failed to insert documents into collection.");

    // Update single document
    let update = doc! {
        "$set" => nested_doc! {
            "director" => Bson::String("Robert Zemeckis".to_owned())
        }
    };

    coll.update_many(doc2.clone(), update, false, None).ok().expect("Failed to update documents.");

    let mut cursor = coll.find(None, None).ok().expect("Failed to execute find command.");
    let results = cursor.next_n(4);
    assert_eq!(4, results.len());

    // Assert director attributes
    for i in 0..3 {

        // Check title
        match results[i].get("title") {
            Some(&Bson::String(ref title)) => {
                let dir_opt = results[i].get("director");

                // Only doc2 models should have a director field
                if "Back to the Future" == title {
                    match dir_opt {
                        Some(&Bson::String(ref director)) => assert_eq!("Robert Zemeckis", director),
                        _ => panic!("Expected Bson::String!"),
                    }
                } else {
                    assert!(dir_opt.is_none());
                }
            },
            _ => panic!("Expected Bson::String!"),
        }
    }
}
<|endoftext|>


<commit_before>/// This module contains helper functions to work with Pueue's asynchronous nature during tests.
/// As the daemon often needs some time to process requests by the client internally, we cannot
/// check whether the requested actions have been taken right away.
///
/// Using continuous lookups, we can allow long waiting times, while still having fast tests if
/// things don't take that long.
use anyhow::{bail, Result};

use pueue_lib::settings::Shared;
use pueue_lib::state::GroupStatus;
use pueue_lib::task::{Task, TaskStatus};

use super::{get_state, sleep_ms};

/// This is a small helper function, which checks in very short intervals, whether a task showed up
/// in the daemon or not.
pub async fn wait_for_task(shared: &Shared, task_id: usize) -> Result<()> {
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        if !state.tasks.contains_key(&task_id) {
            current_try += 1;
            sleep_ms(50);
            continue;
        }

        return Ok(());
    }

    bail!("Task {} didn't show up in about 1 second.", task_id)
}

/// This is a small helper function, which checks in very short intervals, whether a task changed
/// it's state or not.
pub async fn wait_for_status_change(
    shared: &Shared,
    task_id: usize,
    original_status: TaskStatus,
) -> Result<()> {
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        match state.tasks.get(&task_id) {
            Some(task) => {
                // The status changed. We can give our ok!
                if task.status != original_status {
                    return Ok(());
                }

                // The status didn't change. Try again.
                current_try += 1;
                sleep_ms(50);
                continue;
            }
            None => {
                bail!("Couldn't find task {task_id} while waiting for status change")
            }
        }
    }

    bail!("Task {task_id} didn't change state in about 1 second.")
}

/// This is a small helper function, which checks in very short intervals, whether a task fulfills
/// a certain criteria. This is necessary to prevent long or potentially flaky timeouts in our tests.
pub async fn wait_for_task_condition<F>(shared: &Shared, task_id: usize, condition: F) -> Result<()>
where
    F: Fn(&Task) -> bool,
{
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        match state.tasks.get(&task_id) {
            Some(task) => {
                // Check if the condition is met.
                // If it isn't, continue
                if condition(task) {
                    return Ok(());
                }

                // The status didn't change to target. Try again.
                current_try += 1;
                sleep_ms(50);
                continue;
            }
            None => {
                bail!("Couldn't find task {task_id} while waiting for condition")
            }
        }
    }
    bail!("Task {task_id} didn't fulfill condition after about 1 second.")
}

/// This is a small helper function, which checks in very short intervals, whether a group has been
/// initialized. This is necessary, as group creation became an asynchronous task.
pub async fn wait_for_group(shared: &Shared, group: &str) -> Result<()> {
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        if !state.groups.contains_key(group) {
            current_try += 1;
            sleep_ms(50);
            continue;
        }

        return Ok(());
    }

    bail!("Group {group} didn't show up in about 1 second.")
}

/// This is a small helper function, which checks in very short intervals, whether a group has been
/// deleted. This is necessary, as group deletion became an asynchronous task.
pub async fn wait_for_group_absence(shared: &Shared, group: &str) -> Result<()> {
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        if state.groups.contains_key(group) {
            current_try += 1;
            sleep_ms(50);
            continue;
        }

        return Ok(());
    }

    bail!("Group {group} hasn't been removed after about 1 second.")
}

/// Waits for a status on a specific group.
pub async fn wait_for_group_status(
    shared: &Shared,
    group: &str,
    expected_status: GroupStatus,
) -> Result<()> {
    let state = get_state(shared).await?;

    // Give the daemon about 1 sec to shutdown.
    let tries = 20;
    let mut current_try = 0;

    while current_try < tries {
        // Process is still alive, wait a little longer
        if let Some(status) = state.groups.get(group) {
            if matches!(status, _expected_status) {
                return Ok(());
            }
        }

        sleep_ms(50);
        current_try += 1;
    }

    bail!("Group {group} didn't change to state {expected_status:?} after about 1 sec.",);
}
<commit_msg>change: Directly return tasks in wait test helpers<commit_after>/// This module contains helper functions to work with Pueue's asynchronous nature during tests.
/// As the daemon often needs some time to process requests by the client internally, we cannot
/// check whether the requested actions have been taken right away.
///
/// Using continuous lookups, we can allow long waiting times, while still having fast tests if
/// things don't take that long.
use anyhow::{bail, Result};

use pueue_lib::settings::Shared;
use pueue_lib::state::GroupStatus;
use pueue_lib::task::{Task, TaskStatus};

use super::{get_state, sleep_ms};

/// This is a small helper function, which checks in very short intervals, whether a task showed up
/// in the daemon or not.
pub async fn wait_for_task(shared: &Shared, task_id: usize) -> Result<Task> {
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        if !state.tasks.contains_key(&task_id) {
            current_try += 1;
            sleep_ms(50);
            continue;
        }

        return Ok(state.tasks.get(&task_id).unwrap().clone());
    }

    bail!("Task {} didn't show up in about 1 second.", task_id)
}

/// This is a small helper function, which checks in very short intervals, whether a task changed
/// it's state or not.
pub async fn wait_for_status_change(
    shared: &Shared,
    task_id: usize,
    original_status: TaskStatus,
) -> Result<Task> {
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        match state.tasks.get(&task_id) {
            Some(task) => {
                // The status changed. We can give our ok!
                if task.status != original_status {
                    return Ok(task.clone());
                }

                // The status didn't change. Try again.
                current_try += 1;
                sleep_ms(50);
                continue;
            }
            None => {
                bail!("Couldn't find task {task_id} while waiting for status change")
            }
        }
    }

    bail!("Task {task_id} didn't change state in about 1 second.")
}

/// This is a small helper function, which checks in very short intervals, whether a task fulfills
/// a certain criteria. This is necessary to prevent long or potentially flaky timeouts in our tests.
pub async fn wait_for_task_condition<F>(
    shared: &Shared,
    task_id: usize,
    condition: F,
) -> Result<Task>
where
    F: Fn(&Task) -> bool,
{
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        match state.tasks.get(&task_id) {
            Some(task) => {
                // Check if the condition is met.
                // If it isn't, continue
                if condition(task) {
                    return Ok(task.clone());
                }

                // The status didn't change to target. Try again.
                current_try += 1;
                sleep_ms(50);
                continue;
            }
            None => {
                bail!("Couldn't find task {task_id} while waiting for condition")
            }
        }
    }
    bail!("Task {task_id} didn't fulfill condition after about 1 second.")
}

/// This is a small helper function, which checks in very short intervals, whether a group has been
/// initialized. This is necessary, as group creation became an asynchronous task.
pub async fn wait_for_group(shared: &Shared, group: &str) -> Result<()> {
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        if !state.groups.contains_key(group) {
            current_try += 1;
            sleep_ms(50);
            continue;
        }

        return Ok(());
    }

    bail!("Group {group} didn't show up in about 1 second.")
}

/// This is a small helper function, which checks in very short intervals, whether a group has been
/// deleted. This is necessary, as group deletion became an asynchronous task.
pub async fn wait_for_group_absence(shared: &Shared, group: &str) -> Result<()> {
    let tries = 20;
    let mut current_try = 0;
    while current_try <= tries {
        let state = get_state(shared).await?;
        if state.groups.contains_key(group) {
            current_try += 1;
            sleep_ms(50);
            continue;
        }

        return Ok(());
    }

    bail!("Group {group} hasn't been removed after about 1 second.")
}

/// Waits for a status on a specific group.
pub async fn wait_for_group_status(
    shared: &Shared,
    group: &str,
    expected_status: GroupStatus,
) -> Result<()> {
    let state = get_state(shared).await?;

    // Give the daemon about 1 sec to shutdown.
    let tries = 20;
    let mut current_try = 0;

    while current_try < tries {
        // Process is still alive, wait a little longer
        if let Some(status) = state.groups.get(group) {
            if matches!(status, _expected_status) {
                return Ok(());
            }
        }

        sleep_ms(50);
        current_try += 1;
    }

    bail!("Group {group} didn't change to state {expected_status:?} after about 1 sec.",);
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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
//
//    https://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.

use syn::{ItemEnum, ItemStruct};

use super::{
    api::{AnalysisPhase, Api, ApiName, FuncToConvert, TypedefKind},
    convert_error::{ConvertErrorWithContext, ErrorContext},
    ConvertError,
};
use crate::types::{Namespace, QualifiedName};

/// Run some code which may generate a ConvertError.
/// If it does, try to note the problem in our output APIs
/// such that users will see documentation of the error.
pub(crate) fn report_any_error<F, T>(
    ns: &Namespace,
    apis: &mut Vec<Api<impl AnalysisPhase>>,
    fun: F,
) -> Option<T>
where
    F: FnOnce() -> Result<T, ConvertErrorWithContext>,
{
    match fun() {
        Ok(result) => Some(result),
        Err(ConvertErrorWithContext(err, None)) => {
            eprintln!("Ignored item: {}", err);
            None
        }
        Err(ConvertErrorWithContext(err, Some(ctx))) => {
            eprintln!("Ignored item {}: {}", ctx.to_string(), err);
            push_ignored_item(ns, ctx, err, apis);
            None
        }
    }
}

/// Run some code which generates an API. Add that API, or if
/// anything goes wrong, instead add a note of the problem in our
/// output API such that users will see documentation for the problem.
pub(crate) fn convert_apis<FF, SF, EF, TF, A, B>(
    in_apis: Vec<Api<A>>,
    out_apis: &mut Vec<Api<B>>,
    mut func_conversion: FF,
    mut struct_conversion: SF,
    mut enum_conversion: EF,
    mut typedef_conversion: TF,
) where
    A: AnalysisPhase,
    B: AnalysisPhase,
    FF: FnMut(
        ApiName,
        Box<FuncToConvert>,
        A::FunAnalysis,
    ) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
    SF: FnMut(
        ApiName,
        ItemStruct,
        A::StructAnalysis,
    ) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
    EF: FnMut(ApiName, ItemEnum) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
    TF: FnMut(
        ApiName,
        TypedefKind,
        Option<QualifiedName>,
        A::TypedefAnalysis,
    ) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
{
    out_apis.extend(in_apis.into_iter().filter_map(|api| {
        let tn = api.name().clone();
        let result = match api {
            // No changes to any of these...
            Api::ConcreteType {
                name,
                rs_definition,
                cpp_definition,
            } => Ok(Some(Api::ConcreteType {
                name,
                rs_definition,
                cpp_definition,
            })),
            Api::ForwardDeclaration { name } => Ok(Some(Api::ForwardDeclaration { name })),
            Api::StringConstructor { name } => Ok(Some(Api::StringConstructor { name })),
            Api::Const { name, const_item } => Ok(Some(Api::Const { name, const_item })),
            Api::CType { name, typename } => Ok(Some(Api::CType { name, typename })),
            Api::IgnoredItem { name, err, ctx } => Ok(Some(Api::IgnoredItem { name, err, ctx })),
            // Apply a mapping to the following
            Api::Enum { name, item } => enum_conversion(name, item),
            Api::Typedef {
                name,
                item,
                old_tyname,
                analysis,
            } => typedef_conversion(name, item, old_tyname, analysis),
            Api::Function {
                name,
                fun,
                analysis,
            } => func_conversion(name, fun, analysis),
            Api::Struct {
                name,
                item,
                analysis,
            } => struct_conversion(name, item, analysis),
        };
        api_or_error(tn, result)
    }))
}

fn api_or_error<T: AnalysisPhase>(
    name: QualifiedName,
    api_or_error: Result<Option<Api<T>>, ConvertErrorWithContext>,
) -> Option<Api<T>> {
    match api_or_error {
        Ok(opt) => opt,
        Err(ConvertErrorWithContext(err, None)) => {
            eprintln!("Ignored {}: {}", name.to_string(), err);
            None
        }
        Err(ConvertErrorWithContext(err, Some(ctx))) => {
            eprintln!("Ignored {}: {}", name.to_string(), err);
            Some(ignored_item(name.get_namespace(), ctx, err))
        }
    }
}

/// Run some code which generates an API. Add that API, or if
/// anything goes wrong, instead add a note of the problem in our
/// output API such that users will see documentation for the problem.
pub(crate) fn transform_apis<F, A, B>(in_apis: Vec<Api<A>>, out_apis: &mut Vec<Api<B>>, mut fun: F)
where
    F: FnMut(Api<A>) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
    A: AnalysisPhase,
    B: AnalysisPhase,
{
    out_apis.extend(in_apis.into_iter().filter_map(|api| {
        let tn = api.name().clone();
        api_or_error(tn, fun(api))
    }))
}

/// Run some code which generates an API for an item (as opposed to
/// a method). Add that API, or if
/// anything goes wrong, instead add a note of the problem in our
/// output API such that users will see documentation for the problem.
pub(crate) fn convert_item_apis<F, A, B>(
    in_apis: Vec<Api<A>>,
    out_apis: &mut Vec<Api<B>>,
    mut fun: F,
) where
    F: FnMut(Api<A>) -> Result<Option<Api<B>>, ConvertError>,
    A: AnalysisPhase,
    B: AnalysisPhase,
{
    transform_apis(in_apis, out_apis, |api| {
        let id = api.name().get_final_ident();
        fun(api).map_err(|e| ConvertErrorWithContext(e, Some(ErrorContext::Item(id))))
    })
}

fn ignored_item<A: AnalysisPhase>(ns: &Namespace, ctx: ErrorContext, err: ConvertError) -> Api<A> {
    Api::IgnoredItem {
        name: ApiName::new(ns, ctx.get_id().clone()),
        err,
        ctx,
    }
}

fn push_ignored_item(
    ns: &Namespace,
    ctx: ErrorContext,
    err: ConvertError,
    apis: &mut Vec<Api<impl AnalysisPhase>>,
) {
    apis.push(ignored_item(ns, ctx, err));
}
<commit_msg>Inline a function.<commit_after>// Copyright 2020 Google LLC
//
// 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
//
//    https://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.

use syn::{ItemEnum, ItemStruct};

use super::{
    api::{AnalysisPhase, Api, ApiName, FuncToConvert, TypedefKind},
    convert_error::{ConvertErrorWithContext, ErrorContext},
    ConvertError,
};
use crate::types::{Namespace, QualifiedName};

/// Run some code which may generate a ConvertError.
/// If it does, try to note the problem in our output APIs
/// such that users will see documentation of the error.
pub(crate) fn report_any_error<F, T>(
    ns: &Namespace,
    apis: &mut Vec<Api<impl AnalysisPhase>>,
    fun: F,
) -> Option<T>
where
    F: FnOnce() -> Result<T, ConvertErrorWithContext>,
{
    match fun() {
        Ok(result) => Some(result),
        Err(ConvertErrorWithContext(err, None)) => {
            eprintln!("Ignored item: {}", err);
            None
        }
        Err(ConvertErrorWithContext(err, Some(ctx))) => {
            eprintln!("Ignored item {}: {}", ctx.to_string(), err);
            apis.push(ignored_item(ns, ctx, err));
            None
        }
    }
}

/// Run some code which generates an API. Add that API, or if
/// anything goes wrong, instead add a note of the problem in our
/// output API such that users will see documentation for the problem.
pub(crate) fn convert_apis<FF, SF, EF, TF, A, B>(
    in_apis: Vec<Api<A>>,
    out_apis: &mut Vec<Api<B>>,
    mut func_conversion: FF,
    mut struct_conversion: SF,
    mut enum_conversion: EF,
    mut typedef_conversion: TF,
) where
    A: AnalysisPhase,
    B: AnalysisPhase,
    FF: FnMut(
        ApiName,
        Box<FuncToConvert>,
        A::FunAnalysis,
    ) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
    SF: FnMut(
        ApiName,
        ItemStruct,
        A::StructAnalysis,
    ) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
    EF: FnMut(ApiName, ItemEnum) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
    TF: FnMut(
        ApiName,
        TypedefKind,
        Option<QualifiedName>,
        A::TypedefAnalysis,
    ) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
{
    out_apis.extend(in_apis.into_iter().filter_map(|api| {
        let tn = api.name().clone();
        let result = match api {
            // No changes to any of these...
            Api::ConcreteType {
                name,
                rs_definition,
                cpp_definition,
            } => Ok(Some(Api::ConcreteType {
                name,
                rs_definition,
                cpp_definition,
            })),
            Api::ForwardDeclaration { name } => Ok(Some(Api::ForwardDeclaration { name })),
            Api::StringConstructor { name } => Ok(Some(Api::StringConstructor { name })),
            Api::Const { name, const_item } => Ok(Some(Api::Const { name, const_item })),
            Api::CType { name, typename } => Ok(Some(Api::CType { name, typename })),
            Api::IgnoredItem { name, err, ctx } => Ok(Some(Api::IgnoredItem { name, err, ctx })),
            // Apply a mapping to the following
            Api::Enum { name, item } => enum_conversion(name, item),
            Api::Typedef {
                name,
                item,
                old_tyname,
                analysis,
            } => typedef_conversion(name, item, old_tyname, analysis),
            Api::Function {
                name,
                fun,
                analysis,
            } => func_conversion(name, fun, analysis),
            Api::Struct {
                name,
                item,
                analysis,
            } => struct_conversion(name, item, analysis),
        };
        api_or_error(tn, result)
    }))
}

fn api_or_error<T: AnalysisPhase>(
    name: QualifiedName,
    api_or_error: Result<Option<Api<T>>, ConvertErrorWithContext>,
) -> Option<Api<T>> {
    match api_or_error {
        Ok(opt) => opt,
        Err(ConvertErrorWithContext(err, None)) => {
            eprintln!("Ignored {}: {}", name.to_string(), err);
            None
        }
        Err(ConvertErrorWithContext(err, Some(ctx))) => {
            eprintln!("Ignored {}: {}", name.to_string(), err);
            Some(ignored_item(name.get_namespace(), ctx, err))
        }
    }
}

/// Run some code which generates an API. Add that API, or if
/// anything goes wrong, instead add a note of the problem in our
/// output API such that users will see documentation for the problem.
pub(crate) fn transform_apis<F, A, B>(in_apis: Vec<Api<A>>, out_apis: &mut Vec<Api<B>>, mut fun: F)
where
    F: FnMut(Api<A>) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
    A: AnalysisPhase,
    B: AnalysisPhase,
{
    out_apis.extend(in_apis.into_iter().filter_map(|api| {
        let tn = api.name().clone();
        api_or_error(tn, fun(api))
    }))
}

/// Run some code which generates an API for an item (as opposed to
/// a method). Add that API, or if
/// anything goes wrong, instead add a note of the problem in our
/// output API such that users will see documentation for the problem.
pub(crate) fn convert_item_apis<F, A, B>(
    in_apis: Vec<Api<A>>,
    out_apis: &mut Vec<Api<B>>,
    mut fun: F,
) where
    F: FnMut(Api<A>) -> Result<Option<Api<B>>, ConvertError>,
    A: AnalysisPhase,
    B: AnalysisPhase,
{
    transform_apis(in_apis, out_apis, |api| {
        let id = api.name().get_final_ident();
        fun(api).map_err(|e| ConvertErrorWithContext(e, Some(ErrorContext::Item(id))))
    })
}

fn ignored_item<A: AnalysisPhase>(ns: &Namespace, ctx: ErrorContext, err: ConvertError) -> Api<A> {
    Api::IgnoredItem {
        name: ApiName::new(ns, ctx.get_id().clone()),
        err,
        ctx,
    }
}<|endoftext|>


<commit_before>use crate::lexical::num::{AsPrimitive, Float, Integer, Number};

fn check_as_primitive<T: AsPrimitive>(t: T) {
    let _: u8 = t.as_u8();
    let _: u16 = t.as_u16();
    let _: u32 = t.as_u32();
    let _: u64 = t.as_u64();
    let _: u128 = t.as_u128();
    let _: usize = t.as_usize();
    let _: i8 = t.as_i8();
    let _: i16 = t.as_i16();
    let _: i32 = t.as_i32();
    let _: i64 = t.as_i64();
    let _: i128 = t.as_i128();
    let _: isize = t.as_isize();
    let _: f32 = t.as_f32();
    let _: f64 = t.as_f64();
}

#[test]
fn as_primitive_test() {
    check_as_primitive(1u8);
    check_as_primitive(1u16);
    check_as_primitive(1u32);
    check_as_primitive(1u64);
    check_as_primitive(1u128);
    check_as_primitive(1usize);
    check_as_primitive(1i8);
    check_as_primitive(1i16);
    check_as_primitive(1i32);
    check_as_primitive(1i64);
    check_as_primitive(1i128);
    check_as_primitive(1isize);
    check_as_primitive(1f32);
    check_as_primitive(1f64);
}

fn check_number<T: Number>(x: T, mut y: T) {
    // Copy, partialeq, partialord
    let _ = x;
    assert!(x < y);
    assert!(x != y);

    // Operations
    let _ = y + x;
    let _ = y - x;
    let _ = y * x;
    let _ = y / x;
    let _ = y % x;
    y += x;
    y -= x;
    y *= x;
    y /= x;
    y %= x;

    // Conversions already tested.
}

#[test]
fn number_test() {
    check_number(1u8, 5);
    check_number(1u16, 5);
    check_number(1u32, 5);
    check_number(1u64, 5);
    check_number(1u128, 5);
    check_number(1usize, 5);
    check_number(1i8, 5);
    check_number(1i16, 5);
    check_number(1i32, 5);
    check_number(1i64, 5);
    check_number(1i128, 5);
    check_number(1isize, 5);
    check_number(1f32, 5.0);
    check_number(1f64, 5.0);
}

fn check_integer<T: Integer>(x: T) {
    // Bitwise operations
    let _ = x & T::ZERO;
}

#[test]
fn integer_test() {
    check_integer(65u8);
    check_integer(65u16);
    check_integer(65u32);
    check_integer(65u64);
    check_integer(65u128);
    check_integer(65usize);
    check_integer(65i8);
    check_integer(65i16);
    check_integer(65i32);
    check_integer(65i64);
    check_integer(65i128);
    check_integer(65isize);
}

fn check_float<T: Float>(x: T) {
    // Check functions
    let _ = x.pow10(5);
    let _ = x.to_bits();
    assert!(T::from_bits(x.to_bits()) == x);

    // Check properties
    let _ = x.to_bits() & T::SIGN_MASK;
    let _ = x.to_bits() & T::EXPONENT_MASK;
    let _ = x.to_bits() & T::HIDDEN_BIT_MASK;
    let _ = x.to_bits() & T::MANTISSA_MASK;
}

#[test]
fn float_test() {
    check_float(123f32);
    check_float(123f64);
}
<commit_msg>Remove test of removed num types<commit_after>use crate::lexical::num::{AsPrimitive, Float, Integer, Number};

fn check_as_primitive<T: AsPrimitive>(t: T) {
    let _: u32 = t.as_u32();
    let _: u64 = t.as_u64();
    let _: u128 = t.as_u128();
    let _: usize = t.as_usize();
    let _: i32 = t.as_i32();
    let _: f32 = t.as_f32();
    let _: f64 = t.as_f64();
}

#[test]
fn as_primitive_test() {
    check_as_primitive(1u32);
    check_as_primitive(1u64);
    check_as_primitive(1u128);
    check_as_primitive(1usize);
    check_as_primitive(1i32);
    check_as_primitive(1f32);
    check_as_primitive(1f64);
}

fn check_number<T: Number>(x: T, mut y: T) {
    // Copy, partialeq, partialord
    let _ = x;
    assert!(x < y);
    assert!(x != y);

    // Operations
    let _ = y + x;
    let _ = y - x;
    let _ = y * x;
    let _ = y / x;
    let _ = y % x;
    y += x;
    y -= x;
    y *= x;
    y /= x;
    y %= x;

    // Conversions already tested.
}

#[test]
fn number_test() {
    check_number(1u32, 5);
    check_number(1u64, 5);
    check_number(1u128, 5);
    check_number(1usize, 5);
    check_number(1i32, 5);
    check_number(1f32, 5.0);
    check_number(1f64, 5.0);
}

fn check_integer<T: Integer>(x: T) {
    // Bitwise operations
    let _ = x & T::ZERO;
}

#[test]
fn integer_test() {
    check_integer(65u32);
    check_integer(65u64);
    check_integer(65u128);
    check_integer(65usize);
    check_integer(65i32);
}

fn check_float<T: Float>(x: T) {
    // Check functions
    let _ = x.pow10(5);
    let _ = x.to_bits();
    assert!(T::from_bits(x.to_bits()) == x);

    // Check properties
    let _ = x.to_bits() & T::SIGN_MASK;
    let _ = x.to_bits() & T::EXPONENT_MASK;
    let _ = x.to_bits() & T::HIDDEN_BIT_MASK;
    let _ = x.to_bits() & T::MANTISSA_MASK;
}

#[test]
fn float_test() {
    check_float(123f32);
    check_float(123f64);
}
<|endoftext|>


<commit_before>pub extern crate futures;
pub extern crate hyper;
pub extern crate tokio;

pub use std::net::SocketAddr;
pub use self::futures::{future, Future, Stream};
pub use self::futures::sync::oneshot;
pub use self::hyper::{HeaderMap, StatusCode};
pub use self::tokio::runtime::Runtime;

macro_rules! t {
    (
        $name:ident,
        parallel: $range:expr
    ) => (
        #[test]
        fn $name() {

            let mut c = vec![];
            let mut s = vec![];

            for _i in $range {
                c.push((
                    __CReq {
                        uri: "/",
                        ..Default::default()
                    },
                    __CRes {
                        ..Default::default()
                    },
                ));
                s.push((
                    __SReq {
                        uri: "/",
                        ..Default::default()
                    },
                    __SRes {
                        ..Default::default()
                    },
                ));
            }

            __run_test(__TestConfig {
                client_version: 2,
                client_msgs: c,
                server_version: 2,
                server_msgs: s,
                parallel: true,
                connections: 1,
            });

        }
    );
    (
        $name:ident,
        client: $(
            request: $(
                $c_req_prop:ident: $c_req_val:tt,
            )*;
            response: $(
                $c_res_prop:ident: $c_res_val:tt,
            )*;
        )*
        server: $(
            request: $(
                $s_req_prop:ident: $s_req_val:tt,
            )*;
            response: $(
                $s_res_prop:ident: $s_res_val:tt,
            )*;
        )*
    ) => (
        #[test]
        fn $name() {
            let c = vec![$((
                __CReq {
                    $($c_req_prop: __internal_req_res_prop!($c_req_prop: $c_req_val),)*
                    ..Default::default()
                },
                __CRes {
                    $($c_res_prop: __internal_req_res_prop!($c_res_prop: $c_res_val),)*
                    ..Default::default()
                }
            ),)*];
            let s = vec![$((
                __SReq {
                    $($s_req_prop: __internal_req_res_prop!($s_req_prop: $s_req_val),)*
                    ..Default::default()
                },
                __SRes {
                    $($s_res_prop: __internal_req_res_prop!($s_res_prop: $s_res_val),)*
                    ..Default::default()
                }
            ),)*];

            __run_test(__TestConfig {
                client_version: 1,
                client_msgs: c.clone(),
                server_version: 1,
                server_msgs: s.clone(),
                parallel: false,
                connections: 1,
            });

            __run_test(__TestConfig {
                client_version: 2,
                client_msgs: c,
                server_version: 2,
                server_msgs: s,
                parallel: false,
                connections: 1,
            });
        }
    );
}

macro_rules! __internal_req_res_prop {
    (method: $prop_val:expr) => (
        $prop_val
    );
    (status: $prop_val:expr) => (
        StatusCode::from_u16($prop_val).expect("status code")
    );
    (headers: $map:tt) => ({
        #[allow(unused_mut)]
        {
        let mut headers = HeaderMap::new();
        __internal_headers!(headers, $map);
        headers
        }
    });
    ($prop_name:ident: $prop_val:expr) => (
        From::from($prop_val)
    )
}

macro_rules! __internal_headers {
    ($headers:ident, { $($name:expr => $val:expr,)* }) => {
        $(
        $headers.insert($name, $val.to_string().parse().expect("header value"));
        )*
    }
}

#[derive(Clone, Debug, Default)]
pub struct __CReq {
    pub method: &'static str,
    pub uri: &'static str,
    pub headers: HeaderMap,
    pub body: Vec<u8>,
}

#[derive(Clone, Debug, Default)]
pub struct __CRes {
    pub status: hyper::StatusCode,
    pub body: Vec<u8>,
    pub headers: HeaderMap,
}

#[derive(Clone, Debug, Default)]
pub struct __SReq {
    pub method: &'static str,
    pub uri: &'static str,
    pub headers: HeaderMap,
    pub body: Vec<u8>,
}

#[derive(Clone, Debug, Default)]
pub struct __SRes {
    pub status: hyper::StatusCode,
    pub body: Vec<u8>,
    pub headers: HeaderMap,
}

pub struct __TestConfig {
    pub client_version: usize,
    pub client_msgs: Vec<(__CReq, __CRes)>,

    pub server_version: usize,
    pub server_msgs: Vec<(__SReq, __SRes)>,

    pub parallel: bool,
    pub connections: usize,
}

pub fn __run_test(cfg: __TestConfig) {
    extern crate pretty_env_logger;
    use hyper::{Body, Client, Request, Response};
    use hyper::client::HttpConnector;
    use std::sync::{Arc, Mutex};
    let _ = pretty_env_logger::try_init();
    let rt = Runtime::new().expect("new rt");
    let handle = rt.reactor().clone();

    let connector = HttpConnector::new_with_handle(1, handle.clone());
    let client = Client::builder()
        .http2_only(cfg.client_version == 2)
        .executor(rt.executor())
        .build::<_, Body>(connector);

    let serve_handles = Arc::new(Mutex::new(
        cfg.server_msgs
    ));
    let new_service = move || {
        // Move a clone into the service_fn
        let serve_handles = serve_handles.clone();
        hyper::service::service_fn(move |req: Request<Body>| {
            let (sreq, sres) = serve_handles.lock()
                .unwrap()
                .remove(0);

            assert_eq!(req.uri().path(), sreq.uri);
            assert_eq!(req.method(), &sreq.method);
            for (name, value) in &sreq.headers {
                assert_eq!(
                    req.headers()[name],
                    value
                );
            }
            let sbody = sreq.body;
            req.into_body()
                .concat2()
                .map(move |body| {
                    assert_eq!(body.as_ref(), sbody.as_slice());

                    let mut res = Response::builder()
                        .status(sres.status)
                        .body(Body::from(sres.body))
                        .expect("Response::build");
                    *res.headers_mut() = sres.headers;
                    res
                })
        })
    };

    let serve = hyper::server::conn::Http::new()
        .http2_only(cfg.server_version == 2)
        .executor(rt.executor())
        .serve_addr_handle(
            &SocketAddr::from(([127, 0, 0, 1], 0)),
            &handle,
            new_service,
        )
        .expect("serve_addr_handle");

    let addr = serve.incoming_ref().local_addr();
    let exe = rt.executor();
    let (shutdown_tx, shutdown_rx) = oneshot::channel();
    let (success_tx, success_rx) = oneshot::channel();
    let expected_connections = cfg.connections;
    let server = serve
        .fold(0, move |cnt, connecting| {
            let fut = connecting
                .map_err(|never| -> hyper::Error { match never {} })
                .flatten()
                .map_err(|e| panic!("server connection error: {}", e));
            exe.spawn(fut);
            Ok::<_, hyper::Error>(cnt + 1)
        })
        .map(move |cnt| {
            assert_eq!(cnt, expected_connections);
        })
        .map_err(|e| panic!("serve error: {}", e))
        .select2(shutdown_rx)
        .map(move |_| {
            let _ = success_tx.send(());
        })
        .map_err(|_| panic!("shutdown not ok"));

    rt.executor().spawn(server);

    let make_request = Arc::new(move |client: &Client<HttpConnector>, creq: __CReq, cres: __CRes| {
        let uri = format!("http://{}{}", addr, creq.uri);
        let mut req = Request::builder()
            .method(creq.method)
            .uri(uri)
            //.headers(creq.headers)
            .body(creq.body.into())
            .expect("Request::build");
        *req.headers_mut() = creq.headers;
        let cstatus = cres.status;
        let cheaders = cres.headers;
        let cbody = cres.body;

        client.request(req)
            .and_then(move |res| {
                assert_eq!(res.status(), cstatus);
                //assert_eq!(res.version(), c_version);
                for (name, value) in &cheaders {
                    assert_eq!(
                        res.headers()[name],
                        value
                    );
                }
                res.into_body().concat2()
            })
            .map(move |body| {
                assert_eq!(body.as_ref(), cbody.as_slice());
            })
            .map_err(|e| panic!("client error: {}", e))
    });

    let client_futures: Box<Future<Item=(), Error=()> + Send> = if cfg.parallel {
        let mut client_futures = vec![];
        for (creq, cres) in cfg.client_msgs {
            client_futures.push(make_request(&client, creq, cres));
        }
        drop(client);
        Box::new(future::join_all(client_futures).map(|_| ()))
    } else {
        let mut client_futures: Box<Future<Item=Client<HttpConnector>, Error=()> + Send> =
            Box::new(future::ok(client));
        for (creq, cres) in cfg.client_msgs {
            let mk_request = make_request.clone();
            client_futures = Box::new(
                client_futures
                .and_then(move |client| {
                    let fut = mk_request(&client, creq, cres);
                    fut.map(move |()| client)
                })
            );
        }
        Box::new(client_futures.map(|_| ()))
    };

    let client_futures = client_futures.map(move |_| {
        let _ = shutdown_tx.send(());
    });
    rt.executor().spawn(client_futures);
    rt.shutdown_on_idle().wait().expect("rt");
    success_rx
        .map_err(|_| "something panicked")
        .wait()
        .expect("shutdown succeeded");
}

<commit_msg>tests(http2): add bodies to parallel h2 tests<commit_after>pub extern crate futures;
pub extern crate hyper;
pub extern crate tokio;

pub use std::net::SocketAddr;
pub use self::futures::{future, Future, Stream};
pub use self::futures::sync::oneshot;
pub use self::hyper::{HeaderMap, StatusCode};
pub use self::tokio::runtime::Runtime;

macro_rules! t {
    (
        $name:ident,
        parallel: $range:expr
    ) => (
        #[test]
        fn $name() {

            let mut c = vec![];
            let mut s = vec![];

            for _i in $range {
                c.push((
                    __CReq {
                        uri: "/",
                        body: vec![b'x'; 8192],
                        ..Default::default()
                    },
                    __CRes {
                        body: vec![b'x'; 8192],
                        ..Default::default()
                    },
                ));
                s.push((
                    __SReq {
                        uri: "/",
                        body: vec![b'x'; 8192],
                        ..Default::default()
                    },
                    __SRes {
                        body: vec![b'x'; 8192],
                        ..Default::default()
                    },
                ));
            }

            __run_test(__TestConfig {
                client_version: 2,
                client_msgs: c,
                server_version: 2,
                server_msgs: s,
                parallel: true,
                connections: 1,
            });

        }
    );
    (
        $name:ident,
        client: $(
            request: $(
                $c_req_prop:ident: $c_req_val:tt,
            )*;
            response: $(
                $c_res_prop:ident: $c_res_val:tt,
            )*;
        )*
        server: $(
            request: $(
                $s_req_prop:ident: $s_req_val:tt,
            )*;
            response: $(
                $s_res_prop:ident: $s_res_val:tt,
            )*;
        )*
    ) => (
        #[test]
        fn $name() {
            let c = vec![$((
                __CReq {
                    $($c_req_prop: __internal_req_res_prop!($c_req_prop: $c_req_val),)*
                    ..Default::default()
                },
                __CRes {
                    $($c_res_prop: __internal_req_res_prop!($c_res_prop: $c_res_val),)*
                    ..Default::default()
                }
            ),)*];
            let s = vec![$((
                __SReq {
                    $($s_req_prop: __internal_req_res_prop!($s_req_prop: $s_req_val),)*
                    ..Default::default()
                },
                __SRes {
                    $($s_res_prop: __internal_req_res_prop!($s_res_prop: $s_res_val),)*
                    ..Default::default()
                }
            ),)*];

            __run_test(__TestConfig {
                client_version: 1,
                client_msgs: c.clone(),
                server_version: 1,
                server_msgs: s.clone(),
                parallel: false,
                connections: 1,
            });

            __run_test(__TestConfig {
                client_version: 2,
                client_msgs: c,
                server_version: 2,
                server_msgs: s,
                parallel: false,
                connections: 1,
            });
        }
    );
}

macro_rules! __internal_req_res_prop {
    (method: $prop_val:expr) => (
        $prop_val
    );
    (status: $prop_val:expr) => (
        StatusCode::from_u16($prop_val).expect("status code")
    );
    (headers: $map:tt) => ({
        #[allow(unused_mut)]
        {
        let mut headers = HeaderMap::new();
        __internal_headers!(headers, $map);
        headers
        }
    });
    ($prop_name:ident: $prop_val:expr) => (
        From::from($prop_val)
    )
}

macro_rules! __internal_headers {
    ($headers:ident, { $($name:expr => $val:expr,)* }) => {
        $(
        $headers.insert($name, $val.to_string().parse().expect("header value"));
        )*
    }
}

#[derive(Clone, Debug, Default)]
pub struct __CReq {
    pub method: &'static str,
    pub uri: &'static str,
    pub headers: HeaderMap,
    pub body: Vec<u8>,
}

#[derive(Clone, Debug, Default)]
pub struct __CRes {
    pub status: hyper::StatusCode,
    pub body: Vec<u8>,
    pub headers: HeaderMap,
}

#[derive(Clone, Debug, Default)]
pub struct __SReq {
    pub method: &'static str,
    pub uri: &'static str,
    pub headers: HeaderMap,
    pub body: Vec<u8>,
}

#[derive(Clone, Debug, Default)]
pub struct __SRes {
    pub status: hyper::StatusCode,
    pub body: Vec<u8>,
    pub headers: HeaderMap,
}

pub struct __TestConfig {
    pub client_version: usize,
    pub client_msgs: Vec<(__CReq, __CRes)>,

    pub server_version: usize,
    pub server_msgs: Vec<(__SReq, __SRes)>,

    pub parallel: bool,
    pub connections: usize,
}

pub fn __run_test(cfg: __TestConfig) {
    extern crate pretty_env_logger;
    use hyper::{Body, Client, Request, Response};
    use hyper::client::HttpConnector;
    use std::sync::{Arc, Mutex};
    let _ = pretty_env_logger::try_init();
    let rt = Runtime::new().expect("new rt");
    let handle = rt.reactor().clone();

    let connector = HttpConnector::new_with_handle(1, handle.clone());
    let client = Client::builder()
        .http2_only(cfg.client_version == 2)
        .executor(rt.executor())
        .build::<_, Body>(connector);

    let serve_handles = Arc::new(Mutex::new(
        cfg.server_msgs
    ));
    let new_service = move || {
        // Move a clone into the service_fn
        let serve_handles = serve_handles.clone();
        hyper::service::service_fn(move |req: Request<Body>| {
            let (sreq, sres) = serve_handles.lock()
                .unwrap()
                .remove(0);

            assert_eq!(req.uri().path(), sreq.uri);
            assert_eq!(req.method(), &sreq.method);
            for (name, value) in &sreq.headers {
                assert_eq!(
                    req.headers()[name],
                    value
                );
            }
            let sbody = sreq.body;
            req.into_body()
                .concat2()
                .map(move |body| {
                    assert_eq!(body.as_ref(), sbody.as_slice());

                    let mut res = Response::builder()
                        .status(sres.status)
                        .body(Body::from(sres.body))
                        .expect("Response::build");
                    *res.headers_mut() = sres.headers;
                    res
                })
        })
    };

    let serve = hyper::server::conn::Http::new()
        .http2_only(cfg.server_version == 2)
        .executor(rt.executor())
        .serve_addr_handle(
            &SocketAddr::from(([127, 0, 0, 1], 0)),
            &handle,
            new_service,
        )
        .expect("serve_addr_handle");

    let addr = serve.incoming_ref().local_addr();
    let exe = rt.executor();
    let (shutdown_tx, shutdown_rx) = oneshot::channel();
    let (success_tx, success_rx) = oneshot::channel();
    let expected_connections = cfg.connections;
    let server = serve
        .fold(0, move |cnt, connecting| {
            let fut = connecting
                .map_err(|never| -> hyper::Error { match never {} })
                .flatten()
                .map_err(|e| panic!("server connection error: {}", e));
            exe.spawn(fut);
            Ok::<_, hyper::Error>(cnt + 1)
        })
        .map(move |cnt| {
            assert_eq!(cnt, expected_connections);
        })
        .map_err(|e| panic!("serve error: {}", e))
        .select2(shutdown_rx)
        .map(move |_| {
            let _ = success_tx.send(());
        })
        .map_err(|_| panic!("shutdown not ok"));

    rt.executor().spawn(server);

    let make_request = Arc::new(move |client: &Client<HttpConnector>, creq: __CReq, cres: __CRes| {
        let uri = format!("http://{}{}", addr, creq.uri);
        let mut req = Request::builder()
            .method(creq.method)
            .uri(uri)
            //.headers(creq.headers)
            .body(creq.body.into())
            .expect("Request::build");
        *req.headers_mut() = creq.headers;
        let cstatus = cres.status;
        let cheaders = cres.headers;
        let cbody = cres.body;

        client.request(req)
            .and_then(move |res| {
                assert_eq!(res.status(), cstatus);
                //assert_eq!(res.version(), c_version);
                for (name, value) in &cheaders {
                    assert_eq!(
                        res.headers()[name],
                        value
                    );
                }
                res.into_body().concat2()
            })
            .map(move |body| {
                assert_eq!(body.as_ref(), cbody.as_slice());
            })
            .map_err(|e| panic!("client error: {}", e))
    });

    let client_futures: Box<Future<Item=(), Error=()> + Send> = if cfg.parallel {
        let mut client_futures = vec![];
        for (creq, cres) in cfg.client_msgs {
            client_futures.push(make_request(&client, creq, cres));
        }
        drop(client);
        Box::new(future::join_all(client_futures).map(|_| ()))
    } else {
        let mut client_futures: Box<Future<Item=Client<HttpConnector>, Error=()> + Send> =
            Box::new(future::ok(client));
        for (creq, cres) in cfg.client_msgs {
            let mk_request = make_request.clone();
            client_futures = Box::new(
                client_futures
                .and_then(move |client| {
                    let fut = mk_request(&client, creq, cres);
                    fut.map(move |()| client)
                })
            );
        }
        Box::new(client_futures.map(|_| ()))
    };

    let client_futures = client_futures.map(move |_| {
        let _ = shutdown_tx.send(());
    });
    rt.executor().spawn(client_futures);
    rt.shutdown_on_idle().wait().expect("rt");
    success_rx
        .map_err(|_| "something panicked")
        .wait()
        .expect("shutdown succeeded");
}

<|endoftext|>


<commit_before>// Copyright © 2015, Peter Atashian
// Licensed under the MIT License <LICENSE.md>
pub fn link(name: &str, bundled: bool) {
    use std::env::var;
    let target = var("TARGET").unwrap();
    let target: Vec<_> = target.split('-').collect();
    if target[2] == "windows" {
        println!("cargo:rustc-link-lib=dylib={}", name);
        if bundled && target[3] == "gnu" {
            let dir = var("CARGO_MANIFEST_DIR").unwrap();
            println!("cargo:rustc-link-search=native={}/{}", dir, target[0]);
        }
    }
}
<commit_msg>build: avoid panicing build script if target does split to >2 elements<commit_after>// Copyright © 2015, Peter Atashian
// Licensed under the MIT License <LICENSE.md>
pub fn link(name: &str, bundled: bool) {
    use std::env::var;
    let target = var("TARGET").unwrap();
    let target: Vec<_> = target.split('-').collect();
    if target.len() > 2 && target[2] == "windows" {
        println!("cargo:rustc-link-lib=dylib={}", name);
        if bundled && target[3] == "gnu" {
            let dir = var("CARGO_MANIFEST_DIR").unwrap();
            println!("cargo:rustc-link-search=native={}/{}", dir, target[0]);
        }
    }
}
<|endoftext|>


<commit_before>//! `cpuid` intrinsics
#![allow(clippy::module_name_repetitions)]

#[cfg(test)]
use stdarch_test::assert_instr;

/// Result of the `cpuid` instruction.
#[allow(clippy::missing_inline_in_public_items)]
// ^^ the derived impl of Debug for CpuidResult is not #[inline] and that's OK.
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub struct CpuidResult {
    /// EAX register.
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub eax: u32,
    /// EBX register.
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub ebx: u32,
    /// ECX register.
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub ecx: u32,
    /// EDX register.
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub edx: u32,
}

/// Returns the result of the `cpuid` instruction for a given `leaf` (`EAX`)
/// and
/// `sub_leaf` (`ECX`).
///
/// The highest-supported leaf value is returned by the first tuple argument of
/// [`__get_cpuid_max(0)`](fn.__get_cpuid_max.html). For leaves containung
/// sub-leaves, the second tuple argument returns the highest-supported
/// sub-leaf
/// value.
///
/// The [CPUID Wikipedia page][wiki_cpuid] contains how to query which
/// information using the `EAX` and `ECX` registers, and the interpretation of
/// the results returned in `EAX`, `EBX`, `ECX`, and `EDX`.
///
/// The references are:
/// - [Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2:
///   Instruction Set Reference, A-Z][intel64_ref].
/// - [AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and
///   System Instructions][amd64_ref].
///
/// [wiki_cpuid]: https://en.wikipedia.org/wiki/CPUID
/// [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
/// [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf
#[inline]
#[cfg_attr(test, assert_instr(cpuid))]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
    let eax;
    let ebx;
    let ecx;
    let edx;
    #[cfg(target_arch = "x86")]
    {
        asm!("cpuid"
             : "={eax}"(eax), "={ebx}"(ebx), "={ecx}"(ecx), "={edx}"(edx)
             : "{eax}"(leaf), "{ecx}"(sub_leaf)
             : :);
    }
    #[cfg(target_arch = "x86_64")]
    {
        // x86-64 uses %rbx as the base register, so preserve it.
        asm!("cpuid\n"
             : "={eax}"(eax), "={ebx}"(ebx), "={ecx}"(ecx), "={edx}"(edx)
             : "{eax}"(leaf), "{ecx}"(sub_leaf)
             : "rbx" :);
    }
    CpuidResult { eax, ebx, ecx, edx }
}

/// See [`__cpuid_count`](fn.__cpuid_count.html).
#[inline]
#[cfg_attr(test, assert_instr(cpuid))]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn __cpuid(leaf: u32) -> CpuidResult {
    __cpuid_count(leaf, 0)
}

/// Does the host support the `cpuid` instruction?
#[inline]
pub fn has_cpuid() -> bool {
    #[cfg(target_env = "sgx")]
    {
        false
    }
    #[cfg(all(not(target_env = "sgx"), target_arch = "x86_64"))]
    {
        true
    }
    #[cfg(all(not(target_env = "sgx"), target_arch = "x86"))]
    {
        // Optimization for i586 and i686 Rust targets which SSE enabled
        // and support cpuid:
        #[cfg(target_feature = "sse")]
        {
            true
        }

        // If SSE is not enabled, detect whether cpuid is available:
        #[cfg(not(target_feature = "sse"))]
        unsafe {
            // On `x86` the `cpuid` instruction is not always available.
            // This follows the approach indicated in:
            // http://wiki.osdev.org/CPUID#Checking_CPUID_availability
            // https://software.intel.com/en-us/articles/using-cpuid-to-detect-the-presence-of-sse-41-and-sse-42-instruction-sets/
            // which detects whether `cpuid` is available by checking whether
            // the 21st bit of the EFLAGS register is modifiable or not.
            // If it is, then `cpuid` is available.
            let result: u32;
            let _temp: u32;
            asm!(r#"
                 # Read eflags into $0 and copy it into $1:
                 pushfd
                 pop     $0
                 mov     $1, $0
                 # Flip 21st bit of $0.
                 xor     $0, 0x200000
                 # Set eflags to the value of $0
                 #
                 # Bit 21st can only be modified if cpuid is available
                 push    $0
                 popfd          # A
                 # Read eflags into $0:
                 pushfd         # B
                 pop     $0
                 # xor with the original eflags sets the bits that
                 # have been modified:
                 xor     $0, $1
                 "#
                 : "=r"(result), "=r"(_temp)
                 :
                 : "cc", "memory"
                 : "intel");
            // There is a race between popfd (A) and pushfd (B)
            // where other bits beyond 21st may have been modified due to
            // interrupts, a debugger stepping through the asm, etc.
            //
            // Therefore, explicitly check whether the 21st bit
            // was modified or not.
            //
            // If the result is zero, the cpuid bit was not modified.
            // If the result is `0x200000` (non-zero), then the cpuid
            // was correctly modified and the CPU supports the cpuid
            // instruction:
            (result & 0x200000) != 0
        }
    }
}

/// Returns the highest-supported `leaf` (`EAX`) and sub-leaf (`ECX`) `cpuid`
/// values.
///
/// If `cpuid` is supported, and `leaf` is zero, then the first tuple argument
/// contains the highest `leaf` value that `cpuid` supports. For `leaf`s
/// containing sub-leafs, the second tuple argument contains the
/// highest-supported sub-leaf value.
///
/// See also [`__cpuid`](fn.__cpuid.html) and
/// [`__cpuid_count`](fn.__cpuid_count.html).
#[inline]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn __get_cpuid_max(leaf: u32) -> (u32, u32) {
    let CpuidResult { eax, ebx, .. } = __cpuid(leaf);
    (eax, ebx)
}

#[cfg(test)]
mod tests {
    use crate::core_arch::x86::*;

    #[test]
    fn test_always_has_cpuid() {
        // all currently-tested targets have the instruction
        // FIXME: add targets without `cpuid` to CI
        assert!(cpuid::has_cpuid());
    }

    #[test]
    fn test_has_cpuid_idempotent() {
        assert_eq!(cpuid::has_cpuid(), cpuid::has_cpuid());
    }
}
<commit_msg>Remove unnecessary \n from cpuid<commit_after>//! `cpuid` intrinsics
#![allow(clippy::module_name_repetitions)]

#[cfg(test)]
use stdarch_test::assert_instr;

/// Result of the `cpuid` instruction.
#[allow(clippy::missing_inline_in_public_items)]
// ^^ the derived impl of Debug for CpuidResult is not #[inline] and that's OK.
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub struct CpuidResult {
    /// EAX register.
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub eax: u32,
    /// EBX register.
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub ebx: u32,
    /// ECX register.
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub ecx: u32,
    /// EDX register.
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub edx: u32,
}

/// Returns the result of the `cpuid` instruction for a given `leaf` (`EAX`)
/// and
/// `sub_leaf` (`ECX`).
///
/// The highest-supported leaf value is returned by the first tuple argument of
/// [`__get_cpuid_max(0)`](fn.__get_cpuid_max.html). For leaves containung
/// sub-leaves, the second tuple argument returns the highest-supported
/// sub-leaf
/// value.
///
/// The [CPUID Wikipedia page][wiki_cpuid] contains how to query which
/// information using the `EAX` and `ECX` registers, and the interpretation of
/// the results returned in `EAX`, `EBX`, `ECX`, and `EDX`.
///
/// The references are:
/// - [Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2:
///   Instruction Set Reference, A-Z][intel64_ref].
/// - [AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and
///   System Instructions][amd64_ref].
///
/// [wiki_cpuid]: https://en.wikipedia.org/wiki/CPUID
/// [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
/// [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf
#[inline]
#[cfg_attr(test, assert_instr(cpuid))]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn __cpuid_count(leaf: u32, sub_leaf: u32) -> CpuidResult {
    let eax;
    let ebx;
    let ecx;
    let edx;
    #[cfg(target_arch = "x86")]
    {
        asm!("cpuid"
             : "={eax}"(eax), "={ebx}"(ebx), "={ecx}"(ecx), "={edx}"(edx)
             : "{eax}"(leaf), "{ecx}"(sub_leaf)
             : :);
    }
    #[cfg(target_arch = "x86_64")]
    {
        // x86-64 uses %rbx as the base register, so preserve it.
        asm!("cpuid"
             : "={eax}"(eax), "={ebx}"(ebx), "={ecx}"(ecx), "={edx}"(edx)
             : "{eax}"(leaf), "{ecx}"(sub_leaf)
             : "rbx" :);
    }
    CpuidResult { eax, ebx, ecx, edx }
}

/// See [`__cpuid_count`](fn.__cpuid_count.html).
#[inline]
#[cfg_attr(test, assert_instr(cpuid))]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn __cpuid(leaf: u32) -> CpuidResult {
    __cpuid_count(leaf, 0)
}

/// Does the host support the `cpuid` instruction?
#[inline]
pub fn has_cpuid() -> bool {
    #[cfg(target_env = "sgx")]
    {
        false
    }
    #[cfg(all(not(target_env = "sgx"), target_arch = "x86_64"))]
    {
        true
    }
    #[cfg(all(not(target_env = "sgx"), target_arch = "x86"))]
    {
        // Optimization for i586 and i686 Rust targets which SSE enabled
        // and support cpuid:
        #[cfg(target_feature = "sse")]
        {
            true
        }

        // If SSE is not enabled, detect whether cpuid is available:
        #[cfg(not(target_feature = "sse"))]
        unsafe {
            // On `x86` the `cpuid` instruction is not always available.
            // This follows the approach indicated in:
            // http://wiki.osdev.org/CPUID#Checking_CPUID_availability
            // https://software.intel.com/en-us/articles/using-cpuid-to-detect-the-presence-of-sse-41-and-sse-42-instruction-sets/
            // which detects whether `cpuid` is available by checking whether
            // the 21st bit of the EFLAGS register is modifiable or not.
            // If it is, then `cpuid` is available.
            let result: u32;
            let _temp: u32;
            asm!(r#"
                 # Read eflags into $0 and copy it into $1:
                 pushfd
                 pop     $0
                 mov     $1, $0
                 # Flip 21st bit of $0.
                 xor     $0, 0x200000
                 # Set eflags to the value of $0
                 #
                 # Bit 21st can only be modified if cpuid is available
                 push    $0
                 popfd          # A
                 # Read eflags into $0:
                 pushfd         # B
                 pop     $0
                 # xor with the original eflags sets the bits that
                 # have been modified:
                 xor     $0, $1
                 "#
                 : "=r"(result), "=r"(_temp)
                 :
                 : "cc", "memory"
                 : "intel");
            // There is a race between popfd (A) and pushfd (B)
            // where other bits beyond 21st may have been modified due to
            // interrupts, a debugger stepping through the asm, etc.
            //
            // Therefore, explicitly check whether the 21st bit
            // was modified or not.
            //
            // If the result is zero, the cpuid bit was not modified.
            // If the result is `0x200000` (non-zero), then the cpuid
            // was correctly modified and the CPU supports the cpuid
            // instruction:
            (result & 0x200000) != 0
        }
    }
}

/// Returns the highest-supported `leaf` (`EAX`) and sub-leaf (`ECX`) `cpuid`
/// values.
///
/// If `cpuid` is supported, and `leaf` is zero, then the first tuple argument
/// contains the highest `leaf` value that `cpuid` supports. For `leaf`s
/// containing sub-leafs, the second tuple argument contains the
/// highest-supported sub-leaf value.
///
/// See also [`__cpuid`](fn.__cpuid.html) and
/// [`__cpuid_count`](fn.__cpuid_count.html).
#[inline]
#[stable(feature = "simd_x86", since = "1.27.0")]
pub unsafe fn __get_cpuid_max(leaf: u32) -> (u32, u32) {
    let CpuidResult { eax, ebx, .. } = __cpuid(leaf);
    (eax, ebx)
}

#[cfg(test)]
mod tests {
    use crate::core_arch::x86::*;

    #[test]
    fn test_always_has_cpuid() {
        // all currently-tested targets have the instruction
        // FIXME: add targets without `cpuid` to CI
        assert!(cpuid::has_cpuid());
    }

    #[test]
    fn test_has_cpuid_idempotent() {
        assert_eq!(cpuid::has_cpuid(), cpuid::has_cpuid());
    }
}
<|endoftext|>


<commit_before>#[macro_use]
mod util;

pub mod asset;
pub mod crypto;
pub mod tx;

pub mod blockchain;
pub mod constants;
pub mod net;
pub mod script;
pub mod serializer;

pub fn init() -> Result<(), ()> {
    sodiumoxide::init()
}

pub mod prelude {
    pub use super::asset::{Asset, AssetError, AssetErrorKind, AssetSymbol};
    pub use super::blockchain::{Block, Blockchain, Properties, SignedBlock};
    pub use super::crypto::{
        KeyPair, PrivateKey, PublicKey, ScriptHash, SigPair, Wif, WifError, WifErrorKind,
    };
    pub use super::net::{self, MsgRequest, MsgResponse};
    pub use super::script::{self, OpFrame, Script, ScriptEngine};
    pub use super::tx::{MintTx, OwnerTx, RewardTx, TransferTx, Tx, TxType, TxVariant};
}
<commit_msg>Export Balance in prelude<commit_after>#[macro_use]
mod util;

pub mod asset;
pub mod crypto;
pub mod tx;

pub mod blockchain;
pub mod constants;
pub mod net;
pub mod script;
pub mod serializer;

pub fn init() -> Result<(), ()> {
    sodiumoxide::init()
}

pub mod prelude {
    pub use super::asset::{Asset, AssetError, AssetErrorKind, AssetSymbol, Balance};
    pub use super::blockchain::{Block, Blockchain, Properties, SignedBlock};
    pub use super::crypto::{
        KeyPair, PrivateKey, PublicKey, ScriptHash, SigPair, Wif, WifError, WifErrorKind,
    };
    pub use super::net::{self, MsgRequest, MsgResponse};
    pub use super::script::{self, OpFrame, Script, ScriptEngine};
    pub use super::tx::{MintTx, OwnerTx, RewardTx, TransferTx, Tx, TxType, TxVariant};
}
<|endoftext|>


<commit_before>//! In certain situations, rust automatically inserts derefs as necessary: for
//! example, field accesses `foo.bar` still work when `foo` is actually a
//! reference to a type with the field `bar`. This is an approximation of the
//! logic in rustc (which lives in librustc_typeck/check/autoderef.rs).

use std::iter::successors;

use hir_def::{lang_item::LangItemTarget, resolver::Resolver};
use hir_expand::name;
use log::{info, warn};

use crate::{db::HirDatabase, Trait};

use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk};

const AUTODEREF_RECURSION_LIMIT: usize = 10;

pub(crate) fn autoderef<'a>(
    db: &'a impl HirDatabase,
    resolver: &'a Resolver,
    ty: Canonical<Ty>,
) -> impl Iterator<Item = Canonical<Ty>> + 'a {
    successors(Some(ty), move |ty| deref(db, resolver, ty)).take(AUTODEREF_RECURSION_LIMIT)
}

pub(crate) fn deref(
    db: &impl HirDatabase,
    resolver: &Resolver,
    ty: &Canonical<Ty>,
) -> Option<Canonical<Ty>> {
    if let Some(derefed) = ty.value.builtin_deref() {
        Some(Canonical { value: derefed, num_vars: ty.num_vars })
    } else {
        deref_by_trait(db, resolver, ty)
    }
}

fn deref_by_trait(
    db: &impl HirDatabase,
    resolver: &Resolver,
    ty: &Canonical<Ty>,
) -> Option<Canonical<Ty>> {
    let krate = resolver.krate()?;
    let deref_trait = match db.lang_item(krate.into(), "deref".into())? {
        LangItemTarget::TraitId(t) => Trait::from(t),
        _ => return None,
    };
    let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?;

    let generic_params = db.generic_params(target.id.into());
    if generic_params.count_params_including_parent() != 1 {
        // the Target type + Deref trait should only have one generic parameter,
        // namely Deref's Self type
        return None;
    }

    // FIXME make the Canonical handling nicer

    let env = super::lower::trait_env(db, resolver);

    let parameters = Substs::build_for_generics(&generic_params)
        .push(ty.value.clone().shift_bound_vars(1))
        .build();

    let projection = super::traits::ProjectionPredicate {
        ty: Ty::Bound(0),
        projection_ty: super::ProjectionTy { associated_ty: target, parameters },
    };

    let obligation = super::Obligation::Projection(projection);

    let in_env = super::traits::InEnvironment { value: obligation, environment: env };

    let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env };

    let solution = db.trait_solve(krate.into(), canonical)?;

    match &solution {
        Solution::Unique(vars) => {
            // FIXME: vars may contain solutions for any inference variables
            // that happened to be inside ty. To correctly handle these, we
            // would have to pass the solution up to the inference context, but
            // that requires a larger refactoring (especially if the deref
            // happens during method resolution). So for the moment, we just
            // check that we're not in the situation we're we would actually
            // need to handle the values of the additional variables, i.e.
            // they're just being 'passed through'. In the 'standard' case where
            // we have `impl<T> Deref for Foo<T> { Target = T }`, that should be
            // the case.
            for i in 1..vars.0.num_vars {
                if vars.0.value[i] != Ty::Bound((i - 1) as u32) {
                    warn!("complex solution for derefing {:?}: {:?}, ignoring", ty, solution);
                    return None;
                }
            }
            Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars })
        }
        Solution::Ambig(_) => {
            info!("Ambiguous solution for derefing {:?}: {:?}", ty, solution);
            None
        }
    }
}
<commit_msg>Push resolver up<commit_after>//! In certain situations, rust automatically inserts derefs as necessary: for
//! example, field accesses `foo.bar` still work when `foo` is actually a
//! reference to a type with the field `bar`. This is an approximation of the
//! logic in rustc (which lives in librustc_typeck/check/autoderef.rs).

use std::iter::successors;

use hir_def::{lang_item::LangItemTarget, resolver::Resolver};
use hir_expand::name;
use log::{info, warn};
use ra_db::CrateId;

use crate::{db::HirDatabase, Trait};

use super::{
    traits::{InEnvironment, Solution},
    Canonical, Substs, Ty, TypeWalk,
};

const AUTODEREF_RECURSION_LIMIT: usize = 10;

pub(crate) fn autoderef<'a>(
    db: &'a impl HirDatabase,
    resolver: &'a Resolver,
    ty: Canonical<Ty>,
) -> impl Iterator<Item = Canonical<Ty>> + 'a {
    successors(Some(ty), move |ty| deref(db, resolver, ty)).take(AUTODEREF_RECURSION_LIMIT)
}

pub(crate) fn deref(
    db: &impl HirDatabase,
    resolver: &Resolver,
    ty: &Canonical<Ty>,
) -> Option<Canonical<Ty>> {
    if let Some(derefed) = ty.value.builtin_deref() {
        Some(Canonical { value: derefed, num_vars: ty.num_vars })
    } else {
        let krate = resolver.krate()?;
        let environment = super::lower::trait_env(db, resolver);
        deref_by_trait(db, krate, InEnvironment { value: ty, environment })
    }
}

fn deref_by_trait(
    db: &impl HirDatabase,
    krate: CrateId,
    ty: InEnvironment<&Canonical<Ty>>,
) -> Option<Canonical<Ty>> {
    let deref_trait = match db.lang_item(krate.into(), "deref".into())? {
        LangItemTarget::TraitId(t) => Trait::from(t),
        _ => return None,
    };
    let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?;

    let generic_params = db.generic_params(target.id.into());
    if generic_params.count_params_including_parent() != 1 {
        // the Target type + Deref trait should only have one generic parameter,
        // namely Deref's Self type
        return None;
    }

    // FIXME make the Canonical handling nicer

    let parameters = Substs::build_for_generics(&generic_params)
        .push(ty.value.value.clone().shift_bound_vars(1))
        .build();

    let projection = super::traits::ProjectionPredicate {
        ty: Ty::Bound(0),
        projection_ty: super::ProjectionTy { associated_ty: target, parameters },
    };

    let obligation = super::Obligation::Projection(projection);

    let in_env = InEnvironment { value: obligation, environment: ty.environment };

    let canonical = super::Canonical { num_vars: 1 + ty.value.num_vars, value: in_env };

    let solution = db.trait_solve(krate.into(), canonical)?;

    match &solution {
        Solution::Unique(vars) => {
            // FIXME: vars may contain solutions for any inference variables
            // that happened to be inside ty. To correctly handle these, we
            // would have to pass the solution up to the inference context, but
            // that requires a larger refactoring (especially if the deref
            // happens during method resolution). So for the moment, we just
            // check that we're not in the situation we're we would actually
            // need to handle the values of the additional variables, i.e.
            // they're just being 'passed through'. In the 'standard' case where
            // we have `impl<T> Deref for Foo<T> { Target = T }`, that should be
            // the case.
            for i in 1..vars.0.num_vars {
                if vars.0.value[i] != Ty::Bound((i - 1) as u32) {
                    warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
                    return None;
                }
            }
            Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars })
        }
        Solution::Ambig(_) => {
            info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution);
            None
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::event::EventKey;
use anyhow::Result;
use move_core_types::move_resource::MoveResource;
use serde::{Deserialize, Serialize};

/// Struct that represents a NewEpochEvent.
#[derive(Debug, Serialize, Deserialize)]
pub struct NewEpochEvent {
    epoch: u64,
}

impl NewEpochEvent {
    pub fn epoch(&self) -> u64 {
        self.epoch
    }

    pub fn try_from_bytes(bytes: &[u8]) -> Result<Self> {
        lcs::from_bytes(bytes).map_err(Into::into)
    }

    pub fn event_key() -> EventKey {
        crate::on_chain_config::new_epoch_event_key()
    }
}

impl MoveResource for NewEpochEvent {
    const MODULE_NAME: &'static str = "LibraConfig";
    const STRUCT_NAME: &'static str = "NewBlockEvent";
}
<commit_msg>[types] fix bug in Rust struct for NewEpochEvent<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::event::EventKey;
use anyhow::Result;
use move_core_types::move_resource::MoveResource;
use serde::{Deserialize, Serialize};

/// Struct that represents a NewEpochEvent.
#[derive(Debug, Serialize, Deserialize)]
pub struct NewEpochEvent {
    epoch: u64,
}

impl NewEpochEvent {
    pub fn epoch(&self) -> u64 {
        self.epoch
    }

    pub fn try_from_bytes(bytes: &[u8]) -> Result<Self> {
        lcs::from_bytes(bytes).map_err(Into::into)
    }

    pub fn event_key() -> EventKey {
        crate::on_chain_config::new_epoch_event_key()
    }
}

impl MoveResource for NewEpochEvent {
    const MODULE_NAME: &'static str = "LibraConfig";
    const STRUCT_NAME: &'static str = "NewEpochEvent";
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate rustc_serialize;
extern crate queryst;

use rustc_serialize::json;
use iron::prelude::*;
use iron::status;
use queryst::parse;

#[derive(RustcEncodable)]
pub struct PadJson {
    str: String
}

fn main() {
    fn handler(req: &mut Request) -> IronResult<Response> {
        let padded_resp = PadJson {
            str: "Hallo".to_string(),
        };

        let query = req.url.query.clone().unwrap_or("".to_string());

        let query_params = parse(&query.to_string());

        Ok(Response::with((status::Ok, json::encode(&padded_resp).unwrap())))
    }

    Iron::new(handler).http("localhost:3000").unwrap();
}
<commit_msg>Parse query params as json<commit_after>extern crate iron;
extern crate rustc_serialize;
extern crate queryst;

use rustc_serialize::json::{self, Json};
use iron::prelude::*;
use iron::status;
use queryst::parse;

#[derive(RustcEncodable)]
pub struct PadJson {
    str: String
}

fn main() {
    fn handler(req: &mut Request) -> IronResult<Response> {
        let padded_resp = PadJson {
            str: "Hallo".to_string(),
        };

        let query = req.url.query.clone().unwrap_or("".to_string());

        let query_params: Json = parse(&query.to_string()).unwrap();

        Ok(Response::with((status::Ok, json::encode(&padded_resp).unwrap())))
    }

    Iron::new(handler).http("localhost:3000").unwrap();
}
<|endoftext|>