From ef57a268a96ce141fefef9c762a2abb51c33ba32 Mon Sep 17 00:00:00 2001 From: Christiaan Knaap <2102470+cknaap@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:20:02 +0200 Subject: [PATCH] fix: #2802 - let SnapshotSource reuse self-generated snapshot --- .../Specification/Source/SnapshotSource.cs | 2 +- .../Snapshot/SnapshotSourceTest.cs | 59 ++++++++++++++----- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/Hl7.Fhir.Shims.Base/Specification/Source/SnapshotSource.cs b/src/Hl7.Fhir.Shims.Base/Specification/Source/SnapshotSource.cs index 7d8d30ac83..05c3a8aab9 100644 --- a/src/Hl7.Fhir.Shims.Base/Specification/Source/SnapshotSource.cs +++ b/src/Hl7.Fhir.Shims.Base/Specification/Source/SnapshotSource.cs @@ -96,7 +96,7 @@ private async Tasks.Task ensureSnapshot(Resource res) { if (res is StructureDefinition sd) { - if (!sd.HasSnapshot || Generator.Settings.ForceRegenerateSnapshots || !sd.Snapshot.IsCreatedBySnapshotGenerator()) + if (!sd.HasSnapshot || (Generator.Settings.ForceRegenerateSnapshots && !sd.Snapshot.IsCreatedBySnapshotGenerator())) { await Generator.UpdateAsync(sd).ConfigureAwait(false); } diff --git a/src/Hl7.Fhir.Specification.Shared.Tests/Snapshot/SnapshotSourceTest.cs b/src/Hl7.Fhir.Specification.Shared.Tests/Snapshot/SnapshotSourceTest.cs index 1d5646344f..ef93fe669a 100644 --- a/src/Hl7.Fhir.Specification.Shared.Tests/Snapshot/SnapshotSourceTest.cs +++ b/src/Hl7.Fhir.Specification.Shared.Tests/Snapshot/SnapshotSourceTest.cs @@ -14,11 +14,11 @@ public class SnapshotSourceTest [TestMethod] public async Tasks.Task TestElementSnapshot() { + var zipSource = ZipSource.CreateValidationSource(); + var cachedSource = new CachedResolver(zipSource); + var snapSource = new SnapshotSource(cachedSource, regenerate:true); // Request core Element snapshot; verify recursion handling - var orgSource = ZipSource.CreateValidationSource(); - var cachedSource = new CachedResolver(orgSource); - // Assumption: source provides Element structure var sdCached = await cachedSource.FindStructureDefinitionForCoreTypeAsync(FHIRAllTypes.Element); Assert.IsNotNull(sdCached); @@ -28,11 +28,9 @@ public async Tasks.Task TestElementSnapshot() // Generate snapshot by calling SnapshotSource // Important! Specify flag to force re-generation (don't trust existing core snapshots...) - var snapSource = new SnapshotSource(cachedSource, true); - var sd = await snapSource.FindStructureDefinitionForCoreTypeAsync(FHIRAllTypes.Element); Assert.IsNotNull(sd); - Assert.AreEqual(sdCached, sd); // Expecting same (cached) object reference, with updated Snapshot component + Assert.AreEqual(sdCached, sd); // Expecting same (cached) object reference, with updated Snapshot component Assert.IsTrue(sd.HasSnapshot); Assert.IsTrue(sd.Snapshot.IsCreatedBySnapshotGenerator()); @@ -75,7 +73,8 @@ void assert_ele1(ElementDefinition eld) // STU3: Element.id has type code "string" // R4: Element.id has no type code, only special "compiler magic" extensions // => Element.id no longer inherits constraints from "Element", e.g. "ele-1" - if (elem.Type?.FirstOrDefault()?.Code is string typeName && !typeName.StartsWith("http://hl7.org/fhirpath/System.")) + if (elem.Type?.FirstOrDefault()?.Code is string typeName && + !typeName.StartsWith("http://hl7.org/fhirpath/System.")) { assert_ele1(elem); } @@ -85,24 +84,54 @@ void assert_ele1(ElementDefinition eld) [TestMethod] public void CannotCreateSnapshotGeneratorFromSnapshotSource() { - var orgSource = ZipSource.CreateValidationSource(); - var cachedSource = new CachedResolver(orgSource); - var src = new SnapshotSource(cachedSource); + var zipSource = ZipSource.CreateValidationSource(); + var cachedSource = new CachedResolver(zipSource); + var snapSource = new SnapshotSource(cachedSource, regenerate:true); // Verify that SnapshotGenerator ctor rejects SnapshotSource arguments - Assert.ThrowsException(() => new SnapshotGenerator(src)); + Assert.ThrowsException(() => new SnapshotGenerator(snapSource)); } [TestMethod] public void CannotCreateNestedSnapshotSource() { - var orgSource = ZipSource.CreateValidationSource(); - var cachedSource = new CachedResolver(orgSource); - var src = new SnapshotSource(cachedSource); + var zipSource = ZipSource.CreateValidationSource(); + var cachedSource = new CachedResolver(zipSource); + var snapSource = new SnapshotSource(cachedSource, regenerate:true); // Verify that SnapshotSource ctor rejects SnapshotSource arguments - Assert.ThrowsException(() => new SnapshotSource(src)); + Assert.ThrowsException(() => new SnapshotSource(snapSource)); } + [TestMethod] + public async Tasks.Task Generate_ForceRegenerate_DoesNotReuse_SnapshotCreatedByOthers() + { + var zipSource = ZipSource.CreateValidationSource(); + var cachedSource = new CachedResolver(zipSource); + var snapSource = new SnapshotSource(cachedSource, regenerate:true); + + var original = await cachedSource.FindStructureDefinitionForCoreTypeAsync(FHIRAllTypes.Element); + Assert.IsTrue(original.HasSnapshot); + var originalSnapshot = original.Snapshot; + var regenerated = + await snapSource.FindStructureDefinitionForCoreTypeAsync(FHIRAllTypes.Element); + Assert.IsTrue(regenerated.HasSnapshot); + Assert.AreNotSame(originalSnapshot, regenerated.Snapshot); + } + + [TestMethod] + public async Tasks.Task Generate_ForceRegenerate_Reuses_SelfCreatedSnapshot() + { + var zipSource = ZipSource.CreateValidationSource(); + var cachedSource = new CachedResolver(zipSource); + var snapSource = new SnapshotSource(cachedSource, regenerate:true); + + var first = + await snapSource.FindStructureDefinitionForCoreTypeAsync(FHIRAllTypes.Element); + var firstSnapshot = first.Snapshot; + var second = + await snapSource.FindStructureDefinitionForCoreTypeAsync(FHIRAllTypes.Element); + Assert.AreSame(firstSnapshot, second.Snapshot); + } } } \ No newline at end of file