From 28a453044a509c45fc77f0164fb5777c22ad8f69 Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Mon, 5 Feb 2024 15:39:30 -0700 Subject: [PATCH 1/2] Add test for netcdf file cache and file locking when a NetcdfDataset is opened thru enhance --- .../ucar/nc2/dataset/TestNetcdfFileCache.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 cdm/core/src/test/java/ucar/nc2/dataset/TestNetcdfFileCache.java diff --git a/cdm/core/src/test/java/ucar/nc2/dataset/TestNetcdfFileCache.java b/cdm/core/src/test/java/ucar/nc2/dataset/TestNetcdfFileCache.java new file mode 100644 index 0000000000..e17fbb08e7 --- /dev/null +++ b/cdm/core/src/test/java/ucar/nc2/dataset/TestNetcdfFileCache.java @@ -0,0 +1,85 @@ +package ucar.nc2.dataset; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import java.io.IOException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import ucar.nc2.NetcdfFile; +import ucar.nc2.ncml.TestNcmlRead; +import ucar.nc2.util.cache.FileCacheIF; +import ucar.unidata.util.test.TestDir; + +public class TestNetcdfFileCache { + @BeforeClass + public static void setupCaches() { + NetcdfDatasets.initNetcdfFileCache(1, 10, 15, -1); + } + + @AfterClass + public static void shutdownCaches() { + NetcdfDatasets.shutdown(); + } + + @After + public void cleanupAfterEach() { + NetcdfDatasets.getNetcdfFileCache().clearCache(true); + } + + @Test + public void shouldReleaseLockOnNetcdfFileUsingBuilder() throws IOException { + final String filename = "file:./" + TestDir.cdmLocalTestDataDir + "jan.nc"; + final DatasetUrl durl = DatasetUrl.findDatasetUrl(filename); + + final NetcdfFile netcdfFile = NetcdfDatasets.acquireFile(durl, null); + final NetcdfDataset netcdfDatasetFromBuilder = NetcdfDataset.builder(netcdfFile).build(); + // Closing the builder NetcdfDataset should close the original NetcdfFile acquired from cache + netcdfDatasetFromBuilder.close(); + + assertNoFilesAreLocked(); + } + + @Test + public void shouldReleaseLockOnNetcdfDatasetUsingBuilder() throws IOException { + final String filename = "file:./" + TestDir.cdmLocalTestDataDir + "jan.nc"; + final DatasetUrl durl = DatasetUrl.findDatasetUrl(filename); + + final NetcdfDataset netcdfDataset = NetcdfDatasets.acquireDataset(durl, null); + final NetcdfDataset netcdfDatasetFromBuilder = netcdfDataset.toBuilder().build(); + // Closing the builder NetcdfDataset should close the original NetcdfDataset acquired from cache + netcdfDatasetFromBuilder.close(); + + assertNoFilesAreLocked(); + } + + @Test + public void shouldReleaseLockOnDataset() throws IOException { + final String filename = "file:./" + TestDir.cdmLocalTestDataDir + "jan.nc"; + assertLockIsReleasedOnDataset(filename); + } + + @Test + public void shouldReleaseLockOnAggregation() throws IOException { + final String filename = "file:./" + TestNcmlRead.topDir + "aggExisting.xml"; + assertLockIsReleasedOnDataset(filename); + } + + private static void assertLockIsReleasedOnDataset(String filename) throws IOException { + final DatasetUrl durl = DatasetUrl.findDatasetUrl(filename); + final NetcdfFile netcdfFile = NetcdfDatasets.acquireFile(durl, null); + final NetcdfDataset netcdfDataset = NetcdfDatasets.enhance(netcdfFile, NetcdfDataset.getDefaultEnhanceMode(), null); + // Closing the netcdf dataset should close the "wrapped" NetcdfFile acquired from cache + netcdfDataset.close(); + + assertNoFilesAreLocked(); + } + + private static void assertNoFilesAreLocked() { + FileCacheIF cache = NetcdfDatasets.getNetcdfFileCache(); + boolean isAnyFileLocked = cache.showCache().stream().anyMatch(entry -> entry.startsWith("true")); + assertWithMessage(cache.showCache().toString()).that(isAnyFileLocked).isFalse(); + } +} From d3bf12c2e3eec73148a82a884b570f977b58ef36 Mon Sep 17 00:00:00 2001 From: Tara Drwenski Date: Tue, 6 Feb 2024 10:44:04 -0700 Subject: [PATCH 2/2] Make sure resources get closed in cache when NetcdfDataset (e.g. aggregation) is converted to builder --- cdm/core/src/main/java/ucar/nc2/dataset/NetcdfDataset.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cdm/core/src/main/java/ucar/nc2/dataset/NetcdfDataset.java b/cdm/core/src/main/java/ucar/nc2/dataset/NetcdfDataset.java index 12f1258970..830a330fca 100644 --- a/cdm/core/src/main/java/ucar/nc2/dataset/NetcdfDataset.java +++ b/cdm/core/src/main/java/ucar/nc2/dataset/NetcdfDataset.java @@ -1657,8 +1657,7 @@ private Builder addLocalFieldsToBuilder(Builder> b) { this.coordSys.forEach(sys -> b.coords.addCoordinateSystem(sys.toBuilder())); this.coordTransforms.forEach(trans -> b.coords.addCoordinateTransform(trans.toBuilder())); - b.setOrgFile(this.orgFile).setConventionUsed(this.convUsed).setEnhanceMode(this.enhanceMode) - .setAggregation(this.agg); + b.setOrgFile(this).setConventionUsed(this.convUsed).setEnhanceMode(this.enhanceMode).setAggregation(this.agg); return (Builder) super.addLocalFieldsToBuilder(b); }