From f43e2c6c9f15b325fdda7df51d37da629a73b093 Mon Sep 17 00:00:00 2001 From: Ferris Tien <9417900+ACMoretxj@users.noreply.github.com> Date: Tue, 2 Feb 2021 16:57:57 +0800 Subject: [PATCH 1/2] Added FHIR parser functional tests. (#199) * 2021.02.01 added fhir parser functional tests, updated related test resources * 2021.02.01 added fhir-net-api dependency in test project * 2021.02.01 added expect-fail-case for fhir parser to check basic functionality --- .../Hl7v2/Resource/_Observation.liquid | 36 --------------- ...ir.Liquid.Converter.FunctionalTests.csproj | 1 + .../RuleBasedTests.cs | 46 +++++++++++++++++++ .../ORU_R01/ORU-R01-RMGEAD-expected.json | 10 ---- 4 files changed, 47 insertions(+), 46 deletions(-) diff --git a/data/Templates/Hl7v2/Resource/_Observation.liquid b/data/Templates/Hl7v2/Resource/_Observation.liquid index 7f7ce7106..b0aa8d04c 100644 --- a/data/Templates/Hl7v2/Resource/_Observation.liquid +++ b/data/Templates/Hl7v2/Resource/_Observation.liquid @@ -58,24 +58,6 @@ {% endif -%}{% endif -%} }, }, - "valueRange": - { - {% if OBX.2.Value == "SN" -%} - {% include 'DataType/SNRange' SN: OBX.5 -%} - {% endif -%} - "low": - { - {% if OBX.2.Value == "SN" and OBX.5.3.Value == "-" -%} - {% include 'DataType/CWEQuantity' CWE: OBX.6 -%} - {% endif -%} - }, - "high": - { - {% if OBX.2.Value == "SN" and OBX.5.3.Value == "-" -%} - {% include 'DataType/CWEQuantity' CWE: OBX.6 -%} - {% endif -%} - }, - }, "interpretation": [ { {% include 'DataType/CWECodeableConcept' mapping: 'CodeSystem/InterpretationCode', CWE: OBX.8 -%} }, @@ -185,24 +167,6 @@ {% endif -%}{% endif -%} }, }, - "valueRange": - { - {% if OBX.2.Value == "SN" -%} - {% include 'DataType/SNRange' SN: OBX.5 -%} - {% endif -%} - "low": - { - {% if OBX.2.Value == "SN" and OBX.5.3.Value == "-" -%} - {% include 'DataType/CWEQuantity' CWE: OBX.6 -%} - {% endif -%} - }, - "high": - { - {% if OBX.2.Value == "SN" and OBX.5.3.Value == "-" -%} - {% include 'DataType/CWEQuantity' CWE: OBX.6 -%} - {% endif -%} - }, - }, "referenceRange": [ { diff --git a/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests.csproj b/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests.csproj index 70947d1b6..2e447410b 100644 --- a/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests.csproj +++ b/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/RuleBasedTests.cs b/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/RuleBasedTests.cs index eea7c60e5..c051848f3 100644 --- a/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/RuleBasedTests.cs +++ b/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/RuleBasedTests.cs @@ -12,6 +12,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Hl7.Fhir.Serialization; using Microsoft.Health.Fhir.Liquid.Converter.Hl7v2; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -26,6 +27,7 @@ public class RuleBasedTests private static readonly string _hl7DataFolder = Path.Combine(Constants.SampleDataDirectory, "Hl7v2"); private static readonly Hl7v2TemplateProvider _hl7TemplateProvider = new Hl7v2TemplateProvider(_hl7TemplateFolder); + private static readonly FhirJsonParser _fhirParser = new FhirJsonParser(); private static readonly int _maxRevealDepth = 1 << 7; @@ -140,6 +142,50 @@ public async Task CheckPassOfficialValidator(string templateName, string sampleP Directory.Delete(resultFolder, true); } + [Fact] + public async Task CheckParserFunctionality() + { + var jsonResult = await Task.FromResult(@"{ + ""resourceType"": ""Observation"", + ""id"": ""209c8566-dafa-22b6-31f6-e4c00e649c61"", + ""valueQuantity"": { + ""code"": ""mg/dl"" + }, + ""valueRange"": { + ""low"": { + ""value"": ""182"" + } + } + }"); + try + { + var bundle = _fhirParser.Parse(jsonResult); + Assert.Null(bundle); + } + catch (FormatException fe) + { + Assert.NotNull(fe); + } + } + + [Theory] + [MemberData(nameof(GetHL7V2Cases))] + [MemberData(nameof(GetCCDACases))] + public async Task CheckPassFhirParser(string templateName, string samplePath) + { + var result = await ConvertData(templateName, samplePath); + var jsonResult = JsonConvert.SerializeObject(result, Formatting.Indented); + try + { + var bundle = _fhirParser.Parse(jsonResult); + Assert.NotNull(bundle); + } + catch (FormatException fe) + { + Assert.Null(fe); + } + } + private async Task ConvertData(string templateName, string samplePath) => JObject.Parse(new Hl7v2Processor() .Convert(await File.ReadAllTextAsync(samplePath, Encoding.UTF8), templateName, _hl7TemplateProvider)); diff --git a/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/TestData/Expected/Hl7v2/ORU_R01/ORU-R01-RMGEAD-expected.json b/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/TestData/Expected/Hl7v2/ORU_R01/ORU-R01-RMGEAD-expected.json index 96993b295..54ab18484 100644 --- a/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/TestData/Expected/Hl7v2/ORU_R01/ORU-R01-RMGEAD-expected.json +++ b/src/Microsoft.Health.Fhir.Liquid.Converter.FunctionalTests/TestData/Expected/Hl7v2/ORU_R01/ORU-R01-RMGEAD-expected.json @@ -192,11 +192,6 @@ "valueQuantity": { "code": "mg/dl" }, - "valueRange": { - "low": { - "value": "182" - } - }, "interpretation": [ { "coding": [ @@ -223,11 +218,6 @@ "valueQuantity": { "code": "mg/dl" }, - "valueRange": { - "low": { - "value": "182" - } - }, "referenceRange": [ { "text": "70_105" From 695159d8145d1c3f4228fca808528cd23661bc69 Mon Sep 17 00:00:00 2001 From: sowu880 <57981365+sowu880@users.noreply.github.com> Date: Wed, 3 Feb 2021 23:17:45 +0800 Subject: [PATCH 2/2] push layers in order (#202) --- .../OCIArtifactFunctionalTests.cs | 2 +- .../Client/OrasClientTests.cs | 8 ++++---- .../Client/IOrasClient.cs | 3 ++- .../Client/OrasClient.cs | 14 +++++++++----- ...Microsoft.Health.Fhir.TemplateManagement.csproj | 2 +- .../OCIFileManager.cs | 5 ++++- 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.Health.Fhir.TemplateManagement.FunctionalTests/OCIArtifactFunctionalTests.cs b/src/Microsoft.Health.Fhir.TemplateManagement.FunctionalTests/OCIArtifactFunctionalTests.cs index 4012c41a1..6a9211c62 100644 --- a/src/Microsoft.Health.Fhir.TemplateManagement.FunctionalTests/OCIArtifactFunctionalTests.cs +++ b/src/Microsoft.Health.Fhir.TemplateManagement.FunctionalTests/OCIArtifactFunctionalTests.cs @@ -323,7 +323,7 @@ public async Task GivenAnEmptyInputFolder_WhenPushOCIFiles_OneBaseLayerWillBePus string testPushNewBaseLayerImageReference = _containerRegistryServer + "/templatetest:empty"; var pushManager = new OCIFileManager(testPushNewBaseLayerImageReference, emptyFolder); pushManager.PackOCIImage(); - await Assert.ThrowsAsync(() => pushManager.PushOCIImageAsync()); + await Assert.ThrowsAsync(() => pushManager.PushOCIImageAsync()); ClearFolder(emptyFolder); } diff --git a/src/Microsoft.Health.Fhir.TemplateManagement.UnitTests/Client/OrasClientTests.cs b/src/Microsoft.Health.Fhir.TemplateManagement.UnitTests/Client/OrasClientTests.cs index 65f931025..bb62a897d 100644 --- a/src/Microsoft.Health.Fhir.TemplateManagement.UnitTests/Client/OrasClientTests.cs +++ b/src/Microsoft.Health.Fhir.TemplateManagement.UnitTests/Client/OrasClientTests.cs @@ -108,7 +108,7 @@ public async Task GivenAnInValidImageReference_WhenPullAndPushImageUseOras_Excep File.Copy(_userLayerTemplatePath, "TestData/PushTest/userLayer.tar.gz", true); string imageReference = _containerRegistryServer + reference; OrasClient orasClient = new OrasClient(imageReference); - await Assert.ThrowsAsync(() => orasClient.PushImageAsync("TestData/PushTest")); + await Assert.ThrowsAsync(() => orasClient.PushImageAsync("TestData/PushTest", new List { "baseLayer.tar.gz", "userLayer.tar.gz" })); await Assert.ThrowsAsync(() => orasClient.PullImageAsync("TestData/PushTest")); ClearFolder("TestData/PushTest"); } @@ -129,7 +129,7 @@ public async Task GivenValidInputFolder_WhenPushUseOras_ImageWillBePushedAsync(s string testImageReference = _containerRegistryServer + "/testFolder"; OrasClient testOrasClient = new OrasClient(imageReference); - var ex = await Record.ExceptionAsync(async () => await orasClient.PushImageAsync(outputFolder)); + var ex = await Record.ExceptionAsync(async () => await orasClient.PushImageAsync(outputFolder, new List { "TestData/TarGzFiles/baseLayer.tar.gz" })); Assert.Null(ex); ClearFolder(outputFolder); } @@ -147,7 +147,7 @@ public async Task GivenAValidImageReference_WhenPushImageUseOras_ImageWillBePush File.Copy(_userLayerTemplatePath, "TestData/PushTest/userLayer.tar.gz", true); string imageReference = _containerRegistryServer + "/testimage:test"; OrasClient orasClient = new OrasClient(imageReference); - var ex = await Record.ExceptionAsync(() => orasClient.PushImageAsync("TestData/PushTest")); + var ex = await Record.ExceptionAsync(() => orasClient.PushImageAsync("TestData/PushTest", new List { "baseLayer.tar.gz", "userLayer.tar.gz" })); Assert.Null(ex); ClearFolder("TestData/PushTest"); } @@ -163,7 +163,7 @@ public async Task GivenAValidImageReference_WhenPushEmptyFolderUseOras_ImageWill Directory.CreateDirectory("TestData/Empty"); string imageReference = _containerRegistryServer + "/testimage:test"; OrasClient orasClient = new OrasClient(imageReference); - await Assert.ThrowsAsync(async () => await orasClient.PushImageAsync("TestData/Empty")); + await Assert.ThrowsAsync(async () => await orasClient.PushImageAsync("TestData/Empty", new List { })); } [Fact] diff --git a/src/Microsoft.Health.Fhir.TemplateManagement/Client/IOrasClient.cs b/src/Microsoft.Health.Fhir.TemplateManagement/Client/IOrasClient.cs index d5d3f741c..7e56fa92b 100644 --- a/src/Microsoft.Health.Fhir.TemplateManagement/Client/IOrasClient.cs +++ b/src/Microsoft.Health.Fhir.TemplateManagement/Client/IOrasClient.cs @@ -3,6 +3,7 @@ // Licensed under the MIT License (MIT). See LICENSE in the repo root for license information. // ------------------------------------------------------------------------------------------------- +using System.Collections.Generic; using System.Threading.Tasks; namespace Microsoft.Health.Fhir.TemplateManagement.Client @@ -11,6 +12,6 @@ public interface IOrasClient { Task PullImageAsync(string outputFolder); - Task PushImageAsync(string inputFolder); + Task PushImageAsync(string inputFolder, List filePathList); } } diff --git a/src/Microsoft.Health.Fhir.TemplateManagement/Client/OrasClient.cs b/src/Microsoft.Health.Fhir.TemplateManagement/Client/OrasClient.cs index a6418f1a8..efc6f3cfa 100644 --- a/src/Microsoft.Health.Fhir.TemplateManagement/Client/OrasClient.cs +++ b/src/Microsoft.Health.Fhir.TemplateManagement/Client/OrasClient.cs @@ -4,6 +4,7 @@ // ------------------------------------------------------------------------------------------------- using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading.Tasks; @@ -30,18 +31,21 @@ public async Task PullImageAsync(string outputFolder) await OrasExecutionAsync(command, Directory.GetCurrentDirectory()); } - public async Task PushImageAsync(string inputFolder) + public async Task PushImageAsync(string inputFolder, List filePathList) { string argument = string.Empty; string command = $"push \"{_imageReference}\""; - var filePathToPush = Directory.EnumerateFiles(inputFolder, "*.tar.gz", SearchOption.AllDirectories); - // In order to remove image's directory prefix. (e.g. "layers/layer1.tar.gz" --> "layer1.tar.gz" // Change oras working folder to inputFolder - foreach (var filePath in filePathToPush) + foreach (var filePath in filePathList) { - argument += $" \"{Path.GetRelativePath(inputFolder, filePath)}\""; + if (!File.Exists(Path.Combine(inputFolder, filePath))) + { + throw new OverlayException(TemplateManagementErrorCode.ImageLayersNotFound, "Image layer not found"); + } + + argument += $" \"{filePath}\""; } if (string.IsNullOrEmpty(argument)) diff --git a/src/Microsoft.Health.Fhir.TemplateManagement/Microsoft.Health.Fhir.TemplateManagement.csproj b/src/Microsoft.Health.Fhir.TemplateManagement/Microsoft.Health.Fhir.TemplateManagement.csproj index 6a38e53cb..9caa58307 100644 --- a/src/Microsoft.Health.Fhir.TemplateManagement/Microsoft.Health.Fhir.TemplateManagement.csproj +++ b/src/Microsoft.Health.Fhir.TemplateManagement/Microsoft.Health.Fhir.TemplateManagement.csproj @@ -37,7 +37,7 @@ PreserveNewest - + diff --git a/src/Microsoft.Health.Fhir.TemplateManagement/OCIFileManager.cs b/src/Microsoft.Health.Fhir.TemplateManagement/OCIFileManager.cs index 81eeb000b..d3aa23753 100644 --- a/src/Microsoft.Health.Fhir.TemplateManagement/OCIFileManager.cs +++ b/src/Microsoft.Health.Fhir.TemplateManagement/OCIFileManager.cs @@ -72,7 +72,10 @@ public void PackOCIImage(bool ignoreBaseLayers = false) public async Task PushOCIImageAsync() { - await _orasClient.PushImageAsync(_overlayFS.WorkingImageLayerFolder); + var rawLayers = _overlayFS.ReadImageLayers(); + var fileLayers = _overlayOperator.ExtractOCIFileLayers(rawLayers); + var sortedLayers = _overlayOperator.SortOCIFileLayersBySequenceNumber(fileLayers); + await _orasClient.PushImageAsync(_overlayFS.WorkingImageLayerFolder, sortedLayers.Select(layer => layer.FileName).ToList()); } private OCIFileLayer GenerateBaseFileLayer(List baseArtifactLayers)