Skip to content

Commit b464b33

Browse files
committed
[FLINK-40109] Verify Kerberos keytab logs after the YARN application is killed
FLINK-40099 moved YARNSessionFIFOSecuredITCase's keytab check into a pre-kill callback polling waitUntilCondition(cond, 500). The 500 int literal binds to the (cond, int retryAttempts) overload (500*100ms, then "Exhausted retry attempts."), and reading the JobManager log while the application is still alive is racy: the polled jobmanager.log does not reliably contain the keytab login line before teardown. Read the container logs after the application is killed (output flushed) but poll each log with a bounded wait instead of a single read, preserving the FLINK-17662 intent without the pre-kill race. On timeout, fail with the log file and expected strings so a recurrence is diagnosable from the uploaded container logs. Generated-by: Claude Opus 4.8 (1M context)
1 parent 1a5f868 commit b464b33

2 files changed

Lines changed: 32 additions & 53 deletions

File tree

flink-yarn-tests/src/test/java/org/apache/flink/yarn/YARNSessionFIFOITCase.java

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.apache.flink.runtime.testutils.CommonTestUtils;
2424
import org.apache.flink.test.testdata.WordCountData;
2525
import org.apache.flink.testutils.logging.LoggerAuditingExtension;
26-
import org.apache.flink.util.function.ThrowingConsumer;
2726
import org.apache.flink.yarn.cli.FlinkYarnSessionCli;
2827
import org.apache.flink.yarn.configuration.YarnConfigOptions;
2928

@@ -96,23 +95,6 @@ void testDetachedMode() throws Exception {
9695
ApplicationId runDetachedModeTest(
9796
Map<String, String> securityProperties, String viewAcls, String modifyAcls)
9897
throws Exception {
99-
return runDetachedModeTest(securityProperties, viewAcls, modifyAcls, ignored -> {});
100-
}
101-
102-
/**
103-
* Test regular operation, including command line parameter parsing.
104-
*
105-
* @param verifyWhileRunning verification that is invoked once the job has finished but while
106-
* the YARN application and its containers are still alive, before the application is
107-
* killed. This allows subclasses to inspect complete container logs and live container
108-
* state, which is no longer possible once the application has been torn down.
109-
*/
110-
ApplicationId runDetachedModeTest(
111-
Map<String, String> securityProperties,
112-
String viewAcls,
113-
String modifyAcls,
114-
ThrowingConsumer<ApplicationId, Exception> verifyWhileRunning)
115-
throws Exception {
11698
log.info("Starting testDetachedMode()");
11799

118100
File exampleJarLocation = getTestJarPath("StreamingWordCount.jar");
@@ -196,10 +178,6 @@ ApplicationId runDetachedModeTest(
196178
"jobmanager.log"),
197179
testConditionIntervalInMillis);
198180

199-
// Run verification that requires the application and its containers to still be alive, such
200-
// as reading the freshly written container logs, before the application is killed below.
201-
verifyWhileRunning.accept(applicationId);
202-
203181
// kill application "externally".
204182
try {
205183
YarnClient yc = YarnClient.createYarnClient();

flink-yarn-tests/src/test/java/org/apache/flink/yarn/YARNSessionFIFOSecuredITCase.java

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020

2121
import org.apache.flink.configuration.Configuration;
2222
import org.apache.flink.configuration.SecurityOptions;
23+
import org.apache.flink.core.testutils.CommonTestUtils;
2324
import org.apache.flink.runtime.security.SecurityConfiguration;
2425
import org.apache.flink.runtime.security.SecurityUtils;
2526
import org.apache.flink.runtime.security.contexts.HadoopSecurityContext;
26-
import org.apache.flink.runtime.testutils.CommonTestUtils;
2727
import org.apache.flink.test.util.SecureTestEnvironment;
2828
import org.apache.flink.test.util.TestingSecurityContext;
2929
import org.apache.flink.yarn.configuration.YarnConfigOptions;
@@ -47,6 +47,8 @@
4747
import org.slf4j.Logger;
4848
import org.slf4j.LoggerFactory;
4949

50+
import java.time.Duration;
51+
import java.util.Arrays;
5052
import java.util.Collections;
5153
import java.util.HashMap;
5254
import java.util.List;
@@ -156,12 +158,9 @@ void testDetachedModeSecureWithPreInstallKeytab() throws Exception {
156158
SecurityOptions.KERBEROS_LOGIN_PRINCIPAL.key(),
157159
SecureTestEnvironment.getHadoopServicePrincipal());
158160
}
159-
runDetachedModeTest(
160-
securityProperties,
161-
VIEW_ACLS,
162-
MODIFY_ACLS,
163-
YARNSessionFIFOSecuredITCase::verifyKerberosKeytabInLogs);
164-
verifyTokenAndAclsInContainers(VIEW_ACLS, MODIFY_ACLS);
161+
final ApplicationId applicationId =
162+
runDetachedModeTest(securityProperties, VIEW_ACLS, MODIFY_ACLS);
163+
verifyResultContainsKerberosKeytab(applicationId, VIEW_ACLS, MODIFY_ACLS);
165164
});
166165
}
167166

