From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id B323369BDD for ; Wed, 28 Jul 2021 12:05:43 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id A849422E38 for ; Wed, 28 Jul 2021 12:05:13 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 99AC722E28 for ; Wed, 28 Jul 2021 12:05:12 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 709D142A92 for ; Wed, 28 Jul 2021 12:05:12 +0200 (CEST) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Wed, 28 Jul 2021 12:05:11 +0200 Message-Id: <20210728100511.2862784-4-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210728100511.2862784-1-d.csapak@proxmox.com> References: <20210728100511.2862784-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.497 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox-backup 3/3] tape: changer: add tests for decode_element_status_page X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jul 2021 10:05:43 -0000 a test for a valid status_page, one with excess data (in the descriptor as well in the page as a whole) and a test with too little data Signed-off-by: Dominik Csapak --- src/tape/changer/sg_pt_changer.rs | 138 ++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/src/tape/changer/sg_pt_changer.rs b/src/tape/changer/sg_pt_changer.rs index 7ff9bc9d..8451e8e8 100644 --- a/src/tape/changer/sg_pt_changer.rs +++ b/src/tape/changer/sg_pt_changer.rs @@ -818,3 +818,141 @@ pub fn open>(path: P) -> Result { Ok(file) } + +#[cfg(test)] +mod test { + use anyhow::Error; + use super::*; + + struct StorageDesc { + address: u16, + pvoltag: Option, + } + + fn build_element_status_page( + descriptors: Vec, + trailing: &[u8], + element_type: u8, + ) -> Vec { + let descs: Vec> = descriptors.iter().map(|desc| { + build_storage_descriptor(&desc, trailing) + }).collect(); + + let (desc_len, address) = if let Some(el) = descs.get(0) { + (el.len() as u16, descriptors[0].address) + } else { + (0u16, 0u16) + }; + + let descriptor_byte_count = desc_len * descs.len() as u16; + let byte_count = 8 + descriptor_byte_count; + + let mut res = Vec::new(); + + res.extend_from_slice(&address.to_be_bytes()); + res.extend_from_slice(&(descs.len() as u16).to_be_bytes()); + res.push(0); + let byte_count = byte_count as u32; + res.extend_from_slice(&byte_count.to_be_bytes()[1..]); + + res.push(element_type); + res.push(0x80); + res.extend_from_slice(&desc_len.to_be_bytes()); + res.push(0); + let descriptor_byte_count = descriptor_byte_count as u32; + res.extend_from_slice(&descriptor_byte_count.to_be_bytes()[1..]); + + for desc in descs { + res.extend_from_slice(&desc); + } + + res.extend_from_slice(trailing); + + res + } + + fn build_storage_descriptor( + desc: &StorageDesc, + trailing: &[u8], + ) -> Vec { + let mut res = Vec::new(); + res.push(((desc.address >> 8) & 0xFF) as u8); + res.push((desc.address & 0xFF) as u8); + if desc.pvoltag.is_some() { + res.push(0x01); // full + } else { + res.push(0x00); // full + } + + res.extend_from_slice(&[0,0,0,0,0,0,0x80]); + res.push(((desc.address >> 8) & 0xFF) as u8); + res.push((desc.address & 0xFF) as u8); + + if let Some(voltag) = &desc.pvoltag { + res.extend_from_slice(voltag.as_bytes()); + let rem = SCSI_VOLUME_TAG_LEN - voltag.as_bytes().len(); + if rem > 0 { + res.resize(res.len() + rem, 0); + } + } + + res.extend_from_slice(trailing); + + res + } + + #[test] + fn status_page_valid() -> Result<(), Error> { + let descs = vec![ + StorageDesc { + address: 0, + pvoltag: Some("0123456789".to_string()), + }, + StorageDesc { + address: 1, + pvoltag: Some("1234567890".to_string()), + }, + ]; + let test_data = build_element_status_page(descs, &[], 0x2); + let page = decode_element_status_page(&test_data, 0)?; + assert_eq!(page.storage_slots.len(), 2); + Ok(()) + } + + #[test] + fn status_page_too_short() -> Result<(), Error> { + let descs = vec![ + StorageDesc { + address: 0, + pvoltag: Some("0123456789".to_string()), + }, + StorageDesc { + address: 1, + pvoltag: Some("1234567890".to_string()), + }, + ]; + let test_data = build_element_status_page(descs, &[], 0x2); + let len = test_data.len(); + let res = decode_element_status_page(&test_data[..(len - 10)], 0); + assert!(res.is_err()); + Ok(()) + } + + #[test] + fn status_page_too_large() -> Result<(), Error> { + let descs = vec![ + StorageDesc { + address: 0, + pvoltag: Some("0123456789".to_string()), + }, + StorageDesc { + address: 1, + pvoltag: Some("1234567890".to_string()), + }, + ]; + let test_data = build_element_status_page(descs, &[0,0,0,0,0], 0x2); + let page = decode_element_status_page(&test_data, 0)?; + assert_eq!(page.storage_slots.len(), 2); + Ok(()) + } +} -- 2.30.2