Skip to content

Commit

Permalink
add more comprehensive tests for destructors
Browse files Browse the repository at this point in the history
  • Loading branch information
Quba1 committed Jul 26, 2024
1 parent d68b392 commit ae76c5e
Show file tree
Hide file tree
Showing 10 changed files with 270 additions and 28 deletions.
135 changes: 121 additions & 14 deletions src/codes_handle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,11 @@ pub struct GribFile {
/// All available methods for `CodesHandle` iterator can be found in [`FallibleStreamingIterator`](crate::FallibleStreamingIterator) trait.
#[derive(Debug)]
pub struct CodesHandle<SOURCE: Debug> {
_data: DataContainer,
source: SOURCE,
// fields are dropped from top to bottom
product_kind: ProductKind,
current_message: Option<KeyedMessage>,
source: SOURCE,
_data: DataContainer,
}

// 2024-07-26
Expand Down Expand Up @@ -321,13 +322,13 @@ fn open_with_fmemopen(file_data: &Bytes) -> Result<*mut FILE, CodesError> {

#[cfg(test)]
mod tests {
use anyhow::Result;
use bytes::Bytes;
use eccodes_sys::ProductKind_PRODUCT_GRIB;

use crate::codes_handle::{CodesHandle, DataContainer, ProductKind};
#[cfg(feature = "experimental_index")]
use crate::codes_index::{CodesIndex, Select};
use anyhow::{Context, Result};
use bytes::Bytes;
use eccodes_sys::ProductKind_PRODUCT_GRIB;
use fallible_streaming_iterator::FallibleStreamingIterator;
use log::Level;
use std::{fs::File, io::Read, path::Path};

Expand Down Expand Up @@ -405,9 +406,6 @@ mod tests {
drop(handle);

testing_logger::validate(|captured_logs| {
captured_logs
.iter()
.for_each(|clg| println!("{:?}", clg.body));
assert_eq!(captured_logs.len(), 0);
});

Expand All @@ -425,9 +423,6 @@ mod tests {
f.read_to_end(&mut buf)?;
let file_data = Bytes::from(buf);

let handle = CodesHandle::new_from_memory(file_data, product_kind)?;
drop(handle);

//logs from Reqwest are expected
testing_logger::validate(|captured_logs| {
for log in captured_logs {
Expand All @@ -436,14 +431,80 @@ mod tests {
}
});

let handle = CodesHandle::new_from_memory(file_data, product_kind)?;
drop(handle);

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 0);
});

Ok(())
}

#[test]
fn multiple_drops() -> Result<()> {
testing_logger::setup();
{
let file_path = Path::new("./data/iceland-surface.grib");
let product_kind = ProductKind::GRIB;

let mut handle = CodesHandle::new_from_file(file_path, product_kind)?;

let _ref_msg = handle.next()?.context("no message")?;
let clone_msg = _ref_msg.try_clone()?;
let _oth_ref = handle.next()?.context("no message")?;

let _nrst = clone_msg.codes_nearest()?;
let _kiter = clone_msg.default_keys_iterator()?;
}

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 5);

let expected_logs = vec![
("codes_handle_delete", log::Level::Trace),
("codes_keys_iterator_delete", log::Level::Trace),
("codes_grib_nearest_delete", log::Level::Trace),
("codes_handle_delete", log::Level::Trace),
("codes_handle_delete", log::Level::Trace),
];

captured_logs
.iter()
.zip(expected_logs)
.for_each(|(clg, elg)| {
assert_eq!(clg.body, elg.0);
assert_eq!(clg.level, elg.1)
});
});

Ok(())
}

#[test]
#[cfg(feature = "experimental_index")]
fn empty_index_constructor() -> Result<()> {
use fallible_streaming_iterator::FallibleStreamingIterator;
fn codes_handle_drop_index() -> Result<()> {
testing_logger::setup();

let file_path = Path::new("./data/iceland-surface.grib.idx");
let index = CodesIndex::read_from_file(file_path)?;
assert!(!index.pointer.is_null());

let handle = CodesHandle::new_from_index(index)?;
drop(handle);

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 1);
assert_eq!(captured_logs[0].body, "codes_index_delete");
assert_eq!(captured_logs[0].level, log::Level::Trace);
});

Ok(())
}

#[test]
#[cfg(feature = "experimental_index")]
fn empty_index_constructor() -> Result<()> {
let index =
CodesIndex::new_from_keys(&vec!["shortName", "typeOfLevel", "level", "stepType"])?;

Expand All @@ -458,4 +519,50 @@ mod tests {

Ok(())
}

#[test]
#[cfg(feature = "experimental_index")]
fn multiple_drops_with_index() -> Result<()> {
testing_logger::setup();
{
let keys = vec!["typeOfLevel", "level"];
let index = CodesIndex::new_from_keys(&keys)?;
let grib_path = Path::new("./data/iceland-levels.grib");
let index = index
.add_grib_file(grib_path)?
.select("typeOfLevel", "isobaricInhPa")?
.select("level", 600)?;

let mut handle = CodesHandle::new_from_index(index)?;
let _ref_msg = handle.next()?.context("no message")?;
let clone_msg = _ref_msg.try_clone()?;
let _oth_ref = handle.next()?.context("no message")?;

let _nrst = clone_msg.codes_nearest()?;
let _kiter = clone_msg.default_keys_iterator()?;
}

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 6);

let expected_logs = vec![
("codes_handle_delete", log::Level::Trace),
("codes_keys_iterator_delete", log::Level::Trace),
("codes_grib_nearest_delete", log::Level::Trace),
("codes_handle_delete", log::Level::Trace),
("codes_handle_delete", log::Level::Trace),
("codes_index_delete", log::Level::Trace),
];

captured_logs
.iter()
.zip(expected_logs)
.for_each(|(clg, elg)| {
assert_eq!(clg.body, elg.0);
assert_eq!(clg.level, elg.1)
});
});