@@ -181,38 +180,40 @@ void testDetachedMode() throws Exception {
181180
SecurityOptions.KERBEROS_LOGIN_PRINCIPAL.key(),
182181
SecureTestEnvironment.getHadoopServicePrincipal());
183182
}
184-
runDetachedModeTest(
185-
securityProperties,
186-
VIEW_ACLS,
187-
MODIFY_ACLS,
188-
YARNSessionFIFOSecuredITCase::verifyKerberosKeytabInLogs);
189-
verifyTokenAndAclsInContainers(VIEW_ACLS, MODIFY_ACLS);
190-
runDetachedModeTest(
191-
securityProperties,
192-
VIEW_ACLS_WITH_WILDCARD,
193-
MODIFY_ACLS_WITH_WILDCARD,
194-
YARNSessionFIFOSecuredITCase::verifyKerberosKeytabInLogs);
195-
verifyTokenAndAclsInContainers(WILDCARD, WILDCARD);
183+
final ApplicationId applicationId =
184+
runDetachedModeTest(securityProperties, VIEW_ACLS, MODIFY_ACLS);
185+
verifyResultContainsKerberosKeytab(applicationId, VIEW_ACLS, MODIFY_ACLS);
186+
final ApplicationId applicationIdWithWildcard =
187+
runDetachedModeTest(
188+
securityProperties,
189+
VIEW_ACLS_WITH_WILDCARD,
190+
MODIFY_ACLS_WITH_WILDCARD);
191+
verifyResultContainsKerberosKeytab(
192+
applicationIdWithWildcard, WILDCARD, WILDCARD);
196193
});
197194
}
198195

199-
/**
200-
* Verifies that both the JobManager and TaskManager logged a Kerberos keytab login. The
201-
* container log files are polled rather than read once, and this must run while the containers
202-
* are still alive so the logs are complete. A short-lived TaskManager can otherwise be torn
203-
* down before its startup log becomes durably readable.
204-
*/
205-
private static void verifyKerberosKeytabInLogs(ApplicationId applicationId) throws Exception {
196+
private static void verifyResultContainsKerberosKeytab(
197+
ApplicationId applicationId, String viewAcls, String modifyAcls) throws Exception {
206198
final String[] mustHave = {"Login successful for user", "using keytab file"};
199+
// The application has been killed by now, so all container output is flushed. A
200+
// short-lived TaskManager's startup login line can still be briefly unreadable right
201+
// after teardown (FLINK-17662), so poll each log instead of reading it once.
207202
for (final String logFile : new String[] {"jobmanager.log", "taskmanager.log"}) {
208203
log.info("Waiting until {} contains the Kerberos keytab login", logFile);
209-
CommonTestUtils.waitUntilCondition(
210-
() -> verifyStringsInNamedLogFiles(mustHave, applicationId, logFile), 500);
204+
CommonTestUtils.waitUtil(
205+
() -> verifyStringsInNamedLogFiles(mustHave, applicationId, logFile),
206+
Duration.ofSeconds(60),
207+
Duration.ofMillis(500),
208+
"Kerberos keytab login "
209+
+ Arrays.toString(mustHave)
210+
+ " not found in "
211+
+ logFile
212+
+ " for application "
213+
+ applicationId
214+
+ " within the timeout; inspect the uploaded container logs.");
211215
}
212-
}
213216

214-
private static void verifyTokenAndAclsInContainers(String viewAcls, String modifyAcls)
215-
throws Exception {
216217
final List<String> amRMTokens =
217218
Lists.newArrayList(AMRMTokenIdentifier.KIND_NAME.toString());
218219
final String jobmanagerContainerId = getContainerIdByLogName("jobmanager.log");

0 commit comments

Comments
 (0)