This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 4ce25c68433 [test](fe) Cover credential-aware FileSystem cache keys
for object stores (#68803)
4ce25c68433 is described below
commit 4ce25c68433b366f84bbeb4d1cd92dedb3d18b7a
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Fri Oct 9 13:04:18 2026 +0800
[test](fe) Cover credential-aware FileSystem cache keys for object stores
(#68803)
### What problem does this PR solve?
Issue Number: None
Related PR: #65586, #66315
Problem Summary:
**In short.** This ports the test coverage of branch-4.1 #65586
(credential-aware Hadoop FileSystem cache) to master. master already has
the feature (#66315), but the assertions that guard the object-store
Hadoop maps and the merge / vended-credential paths did not come along.
Only tests are added; no production code changes.
**Background.** #65586 stopped force-disabling the Hadoop FileSystem
cache (`fs.<scheme>.impl.disable.cache=true`) and instead made the cache
credential-aware: the Doris-patched `FileSystem.Cache.Key` folds a
fingerprint of the storage definition into the key. master ported this
in #66315 with a different layout. Instead of one scheme-less
`doris.fs.cache.key`, every storage publishes its fingerprint under each
scheme it serves (`doris.fs.cache.key.<scheme>`), so a merge of several
storages keeps all of them and no combined fingerprint is needed.
| | branch-4.1 #65586 | master #66315 |
|---|---|---|
| Cache key property | `doris.fs.cache.key` |
`doris.fs.cache.key.<scheme>`, one per scheme the storage serves |
| Several storages in one map | combined fingerprint | entries simply
coexist |
| Blanket `fs.<scheme>.impl.disable.cache=true` | removed | removed |
**The problem, and what it cost.** On master nothing asserts the shape
of the S3-family `toHadoopConfigurationMap()`, which is the map the
Hadoop FileSystem actually reads. The 4.1 `testS3DisableHadoopCache`
assertions (COS, GCS, OBS, OSS, S3) have no master counterpart, and
`StorageAdapterFsCacheFingerprintTest#testNoBlanketDisableCacheByDefault`
inspects the `AWS_*` backend map, which never held these flags. Today
every FE unit test still passes if a provider re-adds a blanket disable
flag (silently turning the cache off again), or publishes its
fingerprint under fewer schemes than it is opened with (COS is addressed
as `cos://` but opened as `s3a`, so a key published only under `cos` is
never read, and two catalogs with different credentials can share a
FileSystem). The merge through `CredentialUtils` and the
vended-credential overlay were likewise only checked with mocks or not
at all.
**How this PR fixes it.** It adds the 4.1 assertions in master's terms:
| Test | New assertion |
|---|---|
| `S3` / `Cos` / `Obs` / `Oss` / `GcsFileSystemPropertiesTest` |
`toHadoopConfigurationMap()` has no `fs.<scheme>.impl.disable.cache`; it
carries `doris.fs.cache.key.<scheme>` equal to `fsCacheFingerprint()`
for every scheme the storage serves (S3 `{s3, s3a, s3n}`, COS `{cos,
cosn, s3, s3a}`, OSS `{oss, s3, s3a}`, OBS `{obs, s3, s3a}`, GCS `{gs,
s3, s3a}`); it has no scheme-less key; different credentials give a
different fingerprint |
| `CredentialUtilsTest` | merging real HDFS and S3 adapters through
`getBackendPropertiesFromStorageMap` keeps `doris.fs.cache.key.hdfs` and
`doris.fs.cache.key.s3a` with each storage's own fingerprint |
| `DefaultConnectorContextVendTest` | a vended OSS token carries its own
`doris.fs.cache.key.oss` / `.s3a`, and a rotated access key yields
different values |
**Results.** The new tests pass on current master and fail if any of the
regressions above is introduced.
Original author: @CalvinKirs
---
.../connector/DefaultConnectorContextVendTest.java | 29 +++++++++++++++++++++
.../credentials/CredentialUtilsTest.java | 30 ++++++++++++++++++++++
.../cos/CosFileSystemPropertiesTest.java | 28 ++++++++++++++++++++
.../gcs/GcsFileSystemPropertiesTest.java | 27 +++++++++++++++++++
.../obs/ObsFileSystemPropertiesTest.java | 28 ++++++++++++++++++++
.../oss/OssFileSystemPropertiesTest.java | 28 ++++++++++++++++++++
.../filesystem/s3/S3FileSystemPropertiesTest.java | 28 ++++++++++++++++++++
7 files changed, 198 insertions(+)
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/connector/DefaultConnectorContextVendTest.java
b/fe/fe-core/src/test/java/org/apache/doris/connector/DefaultConnectorContextVendTest.java
index b8314046dd5..3a282589205 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/connector/DefaultConnectorContextVendTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/connector/DefaultConnectorContextVendTest.java
@@ -17,6 +17,8 @@
package org.apache.doris.connector;
+import org.apache.doris.filesystem.properties.FsCacheKeys;
+
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -60,6 +62,33 @@ public class DefaultConnectorContextVendTest {
Assertions.assertEquals("testSessionToken789", be.get("AWS_TOKEN"));
}
+ @Test
+ public void vendedTokenCarriesItsOwnFsCacheKey() {
+ Map<String, String> be =
context().vendStorageCredentials(ossToken("STS.testAccessKey123"));
+ Map<String, String> rotated =
context().vendStorageCredentials(ossToken("STS.rotatedAccessKey"));
+
+ // WHY: a vended token is overlaid on the catalog's static storage
properties, and the patched
+ // Hadoop FileSystem caches by doris.fs.cache.key.<scheme>. The
overlay must therefore carry the
+ // token's own fingerprint, or a FileSystem opened with one token
would be reused for another.
+ // MUTATION: dropping the key from the vended map, or deriving it from
anything but the token
+ // -> missing or equal values -> red.
+ for (String scheme : new String[] {"oss", "s3a"}) {
+ String key = FsCacheKeys.fsCacheKeyProperty(scheme);
+ Assertions.assertNotNull(be.get(key), key);
+ Assertions.assertNotEquals(be.get(key), rotated.get(key), key);
+ }
+ Assertions.assertNull(be.get(FsCacheKeys.FS_CACHE_KEY_PROPERTY));
+ }
+
+ private static Map<String, String> ossToken(String accessKeyId) {
+ Map<String, String> token = new HashMap<>();
+ token.put("fs.oss.accessKeyId", accessKeyId);
+ token.put("fs.oss.accessKeySecret", "testSecretKey456");
+ token.put("fs.oss.securityToken", "testSessionToken789");
+ token.put("fs.oss.endpoint", "oss-cn-beijing.aliyuncs.com");
+ return token;
+ }
+
@Test
public void emptyOrNullInputYieldsEmpty() {
// WHY: a non-REST / no-token table passes an empty map; the bridge
must short-circuit to
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/datasource/credentials/CredentialUtilsTest.java
b/fe/fe-core/src/test/java/org/apache/doris/datasource/credentials/CredentialUtilsTest.java
index 67856553076..41a8d405d77 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/datasource/credentials/CredentialUtilsTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/datasource/credentials/CredentialUtilsTest.java
@@ -19,6 +19,7 @@ package org.apache.doris.datasource.credentials;
import org.apache.doris.datasource.storage.StorageAdapter;
import org.apache.doris.datasource.storage.StorageTypeId;
+import org.apache.doris.filesystem.properties.FsCacheKeys;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -196,6 +197,35 @@ public class CredentialUtilsTest {
Assertions.assertEquals("hdfs://namenode:9000",
result.get("HDFS_NAMENODE"));
}
+ @Test
+ public void
testGetBackendPropertiesFromStorageMapKeepsEveryStoragesFsCacheKey() {
+ // Real adapters rather than mocks: the per-scheme FileSystem cache
keys are written by
+ // StorageAdapter itself, and this merge is where several storages'
maps meet.
+ Map<String, String> hdfsProps = new HashMap<>();
+ hdfsProps.put("uri", "hdfs://test/1.orc");
+ hdfsProps.put("hadoop.username", "userA");
+ StorageAdapter hdfs = StorageAdapter.of(hdfsProps);
+ Map<String, String> s3Props = new HashMap<>();
+ s3Props.put("s3.endpoint", "s3.us-west-2.amazonaws.com");
+ s3Props.put("s3.access_key", "ak1");
+ s3Props.put("s3.secret_key", "secret");
+ StorageAdapter s3 = StorageAdapter.of(s3Props);
+
+ Map<StorageTypeId, StorageAdapter> storagePropertiesMap = new
HashMap<>();
+ storagePropertiesMap.put(hdfs.getType(), hdfs);
+ storagePropertiesMap.put(s3.getType(), s3);
+
+ Map<String, String> result =
CredentialUtils.getBackendPropertiesFromStorageMap(storagePropertiesMap);
+
+ // Each storage keeps its own fingerprint under its own schemes; a
single shared key would
+ // let whichever storage merged last decide the cache identity of the
other one.
+ Assertions.assertEquals(hdfs.getFsCacheFingerprint(),
+ result.get(FsCacheKeys.fsCacheKeyProperty("hdfs")));
+ Assertions.assertEquals(s3.getFsCacheFingerprint(),
result.get(FsCacheKeys.fsCacheKeyProperty("s3a")));
+ Assertions.assertNotEquals(hdfs.getFsCacheFingerprint(),
s3.getFsCacheFingerprint());
+ Assertions.assertNull(result.get(FsCacheKeys.FS_CACHE_KEY_PROPERTY));
+ }
+
@Test
public void testGetBackendPropertiesFromStorageMapWithNullValues() {
StorageAdapter s3Properties = Mockito.mock(StorageAdapter.class);
diff --git
a/fe/fe-filesystem/fe-filesystem-cos/src/test/java/org/apache/doris/filesystem/cos/CosFileSystemPropertiesTest.java
b/fe/fe-filesystem/fe-filesystem-cos/src/test/java/org/apache/doris/filesystem/cos/CosFileSystemPropertiesTest.java
index 5bd9508ab99..e21e24a4539 100644
---
a/fe/fe-filesystem/fe-filesystem-cos/src/test/java/org/apache/doris/filesystem/cos/CosFileSystemPropertiesTest.java
+++
b/fe/fe-filesystem/fe-filesystem-cos/src/test/java/org/apache/doris/filesystem/cos/CosFileSystemPropertiesTest.java
@@ -21,6 +21,7 @@ import org.apache.doris.filesystem.FileSystem;
import org.apache.doris.filesystem.FileSystemType;
import org.apache.doris.filesystem.properties.BackendStorageKind;
import org.apache.doris.filesystem.properties.BackendStorageProperties;
+import org.apache.doris.filesystem.properties.FsCacheKeys;
import org.apache.doris.filesystem.properties.StorageKind;
import org.apache.doris.filesystem.spi.S3CompatibleFileSystem;
@@ -29,6 +30,7 @@ import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -158,6 +160,32 @@ class CosFileSystemPropertiesTest {
Assertions.assertEquals("10000",
hadoopKv.get("fs.s3a.connection.timeout"));
}
+ @Test
+ void toHadoopConfigurationMap_keysFileSystemCacheByCredentialFingerprint()
{
+ CosFileSystemProperties properties = CosFileSystemProperties.of(Map.of(
+ "cos.endpoint", "https://cos.ap-guangzhou.myqcloud.com",
+ "cos.access_key", "ak",
+ "cos.secret_key", "sk"));
+ CosFileSystemProperties otherCredentials =
CosFileSystemProperties.of(Map.of(
+ "cos.endpoint", "https://cos.ap-guangzhou.myqcloud.com",
+ "cos.access_key", "other-ak",
+ "cos.secret_key", "other-sk"));
+
+ Map<String, String> hadoopKv = properties.toHadoopConfigurationMap();
+
+ // The Hadoop FileSystem cache stays on. Instead of the retired blanket
+ // fs.<scheme>.impl.disable.cache=true, every scheme this storage can
be opened with carries
+ // its credential fingerprint, which the Doris-patched FileSystem
folds into its cache key.
+ for (String scheme : List.of("cos", "cosn", "s3", "s3a")) {
+ Assertions.assertNull(hadoopKv.get("fs." + scheme +
".impl.disable.cache"), scheme);
+ Assertions.assertEquals(properties.fsCacheFingerprint(),
+ hadoopKv.get(FsCacheKeys.fsCacheKeyProperty(scheme)),
scheme);
+ }
+ // Never the shared, scheme-less name: per-scheme names are what keep
a merge lossless.
+ Assertions.assertNull(hadoopKv.get(FsCacheKeys.FS_CACHE_KEY_PROPERTY));
+ Assertions.assertNotEquals(properties.fsCacheFingerprint(),
otherCredentials.fsCacheFingerprint());
+ }
+
@Test
void bind_rejectsPartialStaticCredentialsLikeFeCore() {
IllegalArgumentException exception =
Assertions.assertThrows(IllegalArgumentException.class,
diff --git
a/fe/fe-filesystem/fe-filesystem-gcs/src/test/java/org/apache/doris/filesystem/gcs/GcsFileSystemPropertiesTest.java
b/fe/fe-filesystem/fe-filesystem-gcs/src/test/java/org/apache/doris/filesystem/gcs/GcsFileSystemPropertiesTest.java
index d1ac47224e0..2802018a50d 100644
---
a/fe/fe-filesystem/fe-filesystem-gcs/src/test/java/org/apache/doris/filesystem/gcs/GcsFileSystemPropertiesTest.java
+++
b/fe/fe-filesystem/fe-filesystem-gcs/src/test/java/org/apache/doris/filesystem/gcs/GcsFileSystemPropertiesTest.java
@@ -17,9 +17,12 @@
package org.apache.doris.filesystem.gcs;
+import org.apache.doris.filesystem.properties.FsCacheKeys;
+
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.util.List;
import java.util.Map;
class GcsFileSystemPropertiesTest {
@@ -125,6 +128,30 @@ class GcsFileSystemPropertiesTest {
Assertions.assertEquals("sk", cfg.get("fs.s3a.secret.key"));
}
+ @Test
+ void toHadoopConfigurationMap_keysFileSystemCacheByCredentialFingerprint()
{
+ GcsFileSystemProperties properties = GcsFileSystemProperties.of(Map.of(
+ "gs.access_key", "ak",
+ "gs.secret_key", "sk"));
+ GcsFileSystemProperties otherCredentials =
GcsFileSystemProperties.of(Map.of(
+ "gs.access_key", "other-ak",
+ "gs.secret_key", "other-sk"));
+
+ Map<String, String> hadoopKv = properties.toHadoopConfigurationMap();
+
+ // The Hadoop FileSystem cache stays on. Instead of the retired blanket
+ // fs.<scheme>.impl.disable.cache=true, every scheme this storage can
be opened with carries
+ // its credential fingerprint, which the Doris-patched FileSystem
folds into its cache key.
+ for (String scheme : List.of("gs", "s3", "s3a")) {
+ Assertions.assertNull(hadoopKv.get("fs." + scheme +
".impl.disable.cache"), scheme);
+ Assertions.assertEquals(properties.fsCacheFingerprint(),
+ hadoopKv.get(FsCacheKeys.fsCacheKeyProperty(scheme)),
scheme);
+ }
+ // Never the shared, scheme-less name: per-scheme names are what keep
a merge lossless.
+ Assertions.assertNull(hadoopKv.get(FsCacheKeys.FS_CACHE_KEY_PROPERTY));
+ Assertions.assertNotEquals(properties.fsCacheFingerprint(),
otherCredentials.fsCacheFingerprint());
+ }
+
@Test
void of_rejectsInvalidUsePathStyle() {
IllegalArgumentException e =
Assertions.assertThrows(IllegalArgumentException.class,
diff --git
a/fe/fe-filesystem/fe-filesystem-obs/src/test/java/org/apache/doris/filesystem/obs/ObsFileSystemPropertiesTest.java
b/fe/fe-filesystem/fe-filesystem-obs/src/test/java/org/apache/doris/filesystem/obs/ObsFileSystemPropertiesTest.java
index a9f288e5f6b..1584a84d7e5 100644
---
a/fe/fe-filesystem/fe-filesystem-obs/src/test/java/org/apache/doris/filesystem/obs/ObsFileSystemPropertiesTest.java
+++
b/fe/fe-filesystem/fe-filesystem-obs/src/test/java/org/apache/doris/filesystem/obs/ObsFileSystemPropertiesTest.java
@@ -21,6 +21,7 @@ import org.apache.doris.filesystem.FileSystem;
import org.apache.doris.filesystem.FileSystemType;
import org.apache.doris.filesystem.properties.BackendStorageKind;
import org.apache.doris.filesystem.properties.BackendStorageProperties;
+import org.apache.doris.filesystem.properties.FsCacheKeys;
import org.apache.doris.filesystem.properties.StorageKind;
import org.apache.doris.filesystem.spi.S3CompatibleFileSystem;
@@ -29,6 +30,7 @@ import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -129,6 +131,32 @@ class ObsFileSystemPropertiesTest {
Assertions.assertEquals("10000",
hadoopKv.get("fs.s3a.connection.timeout"));
}
+ @Test
+ void toHadoopConfigurationMap_keysFileSystemCacheByCredentialFingerprint()
{
+ ObsFileSystemProperties properties = ObsFileSystemProperties.of(Map.of(
+ "obs.endpoint", "https://obs.cn-north-4.myhuaweicloud.com",
+ "obs.access_key", "ak",
+ "obs.secret_key", "sk"));
+ ObsFileSystemProperties otherCredentials =
ObsFileSystemProperties.of(Map.of(
+ "obs.endpoint", "https://obs.cn-north-4.myhuaweicloud.com",
+ "obs.access_key", "other-ak",
+ "obs.secret_key", "other-sk"));
+
+ Map<String, String> hadoopKv = properties.toHadoopConfigurationMap();
+
+ // The Hadoop FileSystem cache stays on. Instead of the retired blanket
+ // fs.<scheme>.impl.disable.cache=true, every scheme this storage can
be opened with carries
+ // its credential fingerprint, which the Doris-patched FileSystem
folds into its cache key.
+ for (String scheme : List.of("obs", "s3", "s3a")) {
+ Assertions.assertNull(hadoopKv.get("fs." + scheme +
".impl.disable.cache"), scheme);
+ Assertions.assertEquals(properties.fsCacheFingerprint(),
+ hadoopKv.get(FsCacheKeys.fsCacheKeyProperty(scheme)),
scheme);
+ }
+ // Never the shared, scheme-less name: per-scheme names are what keep
a merge lossless.
+ Assertions.assertNull(hadoopKv.get(FsCacheKeys.FS_CACHE_KEY_PROPERTY));
+ Assertions.assertNotEquals(properties.fsCacheFingerprint(),
otherCredentials.fsCacheFingerprint());
+ }
+
@Test
void hadoopMap_selectsObsFileSystemWithoutLinkingIt() {
// Premise this test rests on, and the exact shape of a deployment
where fe-core no longer
diff --git
a/fe/fe-filesystem/fe-filesystem-oss/src/test/java/org/apache/doris/filesystem/oss/OssFileSystemPropertiesTest.java
b/fe/fe-filesystem/fe-filesystem-oss/src/test/java/org/apache/doris/filesystem/oss/OssFileSystemPropertiesTest.java
index 12116f65536..d2975a6b606 100644
---
a/fe/fe-filesystem/fe-filesystem-oss/src/test/java/org/apache/doris/filesystem/oss/OssFileSystemPropertiesTest.java
+++
b/fe/fe-filesystem/fe-filesystem-oss/src/test/java/org/apache/doris/filesystem/oss/OssFileSystemPropertiesTest.java
@@ -21,6 +21,7 @@ import org.apache.doris.filesystem.FileSystem;
import org.apache.doris.filesystem.FileSystemType;
import org.apache.doris.filesystem.properties.BackendStorageKind;
import org.apache.doris.filesystem.properties.BackendStorageProperties;
+import org.apache.doris.filesystem.properties.FsCacheKeys;
import org.apache.doris.filesystem.properties.StorageKind;
import org.apache.doris.filesystem.spi.S3CompatibleFileSystem;
@@ -30,6 +31,7 @@ import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -202,6 +204,32 @@ class OssFileSystemPropertiesTest {
Assertions.assertEquals("10000",
hadoopKv.get("fs.s3a.connection.timeout"));
}
+ @Test
+ void toHadoopConfigurationMap_keysFileSystemCacheByCredentialFingerprint()
{
+ OssFileSystemProperties properties = OssFileSystemProperties.of(Map.of(
+ "oss.endpoint", "https://oss-cn-hangzhou.aliyuncs.com",
+ "oss.access_key", "ak",
+ "oss.secret_key", "sk"));
+ OssFileSystemProperties otherCredentials =
OssFileSystemProperties.of(Map.of(
+ "oss.endpoint", "https://oss-cn-hangzhou.aliyuncs.com",
+ "oss.access_key", "other-ak",
+ "oss.secret_key", "other-sk"));
+
+ Map<String, String> hadoopKv = properties.toHadoopConfigurationMap();
+
+ // The Hadoop FileSystem cache stays on. Instead of the retired blanket
+ // fs.<scheme>.impl.disable.cache=true, every scheme this storage can
be opened with carries
+ // its credential fingerprint, which the Doris-patched FileSystem
folds into its cache key.
+ for (String scheme : List.of("oss", "s3", "s3a")) {
+ Assertions.assertNull(hadoopKv.get("fs." + scheme +
".impl.disable.cache"), scheme);
+ Assertions.assertEquals(properties.fsCacheFingerprint(),
+ hadoopKv.get(FsCacheKeys.fsCacheKeyProperty(scheme)),
scheme);
+ }
+ // Never the shared, scheme-less name: per-scheme names are what keep
a merge lossless.
+ Assertions.assertNull(hadoopKv.get(FsCacheKeys.FS_CACHE_KEY_PROPERTY));
+ Assertions.assertNotEquals(properties.fsCacheFingerprint(),
otherCredentials.fsCacheFingerprint());
+ }
+
@Test
void bind_rejectsPartialStaticCredentialsLikeFeCore() {
IllegalArgumentException exception =
Assertions.assertThrows(IllegalArgumentException.class,
diff --git
a/fe/fe-filesystem/fe-filesystem-s3-base/src/test/java/org/apache/doris/filesystem/s3/S3FileSystemPropertiesTest.java
b/fe/fe-filesystem/fe-filesystem-s3-base/src/test/java/org/apache/doris/filesystem/s3/S3FileSystemPropertiesTest.java
index a081233add1..46e8387c4d2 100644
---
a/fe/fe-filesystem/fe-filesystem-s3-base/src/test/java/org/apache/doris/filesystem/s3/S3FileSystemPropertiesTest.java
+++
b/fe/fe-filesystem/fe-filesystem-s3-base/src/test/java/org/apache/doris/filesystem/s3/S3FileSystemPropertiesTest.java
@@ -19,6 +19,7 @@ package org.apache.doris.filesystem.s3;
import org.apache.doris.filesystem.properties.BackendStorageKind;
import org.apache.doris.filesystem.properties.BackendStorageProperties;
+import org.apache.doris.filesystem.properties.FsCacheKeys;
import org.apache.doris.filesystem.properties.HadoopStorageProperties;
import org.junit.jupiter.api.Assertions;
@@ -26,6 +27,7 @@ import org.junit.jupiter.api.Test;
import
software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
class S3FileSystemPropertiesTest {
@@ -256,6 +258,32 @@ class S3FileSystemPropertiesTest {
Assertions.assertEquals("true",
hadoopMap.get("fs.s3a.path.style.access"));
}
+ @Test
+ void toHadoopConfigurationMap_keysFileSystemCacheByCredentialFingerprint()
{
+ S3FileSystemProperties properties = S3FileSystemProperties.of(Map.of(
+ "s3.endpoint", "https://s3.us-west-2.amazonaws.com",
+ "s3.access_key", "ak",
+ "s3.secret_key", "sk"));
+ S3FileSystemProperties otherCredentials =
S3FileSystemProperties.of(Map.of(
+ "s3.endpoint", "https://s3.us-west-2.amazonaws.com",
+ "s3.access_key", "other-ak",
+ "s3.secret_key", "other-sk"));
+
+ Map<String, String> hadoopKv = properties.toHadoopConfigurationMap();
+
+ // The Hadoop FileSystem cache stays on. Instead of the retired blanket
+ // fs.<scheme>.impl.disable.cache=true, every scheme this storage can
be opened with carries
+ // its credential fingerprint, which the Doris-patched FileSystem
folds into its cache key.
+ for (String scheme : List.of("s3", "s3a", "s3n")) {
+ Assertions.assertNull(hadoopKv.get("fs." + scheme +
".impl.disable.cache"), scheme);
+ Assertions.assertEquals(properties.fsCacheFingerprint(),
+ hadoopKv.get(FsCacheKeys.fsCacheKeyProperty(scheme)),
scheme);
+ }
+ // Never the shared, scheme-less name: per-scheme names are what keep
a merge lossless.
+ Assertions.assertNull(hadoopKv.get(FsCacheKeys.FS_CACHE_KEY_PROPERTY));
+ Assertions.assertNotEquals(properties.fsCacheFingerprint(),
otherCredentials.fsCacheFingerprint());
+ }
+
@Test
void of_bindsAndNormalizesCredentialsProviderType() {
Map<String, String> raw = new HashMap<>();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]