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 41CA76AF1A for ; Wed, 17 Feb 2021 14:13:26 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 3FF90224A1 for ; Wed, 17 Feb 2021 14:13:26 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (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 6655322487 for ; Wed, 17 Feb 2021 14:13:24 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 31C8E461DD for ; Wed, 17 Feb 2021 14:13:24 +0100 (CET) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Wed, 17 Feb 2021 14:13:20 +0100 Message-Id: <20210217131322.9129-2-d.csapak@proxmox.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210217131322.9129-1-d.csapak@proxmox.com> References: <20210217131322.9129-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.219 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [task.rs, io.rs, lib.rs, mod.rs] Subject: [pbs-devel] [PATCH proxmox v5 1/2] proxmox: add test/{io, task} modules 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, 17 Feb 2021 13:13:26 -0000 contains: * AsyncBlocking{Reader,Writer} for dummy async code by wrapping a 'standard reader/writer' * poll_result_once for pulling a future once (copied from pxar) Signed-off-by: Dominik Csapak --- proxmox/src/lib.rs | 3 ++ proxmox/src/test/io.rs | 94 ++++++++++++++++++++++++++++++++++++++++ proxmox/src/test/mod.rs | 2 + proxmox/src/test/task.rs | 32 ++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 proxmox/src/test/io.rs create mode 100644 proxmox/src/test/mod.rs create mode 100644 proxmox/src/test/task.rs diff --git a/proxmox/src/lib.rs b/proxmox/src/lib.rs index b74b399..6e95906 100644 --- a/proxmox/src/lib.rs +++ b/proxmox/src/lib.rs @@ -8,6 +8,9 @@ pub mod api; pub mod sys; pub mod tools; +#[cfg(test)] +pub mod test; + /// An identity (nop) macro. Used by the `#[sortable]` proc macro. #[cfg(feature = "sortable-macro")] #[macro_export] diff --git a/proxmox/src/test/io.rs b/proxmox/src/test/io.rs new file mode 100644 index 0000000..919aac1 --- /dev/null +++ b/proxmox/src/test/io.rs @@ -0,0 +1,94 @@ +use std::pin::Pin; +use std::task::{Context, Poll}; + +use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite, ReadBuf}; + +pub struct AsyncBlockingReader { + inner: R, +} + +impl AsyncBlockingReader { + pub fn new(inner: W) -> Self { + Self { + inner + } + } + + pub fn inner(&self) -> &W { + &self.inner + } +} + +pub struct AsyncBlockingWriter { + inner: W, + seek_pos: u64, +} + +impl AsyncBlockingWriter { + pub fn new(inner: W) -> Self { + Self { + inner, + seek_pos: 0, + } + } + + pub fn inner(&self) -> &W { + &self.inner + } +} + +impl AsyncRead for AsyncBlockingReader { + fn poll_read( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + let this = Pin::get_mut(self); + let mut read_buf = buf.initialize_unfilled(); + match this.inner.read(&mut read_buf) { + Ok(len) => { + buf.advance(len); + Poll::Ready(Ok(())) + } + Err(err) => Poll::Ready(Err(err)), + } + } +} + +impl AsyncWrite for AsyncBlockingWriter { + fn poll_write( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + let this = Pin::get_mut(self); + match this.inner.write(buf) { + Ok(len) => Poll::Ready(Ok(len)), + Err(err) => Poll::Ready(Err(err)), + } + } + + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } +} + +impl AsyncSeek for AsyncBlockingWriter { + fn start_seek(self: Pin<&mut Self>, position: std::io::SeekFrom) -> std::io::Result<()> { + let this = Pin::get_mut(self); + this.seek_pos = this.inner.seek(position)?; + Ok(()) + } + + fn poll_complete( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + ) -> Poll> { + let this = Pin::get_mut(self); + Poll::Ready(Ok(this.seek_pos)) + } +} diff --git a/proxmox/src/test/mod.rs b/proxmox/src/test/mod.rs new file mode 100644 index 0000000..82ac3e2 --- /dev/null +++ b/proxmox/src/test/mod.rs @@ -0,0 +1,2 @@ +pub mod io; +pub mod task; diff --git a/proxmox/src/test/task.rs b/proxmox/src/test/task.rs new file mode 100644 index 0000000..4f5eca6 --- /dev/null +++ b/proxmox/src/test/task.rs @@ -0,0 +1,32 @@ +use std::future::Future; +use std::pin::Pin; +use std::task::{Context, Poll}; + +pub fn poll_result_once(mut fut: T) -> std::io::Result +where + T: Future>, +{ + let waker = std::task::RawWaker::new(std::ptr::null(), &WAKER_VTABLE); + let waker = unsafe { std::task::Waker::from_raw(waker) }; + let mut cx = Context::from_waker(&waker); + unsafe { + match Pin::new_unchecked(&mut fut).poll(&mut cx) { + Poll::Pending => Err(crate::sys::error::io_err_other( + "got Poll::Pending synchronous context", + )), + Poll::Ready(r) => r, + } + } +} + +const WAKER_VTABLE: std::task::RawWakerVTable = +std::task::RawWakerVTable::new(forbid_clone, forbid_wake, forbid_wake, ignore_drop); + +unsafe fn forbid_clone(_: *const ()) -> std::task::RawWaker { + panic!("tried to clone waker for synchronous task"); +} + +unsafe fn forbid_wake(_: *const ()) { + panic!("tried to wake synchronous task"); +} +unsafe fn ignore_drop(_: *const ()) {} -- 2.20.1