Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -1981,14 +1981,21 @@ private void validateChannelAcquisitionContext(CosmosDiagnostics diagnostics, bo
private String generateHttp2OptedInUserAgentIfRequired(String userAgent) {
// Mirrors RxDocumentClientImpl.addUserAgentSuffix + UserAgentContainer.setFeatureEnabledFlagsAsSuffix:
// when HTTP/2 is enabled, the Http2 bit is set; when PING keepalive is also effectively enabled
// (kill-switch on AND positive interval), the Http2PingHealth bit is OR'd in.
// (kill-switch on AND positive interval), the Http2PingHealth bit is OR'd in. ThinClient is set when
// COSMOS.THINCLIENT_ENABLED is true (default true after Gateway V2 default enablement).
// Tests here do not override Http2ConnectionConfig.setEnabled(...) so the per-client override branch
// in addUserAgentSuffix is a no-op for this helper.
int featureValue = 0;
if (Configs.isThinClientEnabled()) {
featureValue |= UserAgentFeatureFlags.ThinClient.getValue();
}
if (Configs.isHttp2Enabled()) {
int featureValue = UserAgentFeatureFlags.Http2.getValue();
featureValue |= UserAgentFeatureFlags.Http2.getValue();
if (Configs.isHttp2PingHealthEnabled() && Configs.getHttp2PingIntervalInSeconds() > 0) {
featureValue |= UserAgentFeatureFlags.Http2PingHealth.getValue();
}
}
if (featureValue != 0) {
userAgent = userAgent + "|F" + Integer.toHexString(featureValue).toUpperCase(Locale.ROOT);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,19 @@ private void validateUserAgentSuffix(String actualUserAgent, String expectedUser

// Mirrors RxDocumentClientImpl.addUserAgentSuffix + UserAgentContainer.setFeatureEnabledFlagsAsSuffix:
// when HTTP/2 is enabled, the Http2 bit is set; when PING keepalive is also effectively enabled
// (kill-switch on AND positive interval), the Http2PingHealth bit is OR'd in.
// (kill-switch on AND positive interval), the Http2PingHealth bit is OR'd in. ThinClient is set when
// COSMOS.THINCLIENT_ENABLED is true (default true after Gateway V2 default enablement).
int featureValue = 0;
if (Configs.isThinClientEnabled()) {
featureValue |= UserAgentFeatureFlags.ThinClient.getValue();
}
if (Configs.isHttp2Enabled()) {
int featureValue = UserAgentFeatureFlags.Http2.getValue();
featureValue |= UserAgentFeatureFlags.Http2.getValue();
if (Configs.isHttp2PingHealthEnabled() && Configs.getHttp2PingIntervalInSeconds() > 0) {
featureValue |= UserAgentFeatureFlags.Http2PingHealth.getValue();
}
}
if (featureValue != 0) {
expectedUserAgentSuffix = expectedUserAgentSuffix + "|F" + Integer.toHexString(featureValue).toUpperCase(Locale.ROOT);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ public void beforeClass() {
// set externally (Maven profile or -D) so a single test class covers both transports
// across two pipeline runs.
System.setProperty("COSMOS.HTTP2_ENABLED", "true");
// Disable the thin-client connectivity probe for the duration of this test.
// The probe fires HTTP/2 POSTs to thin-client port 10250 on every account refresh;
// when this test installs an iptables DROP on port 10250 (THIN_CLIENT_ENABLED=true
// branch) those probe requests time out, the probe trips
// isProxyProbeHealthy()->false, and routing falls back to Gateway V1 on port 443
// -- bypassing the very PING handler this test is exercising. Disable the probe
// so EndpointProbeClient.proxyHealthy stays optimistically true and the data plane
// request actually flows over port 10250 where the iptables DROP can take effect.
System.setProperty("COSMOS.THINCLIENT_PROBE_ENABLED", "false");
logger.info("Transport selected: thinClient={}, h2Port={}", THIN_CLIENT_ENABLED, H2_PORT);

this.client = getClientBuilder().buildAsyncClient();
Expand All @@ -101,6 +110,7 @@ public void beforeClass() {
public void afterClass() {
safeClose(this.client);
System.clearProperty("COSMOS.HTTP2_ENABLED");
System.clearProperty("COSMOS.THINCLIENT_PROBE_ENABLED");
}

@BeforeMethod(groups = {"manual-http-network-fault"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,10 @@ public void rntbd() throws Exception {
assertThat(objectNode.get("connCfg").get("rntbd").asText()).isEqualTo("(cto:PT5S, nrto:PT5S, icto:PT0S, ieto:PT1H, mcpe:130, mrpc:30, cer:true)");

String http2Enabled = Configs.isHttp2Enabled() ? "true" : "false";
assertThat(objectNode.get("connCfg").get("gw").asText()).isEqualTo("(cps:1000, nrto:PT1M, icto:PT1M, cto:PT45S, gwV2Cto:n/a, p:false, http2:(enabled:"+ http2Enabled + ", maxc:1000, minc:" + Math.max(8, Runtime.getRuntime().availableProcessors()) + ", maxs:30))");
String gwV2Cto = Configs.isThinClientEnabled()
? Duration.ofMillis(Configs.getThinClientConnectionTimeoutInMs()).toString()
: "n/a";
assertThat(objectNode.get("connCfg").get("gw").asText()).isEqualTo("(cps:1000, nrto:PT1M, icto:PT1M, cto:PT45S, gwV2Cto:" + gwV2Cto + ", p:false, http2:(enabled:"+ http2Enabled + ", maxc:1000, minc:" + Math.max(8, Runtime.getRuntime().availableProcessors()) + ", maxs:30))");
assertThat(objectNode.get("connCfg").get("other").asText()).isEqualTo("(ed: false, cs: false, rv: true)");
}

Expand Down Expand Up @@ -244,7 +247,10 @@ public void gw() throws Exception {
assertThat(objectNode.get("connCfg").get("rntbd").asText()).isEqualTo("null");

String http2Enabled = Configs.isHttp2Enabled() ? "true" : "false";
assertThat(objectNode.get("connCfg").get("gw").asText()).isEqualTo("(cps:500, nrto:PT18S, icto:PT17S, cto:PT45S, gwV2Cto:n/a, p:false, http2:(enabled:" + http2Enabled + ", maxc:1000, minc:" + Math.max(8, Runtime.getRuntime().availableProcessors()) + ", maxs:30))");
String gwV2Cto = Configs.isThinClientEnabled()
? Duration.ofMillis(Configs.getThinClientConnectionTimeoutInMs()).toString()
: "n/a";
assertThat(objectNode.get("connCfg").get("gw").asText()).isEqualTo("(cps:500, nrto:PT18S, icto:PT17S, cto:PT45S, gwV2Cto:" + gwV2Cto + ", p:false, http2:(enabled:" + http2Enabled + ", maxc:1000, minc:" + Math.max(8, Runtime.getRuntime().availableProcessors()) + ", maxs:30))");
assertThat(objectNode.get("connCfg").get("other").asText()).isEqualTo("(ed: false, cs: false, rv: true)");
}

Expand Down Expand Up @@ -318,7 +324,10 @@ public void full(
assertThat(objectNode.get("connCfg").get("rntbd").asText()).isEqualTo("null");

String http2Enabled = Configs.isHttp2Enabled() ? "true" : "false";
assertThat(objectNode.get("connCfg").get("gw").asText()).isEqualTo("(cps:500, nrto:PT18S, icto:PT17S, cto:PT45S, gwV2Cto:n/a, p:false, http2:(enabled:" + http2Enabled + ", maxc:1000, minc:" + Math.max(8, Runtime.getRuntime().availableProcessors()) + ", maxs:30))");
String gwV2Cto = Configs.isThinClientEnabled()
? Duration.ofMillis(Configs.getThinClientConnectionTimeoutInMs()).toString()
: "n/a";
assertThat(objectNode.get("connCfg").get("gw").asText()).isEqualTo("(cps:500, nrto:PT18S, icto:PT17S, cto:PT45S, gwV2Cto:" + gwV2Cto + ", p:false, http2:(enabled:" + http2Enabled + ", maxc:1000, minc:" + Math.max(8, Runtime.getRuntime().availableProcessors()) + ", maxs:30))");
assertThat(objectNode.get("connCfg").get("other").asText()).isEqualTo("(ed: true, cs: true, rv: false)");
assertThat(objectNode.get("excrgns").asText()).isEqualTo("[westus2]");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,19 @@ public void http2MaxFrameSizeInBytes() {

@Test(groups = { "emulator" })
public void thinClientEnabledTest() {
assertThat(isThinClientEnabled()).isFalse();
// Default flipped to true in the probe-flow work; explicit "false" must still opt out.
System.clearProperty("COSMOS.THINCLIENT_ENABLED");
try {
assertThat(isThinClientEnabled()).isTrue();
} finally {
System.clearProperty("COSMOS.THINCLIENT_ENABLED");
}
System.setProperty("COSMOS.THINCLIENT_ENABLED", "false");
try {
assertThat(isThinClientEnabled()).isFalse();
} finally {
System.clearProperty("COSMOS.THINCLIENT_ENABLED");
}
System.setProperty("COSMOS.THINCLIENT_ENABLED", "true");
try {
assertThat(isThinClientEnabled()).isTrue();
Expand All @@ -242,6 +253,92 @@ public void thinClientEnabledTest() {
}
}

@Test(groups = { "unit" })
public void thinClientProbeEnabledDefaultTest() {
System.clearProperty("COSMOS.THINCLIENT_PROBE_ENABLED");
try {
assertThat(Configs.isThinClientProbeEnabled()).isTrue();
} finally {
System.clearProperty("COSMOS.THINCLIENT_PROBE_ENABLED");
}
}

@Test(groups = { "unit" })
public void thinClientProbeEnabledOverrideTest() {
System.setProperty("COSMOS.THINCLIENT_PROBE_ENABLED", "false");
try {
assertThat(Configs.isThinClientProbeEnabled()).isFalse();
} finally {
System.clearProperty("COSMOS.THINCLIENT_PROBE_ENABLED");
}
}

@Test(groups = { "unit" })
public void thinClientProbeFailureThresholdDefaultTest() {
System.clearProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD");
try {
assertThat(Configs.getThinClientProbeFailureThreshold()).isEqualTo(1);
} finally {
System.clearProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD");
}
}

@Test(groups = { "unit" })
public void thinClientProbeFailureThresholdOverrideTest() {
System.setProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD", "5");
try {
assertThat(Configs.getThinClientProbeFailureThreshold()).isEqualTo(5);
} finally {
System.clearProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD");
}
}

@Test(groups = { "unit" })
public void thinClientProbeFailureThresholdCoercionTest() {
System.setProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD", "0");
try {
assertThat(Configs.getThinClientProbeFailureThreshold()).isEqualTo(1);
} finally {
System.clearProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD");
}
System.setProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD", "-3");
try {
assertThat(Configs.getThinClientProbeFailureThreshold()).isEqualTo(1);
} finally {
System.clearProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD");
}
}

@Test(groups = { "unit" })
public void thinClientProbeFailureThresholdInvalidFallsBackToDefaultTest() {
System.setProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD", "not-a-number");
try {
assertThat(Configs.getThinClientProbeFailureThreshold()).isEqualTo(1);
} finally {
System.clearProperty("COSMOS.THINCLIENT_PROBE_FAILURE_THRESHOLD");
}
}

@Test(groups = { "unit" })
public void thinClientProbePathDefaultTest() {
System.clearProperty("COSMOS.THINCLIENT_PROBE_PATH");
try {
assertThat(Configs.getThinClientProbePath()).isEqualTo("/connectivity-probe");
} finally {
System.clearProperty("COSMOS.THINCLIENT_PROBE_PATH");
}
}

@Test(groups = { "unit" })
public void thinClientProbePathOverrideTest() {
System.setProperty("COSMOS.THINCLIENT_PROBE_PATH", "/custom-probe");
try {
assertThat(Configs.getThinClientProbePath()).isEqualTo("/custom-probe");
} finally {
System.clearProperty("COSMOS.THINCLIENT_PROBE_PATH");
}
}

@Test(groups = { "unit" })
public void thinClientConnectionTimeoutDefaultTest() {
// Default thin client connection timeout should be 5000 milliseconds
Expand Down
Loading
Loading