Skip to content

Commit

Permalink
Worked on benchmarking utility
Browse files Browse the repository at this point in the history
Fixed issues with routes not using Executor struct.
Worked on benchmark
  • Loading branch information
emilpriver committed Sep 17, 2023
1 parent 10084fe commit ab91abf
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 28 deletions.
92 changes: 75 additions & 17 deletions src/benchmark.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,89 @@
use reqwest::StatusCode;
use tokio::time::{Duration, Instant};

use crate::routes;

/**
* TODO:
- Run loop for x seconds.
- Report back to main thread the result of test
*/

pub fn run_benchmark(test: routes::CreateTest) {
struct Result {
pub connection_id: u64,
pub second: u64,
pub error_codes: Vec<StatusCode>,
pub requests: u64,
}

pub fn run_benchmark(test: routes::CreateTest) -> Vec<Result> {
let mut results: Vec<Result> = vec![];

for c in 0..test.connections {
tokio::spawn(async move {
match test.method.to_uppercase().as_str() {
"GET" => {
let resp = match reqwest::get(test.url).await {
Ok(r) => {}
Err(err) => {}
};
}
"POST" => {
let client = reqwest::Client::new();
let req = client.post(test.url);
let thread_test = test.clone();

tokio::task::spawn(async move {
let mut total_result: Vec<Result> = vec![];

// We need to fill the vec
for s in 0..test.seconds {
total_result.push(Result {
connection_id: c,
second: s,
error_codes: vec![],
requests: 0,
})
}

let total_duration = Duration::new(test.seconds, 0);
let start_time = Instant::now();

while start_time.elapsed() < total_duration {
let second = start_time.elapsed().as_secs() as usize;

if test.body.is_some() {
req = req.body(test.body); // TODO: only append body if we get body. Also
// set header depending on content_type
let resp = match thread_test.method.to_uppercase().as_str() {
"GET" => reqwest::get(thread_test.url.clone()).await,
"POST" => {
let client = reqwest::Client::new();
let mut req = client.post(thread_test.url.clone());

if let Some(b) = thread_test.body.clone() {
req = req.body(b);
}

if let Some(c) = thread_test.content_type.clone() {
req = req.header("Content-Type", c);
}

req.send().await
}
_ => {
panic!("method {} not supported", thread_test.method)
}
};

if total_result.get(second).is_some() {
total_result[second].requests += 1;

match resp {
Ok(res) => {
if !res.status().is_success() {
total_result[second].error_codes.push(res.status());
}
}
Err(err) => {
if let Some(err_status) = err.status() {
total_result[second].error_codes.push(err_status);
}
}
}
}
};
}

for r in total_result {
// results.push(r);
}
});
}

results
}
8 changes: 4 additions & 4 deletions src/database.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use anyhow::Result;
use sqlx::SqlitePool;
use sqlx::{migrate, Pool, Sqlite};

pub async fn setup() -> Result<SqlitePool> {
let pool = sqlx::SqlitePool::connect("sqlite::memory:").await?;
pub async fn setup() -> Result<Pool<Sqlite>> {
let pool = Pool::<Sqlite>::connect("sqlite::memory:").await?;

sqlx::migrate!("./migrations").run(&pool).await?;
migrate!("./migrations").run(&pool).await?;

Ok(pool)
}
16 changes: 9 additions & 7 deletions src/routes.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
use actix_web::{web, HttpResponse, Responder};
use rand::{self, Rng};
use serde::{Deserialize, Serialize};
use sqlx::SqlitePool;
use sqlx::{Pool, Sqlite};

use crate::benchmark;

#[derive(Deserialize)]
#[derive(Deserialize, Clone)]
pub struct CreateTest {
pub method: String,
pub connections: u64,
pub seconds: u64,
pub start_at: String, // TODO: change this to chrono timestamp
pub content_type: String,
pub url: String,
pub content_type: Option<String>,
pub body: Option<String>,
}

#[derive(Serialize, sqlx::FromRow)]
#[derive(Serialize, Clone, sqlx::FromRow)]
pub struct Test {
pub id: String,
pub method: String,
pub url: String,
}

pub async fn create_test(
pool: web::Data<SqlitePool>,
pool: web::Data<Pool<Sqlite>>,
payload: web::Json<CreateTest>,
) -> impl Responder {
let mut rng = rand::thread_rng();
let random_number: u32 = rng.gen_range(100_000..1_000_000);
let id = random_number.to_string();

let db_pool = pool.get_ref();

let test: Test = sqlx::query_as(
"INSERT INTO tests(id, url, method, content_type, body) VALUES($1, $2, $3, $4, $5) RETURNING id, method, url",
)
Expand All @@ -39,7 +41,7 @@ pub async fn create_test(
.bind(payload.method.clone())
.bind(payload.content_type.clone())
.bind(payload.body.clone())
.fetch_one(&mut pool)
.fetch_one(db_pool)
.await
.unwrap();

Expand All @@ -48,7 +50,7 @@ pub async fn create_test(
HttpResponse::Created().json(test)
}

pub async fn get_test() -> impl Responder {
pub async fn get_test(pool: web::Data<Pool<Sqlite>>) -> impl Responder {
let p = Test {
id: String::from(""),
method: String::from(""),
Expand Down

0 comments on commit ab91abf

Please sign in to comment.