feat(ci): fix other tests, part 9000
This commit is contained in:
parent
a1947518da
commit
4ec4ecaa8d
|
|
@ -169,6 +169,11 @@ pub async fn create_label(
|
||||||
) -> Result<Json<Label>, StatusCode> {
|
) -> Result<Json<Label>, StatusCode> {
|
||||||
let user_id = auth_user.user.id;
|
let user_id = auth_user.user.id;
|
||||||
|
|
||||||
|
// Validate name is not empty
|
||||||
|
if payload.name.trim().is_empty() {
|
||||||
|
return Err(StatusCode::BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
// Validate color format
|
// Validate color format
|
||||||
if !payload.color.starts_with('#') || payload.color.len() != 7 {
|
if !payload.color.starts_with('#') || payload.color.len() != 7 {
|
||||||
return Err(StatusCode::BAD_REQUEST);
|
return Err(StatusCode::BAD_REQUEST);
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,7 @@
|
||||||
|
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::Duration;
|
||||||
use tokio::time::sleep;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use readur::models::{CreateUser, LoginRequest, LoginResponse, UserRole, SourceType};
|
use readur::models::{CreateUser, LoginRequest, LoginResponse, UserRole, SourceType};
|
||||||
|
|
@ -48,12 +47,13 @@ impl SourceTestClient {
|
||||||
let timestamp = std::time::SystemTime::now()
|
let timestamp = std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_millis();
|
.as_nanos();
|
||||||
let username = format!("source_test_{}_{}", role.to_string(), timestamp);
|
let random_suffix = uuid::Uuid::new_v4().to_string().replace("-", "")[..8].to_string();
|
||||||
|
let username = format!("source_test_{}_{}_{}", role.to_string(), timestamp, random_suffix);
|
||||||
let email = format!("source_test_{}@example.com", timestamp);
|
let email = format!("source_test_{}@example.com", timestamp);
|
||||||
let password = "testpassword123";
|
let password = "testpassword123";
|
||||||
|
|
||||||
// Register user
|
// Register user with retry logic
|
||||||
let user_data = CreateUser {
|
let user_data = CreateUser {
|
||||||
username: username.clone(),
|
username: username.clone(),
|
||||||
email: email.clone(),
|
email: email.clone(),
|
||||||
|
|
@ -61,14 +61,30 @@ impl SourceTestClient {
|
||||||
role: Some(role),
|
role: Some(role),
|
||||||
};
|
};
|
||||||
|
|
||||||
let register_response = self.client
|
let mut retry_count = 0;
|
||||||
.post(&format!("{}/api/auth/register", get_base_url()))
|
let register_response = loop {
|
||||||
.json(&user_data)
|
match self.client
|
||||||
.send()
|
.post(&format!("{}/api/auth/register", get_base_url()))
|
||||||
.await?;
|
.json(&user_data)
|
||||||
|
.timeout(Duration::from_secs(10))
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(resp) => break resp,
|
||||||
|
Err(e) => {
|
||||||
|
retry_count += 1;
|
||||||
|
if retry_count >= 3 {
|
||||||
|
return Err(format!("Registration failed after 3 retries: {}", e).into());
|
||||||
|
}
|
||||||
|
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if !register_response.status().is_success() {
|
if !register_response.status().is_success() {
|
||||||
return Err(format!("Registration failed: {}", register_response.text().await?).into());
|
let status = register_response.status();
|
||||||
|
let text = register_response.text().await.unwrap_or_else(|_| "No response body".to_string());
|
||||||
|
return Err(format!("Registration failed with status {}: {}", status, text).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login to get token
|
// Login to get token
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,9 @@ impl ErrorHandlingTestClient {
|
||||||
let timestamp = std::time::SystemTime::now()
|
let timestamp = std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_millis();
|
.as_nanos();
|
||||||
let username = format!("error_test_{}_{}", role.to_string(), timestamp);
|
let random_suffix = uuid::Uuid::new_v4().to_string().replace("-", "")[..8].to_string();
|
||||||
|
let username = format!("error_test_{}_{}_{}", role.to_string(), timestamp, random_suffix);
|
||||||
let email = format!("error_test_{}@example.com", timestamp);
|
let email = format!("error_test_{}@example.com", timestamp);
|
||||||
let password = "testpassword123";
|
let password = "testpassword123";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,12 +62,13 @@ impl FileProcessingTestClient {
|
||||||
let timestamp = std::time::SystemTime::now()
|
let timestamp = std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_millis();
|
.as_nanos();
|
||||||
let username = format!("file_proc_test_{}", timestamp);
|
let random_suffix = uuid::Uuid::new_v4().to_string().replace("-", "")[..8].to_string();
|
||||||
|
let username = format!("file_proc_test_{}_{}", timestamp, random_suffix);
|
||||||
let email = format!("file_proc_test_{}@example.com", timestamp);
|
let email = format!("file_proc_test_{}@example.com", timestamp);
|
||||||
let password = "fileprocessingpassword123";
|
let password = "fileprocessingpassword123";
|
||||||
|
|
||||||
// Register user
|
// Register user with retry logic
|
||||||
let user_data = CreateUser {
|
let user_data = CreateUser {
|
||||||
username: username.clone(),
|
username: username.clone(),
|
||||||
email: email.clone(),
|
email: email.clone(),
|
||||||
|
|
@ -75,14 +76,30 @@ impl FileProcessingTestClient {
|
||||||
role: Some(UserRole::User),
|
role: Some(UserRole::User),
|
||||||
};
|
};
|
||||||
|
|
||||||
let register_response = self.client
|
let mut retry_count = 0;
|
||||||
.post(&format!("{}/api/auth/register", get_base_url()))
|
let register_response = loop {
|
||||||
.json(&user_data)
|
match self.client
|
||||||
.send()
|
.post(&format!("{}/api/auth/register", get_base_url()))
|
||||||
.await?;
|
.json(&user_data)
|
||||||
|
.timeout(Duration::from_secs(10))
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(resp) => break resp,
|
||||||
|
Err(e) => {
|
||||||
|
retry_count += 1;
|
||||||
|
if retry_count >= 3 {
|
||||||
|
return Err(format!("Registration failed after 3 retries: {}", e).into());
|
||||||
|
}
|
||||||
|
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if !register_response.status().is_success() {
|
if !register_response.status().is_success() {
|
||||||
return Err(format!("Registration failed: {}", register_response.text().await?).into());
|
let status = register_response.status();
|
||||||
|
let text = register_response.text().await.unwrap_or_else(|_| "No response body".to_string());
|
||||||
|
return Err(format!("Registration failed with status {}: {}", status, text).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login to get token
|
// Login to get token
|
||||||
|
|
|
||||||
|
|
@ -437,6 +437,10 @@ fn test_concurrent_access_safety() {
|
||||||
let base_path = Arc::new(temp_dir.path().to_path_buf());
|
let base_path = Arc::new(temp_dir.path().to_path_buf());
|
||||||
let file_count = Arc::new(Mutex::new(0));
|
let file_count = Arc::new(Mutex::new(0));
|
||||||
|
|
||||||
|
// Verify the directory has files before testing concurrent access
|
||||||
|
let initial_count = fs::read_dir(&*base_path).unwrap().count();
|
||||||
|
assert!(initial_count > 0, "Test directory should contain files");
|
||||||
|
|
||||||
let mut handles = vec![];
|
let mut handles = vec![];
|
||||||
|
|
||||||
// Spawn multiple threads to read the same directory
|
// Spawn multiple threads to read the same directory
|
||||||
|
|
@ -446,16 +450,25 @@ fn test_concurrent_access_safety() {
|
||||||
|
|
||||||
let handle = thread::spawn(move || {
|
let handle = thread::spawn(move || {
|
||||||
let mut local_count = 0;
|
let mut local_count = 0;
|
||||||
if let Ok(entries) = fs::read_dir(&*base_path) {
|
|
||||||
for entry in entries {
|
// Recursively count files
|
||||||
if let Ok(entry) = entry {
|
fn count_files_in_dir(path: &std::path::Path, count: &mut usize) {
|
||||||
if entry.file_type().unwrap().is_file() {
|
if let Ok(entries) = fs::read_dir(path) {
|
||||||
local_count += 1;
|
for entry in entries {
|
||||||
|
if let Ok(entry) = entry {
|
||||||
|
let path = entry.path();
|
||||||
|
if path.is_file() {
|
||||||
|
*count += 1;
|
||||||
|
} else if path.is_dir() {
|
||||||
|
count_files_in_dir(&path, count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
count_files_in_dir(&*base_path, &mut local_count);
|
||||||
|
|
||||||
let mut count = file_count.lock().unwrap();
|
let mut count = file_count.lock().unwrap();
|
||||||
*count += local_count;
|
*count += local_count;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue