Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
179d435
Fix oracle storage failure
mgaffigan Sep 19, 2026
e144295
Restore some of disabled *Tests
mgaffigan Sep 19, 2026
58368f7
Re-add EDISerializerTests using new fixtures
mgaffigan Sep 19, 2026
93e73a6
Re-add NCPDP Tests, expand to include D.0 response, add bijection
mgaffigan Sep 19, 2026
c1ca290
Re-add DICOM tests, thanks Saga
mgaffigan Sep 19, 2026
af980d5
Drop dead test entrypoints (junit reigns)
mgaffigan Sep 19, 2026
a6c813c
Restore DocumentSerailizerTests
mgaffigan Sep 19, 2026
67ad0d3
Re-add MigrationUtilTest assuming current behavior is correct
mgaffigan Sep 19, 2026
5119040
Translate FilterTransformerTests to fixtures
mgaffigan Sep 20, 2026
b9eee24
Translate testOutboundSerializationFailure to fixture test
mgaffigan Sep 20, 2026
580acc5
Fix test run outside of container
mgaffigan Sep 20, 2026
05a579d
Translate ChannelTests message storage settings to fixtures
mgaffigan Sep 20, 2026
0c5d85d
Translated DestinationChainTests to fixtures
mgaffigan Sep 20, 2026
0b1d461
Translate response tests to fixtures
mgaffigan Sep 20, 2026
cc90f18
Translate testAfterSend to fixture test
mgaffigan Sep 21, 2026
e304e30
Translate metadata tests to fixtures
mgaffigan Sep 21, 2026
842f92f
Translate testEncryption to ci
mgaffigan Sep 21, 2026
484d9cb
Add atomic set configuration map entry endpoint
mgaffigan Sep 21, 2026
3bb6ea9
Translate QueueTests and others to ci and unit tests
mgaffigan Sep 21, 2026
de52d22
Translate testInsertMessageAttachment to fixture test
mgaffigan Sep 21, 2026
5c02198
Translate testDeleteMessage to ci test
mgaffigan Sep 21, 2026
b9ad245
Fix statistics errors caused by channel ID scoping
mgaffigan Sep 21, 2026
483aa6d
Translate StatisticsTests to ci test
mgaffigan Sep 21, 2026
896dd6f
Fix 500 after metadata schema changes
mgaffigan Sep 21, 2026
9e052d8
Ignore precision on metadata ci tests
mgaffigan Sep 21, 2026
06a6488
Add comment and warning for MySQL repeatable read
mgaffigan Sep 21, 2026
fbfa093
Add an unrecognised message type to the strict-serialization fixture
pacmano1 Sep 22, 2026
7fa7e89
Cover strict validation in the strict-serialization fixture
pacmano1 Sep 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ configure-from-env text eol=lf

# Binary files are left untouched
*.jar binary
*.dcm binary

# NCPDP fixtures delimit with control characters (0x1C/0x1D/0x1E), not line breaks
/server/tests/test-ncpdp-*-input.txt binary
31 changes: 28 additions & 3 deletions ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,39 @@ the payload sent to the channel. The other files are optional assertions:
| `source_sourcemap.yml` | Source map supplied with `source` |
| `source_metadata.yml` | Selected source message metadata |
| `source_status` | Source status |
| `source_raw` | Raw source payload as stored |
| `source_response` | Source response payload |
| `source_transformed` | Transformed source payload |
| `source_encoded` | Encoded source payload |
| `source_processing_error` | Processing error recorded against the source |
| `destNN` | Sent payload for destination `NN` |
| `destNN_transformed` | Transformed payload for destination `NN` |
| `destNN_response` | Response payload from destination `NN` |
| `destNN_response` | Response payload from destination `NN`, before its response transformer |
| `destNN_processed_response` | Response payload for destination `NN` after its response transformer |
| `destNN_processing_error` | Processing error recorded against destination `NN` |
| `destNN_metadata.yml` | Selected metadata for destination `NN` |
| `destNN_status` | Status for destination `NN` |
| `attachmentNN` | Content of attachment `NN` |
| `attachmentNN_type` | MIME type of attachment `NN` |

