diff --git a/functional-tests/era-functional-tests.scm b/functional-tests/era-functional-tests.scm
index 3847b82..7a24f6b 100644
--- a/functional-tests/era-functional-tests.scm
+++ b/functional-tests/era-functional-tests.scm
@@ -66,21 +66,4 @@
(assert-starts-with
(string-append bad-xml ": No such file or directory")
stderr)))))
-
- ;;;-----------------------------------------------------------
- ;;; era_dump scenarios
- ;;;-----------------------------------------------------------
- (define-scenario (era-dump small-input-file)
- "Fails with small input file"
- (with-temp-file-sized ((md "era.bin" 512))
- (run-fail (era-dump md))))
-
- (define-scenario (era-dump restore-is-noop)
- "era_dump followed by era_restore is a noop."
- (with-valid-metadata (md)
- (run-ok-rcv (d1-stdout _) (era-dump md)
- (with-temp-file-containing ((xml "era.xml" d1-stdout))
- (run-ok (era-restore "-i" xml "-o" md))
- (run-ok-rcv (d2-stdout _) (era-dump md)
- (assert-equal d1-stdout d2-stdout))))))
)
diff --git a/tests/common/input_arg.rs b/tests/common/input_arg.rs
index 2dfae10..e1970f8 100644
--- a/tests/common/input_arg.rs
+++ b/tests/common/input_arg.rs
@@ -180,6 +180,32 @@ macro_rules! test_unreadable_input_file {
//------------------------------------------
// test invalid content
+pub fn test_tiny_input_file<'a, P>() -> Result<()>
+where
+ P: MetadataReader<'a>,
+{
+ let mut td = TestDir::new()?;
+
+ let input = td.mk_path("meta.bin");
+ file_utils::create_sized_file(&input, 1024)?;
+
+ let wrapper = build_args_fn(P::arg_type())?;
+ wrapper(&mut td, input.as_ref(), &|args: &[&OsStr]| {
+ run_fail(P::cmd(args))?;
+ Ok(())
+ })
+}
+
+#[macro_export]
+macro_rules! test_tiny_input_file {
+ ($program: ident) => {
+ #[test]
+ fn tiny_input_file() -> Result<()> {
+ test_tiny_input_file::<$program>()
+ }
+ };
+}
+
pub fn test_help_message_for_tiny_input_file<'a, P>() -> Result<()>
where
P: MetadataReader<'a>,
diff --git a/tests/era_dump.rs b/tests/era_dump.rs
new file mode 100644
index 0000000..8e71108
--- /dev/null
+++ b/tests/era_dump.rs
@@ -0,0 +1,123 @@
+use anyhow::Result;
+use std::fs::OpenOptions;
+use std::io::Write;
+
+mod common;
+
+use common::common_args::*;
+use common::era::*;
+use common::fixture::*;
+use common::input_arg::*;
+use common::process::*;
+use common::program::*;
+use common::target::*;
+use common::test_dir::*;
+
+//------------------------------------------
+
+const USAGE: &str = "era_dump 0.9.0
+Dump the era metadata to stdout in XML format
+
+USAGE:
+ era_dump [FLAGS] [OPTIONS]
+
+FLAGS:
+ --logical Fold any unprocessed write sets into the final era array
+ -r, --repair Repair the metadata whilst dumping it
+ -h, --help Prints help information
+ -V, --version Prints version information
+
+OPTIONS:
+ -o, --output Specify the output file rather than stdout
+
+ARGS:
+ Specify the input device to dump";
+
+//------------------------------------------
+
+struct EraDump;
+
+impl<'a> Program<'a> for EraDump {
+ fn name() -> &'a str {
+ "era_dump"
+ }
+
+ fn cmd(args: I) -> Command
+ where
+ I: IntoIterator,
+ I::Item: Into,
+ {
+ era_dump_cmd(args)
+ }
+
+ fn usage() -> &'a str {
+ USAGE
+ }
+
+ fn arg_type() -> ArgType {
+ ArgType::InputArg
+ }
+
+ fn bad_option_hint(option: &str) -> String {
+ msg::bad_option_hint(option)
+ }
+}
+
+impl<'a> InputProgram<'a> for EraDump {
+ fn mk_valid_input(td: &mut TestDir) -> Result {
+ mk_valid_md(td)
+ }
+
+ fn file_not_found() -> &'a str {
+ msg::FILE_NOT_FOUND
+ }
+
+ fn missing_input_arg() -> &'a str {
+ msg::MISSING_INPUT_ARG
+ }
+
+ fn corrupted_input() -> &'a str {
+ msg::BAD_SUPERBLOCK
+ }
+}
+
+impl<'a> MetadataReader<'a> for EraDump {}
+
+//------------------------------------------
+
+test_accepts_help!(EraDump);
+test_accepts_version!(EraDump);
+test_rejects_bad_option!(EraDump);
+
+test_missing_input_arg!(EraDump);
+test_input_file_not_found!(EraDump);
+test_input_cannot_be_a_directory!(EraDump);
+test_unreadable_input_file!(EraDump);
+test_tiny_input_file!(EraDump);
+
+//------------------------------------------
+
+// TODO: share with thin_dump
+#[test]
+fn dump_restore_cycle() -> Result<()> {
+ let mut td = TestDir::new()?;
+ let md = mk_valid_md(&mut td)?;
+ let output = run_ok_raw(era_dump_cmd(args![&md]))?;
+
+ let xml = td.mk_path("meta.xml");
+ let mut file = OpenOptions::new()
+ .read(false)
+ .write(true)
+ .create(true)
+ .open(&xml)?;
+ file.write_all(&output.stdout[0..])?;
+ drop(file);
+
+ let md2 = mk_zeroed_md(&mut td)?;
+ run_ok(era_restore_cmd(args!["-i", &xml, "-o", &md2]))?;
+
+ let output2 = run_ok_raw(era_dump_cmd(args![&md2]))?;
+ assert_eq!(output.stdout, output2.stdout);
+
+ Ok(())
+}