deniskuzZ commented on code in PR #6584:
URL: https://github.com/apache/hive/pull/6584#discussion_r3579153081


##########
llap-server/src/test/org/apache/hadoop/hive/llap/cache/TestMetadataCache.java:
##########
@@ -185,6 +185,104 @@ public void testBuffers() throws Exception {
     assertFalse(b0.incRef() > 0); // Should have also been thrown out.
   }
 
+  /**
+   * A footer of exactly maxAlloc: the split condition used a strict {@code 
<}, so no buffer was
+   * allocated and the InputStream put path returned an empty wrapper (NPE on 
lock).
+   */
+  @Test
+  public void testStreamFooterEqualToMaxAlloc() throws Exception {
+    verifyFooterFromStream(newMetadataCache(), MAX_ALLOC, true);
+  }
+
+  /**
+   * A footer larger than maxAlloc is split into a multi-buffer wrapper: an 
exact multiple of maxAlloc
+   * (only full chunks) and a multiple plus a remainder (full chunks + a 
smaller last chunk). The
+   * remainder buffer used to be allocated with the full footer length, 
exceeding the max allocation.
+   */
+  @Test
+  public void testStreamFooterLargerThanMaxAlloc() throws Exception {
+    MetadataCache cache = newMetadataCache();
+    verifyFooterFromStream(cache, 2 * MAX_ALLOC, false);
+    verifyFooterFromStream(cache, 2 * MAX_ALLOC + 3, false);
+  }
+
+  /**
+   * If reading the footer stream fails after some buffers were already 
allocated, every allocated
+   * buffer must be released back to the allocator. Otherwise the long-lived 
LLAP daemon leaks arena
+   * memory on every failed footer read (a truncated file, an IO error, or an 
oversized chunk).
+   */
+  @Test
+  public void testStreamFooterReadFailureReleasesBuffers() {
+    assertFooterReadFailureReleasesBuffers(MAX_ALLOC);         // 
single-buffer path
+    assertFooterReadFailureReleasesBuffers(2 * MAX_ALLOC);     // 
multi-buffer, exact multiple
+    assertFooterReadFailureReleasesBuffers(2 * MAX_ALLOC + 3); // 
multi-buffer, with remainder
+  }
+
+  private void assertFooterReadFailureReleasesBuffers(int length) {
+    final int arenaSize = 4096;
+    DummyMemoryManager mm = new DummyMemoryManager();
+    LlapDaemonCacheMetrics metrics = LlapDaemonCacheMetrics.create("", "");
+    BuddyAllocator alloc = new BuddyAllocator(
+        false, false, 8, MAX_ALLOC, 1, arenaSize, 0, null, mm, metrics, null, 
true);
+    MetadataCache cache = new MetadataCache(alloc, mm, new DummyCachePolicy(), 
true, metrics);
+
+    Object fileKey = new Object();
+    // One byte short of the footer, so reading the last chunk hits EOF 
part-way through.
+    ByteArrayInputStream truncated = new ByteArrayInputStream(new byte[length 
- 1]);
+    try {
+      cache.putFileMetadata(fileKey, length, truncated, null, null);
+      fail("Expected an EOFException for a truncated footer stream of length " 
+ length);
+    } catch (IOException expected) {
+      // expected

Review Comment:
   narrowed the catch to EOFException



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to