`NN` is the destination connector's metadata ID: `dest01` is the first
destination, `dest02` the second, and so on. Metadata files are YAML mappings; list
only the keys that matter to the test. Content assertions are byte-for-byte, except
that `((ANY))` matches variable content such as generated IDs or timestamps.
only the keys that matter to the test. A key whose value is `((NONE))` asserts that
nothing is stored under it, which is how a custom metadata column with no value is
asserted. A TIMESTAMP custom metadata column is compared as its UTC instant, so write
it as `2010-01-02T13:01:02Z`. Content assertions are byte-for-byte, except
that `((ANY))` matches variable content such as generated IDs or timestamps. A content
assertion file whose entire contents are `((NONE))` asserts the opposite: that the server
stored no such content at all, which is not the same as storing an empty string.

For an attachment, `NN` is a position rather than an ID: `attachment01` is the attachment
whose `${ATTACH:id}` token appears first in the source raw content, `attachment02` the next,
and any attachment the message does not reference comes after those, ordered by ID. The
server's own list is ordered by ID, which is a generated UUID, so it is not something a
fixture can count along. An `attachmentNN` file holds raw bytes and is compared byte for
byte, so it can hold an image or any other binary attachment, and `((NONE))` in it asserts
that there is no attachment in that position - which is also how a fixture pins down how
many attachments there are.

A fixture case runs in every configuration by default. To limit it, add a
`configurations` file at the case root with one configuration name per line:
Expand Down Expand Up @@ -87,6 +108,10 @@ Put hand-written JUnit 5 tests in
the fixture tests and are appropriate for multi-step workflows, computed
expectations, or assertions that do not fit the fixture files.

A Java test's channels go in `smoketest/src/test/resources/channels/`, not under
`ci/tests/`, which is the fixture generator's tree; `Harness.deploy` loads either from
the classpath.

## Run Locally

Run every configuration:
Expand Down
2 changes: 1 addition & 1 deletion ci/configurations/alpine-temurin21-mysql.compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ services:
condition: service_healthy
environment:
DATABASE: mysql
DATABASE_URL: jdbc:mysql://db:3306/mirthdb
DATABASE_URL: jdbc:mysql://db:3306/mirthdb?sessionVariables=transaction_isolation='READ-COMMITTED'
DATABASE_USERNAME: mirthdb
DATABASE_PASSWORD: mirthdb
DATABASE_MAX_CONNECTIONS: 20
Expand Down
7 changes: 7 additions & 0 deletions ci/tests/101-raw-no-op/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# 101-raw-no-op

A channel that does nothing: the RAW data type at both ends, no filter or transformer elements,
Channel Reader to a Channel Writer templated on `${message.encodedData}`.

With no filter or transformer the engine skips serialization altogether and the encoded content is
the raw content, so `dest01` asserts the payload reaches the destination unchanged.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello world!
8 changes: 8 additions & 0 deletions ci/tests/110-hl7-no-op/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 110-hl7-no-op

The same no-op channel as 101 with the HL7 v2 data type at both ends, responding with
`Auto-generate (Destinations completed)`.

- `dest01_metadata.yml` - the custom metadata columns the HL7 serializer fills in from MSH-4 and
MSH-9 on its own, with no transformer having run.
- `source_response` - the generated ACK, echoing the inbound MSH fields and MSA-2.
13 changes: 13 additions & 0 deletions ci/tests/120-filter-transformer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# 120-filter-transformer

Filter and transformer outcomes, on the RAW data type so that the transformed and encoded content
are exactly what the script left in `msg`.

- `01-source-filter` - a JavaScript rule rejecting messages containing `REJECT`. An accepted
message is TRANSFORMED and reaches `dest01`; a rejected one is FILTERED, and its transformed
content is stored all the same, because the filter runs after the content is handed to the script.
- `02-source-transformer` - a JavaScript step prefixing the message. The transformed content is the
script's output, and RAW encodes to it unchanged, so the destination receives the same thing.
- `03-transformer-error` - a step that throws, giving ERROR.

