#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::shadow_unrelated,
clippy::pattern_type_mismatch,
clippy::assertions_on_result_states,
clippy::as_conversions
)]
use crate::{
schema::{error::ValidationError, validate::SchemaValidator, Schema},
*,
};
use serde_json::json;
fn create_resource_schema() -> Rc<Schema> {
let schema_json = json!({
"enum": ["Microsoft.Compute/virtualMachines", "Microsoft.Storage/storageAccounts", "Microsoft.Network/virtualNetworks"],
"description": "Azure Resource types"
});
let schema = Schema::from_serde_json_value(schema_json).unwrap();
Rc::new(schema)
}
fn create_vm_resource_schema() -> Rc<Schema> {
let schema_json = json!({
"type": "object",
"properties": {
"type": {
"const": "Microsoft.Compute/virtualMachines"
},
"apiVersion": {
"enum": ["2021-03-01", "2021-07-01", "2022-03-01"]
},
"name": {
"type": "string",
"pattern": "^[a-zA-Z0-9-._]{1,64}$"
},
"location": {
"type": "string",
"description": "Azure region where the VM will be deployed"
},
"properties": {
"type": "object",
"properties": {
"hardwareProfile": {
"type": "object",
"properties": {
"vmSize": {
"enum": ["Standard_B1s", "Standard_B2s", "Standard_D2s_v3", "Standard_D4s_v3"]
}
},
"required": ["vmSize"]
},
"osProfile": {
"type": "object",
"properties": {
"computerName": {
"type": "string"
},
"adminUsername": {
"type": "string"
}
},
"required": ["computerName", "adminUsername"]
}
},
"required": ["hardwareProfile", "osProfile"]
}
},
"required": ["type", "apiVersion", "name", "location", "properties"],
"description": "Schema for Azure Virtual Machine resources"
});
let schema = Schema::from_serde_json_value(schema_json).unwrap();
Rc::new(schema)
}
fn create_storage_resource_schema() -> Rc<Schema> {
let schema_json = json!({
"type": "object",
"properties": {
"type": {
"const": "Microsoft.Storage/storageAccounts"
},
"apiVersion": {
"enum": ["2021-04-01", "2021-06-01", "2022-05-01"]
},
"name": {
"type": "string",
"pattern": "^[a-z0-9]{3,24}$"
},
"location": {
"type": "string",
"description": "Azure region for the storage account"
},
"sku": {
"type": "object",
"properties": {
"name": {
"enum": ["Standard_LRS", "Standard_GRS", "Standard_RAGRS", "Premium_LRS"]
}
},
"required": ["name"]
},
"kind": {
"enum": ["Storage", "StorageV2", "BlobStorage", "FileStorage", "BlockBlobStorage"]
},
"properties": {
"type": "object",
"properties": {
"accessTier": {
"enum": ["Hot", "Cool"]
},
"encryption": {
"type": "object",
"properties": {
"services": {
"type": "object"
}
}
}
}
}
},
"required": ["type", "apiVersion", "name", "location", "sku", "kind"],
"description": "Schema for Azure Storage Account resources"
});
let schema = Schema::from_serde_json_value(schema_json).unwrap();
Rc::new(schema)
}
fn create_network_resource_schema() -> Rc<Schema> {
let schema_json = json!({
"type": "object",
"properties": {
"type": {
"const": "Microsoft.Network/virtualNetworks"
},
"apiVersion": {
"enum": ["2020-11-01", "2021-02-01", "2021-05-01"]
},
"name": {
"type": "string",
"pattern": "^[a-zA-Z0-9-._]{2,64}$"
},
"location": {
"type": "string",
"description": "Azure region for the virtual network"
},
"properties": {
"type": "object",
"properties": {
"addressSpace": {
"type": "object",
"properties": {
"addressPrefixes": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$"
}
}
},
"required": ["addressPrefixes"]
},
"subnets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"properties": {
"type": "object",
"properties": {
"addressPrefix": {
"type": "string",
"pattern": "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$"
}
},
"required": ["addressPrefix"]
}
},
"required": ["name", "properties"]
}
}
},
"required": ["addressSpace"]
}
},
"required": ["type", "apiVersion", "name", "location", "properties"],
"description": "Schema for Azure Virtual Network resources"
});
let schema = Schema::from_serde_json_value(schema_json).unwrap();
Rc::new(schema)
}
#[test]
fn test_validate_vm_resource_valid() {
let schema = create_vm_resource_schema();
let valid_vm_data = json!({
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-03-01",
"name": "my-vm-01",
"location": "eastus",
"properties": {
"hardwareProfile": {
"vmSize": "Standard_B2s"
},
"osProfile": {
"computerName": "my-computer",
"adminUsername": "azureuser"
}
}
});
let value = Value::from(valid_vm_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_ok());
}
#[test]
fn test_validate_vm_resource_missing_required() {
let schema = create_vm_resource_schema();
let invalid_vm_data = json!({
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-03-01",
"name": "my-vm-01"
});
let value = Value::from(invalid_vm_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_err());
match result.unwrap_err() {
ValidationError::MissingRequiredProperty { property, .. } => {
assert!(property == "location".into() || property == "properties".into());
}
other => panic!("Expected MissingRequiredProperty error, got: {:?}", other),
}
}
#[test]
fn test_validate_vm_resource_invalid_vm_size() {
let schema = create_vm_resource_schema();
let invalid_vm_data = json!({
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-03-01",
"name": "my-vm-01",
"location": "eastus",
"properties": {
"hardwareProfile": {
"vmSize": "InvalidSize"
},
"osProfile": {
"computerName": "my-computer",
"adminUsername": "azureuser"
}
}
});
let value = Value::from(invalid_vm_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_err());
match result.unwrap_err() {
ValidationError::PropertyValidationFailed {
property, error, ..
} => {
assert_eq!(property, "properties".into());
match error.as_ref() {
ValidationError::PropertyValidationFailed {
property: inner_prop,
error: inner_error,
..
} => {
assert_eq!(*inner_prop, "hardwareProfile".into());
match inner_error.as_ref() {
ValidationError::PropertyValidationFailed {
property: vm_size_prop,
error: vm_size_error,
..
} => {
assert_eq!(*vm_size_prop, "vmSize".into());
match vm_size_error.as_ref() {
ValidationError::NotInEnum { .. } => {
}
other => {
panic!("Expected NotInEnum error for vmSize, got: {:?}", other)
}
}
}
other => panic!(
"Expected PropertyValidationFailed for vmSize, got: {:?}",
other
),
}
}
other => panic!(
"Expected PropertyValidationFailed for hardwareProfile, got: {:?}",
other
),
}
}
other => panic!("Expected PropertyValidationFailed error, got: {:?}", other),
}
}
#[test]
fn test_validate_storage_resource_valid() {
let schema = create_storage_resource_schema();
let valid_storage_data = json!({
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "mystorageaccount001",
"location": "westus2",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"properties": {
"accessTier": "Hot",
"encryption": {
"services": {}
}
}
});
let value = Value::from(valid_storage_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_ok());
}
#[test]
fn test_validate_storage_resource_invalid_name() {
let schema = create_storage_resource_schema();
let invalid_storage_data = json!({
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "Invalid-Storage-Name-With-Caps-And-Dashes",
"location": "westus2",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2"
});
let value = Value::from(invalid_storage_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_err());
match result.unwrap_err() {
ValidationError::PropertyValidationFailed {
property, error, ..
} => {
assert_eq!(property, "name".into());
match error.as_ref() {
ValidationError::PatternMismatch { .. } => {
}
other => panic!("Expected PatternMismatch error for name, got: {:?}", other),
}
}
other => panic!("Expected PropertyValidationFailed error, got: {:?}", other),
}
}
#[test]
fn test_validate_storage_resource_invalid_sku() {
let schema = create_storage_resource_schema();
let invalid_storage_data = json!({
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "mystorageaccount001",
"location": "westus2",
"sku": {
"name": "Invalid_SKU"
},
"kind": "StorageV2"
});
let value = Value::from(invalid_storage_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_err());
match result.unwrap_err() {
ValidationError::PropertyValidationFailed {
property, error, ..
} => {
assert_eq!(property, "sku".into());
match error.as_ref() {
ValidationError::PropertyValidationFailed {
property: sku_prop,
error: sku_error,
..
} => {
assert_eq!(*sku_prop, "name".into());
match sku_error.as_ref() {
ValidationError::NotInEnum { .. } => {
}
other => panic!("Expected NotInEnum error for sku name, got: {:?}", other),
}
}
other => panic!(
"Expected PropertyValidationFailed for sku name, got: {:?}",
other
),
}
}
other => panic!("Expected PropertyValidationFailed error, got: {:?}", other),
}
}
#[test]
fn test_validate_network_resource_valid() {
let schema = create_network_resource_schema();
let valid_network_data = json!({
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2021-02-01",
"name": "my-vnet",
"location": "eastus",
"properties": {
"addressSpace": {
"addressPrefixes": ["10.0.0.0/16"]
},
"subnets": [
{
"name": "default",
"properties": {
"addressPrefix": "10.0.1.0/24"
}
}
]
}
});
let value = Value::from(valid_network_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_ok());
}
#[test]
fn test_validate_network_resource_invalid_address_prefix() {
let schema = create_network_resource_schema();
let invalid_network_data = json!({
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2021-02-01",
"name": "my-vnet",
"location": "eastus",
"properties": {
"addressSpace": {
"addressPrefixes": ["invalid-cidr"]
}
}
});
let value = Value::from(invalid_network_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_err());
match result.unwrap_err() {
ValidationError::PropertyValidationFailed {
property, error, ..
} => {
assert_eq!(property, "properties".into());
match error.as_ref() {
ValidationError::PropertyValidationFailed {
property: addr_prop,
..
} => {
assert_eq!(*addr_prop, "addressSpace".into());
}
other => panic!(
"Expected PropertyValidationFailed for addressSpace, got: {:?}",
other
),
}
}
other => panic!("Expected PropertyValidationFailed error, got: {:?}", other),
}
}
#[test]
fn test_validate_basic_resource_enum() {
let schema = create_resource_schema();
let valid_types = [
"Microsoft.Compute/virtualMachines",
"Microsoft.Storage/storageAccounts",
"Microsoft.Network/virtualNetworks",
];
for resource_type in valid_types {
let value = Value::from(resource_type);
let result = SchemaValidator::validate(&value, &schema);
assert!(
result.is_ok(),
"Resource type '{resource_type}' should be valid"
);
}
let invalid_value = Value::from("Microsoft.Invalid/resourceType");
let result = SchemaValidator::validate(&invalid_value, &schema);
assert!(result.is_err());
match result.unwrap_err() {
ValidationError::NotInEnum { .. } => {
}
other => panic!("Expected NotInEnum error, got: {:?}", other),
}
}
#[test]
fn test_validate_complex_arm_template() {
let complex_schema_json = json!({
"type": "object",
"properties": {
"$schema": {
"type": "string"
},
"contentVersion": {
"type": "string"
},
"parameters": {
"type": "object",
"additionalProperties": { "type": "any" }
},
"variables": {
"type": "object",
"additionalProperties": { "type": "any" }
},
"resources": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"apiVersion": {
"type": "string"
},
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"properties": {
"type": "object",
"additionalProperties": { "type": "any" }
},
"tags": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"required": ["type", "apiVersion", "name"],
"additionalProperties": { "type": "any" }
}
},
"outputs": {
"type": "object",
"additionalProperties": { "type": "any" }
}
},
"required": ["resources"],
"additionalProperties": { "type": "any" }
});
let schema = Schema::from_serde_json_value(complex_schema_json).unwrap();
let valid_template_data = json!({
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vmName": {
"type": "string",
"defaultValue": "myVM"
}
},
"variables": {
"storageAccountName": "[concat('storage', uniqueString(resourceGroup().id))]"
},
"resources": [
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-03-01",
"name": "[parameters('vmName')]",
"location": "[resourceGroup().location]",
"properties": {
"hardwareProfile": {
"vmSize": "Standard_B1s"
}
},
"tags": {
"environment": "dev",
"project": "test"
}
}
],
"outputs": {
"vmId": {
"type": "string",
"value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]"
}
}
});
let value = Value::from(valid_template_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_ok());
}
#[test]
fn test_validate_resource_type_mismatch() {
let schema = create_vm_resource_schema();
let invalid_data = Value::from("not an object");
let result = SchemaValidator::validate(&invalid_data, &schema);
assert!(result.is_err());
match result.unwrap_err() {
ValidationError::TypeMismatch {
expected, actual, ..
} => {
assert_eq!(expected, "object".into());
assert_eq!(actual, "string".into());
}
other => panic!("Expected TypeMismatch error, got: {:?}", other),
}
}
#[test]
fn test_complex_nested_azure_template_validation() {
let complex_schema = json!({
"type": "object",
"properties": {
"$schema": { "type": "string" },
"contentVersion": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$" },
"metadata": {
"type": "object",
"properties": {
"description": { "type": "string" },
"author": { "type": "string" },
"tags": {
"type": "object",
"additionalProperties": { "type": "string" }
}
}
},
"parameters": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"type": { "enum": ["string", "int", "bool", "array", "object"] },
"defaultValue": { "type": "any" },
"allowedValues": { "type": "array", "items": { "type": "any" } },
"minValue": { "type": "number" },
"maxValue": { "type": "number" },
"minLength": { "type": "integer" },
"maxLength": { "type": "integer" },
"metadata": {
"type": "object",
"properties": {
"description": { "type": "string" },
"strongType": { "type": "string" }
}
}
},
"required": ["type"]
}
},
"variables": { "type": "object" },
"resources": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "type": "string" },
"apiVersion": { "type": "string" },
"name": { "type": "string" },
"location": { "type": "string" },
"dependsOn": {
"type": "array",
"items": { "type": "string" }
},
"condition": { "type": "boolean" },
"copy": {
"type": "object",
"properties": {
"name": { "type": "string" },
"count": { "type": "integer", "minimum": 1, "maximum": 800 },
"mode": { "enum": ["Parallel", "Serial"] },
"batchSize": { "type": "integer", "minimum": 1 }
},
"required": ["name", "count"]
},
"properties": { "type": "object" },
"tags": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"required": ["type", "apiVersion", "name"]
}
},
"outputs": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"type": { "enum": ["string", "int", "bool", "array", "object"] },
"value": { "type": "any" },
"condition": { "type": "boolean" },
"copy": {
"type": "object",
"properties": {
"count": { "type": "integer", "minimum": 1 },
"input": { "type": "any" }
},
"required": ["count", "input"]
}
},
"required": ["type", "value"]
}
}
},
"required": ["$schema", "contentVersion", "resources"]
});
let schema = Schema::from_serde_json_value(complex_schema).unwrap();
let valid_template = json!({
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.2.3.4",
"metadata": {
"description": "Complex deployment with copy loops and conditions",
"author": "Azure DevOps Team",
"tags": {
"environment": "production",
"cost-center": "engineering",
"department": "cloud-infrastructure"
}
},
"parameters": {
"vmCount": {
"type": "int",
"defaultValue": 3,
"minValue": 1,
"maxValue": 10,
"metadata": {
"description": "Number of VMs to deploy",
"strongType": "Microsoft.Compute/SKUs"
}
},
"environment": {
"type": "string",
"defaultValue": "dev",
"allowedValues": ["dev", "test", "staging", "prod"],
"metadata": {
"description": "Environment name for resource naming"
}
},
"enableMonitoring": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Whether to enable monitoring extensions"
}
}
},
"variables": {
"vmPrefix": "[concat(parameters('environment'), '-vm-')]",
"storageAccountName": "[concat('storage', uniqueString(resourceGroup().id))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-04-01",
"name": "[variables('storageAccountName')]",
"location": "eastus",
"properties": {
"accountType": "Standard_LRS"
},
"tags": {
"purpose": "vm-diagnostics",
"environment": "[parameters('environment')]"
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-03-01",
"name": "[concat(variables('vmPrefix'), copyIndex(1))]",
"location": "eastus",
"condition": true,
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"copy": {
"name": "vmLoop",
"count": 5,
"mode": "Parallel",
"batchSize": 2
},
"properties": {
"hardwareProfile": {
"vmSize": "Standard_B2s"
}
},
"tags": {
"environment": "[parameters('environment')]",
"vm-index": "[string(copyIndex())]"
}
}
],
"outputs": {
"storageAccountId": {
"type": "string",
"value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
},
"vmIds": {
"type": "array",
"copy": {
"count": 5,
"input": "[resourceId('Microsoft.Compute/virtualMachines', concat(variables('vmPrefix'), copyIndex(1)))]"
},
"value" : "[resourceId('Microsoft.Compute/virtualMachines', concat(variables('vmPrefix'), copyIndex(1)))]"
}
}
});
let value = Value::from(valid_template);
let result = SchemaValidator::validate(&value, &schema);
assert!(
result.is_ok(),
"Complex valid template should pass validation"
);
let invalid_template = json!({
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "invalid-version", "resources": [
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-03-01",
"name": "test-vm",
"copy": {
"name": "vmLoop",
"count": 1000 }
}
]
});
let value = Value::from(invalid_template);
let result = SchemaValidator::validate(&value, &schema);
assert!(
result.is_err(),
"Template with constraint violations should fail"
);
}
#[test]
fn test_deep_nesting_and_recursive_structures() {
let deep_schema = json!({
"type": "object",
"properties": {
"level1": {
"type": "object",
"properties": {
"level2": {
"type": "object",
"properties": {
"level3": {
"type": "object",
"properties": {
"level4": {
"type": "object",
"properties": {
"level5": {
"type": "object",
"properties": {
"deepValue": {
"type": "string",
"pattern": "^deep-[0-9]+$"
},
"recursiveArray": {
"type": "array",
"items": {
"type": "object",
"properties": {
"nested": {
"type": "object",
"properties": {
"value": { "type": "number" },
"metadata": {
"type": "object",
"additionalProperties": { "type": "string" }
}
}
}
}
}
}
},
"required": ["deepValue"]
}
}
}
}
}
}
}
}
}
},
"required": ["level1"]
});
let schema = Schema::from_serde_json_value(deep_schema).unwrap();
let valid_deep_data = json!({
"level1": {
"level2": {
"level3": {
"level4": {
"level5": {
"deepValue": "deep-12345",
"recursiveArray": [
{
"nested": {
"value": 42.5,
"metadata": {
"type": "numeric",
"unit": "percentage",
"source": "sensor-1"
}
}
},
{
"nested": {
"value": 15.3,
"metadata": {
"type": "numeric",
"unit": "temperature",
"source": "sensor-2"
}
}
}
]
}
}
}
}
}
});
let value = Value::from(valid_deep_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_ok(), "Valid deeply nested structure should pass");
let invalid_deep_data = json!({
"level1": {
"level2": {
"level3": {
"level4": {
"level5": {
"recursiveArray": []
}
}
}
}
}
});
let value = Value::from(invalid_deep_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(
result.is_err(),
"Structure missing required deep field should fail"
);
}
#[test]
fn test_unicode_and_internationalization_validation() {
let unicode_schema = json!({
"type": "object",
"properties": {
"names": {
"type": "object",
"properties": {
"chinese": { "type": "string", "pattern": "^[\\u4e00-\\u9fff]+$" },
"russian": { "type": "string", "pattern": "^[\\u0400-\\u04ff]+$" },
"japanese": { "type": "string", "pattern": "^[\\u3040-\\u309f\\u30a0-\\u30ff\\u4e00-\\u9fff]+$" },
"korean": { "type": "string", "pattern": "^[\\uac00-\\ud7af]+$" },
"hindi": { "type": "string", "pattern": "^[\\u0900-\\u097f]+$" },
"french": { "type": "string", "pattern": "^[a-zA-ZàâäéèêëïîôöùûüÿñæœÀÂÄÉÈÊËÏÎÔÖÙÛÜŸÑÆŒ\\s-]+$" }
}
},
"descriptions": {
"type": "object",
"additionalProperties": {
"type": "string",
"minLength": 1,
"maxLength": 1000
}
},
"metadata": {
"type": "object",
"properties": {
"encoding": { "enum": ["UTF-8", "UTF-16", "UTF-32"] },
"locale": { "type": "string", "pattern": "^[a-z]{2}-[A-Z]{2}$" },
"timezone": { "type": "string" }
}
}
},
"required": ["names", "metadata"]
});
let schema = Schema::from_serde_json_value(unicode_schema).unwrap();
let valid_unicode_data = json!({
"names": {
"chinese": "你好世界",
"russian": "привет",
"japanese": "こんにちは世界",
"korean": "안녕하세요",
"hindi": "नमस्ते",
"french": "Bonjour le Monde"
},
"descriptions": {
"en-US": "Hello World application for international users",
"zh-CN": "面向国际用户的你好世界应用程序",
"ru-RU": "Приложение Hello World для международных пользователей",
"ja-JP": "国際ユーザー向けのHello Worldアプリケーション",
"ko-KR": "국제 사용자를 위한 Hello World 애플리케이션",
"hi-IN": "अंतर्राष्ट्रीय उपयोगकर्ताओं के लिए हैलो वर्ल्ड एप्लिकेशन",
"fr-FR": "Application Hello World pour les utilisateurs internationaux"
},
"metadata": {
"encoding": "UTF-8",
"locale": "en-US",
"timezone": "UTC"
}
});
let value = Value::from(valid_unicode_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(result.is_ok(), "Valid Unicode data should pass validation");
let invalid_unicode_data = json!({
"names": {
"chinese": "Hello", "russian": "Goodbye", "japanese": "Test", "korean": "Invalid", "hindi": "Wrong", "french": "123456" },
"metadata": {
"encoding": "UTF-8",
"locale": "invalid-locale", "timezone": "UTC"
}
});
let value = Value::from(invalid_unicode_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(
result.is_err(),
"Invalid Unicode patterns should fail validation"
);
}
#[test]
fn test_edge_cases_and_boundary_conditions() {
let boundary_schema = json!({
"type": "object",
"properties": {
"strings": {
"type": "object",
"properties": {
"empty": { "type": "string", "minLength": 0, "maxLength": 0 },
"single": { "type": "string", "minLength": 1, "maxLength": 1 },
"exact_length": { "type": "string", "minLength": 10, "maxLength": 10 },
"very_long": { "type": "string", "maxLength": 10000 }
}
},
"numbers": {
"type": "object",
"properties": {
"zero": { "type": "number", "minimum": 0, "maximum": 0 },
"negative": { "type": "number", "minimum": -1000, "maximum": -1 },
"positive": { "type": "number", "minimum": 1, "maximum": 1000 },
"float_precision": { "type": "number" }
}
},
"arrays": {
"type": "object",
"properties": {
"empty": { "type": "array", "minItems": 0, "maxItems": 0, "items": { "type": "string" } },
"single_item": { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } },
"exact_size": { "type": "array", "minItems": 5, "maxItems": 5, "items": { "type": "integer" } },
"large_array": { "type": "array", "maxItems": 1000, "items": { "type": "boolean" } }
}
},
"objects": {
"type": "object",
"properties": {
"empty": { "type": "object", "additionalProperties": false },
"single_prop": {
"type": "object",
"properties": { "only": { "type": "string" } },
"additionalProperties": false,
"required": ["only"]
}
}
},
"nulls_and_optionals": {
"type": "object",
"properties": {
"nullable": { "type": "string" },
"optional": { "type": "string" },
"required_null": { "type": "null" }
},
"required": ["required_null"]
}
},
"required": ["strings", "numbers", "arrays", "objects", "nulls_and_optionals"]
});
let schema = Schema::from_serde_json_value(boundary_schema).unwrap();
let valid_boundary_data = json!({
"strings": {
"empty": "",
"single": "a",
"exact_length": "exactly_10",
"very_long": "a".repeat(9999)
},
"numbers": {
"zero": 0,
"negative": -500,
"positive": 250,
"float_precision": 123.45
},
"arrays": {
"empty": [],
"single_item": ["test"],
"exact_size": [1, 2, 3, 4, 5],
"large_array": vec![true; 500]
},
"objects": {
"empty": {},
"single_prop": {
"only": "value"
}
},
"nulls_and_optionals": {
"nullable": "string_value",
"optional": "present",
"required_null": null
}
});
let value = Value::from(valid_boundary_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(
result.is_ok(),
"Valid boundary conditions should pass validation"
);
let invalid_boundary_data = json!({
"strings": {
"empty": "not empty", "single": "too long", "exact_length": "wrong", "very_long": "a".repeat(10001) },
"numbers": {
"zero": 0.1, "negative": 1, "positive": -1, "float_precision": 123.456 },
"arrays": {
"empty": ["not empty"], "single_item": [], "exact_size": [1, 2, 3], "large_array": vec![true; 1001] },
"objects": {
"empty": { "should_be_empty": true }, "single_prop": {} },
"nulls_and_optionals": {
"nullable": "should allow null or string",
"required_null": "should be null" }
});
let value = Value::from(invalid_boundary_data);
let result = SchemaValidator::validate(&value, &schema);
assert!(
result.is_err(),
"Boundary violations should fail validation"
);
}
#[test]
fn test_concurrent_schema_validation_stress() {
use std::{sync::Arc, thread};
let concurrent_schema = json!({
"type": "object",
"properties": {
"id": { "type": "string", "pattern": "^[a-zA-Z0-9-]{8,64}$" },
"timestamp": { "type": "string" },
"data": {
"type": "object",
"properties": {
"values": {
"type": "array",
"items": { "type": "number" },
"minItems": 1,
"maxItems": 100
},
"metadata": {
"type": "object",
"additionalProperties": { "type": "string" }
}
},
"required": ["values"]
}
},
"required": ["id", "timestamp", "data"]
});
let schema = Arc::new(Schema::from_serde_json_value(concurrent_schema).unwrap());
let mut handles = vec![];
for thread_id in 0..10 {
let schema_clone = Arc::clone(&schema);
let handle = thread::spawn(move || {
let mut results = Vec::new();
for i in 0..100 {
let test_data = json!({
"id": format!("thread-{}-item-{}", thread_id, i),
"timestamp": "2023-12-31T23:59:59Z",
"data": {
"values": vec![1.0, 2.0, 3.0, (i as f64)],
"metadata": {
"thread": thread_id.to_string(),
"iteration": i.to_string(),
"test_type": "concurrent"
}
}
});
let value = Value::from(test_data);
let result = SchemaValidator::validate(&value, &schema_clone);
results.push(result.is_ok());
}
results
});
handles.push(handle);
}
let mut all_results = Vec::new();
for handle in handles {
let thread_results = handle.join().expect("Thread should complete successfully");
all_results.extend(thread_results);
}
let successful_validations = all_results.iter().filter(|&&result| result).count();
assert_eq!(
successful_validations, 1000,
"All 1000 concurrent validations should pass"
);
}