Skip to content

Commit

Permalink
Successful repro case for #230
Browse files Browse the repository at this point in the history
Thank you, @CeNiEi.
  • Loading branch information
scouten-adobe committed Jul 26, 2024
1 parent 757d82f commit c70ef86
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,9 @@ fs_extra = "1.3"

[dev-dependencies]
anyhow = "1.0.67"
futures = "0.3.30"
pretty_assertions = "1.4.0"
rand = "0.8.5"
tempfile = "3.2"
tokio = { version = "1.39", features = ["full"] }
tokio-macros = "2.4"
Binary file added src/tests/fixtures/image2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 101 additions & 0 deletions src/tests/issues/issue_230.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright 2024 Adobe. All rights reserved.
// This file is licensed to you under the Apache License,
// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
// or the MIT license (http://opensource.org/licenses/MIT),
// at your option.

// Unless required by applicable law or agreed to in writing,
// this software is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
// implied. See the LICENSE-MIT and LICENSE-APACHE files for the
// specific language governing permissions and limitations under
// each license.

// Test case for https://github.com/adobe/xmp-toolkit-rs/issues/230:
// Updating the XMP data of same image concurrently aborts the entire process.

use std::thread::sleep;

use futures::stream::StreamExt;
use rand::{thread_rng, Rng};
use tempfile::tempdir;
use tokio::task::spawn_blocking;
use tokio_macros::test;

use crate::{
tests::fixtures::temp_copy_of_fixture, xmp_ns::TIFF, OpenFileOptions, XmpFile, XmpMeta,
XmpValue,
};

#[test(flavor = "multi_thread")]
async fn main() {
let tempdir: tempfile::TempDir = tempdir().unwrap();
let image2 = temp_copy_of_fixture(tempdir.path(), "image2.jpg");

let mut handles = Vec::new();

for _ in 0..2 {
let image2 = image2.clone();

let handle = spawn_blocking(move || {
let flip = thread_rng().gen_range(1..=8);

let (mut xmp_file, mut meta) = open_file(&image2);

sleep(std::time::Duration::from_secs(3));
update(&mut meta, flip);

sleep(std::time::Duration::from_secs(3));
write_to_file(&mut xmp_file, &meta);
});

handles.push(handle);
}

futures::stream::iter(handles)
.buffer_unordered(4)
.collect::<Vec<_>>()
.await
.into_iter()
.collect::<Result<Vec<_>, _>>()
.unwrap();
}

fn open_file(path: impl AsRef<std::path::Path>) -> (XmpFile, XmpMeta) {
let path = path.as_ref();

let mut xmp_file = XmpFile::new().unwrap();

xmp_file
.open_file(
&path,

Check failure on line 71 in src/tests/issues/issue_230.rs

View workflow job for this annotation

GitHub Actions / clippy

the borrowed expression implements the required traits

error: the borrowed expression implements the required traits --> src/tests/issues/issue_230.rs:71:13 | 71 | &path, | ^^^^^ help: change this to: `path` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args note: the lint level is defined here --> src/lib.rs:18:9 | 18 | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(clippy::needless_borrows_for_generic_args)]` implied by `#[deny(warnings)]`
OpenFileOptions::default()
.only_xmp()
.for_update()
.use_smart_handler(),
)
.or_else(|_| {
xmp_file.open_file(
&path,

Check failure on line 79 in src/tests/issues/issue_230.rs

View workflow job for this annotation

GitHub Actions / clippy

the borrowed expression implements the required traits

error: the borrowed expression implements the required traits --> src/tests/issues/issue_230.rs:79:17 | 79 | &path, | ^^^^^ help: change this to: `path` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args
OpenFileOptions::default()
.only_xmp()
.for_update()
.use_packet_scanning(),
)
})
.unwrap();

let xmp = xmp_file.xmp().unwrap_or(XmpMeta::new().unwrap());

(xmp_file, xmp)
}

fn update(meta: &mut XmpMeta, flip: u8) {
meta.set_property(TIFF, "Orientation", &XmpValue::new(flip.to_string()))
.unwrap();
}

fn write_to_file(xmp_file: &mut XmpFile, meta: &XmpMeta) {
xmp_file.put_xmp(meta).unwrap();
xmp_file.close();
}
16 changes: 16 additions & 0 deletions src/tests/issues/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2024 Adobe. All rights reserved.
// This file is licensed to you under the Apache License,
// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
// or the MIT license (http://opensource.org/licenses/MIT),
// at your option.

// Unless required by applicable law or agreed to in writing,
// this software is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
// implied. See the LICENSE-MIT and LICENSE-APACHE files for the
// specific language governing permissions and limitations under
// each license.

// Test cases for specific GitHub issues will be added here.

mod issue_230;
1 change: 1 addition & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#![allow(clippy::unwrap_used)]

mod fixtures;
mod issues;
mod xmp_core_coverage;
mod xmp_date_time;
#[cfg(feature = "chrono")]
Expand Down

0 comments on commit c70ef86

Please sign in to comment.