This is an automated email from the ASF dual-hosted git repository. xuanwo pushed a commit to branch add-test-case-for-fuzzing in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
commit 2b54f1a186a66522561a6fe16222b471fc391c76 Author: Xuanwo <[email protected]> AuthorDate: Thu Jul 27 11:43:03 2023 +0800 feat(tests): Extract fuzz test of #2717 Signed-off-by: Xuanwo <[email protected]> --- core/tests/behavior/fuzz.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++ core/tests/behavior/main.rs | 4 ++ 2 files changed, 95 insertions(+) diff --git a/core/tests/behavior/fuzz.rs b/core/tests/behavior/fuzz.rs new file mode 100644 index 000000000..2f5981d26 --- /dev/null +++ b/core/tests/behavior/fuzz.rs @@ -0,0 +1,91 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +use std::io::SeekFrom; +use std::{io, vec}; + +use anyhow::Result; +use futures::AsyncSeekExt; +use log::{debug}; + +use crate::*; + +pub fn behavior_fuzz_tests(op: &Operator) -> Vec<Trial> { + async_trials!(op, test_fuzz_issue_2717) +} + +/// This fuzz test is to reproduce <https://github.com/apache/incubator-opendal/issues/2717>. +/// +/// The simplified cases could be seen as: +/// +/// ``` +/// FuzzInput { +/// actions: [ +/// Seek( +/// End( +/// -2, +/// ), +/// ), +/// Read { +/// size: 0, +/// }, +/// ], +/// data: [ +/// 0, +/// 0, +/// ], +/// range: ( +/// 1, +/// 2, +/// ) +/// ] +/// } +/// ``` +/// +/// Which means: +/// +/// - A file with 2 bytes of content. +/// - Open as an range reader of `1..2`. +/// - Seek to `End(-2)` first +/// +/// The expected result is seek returns InvalidInput error because the seek position +/// is invalid for given range `1..2`. However, the actual behavior is we seek to `0` +/// and results in a panic. +pub async fn test_fuzz_issue_2717(op: Operator) -> Result<()> { + let cap = op.info().capability(); + + if !(cap.read && cap.write & cap.read_with_range) { + return Ok(()); + } + + let path = uuid::Uuid::new_v4().to_string(); + debug!("Generate a random file: {}", &path); + let content = gen_fixed_bytes(2); + + op.write(&path, content.clone()) + .await + .expect("write must succeed"); + + let mut r = op.range_reader(&path, 1..2).await?; + + // Perform a seek + let result = r.seek(SeekFrom::End(-2)).await; + assert!(result.is_err()); + assert_eq!(result.unwrap_err().kind(), io::ErrorKind::InvalidInput); + + Ok(()) +} diff --git a/core/tests/behavior/main.rs b/core/tests/behavior/main.rs index 867ad736c..cc6d7f977 100644 --- a/core/tests/behavior/main.rs +++ b/core/tests/behavior/main.rs @@ -24,6 +24,7 @@ pub use utils::*; // Async test cases mod append; mod copy; +mod fuzz; mod list; mod list_only; mod presign; @@ -32,6 +33,7 @@ mod rename; mod write; use append::behavior_append_tests; use copy::behavior_copy_tests; +use fuzz::behavior_fuzz_tests; use list::behavior_list_tests; use list_only::behavior_list_only_tests; use presign::behavior_presign_tests; @@ -45,6 +47,7 @@ mod blocking_list; mod blocking_read_only; mod blocking_rename; mod blocking_write; + use blocking_copy::behavior_blocking_copy_tests; use blocking_list::behavior_blocking_list_tests; use blocking_read_only::behavior_blocking_read_only_tests; @@ -84,6 +87,7 @@ fn behavior_test<B: Builder>() -> Vec<Trial> { trials.extend(behavior_read_only_tests(&operator)); trials.extend(behavior_rename_tests(&operator)); trials.extend(behavior_write_tests(&operator)); + trials.extend(behavior_fuzz_tests(&operator)); trials }
