Files
JIMRI/java/test/jmri/jmrit/MemoryContentsTest.java
T
2026-06-17 14:00:51 +02:00

521 lines
18 KiB
Java

package jmri.jmrit;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import jmri.util.FileUtil;
import jmri.util.JUnitAppender;
import org.junit.jupiter.api.*;
/**
* Test simple functioning of MemoryContents
*
* @author Bob Jacobsen Copyright (C) 2008
* @suthor B. Milhaupt Copyright (C) 2014
*/
public class MemoryContentsTest {
@Test
public void testReadNormalFile() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadNormalFile");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile.hex";
assertDoesNotThrow( () ->
m.readHex(new File(fileName)));
assertEquals(864, m.nextContent(500), "content restarts");
}
@Test
public void testReadSegmentsTestFile() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadSegmentsTestFile");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_extSegRecords.hex";
assertDoesNotThrow( () ->
m.readHex(new File(fileName)));
verifyMemoryData(0x00000, 0x01, m);
verifyMemoryData(0x00001, 0x02, m);
verifyMemoryData(0x00002, -1, m);
verifyMemoryData(0x00003, -1, m);
verifyMemoryData(0x0FFFF, -1, m);
verifyMemoryData(0x10000, 0x03, m);
verifyMemoryData(0x10001, 0x04, m);
verifyMemoryData(0x10002, -1, m);
verifyMemoryData(0x10003, -1, m);
verifyMemoryData(0x1FFFF, -1, m);
verifyMemoryData(0x20000, 0x05, m);
verifyMemoryData(0x20001, 0x06, m);
verifyMemoryData(0x20002, -1, m);
verifyMemoryData(0x20003, -1, m);
verifyMemoryData(0x2FFFF, -1, m);
verifyMemoryData(0x30000, 0x07, m);
verifyMemoryData(0x30001, 0x08, m);
verifyMemoryData(0x30002, -1, m);
verifyMemoryData(0x30003, -1, m);
verifyMemoryData(0x3FFFF, -1, m);
verifyMemoryData(0x9FFFF, -1, m);
JUnitAppender.assertErrorMessage("Error in getLocation(0x9ffff): accessed uninitialized page 9");
verifyMemoryData(0xA0000, 0xa0, m);
verifyMemoryData(0xA0001, 0xa1, m);
verifyMemoryData(0xA0002, -1, m);
verifyMemoryData(0xA0003, -1, m);
}
@Test
public void testReadNormal24BitAddressFile() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadNormal24BitAddressFile");
String filename1 = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_24bit.hex";
assertDoesNotThrow( () ->
m.readHex(new File(filename1)));
verifyMemoryData(0x10000, 0x54, m);
verifyMemoryData(0x10001, 0x32, m);
verifyMemoryData(0x20001, 0xBE, m);
verifyMemoryData(0x20002, 0xEF, m);
// Write a copy of the MemoryContents to a new file
// File path for this file generated by the testcase is modeled after
// the temp file used in jmri.jmrix.rps.PackageFileTest.java
String tempDirectoryName = "temp";
if (!(new File(tempDirectoryName).isDirectory())) {
// create the temp directory if it does not exist
FileUtil.createDirectory(tempDirectoryName);
}
String filename = tempDirectoryName + File.separator + "MemoryContentsTestOutputFile.hex";
File memoryContentsTestWrite_24AddrFile = new File(filename);
if (memoryContentsTestWrite_24AddrFile.exists()) {
boolean deleted = assertDoesNotThrow( () -> memoryContentsTestWrite_24AddrFile.delete(),
"Exception while trying to delete the existing file "
+ filename + " before creating a new copy of the file.\n Exception reported: "
);
assertTrue(deleted);
// return;
}
m.setAddressFormat(MemoryContents.LoadOffsetFieldType.ADDRESSFIELDSIZE24BITS);
m.addKeyValueComment("Harrumph", "TRUE");
try (java.io.FileWriter writer = new java.io.FileWriter(memoryContentsTestWrite_24AddrFile)) {
m.writeHex(writer,
true, 16);
} catch (IOException e) {
fail("I/O exception attempting to write a .hex file ", e);
} catch (MemoryContents.MemoryFileAddressingFormatException e) {
fail("Memory Addressing format exception attempting to write .hex file", e);
}
// make sure the new file is in 24-bit address format
m.setAddressFormat(MemoryContents.LoadOffsetFieldType.ADDRESSFIELDSIZE24BITS);
MemoryContents n = new MemoryContents();
assertDoesNotThrow( () ->
n.readHex(new File(filename)));
// attempt to delete the file if debug logging is not enabled.
if (log.isDebugEnabled()) {
log.debug("Path to written hex file is: {}", filename);
} else {
assertTrue(memoryContentsTestWrite_24AddrFile.delete());
}
assertEquals(864, n.nextContent(500),
() -> "NextContent didn't reply as expected for nextContent(500) - "
+ "expected 864, got "
+ m.nextContent(500)
+ ".");
// Code here uses manual validity checks (the "if" statements) below
// instead of Assert.assertEquals because of unexplainable lack of
// failure in some forced failing cases.
verifyMemoryData(0x00, 0xa8, n);
verifyMemoryData(0x01, 0x29, n);
if (m.locationInUse(0x02)) {
verifyMemoryData(0x02, -1, n);
}
if (m.locationInUse(0x03)) {
verifyMemoryData(0x03, -1, n);
}
if (m.locationInUse(0x04)) {
verifyMemoryData(0x04, -1, n);
}
if (m.locationInUse(0x05)) {
verifyMemoryData(0x05, -1, n);
}
if (m.locationInUse(0x06)) {
verifyMemoryData(0x06, -1, n);
}
if (m.locationInUse(0x07)) {
verifyMemoryData(0x07, -1, n);
}
verifyMemoryData(0xA0, 0x0B, n);
verifyMemoryData(0xA1, 0x16, n);
verifyMemoryData(0x400E, 0x5c, n);
verifyMemoryData(0x400F, 0x09, n);
verifyMemoryData(0x4010, 0xFF, n);
verifyMemoryData(0x4011, 0x3F, n);
}
@Test
public void testReadFileCksumError() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileCksumError");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_cksumErr.hex";
MemoryContents.MemoryFileChecksumException e = assertThrowsExactly(MemoryContents.MemoryFileChecksumException.class,
() -> m.readHex(new File(fileName)),
"Checksum Exception was expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"Record checksum error in line 29 - computed checksum = 0x1f, expected checksum = 0x1e.");
}
@Test
public void testReadFileRecordTypeError() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileRecordTypeError");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_recordTypeError.hex";
MemoryContents.MemoryFileUnknownRecordType e = assertThrowsExactly(MemoryContents.MemoryFileUnknownRecordType.class,
() -> m.readHex(new File(fileName)),
"Record Type Exception was expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"Unknown RECTYP 0x3 was found in line 16. Aborting file read.");
}
@Test
public void testReadFileRecordLengthError() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileRecordLengthError");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_recordLenError.hex";
MemoryContents.MemoryFileRecordLengthException e = assertThrowsExactly(MemoryContents.MemoryFileRecordLengthException.class,
() -> m.readHex(new File(fileName)),
"Record Length Exception was expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"Data record line length is incorrect for inferred addressing type and for data count field in line 10");
if (!(m.extractValueOfKey("KeyName2").matches("ValueInfo99"))) {
fail("Expect to retrieve 'ValueInfo99' as value of key KeyName2, but got '"
+ m.extractValueOfKey("KeyName2")
+ "' instead.");
}
assertNull(m.extractValueOfKey("non-existent_Key"));
assertNull(m.extractValueOfKey("fictitiousKeyName"),
"Failed to return <null> for non-existant key name 'fictitiousKeyName'.");
}
@Test
public void testReadFileFileNotFound() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileFileNotFound");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_file_doesnt_exist.hex";
FileNotFoundException e = assertThrowsExactly(FileNotFoundException.class,
() -> m.readHex(new File(fileName)),
"File-not-found Exception was expected");
assertNotNull(e);
// make sure that key/value from previous test is gone now.
assertNull( m.extractValueOfKey(m.extractValueOfKey("KeyName2")),
"old key/value disappears");
assertEquals(-1, m.nextContent(500), "old data disappears");
}
@Test
public void testReadFileMalformedLine() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileMalformedLine");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_malformed_line.hex";
MemoryContents.MemoryFileRecordLengthException e = assertThrowsExactly(MemoryContents.MemoryFileRecordLengthException.class,
() -> m.readHex(new File(fileName)),
"Record Content Length exception expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"Data record line length is incorrect for inferred addressing type and for data count field in line 7");
}
@Test
public void testReadFileNoEOFRecordFile() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileNoEOFRecordFile");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_noEOFRecord.hex";
MemoryContents.MemoryFileNoEOFRecordException e = assertThrowsExactly(MemoryContents.MemoryFileNoEOFRecordException.class,
() -> m.readHex(new File(fileName)),
"No EOF Record exception expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"No EOF Record found in file - aborting.");
}
@Test
public void testReadFileNoContentFile() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileNoContentFile");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_no_data_records.dmf";
MemoryContents.MemoryFileNoDataRecordsException e = assertThrowsExactly(MemoryContents.MemoryFileNoDataRecordsException.class,
() -> m.readHex(new File(fileName)),
"'No records found' exception expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"No Data Records found in file - aborting.");
}
@Test
public void testReadFile16bitContentFile() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFile16bitContentFile");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_16bit.hex";
assertDoesNotThrow( () ->
m.readHex(new File(fileName)));
}
@Test
public void testReadFileRecordType02BadFile() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileRecordType02BadFile");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_RecType02bad.hex";
MemoryContents.MemoryFileAddressingRangeException e = assertThrowsExactly(MemoryContents.MemoryFileAddressingRangeException.class,
() -> m.readHex(new File(fileName)),
"'Addressing range' exception expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"Unsupported Extended Segment Address Record data value 0x1000 in line 3");
}
@Test
public void testReadFileRecordType02BadFile2() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileRecordType02BadFile2");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_RecType02bad_2.hex";
MemoryContents.MemoryFileAddressingRangeException e = assertThrowsExactly(MemoryContents.MemoryFileAddressingRangeException.class,
() -> m.readHex(new File(fileName)),
"'Addressing range' exception expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"Unsupported Extended Segment Address Record data value 0x1000 in line 2");
}
@Test
public void testReadFileHighSegments() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFileHighSegments");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_24bitHighSegs.hex";
assertDoesNotThrow( () -> m.readHex(new File(fileName)));
verifyMemoryData(0xFFFFFF, 0x7B, m);
if (m.locationInUse(0xFFFFFE)) {
verifyMemoryData(0xFFFFFE, -1, m);
}
if (m.locationInUse(0x0)) {
verifyMemoryData(0x0, -1, m);
}
verifyMemoryData(0xF000FF, 0xD0, m);
verifyMemoryData(0xFF0000, 0x9A, m);
verifyMemoryData(0xD000FF, 0x12, m);
verifyMemoryData(0xD00100, 0x34, m);
}
@Test
public void testReadFilePageCross() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFilePageCross");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_16bit_pagecross.hex";
MemoryContents.MemoryFileAddressingRangeException e = assertThrowsExactly(MemoryContents.MemoryFileAddressingRangeException.class,
() -> m.readHex(new File(fileName)),
"Address Range exception was expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"Data crosses boundary which could lead to mis-interpretation. Aborting read at line :02FFFF000102FD");
if (m.locationInUse(0x00FFFF)) {
verifyMemoryData(0x00FFFF, -1, m);
}
if (m.locationInUse(0x00FFFE)) {
verifyMemoryData(0x00FFFE, -1, m);
}
if (m.locationInUse(0x00FF00)) {
verifyMemoryData(0x00FF00, -1, m);
}
if (m.locationInUse(0x00FF01)) {
verifyMemoryData(0x00FF01, -1, m);
}
if (m.locationInUse(0x00FF02)) {
verifyMemoryData(0x00FF02, -1, m);
}
if (m.locationInUse(0x00FF03)) {
verifyMemoryData(0x00FF03, -1, m);
}
if (m.locationInUse(0x010000)) {
verifyMemoryData(0x010000, -1, m);
}
if (m.locationInUse(0x010001)) {
verifyMemoryData(0x010001, -1, m);
}
if (m.locationInUse(0x010002)) {
verifyMemoryData(0x010002, -1, m);
}
if (m.locationInUse(0x010003)) {
verifyMemoryData(0x010003, -1, m);
}
}
@Test
public void testReadFile24bitPageCross() {
MemoryContents m = new MemoryContents();
log.debug("Begin of testReadFile24bitPageCross");
String fileName = "java/test/jmri/jmrit/MemoryContentsTestFiles/TestFiles/MemoryContentsTestFile_24bit_pagecross.hex";
MemoryContents.MemoryFileAddressingRangeException e = assertThrowsExactly(MemoryContents.MemoryFileAddressingRangeException.class,
() -> m.readHex(new File(fileName)),
"Address Range exception was expected");
assertNotNull(e);
JUnitAppender.assertErrorMessage(
"Data crosses boundary which could lead to mis-interpretation. Aborting read at line :0201FFFF000709EF");
if (m.locationInUse(0x01FFFF)) {
verifyMemoryData(0x01FFFF, -1, m);
}
if (m.locationInUse(0x01FFFE)) {
verifyMemoryData(0x01FFFE, -1, m);
}
if (m.locationInUse(0x020000)) {
verifyMemoryData(0x020000, -1, m);
}
if (m.locationInUse(0x020001)) {
verifyMemoryData(0x020001, -1, m);
}
if (m.locationInUse(0x020002)) {
verifyMemoryData(0x020002, -1, m);
}
if (m.locationInUse(0x020003)) {
verifyMemoryData(0x020003, -1, m);
}
if (m.locationInUse(0x010000)) {
verifyMemoryData(0x010000, -1, m);
}
if (m.locationInUse(0x010001)) {
verifyMemoryData(0x010001, -1, m);
}
if (m.locationInUse(0x010002)) {
verifyMemoryData(0x010002, -1, m);
}
if (m.locationInUse(0x010003)) {
verifyMemoryData(0x010003, -1, m);
}
}
private void verifyMemoryData(int address, int expect, MemoryContents mc) {
int reported = mc.getLocation(address);
assertEquals(expect, reported,
() -> "Verify that address 0x" + Integer.toHexString(address)
+ " has correct value: expected 0x" + Integer.toHexString(expect)
+ ", got 0x" + Integer.toHexString(reported));
}
@BeforeEach
public void setUp() {
jmri.util.JUnitUtil.setUp();
}
@AfterEach
public void tearDown() {
jmri.util.JUnitUtil.tearDown();
}
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MemoryContentsTest.class);
}