The case of no filter and no transformer at all is 101 and 110.
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
<channel version="4.5.2">
<id>8f1d2c40-1a11-4a1e-9f9b-2c0a5a4e1001</id>
<nextMetaDataId>2</nextMetaDataId>
<name>filter-transformer-source-filter</name>
<description></description>
<revision>1</revision>
<sourceConnector version="4.5.2">
<metaDataId>0</metaDataId>
<name>sourceConnector</name>
<properties class="com.mirth.connect.connectors.vm.VmReceiverProperties" version="4.5.2">
<pluginProperties/>
<sourceConnectorProperties version="4.5.2">
<responseVariable>None</responseVariable>
<respondAfterProcessing>true</respondAfterProcessing>
<processBatch>false</processBatch>
<firstResponse>false</firstResponse>
<processingThreads>1</processingThreads>
<resourceIds class="linked-hash-map">
<entry>
<string>Default Resource</string>
<string>[Default Resource]</string>
</entry>
</resourceIds>
<queueBufferSize>1000</queueBufferSize>
</sourceConnectorProperties>
</properties>
<transformer version="4.5.2">
<elements/>
<inboundDataType>RAW</inboundDataType>
<outboundDataType>RAW</outboundDataType>
<inboundProperties class="com.mirth.connect.plugins.datatypes.raw.RawDataTypeProperties" version="4.5.2">
<batchProperties class="com.mirth.connect.plugins.datatypes.raw.RawBatchProperties" version="4.5.2">
<splitType>JavaScript</splitType>
<batchScript></batchScript>
</batchProperties>
</inboundProperties>
<outboundProperties class="com.mirth.connect.plugins.datatypes.raw.RawDataTypeProperties" version="4.5.2">
<batchProperties class="com.mirth.connect.plugins.datatypes.raw.RawBatchProperties" version="4.5.2">
<splitType>JavaScript</splitType>
<batchScript></batchScript>
</batchProperties>
</outboundProperties>
</transformer>
<filter version="4.5.2">
<elements>
<com.mirth.connect.plugins.javascriptrule.JavaScriptRule version="4.5.2">
<name>Reject flagged messages</name>
<sequenceNumber>0</sequenceNumber>
<enabled>true</enabled>
<operator>NONE</operator>
<script>return msg.indexOf('REJECT') &lt; 0;</script>
</com.mirth.connect.plugins.javascriptrule.JavaScriptRule>
</elements>
</filter>
<transportName>Channel Reader</transportName>
<mode>SOURCE</mode>
<enabled>true</enabled>
<waitForPrevious>true</waitForPrevious>
</sourceConnector>
<destinationConnectors>
<connector version="4.5.2">
<metaDataId>1</metaDataId>
<name>Destination 1</name>
<properties class="com.mirth.connect.connectors.vm.VmDispatcherProperties" version="4.5.2">
<pluginProperties/>
<destinationConnectorProperties version="4.5.2">
<queueEnabled>false</queueEnabled>
<sendFirst>false</sendFirst>
<retryIntervalMillis>10000</retryIntervalMillis>
<regenerateTemplate>false</regenerateTemplate>
<retryCount>0</retryCount>
<rotate>false</rotate>
<includeFilterTransformer>false</includeFilterTransformer>
<threadCount>1</threadCount>
<threadAssignmentVariable></threadAssignmentVariable>
<validateResponse>false</validateResponse>
<resourceIds class="linked-hash-map">
<entry>
<string>Default Resource</string>
<string>[Default Resource]</string>
</entry>
</resourceIds>
<queueBufferSize>1000</queueBufferSize>
<reattachAttachments>true</reattachAttachments>
</destinationConnectorProperties>
<channelId>none</channelId>
<channelTemplate>${message.encodedData}</channelTemplate>
<mapVariables/>
</properties>
<transformer version="4.5.2">
<elements/>
<inboundDataType>RAW</inboundDataType>
<outboundDataType>RAW</outboundDataType>
<inboundProperties class="com.mirth.connect.plugins.datatypes.raw.RawDataTypeProperties" version="4.5.2">
<batchProperties class="com.mirth.connect.plugins.datatypes.raw.RawBatchProperties" version="4.5.2">
<splitType>JavaScript</splitType>
<batchScript></batchScript>
</batchProperties>
</inboundProperties>
<outboundProperties class="com.mirth.connect.plugins.datatypes.raw.RawDataTypeProperties" version="4.5.2">
<batchProperties class="com.mirth.connect.plugins.datatypes.raw.RawBatchProperties" version="4.5.2">
<splitType>JavaScript</splitType>
<batchScript></batchScript>
</batchProperties>
</outboundProperties>
</transformer>
<responseTransformer version="4.5.2">
<elements/>
<inboundDataType>RAW</inboundDataType>
<outboundDataType>RAW</outboundDataType>
<inboundProperties class="com.mirth.connect.plugins.datatypes.raw.RawDataTypeProperties" version="4.5.2">
<batchProperties class="com.mirth.connect.plugins.datatypes.raw.RawBatchProperties" version="4.5.2">
<splitType>JavaScript</splitType>
<batchScript></batchScript>
</batchProperties>
</inboundProperties>
<outboundProperties class="com.mirth.connect.plugins.datatypes.raw.RawDataTypeProperties" version="4.5.2">
<batchProperties class="com.mirth.connect.plugins.datatypes.raw.RawBatchProperties" version="4.5.2">
<splitType>JavaScript</splitType>
<batchScript></batchScript>
</batchProperties>
</outboundProperties>
</responseTransformer>
<filter version="4.5.2">
<elements/>
</filter>
<transportName>Channel Writer</transportName>
<mode>DESTINATION</mode>
<enabled>true</enabled>
<waitForPrevious>true</waitForPrevious>
</connector>
</destinationConnectors>
<preprocessingScript>// Modify the message variable below to pre process data
return message;</preprocessingScript>
<postprocessingScript>// This script executes once after a message has been processed
// Responses returned from here will be stored as &quot;Postprocessor&quot; in the response map
return;</postprocessingScript>
<deployScript>// This script executes once when the channel is deployed
// You only have access to the globalMap and globalChannelMap here to persist data
return;</deployScript>
<undeployScript>// This script executes once when the channel is undeployed
// You only have access to the globalMap and globalChannelMap here to persist data
return;</undeployScript>
<properties version="4.5.2">
<clearGlobalChannelMap>true</clearGlobalChannelMap>
<messageStorageMode>DEVELOPMENT</messageStorageMode>
<encryptData>false</encryptData>
<encryptAttachments>false</encryptAttachments>
<encryptCustomMetaData>false</encryptCustomMetaData>
<removeContentOnCompletion>false</removeContentOnCompletion>
<removeOnlyFilteredOnCompletion>false</removeOnlyFilteredOnCompletion>
<removeAttachmentsOnCompletion>false</removeAttachmentsOnCompletion>
<initialState>STARTED</initialState>
<storeAttachments>true</storeAttachments>
<metaDataColumns>
<metaDataColumn>
<name>SOURCE</name>
<type>STRING</type>
<mappingName>mirth_source</mappingName>
</metaDataColumn>
<metaDataColumn>
<name>TYPE</name>
<type>STRING</type>
<mappingName>mirth_type</mappingName>
</metaDataColumn>
</metaDataColumns>
<attachmentProperties version="4.5.2">
<type>None</type>
<properties/>
</attachmentProperties>
<resourceIds class="linked-hash-map">
<entry>
<string>Default Resource</string>
<string>[Default Resource]</string>
</entry>
</resourceIds>
</properties>
<exportData>
<metadata>
<enabled>true</enabled>
<lastModified>
<time>1775955953073</time>
<timezone>America/Chicago</timezone>
</lastModified>
<pruningSettings>
<archiveEnabled>true</archiveEnabled>
<pruneErroredMessages>false</pruneErroredMessages>
</pruningSettings>
<userId>1</userId>
</metadata>
</exportData>
</channel>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
((ANY))KEEP this one((ANY))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SENT
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
KEEP this one
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TRANSFORMED
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
KEEP this one
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
REJECT this one
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FILTERED
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
REJECT this one
Loading
Loading