forked from proxmox-mirrors/proxmox
		
	 1e0c04a4ba
			
		
	
	
		1e0c04a4ba
		
	
	
	
	
		
			
			it's not actually testing anything useful Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
		
			
				
	
	
		
			398 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			398 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use anyhow::bail;
 | |
| use serde_json::Value;
 | |
| use url::form_urlencoded;
 | |
| 
 | |
| use proxmox_schema::*;
 | |
| 
 | |
| fn parse_query_string<T: Into<ParameterSchema>>(
 | |
|     query: &str,
 | |
|     schema: T,
 | |
|     test_required: bool,
 | |
| ) -> Result<Value, ParameterError> {
 | |
|     let param_list: Vec<(String, String)> = form_urlencoded::parse(query.as_bytes())
 | |
|         .into_owned()
 | |
|         .collect();
 | |
| 
 | |
|     schema
 | |
|         .into()
 | |
|         .parse_parameter_strings(¶m_list, test_required)
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_schema1() {
 | |
|     let schema = Schema::Object(ObjectSchema {
 | |
|         description: "TEST",
 | |
|         additional_properties: false,
 | |
|         properties: &[],
 | |
|         default_key: None,
 | |
|     });
 | |
| 
 | |
|     println!("TEST Schema: {:?}", schema);
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_query_string() {
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[("name", false, &StringSchema::new("Name.").schema())],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
|     }
 | |
| 
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[("name", true, &StringSchema::new("Name.").schema())],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|     }
 | |
| 
 | |
|     // TEST min_length and max_length
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[(
 | |
|                 "name",
 | |
|                 true,
 | |
|                 &StringSchema::new("Name.")
 | |
|                     .min_length(5)
 | |
|                     .max_length(10)
 | |
|                     .schema(),
 | |
|             )],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("name=abcd", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("name=abcde", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("name=abcdefghijk", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("name=abcdefghij", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|     }
 | |
| 
 | |
|     // TEST regex pattern
 | |
|     crate::const_regex! {
 | |
|         TEST_REGEX = "test";
 | |
|         TEST2_REGEX = "^test$";
 | |
|     }
 | |
| 
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[(
 | |
|                 "name",
 | |
|                 false,
 | |
|                 &StringSchema::new("Name.")
 | |
|                     .format(&ApiStringFormat::Pattern(&TEST_REGEX))
 | |
|                     .schema(),
 | |
|             )],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("name=abcd", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("name=ateststring", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|     }
 | |
| 
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[(
 | |
|                 "name",
 | |
|                 false,
 | |
|                 &StringSchema::new("Name.")
 | |
|                     .format(&ApiStringFormat::Pattern(&TEST2_REGEX))
 | |
|                     .schema(),
 | |
|             )],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("name=ateststring", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("name=test", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|     }
 | |
| 
 | |
|     // TEST string enums
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[(
 | |
|                 "name",
 | |
|                 false,
 | |
|                 &StringSchema::new("Name.")
 | |
|                     .format(&ApiStringFormat::Enum(&[
 | |
|                         EnumEntry::new("ev1", "desc ev1"),
 | |
|                         EnumEntry::new("ev2", "desc ev2"),
 | |
|                     ]))
 | |
|                     .schema(),
 | |
|             )],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("name=noenum", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("name=ev1", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("name=ev2", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("name=ev3", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_query_integer() {
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[("count", false, &IntegerSchema::new("Count.").schema())],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
|     }
 | |
| 
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[(
 | |
|                 "count",
 | |
|                 true,
 | |
|                 &IntegerSchema::new("Count.")
 | |
|                     .minimum(-3)
 | |
|                     .maximum(50)
 | |
|                     .schema(),
 | |
|             )],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("count=abc", &SCHEMA, false);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("count=30", &SCHEMA, false);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("count=-1", &SCHEMA, false);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("count=300", &SCHEMA, false);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("count=-30", &SCHEMA, false);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("count=50", &SCHEMA, false);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("count=-3", &SCHEMA, false);
 | |
|         assert!(res.is_ok());
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_query_boolean() {
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[("force", false, &BooleanSchema::new("Force.").schema())],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
|     }
 | |
| 
 | |
|     {
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[("force", true, &BooleanSchema::new("Force.").schema())],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("a=b", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("force", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("force=yes", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|         let res = parse_query_string("force=1", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|         let res = parse_query_string("force=On", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|         let res = parse_query_string("force=TRUE", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|         let res = parse_query_string("force=TREU", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("force=NO", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|         let res = parse_query_string("force=0", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|         let res = parse_query_string("force=off", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|         let res = parse_query_string("force=False", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_verify_function() {
 | |
|     const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|         "Parameters.",
 | |
|         &[(
 | |
|             "p1",
 | |
|             false,
 | |
|             &StringSchema::new("P1")
 | |
|                 .format(&ApiStringFormat::VerifyFn(|value| {
 | |
|                     if value == "test" {
 | |
|                         return Ok(());
 | |
|                     };
 | |
|                     bail!("format error");
 | |
|                 }))
 | |
|                 .schema(),
 | |
|         )],
 | |
|     );
 | |
| 
 | |
|     let res = parse_query_string("p1=tes", &SCHEMA, true);
 | |
|     assert!(res.is_err());
 | |
|     let res = parse_query_string("p1=test", &SCHEMA, true);
 | |
|     assert!(res.is_ok());
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_verify_complex_object() {
 | |
|     const NIC_MODELS: ApiStringFormat = ApiStringFormat::Enum(&[
 | |
|         EnumEntry::new("e1000", "Intel E1000"),
 | |
|         EnumEntry::new("virtio", "Paravirtualized ethernet device"),
 | |
|     ]);
 | |
| 
 | |
|     const PARAM_SCHEMA: Schema = ObjectSchema::new(
 | |
|         "Properties.",
 | |
|         &[
 | |
|             (
 | |
|                 "enable",
 | |
|                 true,
 | |
|                 &BooleanSchema::new("Enable device.").schema(),
 | |
|             ),
 | |
|             (
 | |
|                 "model",
 | |
|                 false,
 | |
|                 &StringSchema::new("Ethernet device Model.")
 | |
|                     .format(&NIC_MODELS)
 | |
|                     .schema(),
 | |
|             ),
 | |
|         ],
 | |
|     )
 | |
|     .default_key("model")
 | |
|     .schema();
 | |
| 
 | |
|     const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|         "Parameters.",
 | |
|         &[(
 | |
|             "net0",
 | |
|             false,
 | |
|             &StringSchema::new("First Network device.")
 | |
|                 .format(&ApiStringFormat::PropertyString(&PARAM_SCHEMA))
 | |
|                 .schema(),
 | |
|         )],
 | |
|     );
 | |
| 
 | |
|     let res = parse_query_string("", &SCHEMA, true);
 | |
|     assert!(res.is_err());
 | |
| 
 | |
|     let res = parse_query_string("test=abc", &SCHEMA, true);
 | |
|     assert!(res.is_err());
 | |
| 
 | |
|     let res = parse_query_string("net0=model=abc", &SCHEMA, true);
 | |
|     assert!(res.is_err());
 | |
| 
 | |
|     let res = parse_query_string("net0=model=virtio", &SCHEMA, true);
 | |
|     assert!(res.is_ok());
 | |
| 
 | |
|     let res = parse_query_string("net0=model=virtio,enable=1", &SCHEMA, true);
 | |
|     assert!(res.is_ok());
 | |
| 
 | |
|     let res = parse_query_string("net0=virtio,enable=no", &SCHEMA, true);
 | |
|     assert!(res.is_ok());
 | |
| }
 | |
| 
 | |
| #[test]
 | |
| fn test_verify_complex_array() {
 | |
|     {
 | |
|         const PARAM_SCHEMA: Schema =
 | |
|             ArraySchema::new("Integer List.", &IntegerSchema::new("Soemething").schema()).schema();
 | |
| 
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[(
 | |
|                 "list",
 | |
|                 false,
 | |
|                 &StringSchema::new("A list on integers, comma separated.")
 | |
|                     .format(&ApiStringFormat::PropertyString(&PARAM_SCHEMA))
 | |
|                     .schema(),
 | |
|             )],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("list=", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("list=abc", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("list=1", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("list=2,3,4,5", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
|     }
 | |
| 
 | |
|     {
 | |
|         const PARAM_SCHEMA: Schema =
 | |
|             ArraySchema::new("Integer List.", &IntegerSchema::new("Soemething").schema())
 | |
|                 .min_length(1)
 | |
|                 .max_length(3)
 | |
|                 .schema();
 | |
| 
 | |
|         const SCHEMA: ObjectSchema = ObjectSchema::new(
 | |
|             "Parameters.",
 | |
|             &[(
 | |
|                 "list",
 | |
|                 false,
 | |
|                 &StringSchema::new("A list on integers, comma separated.")
 | |
|                     .format(&ApiStringFormat::PropertyString(&PARAM_SCHEMA))
 | |
|                     .schema(),
 | |
|             )],
 | |
|         );
 | |
| 
 | |
|         let res = parse_query_string("list=", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
| 
 | |
|         let res = parse_query_string("list=1,2,3", &SCHEMA, true);
 | |
|         assert!(res.is_ok());
 | |
| 
 | |
|         let res = parse_query_string("list=2,3,4,5", &SCHEMA, true);
 | |
|         assert!(res.is_err());
 | |
|     }
 | |
| }
 |