Ok(())
}
}
48 changes: 46 additions & 2 deletions src/codes_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,13 @@ impl Drop for CodesIndex {

#[cfg(test)]
mod tests {
use anyhow::{bail, Result};
use anyhow::{bail, Context, Result};
use fallible_streaming_iterator::FallibleStreamingIterator;

use crate::{
codes_index::{CodesIndex, Select},
errors::CodesInternal,
CodesError,
CodesError, CodesHandle,
};
use std::path::Path;
#[test]
Expand All @@ -295,6 +296,13 @@ mod tests {
let index = CodesIndex::new_from_keys(&keys)?;

drop(index);

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 1);
assert_eq!(captured_logs[0].body, "codes_index_delete");
assert_eq!(captured_logs[0].level, log::Level::Trace);
});

Ok(())
}

Expand Down Expand Up @@ -334,4 +342,40 @@ mod tests {
}
Ok(())
}

#[test]
fn handle_from_index_destructor() -> Result<()> {
testing_logger::setup();
{
let keys = vec!["typeOfLevel", "level"];
let index = CodesIndex::new_from_keys(&keys)?;
let grib_path = Path::new("./data/iceland-levels.grib");
let index = index
.add_grib_file(grib_path)?
.select("typeOfLevel", "isobaricInhPa")?
.select("level", 600)?;

let mut handle = CodesHandle::new_from_index(index)?;
let _ref_msg = handle.next()?.context("no message")?;
}

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 2);

let expected_logs = vec![
("codes_handle_delete", log::Level::Trace),
("codes_index_delete", log::Level::Trace),
];

captured_logs
.iter()
.zip(expected_logs)
.for_each(|(clg, elg)| {
assert_eq!(clg.body, elg.0);
assert_eq!(clg.level, elg.1)
});
});

Ok(())
}
}
29 changes: 29 additions & 0 deletions src/codes_nearest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,33 @@ mod tests {

Ok(())
}

#[test]
fn destructor() -> Result<()> {
let file_path = Path::new("./data/iceland.grib");
let product_kind = ProductKind::GRIB;

let mut handle = CodesHandle::new_from_file(file_path, product_kind)?;
let current_message = handle.next()?.context("Message not some")?;

let _nrst = current_message.codes_nearest()?;

drop(_nrst);

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 1);
assert_eq!(captured_logs[0].body, "codes_grib_nearest_delete");
assert_eq!(captured_logs[0].level, log::Level::Trace);
});

drop(handle);

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 1);
assert_eq!(captured_logs[0].body, "codes_handle_delete");
assert_eq!(captured_logs[0].level, log::Level::Trace);
});

Ok(())
}
}
2 changes: 1 addition & 1 deletion src/intermediate_bindings/codes_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub unsafe fn codes_handle_new_from_file(

pub unsafe fn codes_handle_delete(handle: *mut codes_handle) -> Result<(), CodesError> {
#[cfg(test)]
log::info!("codes_handle_delete");
log::trace!("codes_handle_delete");

if handle.is_null() {
return Ok(());
Expand Down
2 changes: 1 addition & 1 deletion src/intermediate_bindings/codes_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub unsafe fn codes_index_read(filename: &str) -> Result<*mut codes_index, Codes

pub unsafe fn codes_index_delete(index: *mut codes_index) {
#[cfg(test)]
log::info!("codes_index_delete");
log::trace!("codes_index_delete");

if index.is_null() {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/intermediate_bindings/codes_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub unsafe fn codes_keys_iterator_delete(
keys_iterator: *mut codes_keys_iterator,
) -> Result<(), CodesError> {
#[cfg(test)]
log::info!("codes_keys_iterator_delete");
log::trace!("codes_keys_iterator_delete");

if keys_iterator.is_null() {
return Ok(());
Expand Down
2 changes: 1 addition & 1 deletion src/intermediate_bindings/grib_nearest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub unsafe fn codes_grib_nearest_new(

pub unsafe fn codes_grib_nearest_delete(nearest: *mut codes_nearest) -> Result<(), CodesError> {
#[cfg(test)]
log::info!("codes_grib_nearest_delete");
log::trace!("codes_grib_nearest_delete");

if nearest.is_null() {
return Ok(());
Expand Down
25 changes: 17 additions & 8 deletions src/keyed_message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,24 +290,33 @@ mod tests {
}

#[test]
fn message_drop() -> Result<()> {
fn message_clone_drop() -> Result<()> {
testing_logger::setup();
let file_path = Path::new("./data/iceland.grib");
let product_kind = ProductKind::GRIB;

let mut handle = CodesHandle::new_from_file(file_path, product_kind)?;
let current_message = handle.next()?.context("Message not some")?.try_clone()?;
let _msg_ref = handle.next()?.context("Message not some")?;
let _msg_clone = _msg_ref.try_clone()?;

let _kiter = current_message.default_keys_iterator()?;
let _niter = current_message.codes_nearest()?;
testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 0);
});

drop(_msg_clone);

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 1);
assert_eq!(captured_logs[0].body, "codes_handle_delete");
assert_eq!(captured_logs[0].level, log::Level::Trace);
});

drop(handle);
drop(_kiter);
drop(_niter);
drop(current_message);

testing_logger::validate(|captured_logs| {
assert_eq!(captured_logs.len(), 0);
assert_eq!(captured_logs.len(), 1);
assert_eq!(captured_logs[0].body, "codes_handle_delete");
assert_eq!(captured_logs[0].level, log::Level::Trace);
});

Ok(())
Expand Down
Loading

0 comments on commit ae76c5e

Please sign in to comment.