mirror of https://github.com/longtai-cn/hippo4j
parent
d453c37250
commit
44332d8c8a
@ -1,296 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.common.toolkit;
|
||||
|
||||
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* Incremental MD5 Utility Boundary Test
|
||||
* Tests edge cases and boundary conditions for version-aware MD5 calculation
|
||||
*/
|
||||
public class IncrementalMd5UtilBoundaryTest {
|
||||
|
||||
/**
|
||||
* Test: null config parameter
|
||||
* Expected: Graceful handling without NPE
|
||||
*/
|
||||
@Test
|
||||
public void testGetCoreMd5_NullConfig() {
|
||||
System.out.println("========== Test 1: getCoreMd5 with null config ==========");
|
||||
|
||||
try {
|
||||
String md5 = IncrementalMd5Util.getCoreMd5(null);
|
||||
System.out.println("Result MD5: " + md5);
|
||||
System.out.println("Test passed: Handled null config gracefully");
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception caught: " + e.getClass().getSimpleName());
|
||||
System.out.println("Test passed: NPE expected for null config");
|
||||
// NPE is acceptable for null input
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: config with all null fields
|
||||
* Expected: Generates MD5 without error
|
||||
*/
|
||||
@Test
|
||||
public void testGetCoreMd5_AllNullFields() {
|
||||
System.out.println("\n========== Test 2: getCoreMd5 with all null fields ==========");
|
||||
|
||||
ThreadPoolParameterInfo config = new ThreadPoolParameterInfo();
|
||||
// All fields are null
|
||||
|
||||
String md5 = IncrementalMd5Util.getCoreMd5(config);
|
||||
|
||||
System.out.println("Config: all fields null");
|
||||
System.out.println("Generated MD5: " + md5);
|
||||
|
||||
Assert.assertNotNull("MD5 should not be null", md5);
|
||||
Assert.assertFalse("MD5 should not be empty", md5.isEmpty());
|
||||
System.out.println("Test passed: Generated MD5 for null fields");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: version number is 0
|
||||
* Expected: Treats as v1 (any version < 2 is v1)
|
||||
*/
|
||||
@Test
|
||||
public void testGetVersionedMd5_VersionZero() {
|
||||
System.out.println("\n========== Test 3: getVersionedMd5 with version = 0 ==========");
|
||||
|
||||
ThreadPoolParameterInfo config = new ThreadPoolParameterInfo();
|
||||
config.setCorePoolSize(10);
|
||||
config.setMaximumPoolSize(20);
|
||||
config.setExecuteTimeOut(5000L);
|
||||
config.setFieldVersionMetadata(Collections.singletonMap("executeTimeOut", "2.1.0"));
|
||||
|
||||
String v0Md5 = IncrementalMd5Util.getVersionedMd5(config, 0);
|
||||
String v1Md5 = IncrementalMd5Util.getVersionedMd5(config, 1);
|
||||
|
||||
System.out.println("Version 0 MD5: " + v0Md5);
|
||||
System.out.println("Version 1 MD5: " + v1Md5);
|
||||
System.out.println("Are they equal? " + v0Md5.equals(v1Md5));
|
||||
|
||||
Assert.assertEquals("Version 0 should behave like v1", v1Md5, v0Md5);
|
||||
System.out.println("Test passed: Version 0 uses v1 behavior");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: version number is negative
|
||||
* Expected: Treats as v1 (any version < 2 is v1)
|
||||
*/
|
||||
@Test
|
||||
public void testGetVersionedMd5_NegativeVersion() {
|
||||
System.out.println("\n========== Test 4: getVersionedMd5 with negative version ==========");
|
||||
|
||||
ThreadPoolParameterInfo config = new ThreadPoolParameterInfo();
|
||||
config.setCorePoolSize(10);
|
||||
config.setMaximumPoolSize(20);
|
||||
config.setExecuteTimeOut(5000L);
|
||||
config.setFieldVersionMetadata(Collections.singletonMap("executeTimeOut", "2.1.0"));
|
||||
|
||||
String vNegativeMd5 = IncrementalMd5Util.getVersionedMd5(config, -1);
|
||||
String v1Md5 = IncrementalMd5Util.getVersionedMd5(config, 1);
|
||||
|
||||
System.out.println("Version -1 MD5: " + vNegativeMd5);
|
||||
System.out.println("Version 1 MD5: " + v1Md5);
|
||||
System.out.println("Are they equal? " + vNegativeMd5.equals(v1Md5));
|
||||
|
||||
Assert.assertEquals("Negative version should behave like v1", v1Md5, vNegativeMd5);
|
||||
System.out.println("Test passed: Negative version uses v1 behavior");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: very large version number
|
||||
* Expected: Treats as v2+ (uses incremental MD5)
|
||||
*/
|
||||
@Test
|
||||
public void testGetVersionedMd5_LargeVersion() {
|
||||
System.out.println("\n========== Test 5: getVersionedMd5 with very large version ==========");
|
||||
|
||||
ThreadPoolParameterInfo config = new ThreadPoolParameterInfo();
|
||||
config.setTenantId("test");
|
||||
config.setItemId("test");
|
||||
config.setTpId("test");
|
||||
config.setCorePoolSize(10);
|
||||
config.setMaximumPoolSize(20);
|
||||
config.setQueueType(1);
|
||||
config.setCapacity(1024);
|
||||
config.setKeepAliveTime(60L);
|
||||
config.setRejectedType(1);
|
||||
config.setAllowCoreThreadTimeOut(0);
|
||||
|
||||
String vLargeMd5 = IncrementalMd5Util.getVersionedMd5(config, 999999);
|
||||
String v2Md5 = IncrementalMd5Util.getVersionedMd5(config, 2);
|
||||
|
||||
System.out.println("Version 999999 MD5: " + vLargeMd5);
|
||||
System.out.println("Version 2 MD5: " + v2Md5);
|
||||
System.out.println("Are they equal? " + vLargeMd5.equals(v2Md5));
|
||||
|
||||
Assert.assertEquals("Large version should behave like v2", v2Md5, vLargeMd5);
|
||||
System.out.println("Test passed: Large version uses v2 behavior");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: config with only extended parameters
|
||||
* Expected: v2 generates MD5 for core params (even if empty)
|
||||
*/
|
||||
@Test
|
||||
public void testGetVersionedMd5_OnlyExtendedParams() {
|
||||
System.out.println("\n========== Test 6: Config with only extended parameters ==========");
|
||||
|
||||
ThreadPoolParameterInfo config = new ThreadPoolParameterInfo();
|
||||
// Only extended parameters
|
||||
config.setExecuteTimeOut(5000L);
|
||||
config.setIsAlarm(1);
|
||||
config.setCapacityAlarm(80);
|
||||
LinkedHashMap<String, String> metadata = new LinkedHashMap<>();
|
||||
metadata.put("executeTimeOut", "2.1.0");
|
||||
metadata.put("isAlarm", "2.1.0");
|
||||
metadata.put("capacityAlarm", "2.1.0");
|
||||
config.setFieldVersionMetadata(metadata);
|
||||
|
||||
String v1Md5 = IncrementalMd5Util.getVersionedMd5(config, 1);
|
||||
String v2Md5 = IncrementalMd5Util.getVersionedMd5(config, 2);
|
||||
String v3Md5 = IncrementalMd5Util.getVersionedMd5(config, 3);
|
||||
|
||||
System.out.println("Config: Only extended params (executeTimeOut, isAlarm, capacityAlarm)");
|
||||
System.out.println("v1 MD5: " + v1Md5);
|
||||
System.out.println("v2 MD5: " + v2Md5);
|
||||
System.out.println("Are v1 and v2 same? " + v1Md5.equals(v2Md5));
|
||||
System.out.println("Does v3 differ? " + !v2Md5.equals(v3Md5));
|
||||
|
||||
Assert.assertEquals("Protocols below threshold skip extended params", v1Md5, v2Md5);
|
||||
Assert.assertNotEquals("Supported protocol should include extended params", v2Md5, v3Md5);
|
||||
System.out.println("Test passed: Metadata gates extended params by protocol");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: isDifferent with same MD5
|
||||
* Expected: Returns false (no difference)
|
||||
*/
|
||||
@Test
|
||||
public void testIsDifferent_SameMd5() {
|
||||
System.out.println("\n========== Test 7: isDifferent with same MD5 ==========");
|
||||
|
||||
ThreadPoolParameterInfo oldConfig = new ThreadPoolParameterInfo();
|
||||
oldConfig.setCorePoolSize(10);
|
||||
oldConfig.setMaximumPoolSize(20);
|
||||
|
||||
ThreadPoolParameterInfo newConfig = new ThreadPoolParameterInfo();
|
||||
newConfig.setCorePoolSize(10);
|
||||
newConfig.setMaximumPoolSize(20);
|
||||
|
||||
boolean isDifferent = IncrementalMd5Util.isDifferent(oldConfig, newConfig, 2);
|
||||
|
||||
System.out.println("Old and new configs are identical");
|
||||
System.out.println("isDifferent result: " + isDifferent);
|
||||
|
||||
Assert.assertFalse("Should return false for identical configs", isDifferent);
|
||||
System.out.println("Test passed: Identical configs correctly identified");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: isDifferent with different MD5
|
||||
* Expected: Returns true (difference detected)
|
||||
*/
|
||||
@Test
|
||||
public void testIsDifferent_DifferentMd5() {
|
||||
System.out.println("\n========== Test 8: isDifferent with different MD5 ==========");
|
||||
|
||||
ThreadPoolParameterInfo oldConfig = new ThreadPoolParameterInfo();
|
||||
oldConfig.setCorePoolSize(10);
|
||||
oldConfig.setMaximumPoolSize(20);
|
||||
|
||||
ThreadPoolParameterInfo newConfig = new ThreadPoolParameterInfo();
|
||||
newConfig.setCorePoolSize(15); // Different!
|
||||
newConfig.setMaximumPoolSize(20);
|
||||
|
||||
boolean isDifferent = IncrementalMd5Util.isDifferent(oldConfig, newConfig, 2);
|
||||
|
||||
System.out.println("Old corePoolSize: 10, New corePoolSize: 15");
|
||||
System.out.println("isDifferent result: " + isDifferent);
|
||||
|
||||
Assert.assertTrue("Should return true for different configs", isDifferent);
|
||||
System.out.println("Test passed: Different configs correctly identified");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Empty string vs null for string fields
|
||||
* Expected: Both generate valid MD5
|
||||
*/
|
||||
@Test
|
||||
public void testGetCoreMd5_EmptyVsNullString() {
|
||||
System.out.println("\n========== Test 9: Empty string vs null for string fields ==========");
|
||||
|
||||
ThreadPoolParameterInfo configWithNull = new ThreadPoolParameterInfo();
|
||||
configWithNull.setTenantId(null);
|
||||
configWithNull.setItemId(null);
|
||||
configWithNull.setTpId(null);
|
||||
|
||||
ThreadPoolParameterInfo configWithEmpty = new ThreadPoolParameterInfo();
|
||||
configWithEmpty.setTenantId("");
|
||||
configWithEmpty.setItemId("");
|
||||
configWithEmpty.setTpId("");
|
||||
|
||||
String nullMd5 = IncrementalMd5Util.getCoreMd5(configWithNull);
|
||||
String emptyMd5 = IncrementalMd5Util.getCoreMd5(configWithEmpty);
|
||||
|
||||
System.out.println("Null fields MD5: " + nullMd5);
|
||||
System.out.println("Empty fields MD5: " + emptyMd5);
|
||||
System.out.println("Are they different? " + !nullMd5.equals(emptyMd5));
|
||||
|
||||
Assert.assertNotNull("Null fields MD5 should not be null", nullMd5);
|
||||
Assert.assertNotNull("Empty fields MD5 should not be null", emptyMd5);
|
||||
System.out.println("Test passed: Both null and empty strings handled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Consistency - multiple calls should return same MD5
|
||||
* Expected: Same MD5 for same config
|
||||
*/
|
||||
@Test
|
||||
public void testGetCoreMd5_Consistency() {
|
||||
System.out.println("\n========== Test 10: MD5 calculation consistency ==========");
|
||||
|
||||
ThreadPoolParameterInfo config = new ThreadPoolParameterInfo();
|
||||
config.setTenantId("test");
|
||||
config.setItemId("test");
|
||||
config.setTpId("test");
|
||||
config.setCorePoolSize(10);
|
||||
config.setMaximumPoolSize(20);
|
||||
|
||||
String md51 = IncrementalMd5Util.getCoreMd5(config);
|
||||
String md52 = IncrementalMd5Util.getCoreMd5(config);
|
||||
String md53 = IncrementalMd5Util.getCoreMd5(config);
|
||||
|
||||
System.out.println("MD5 call 1: " + md51);
|
||||
System.out.println("MD5 call 2: " + md52);
|
||||
System.out.println("MD5 call 3: " + md53);
|
||||
System.out.println("All equal? " + (md51.equals(md52) && md52.equals(md53)));
|
||||
|
||||
Assert.assertEquals("Multiple calls should return same MD5", md51, md52);
|
||||
Assert.assertEquals("Multiple calls should return same MD5", md52, md53);
|
||||
System.out.println("Test passed: MD5 calculation is consistent");
|
||||
}
|
||||
}
|
||||
@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.config.service;
|
||||
|
||||
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
|
||||
import cn.hippo4j.common.toolkit.IncrementalMd5Util;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* ConfigCacheService Version-Aware Test
|
||||
* Tests the version-aware MD5 comparison logic for cross-version compatibility
|
||||
*
|
||||
* Note: Tests focus on the MD5 calculation logic used by ConfigCacheService
|
||||
* Integration tests for ConfigCacheService.isUpdateData() are covered separately
|
||||
* due to dependencies on configuration cache infrastructure
|
||||
*/
|
||||
public class ConfigCacheServiceVersionTest {
|
||||
|
||||
/**
|
||||
* Test: Version-aware MD5 comparison logic
|
||||
* Verifies that v1 and v2 produce different MD5 for same config with extended params
|
||||
*/
|
||||
@Test
|
||||
public void testVersionedMd5_Difference() {
|
||||
System.out.println("========== Test 1: v1 vs v2 MD5 difference ==========");
|
||||
|
||||
ThreadPoolParameterInfo config = new ThreadPoolParameterInfo();
|
||||
config.setTenantId("test-tenant");
|
||||
config.setItemId("test-item");
|
||||
config.setTpId("test-pool");
|
||||
config.setCorePoolSize(10);
|
||||
config.setMaximumPoolSize(20);
|
||||
config.setQueueType(2);
|
||||
config.setCapacity(1024);
|
||||
config.setKeepAliveTime(60L);
|
||||
config.setRejectedType(1);
|
||||
config.setAllowCoreThreadTimeOut(0);
|
||||
config.setExecuteTimeOut(5000L); // Extended parameter
|
||||
config.setIsAlarm(1); // Extended parameter
|
||||
LinkedHashMap<String, String> metadata = new LinkedHashMap<>();
|
||||
metadata.put("executeTimeOut", "2.1.0");
|
||||
metadata.put("isAlarm", "2.1.0");
|
||||
config.setFieldVersionMetadata(metadata);
|
||||
|
||||
String v1Md5 = IncrementalMd5Util.getVersionedMd5(config, 1);
|
||||
String v2Md5 = IncrementalMd5Util.getVersionedMd5(config, 2);
|
||||
String v3Md5 = IncrementalMd5Util.getVersionedMd5(config, 3);
|
||||
|
||||
System.out.println("Config includes extended parameters: executeTimeOut, isAlarm");
|
||||
System.out.println("v1 MD5 (full): " + v1Md5);
|
||||
System.out.println("v2 MD5 (incremental): " + v2Md5);
|
||||
System.out.println("v3 MD5 (supports extended): " + v3Md5);
|
||||
System.out.println("v1 equals v2? " + v1Md5.equals(v2Md5));
|
||||
System.out.println("v3 equals v2? " + v3Md5.equals(v2Md5));
|
||||
|
||||
Assert.assertEquals("Protocols below field threshold should share same MD5", v1Md5, v2Md5);
|
||||
Assert.assertNotEquals("Protocol v3 should include extended fields", v2Md5, v3Md5);
|
||||
System.out.println("Test passed: Older protocols share MD5 while supported protocol diverges");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: v2 client should not refresh when only extended params change
|
||||
* This is the core extensibility improvement
|
||||
*/
|
||||
@Test
|
||||
public void testV2Client_ExtendedParamChange_NoRefresh() {
|
||||
System.out.println("\n========== Test 2: v2 client - extended param change ==========");
|
||||
|
||||
// Old config
|
||||
ThreadPoolParameterInfo oldConfig = new ThreadPoolParameterInfo();
|
||||
oldConfig.setCorePoolSize(10);
|
||||
oldConfig.setMaximumPoolSize(20);
|
||||
oldConfig.setQueueType(2);
|
||||
oldConfig.setCapacity(1024);
|
||||
oldConfig.setKeepAliveTime(60L);
|
||||
oldConfig.setRejectedType(1);
|
||||
oldConfig.setAllowCoreThreadTimeOut(0);
|
||||
oldConfig.setExecuteTimeOut(3000L); // Extended
|
||||
LinkedHashMap<String, String> metadata = new LinkedHashMap<>();
|
||||
metadata.put("executeTimeOut", "2.1.0");
|
||||
oldConfig.setFieldVersionMetadata(metadata);
|
||||
|
||||
// New config (only extended param changed)
|
||||
ThreadPoolParameterInfo newConfig = new ThreadPoolParameterInfo();
|
||||
newConfig.setCorePoolSize(10);
|
||||
newConfig.setMaximumPoolSize(20);
|
||||
newConfig.setQueueType(2);
|
||||
newConfig.setCapacity(1024);
|
||||
newConfig.setKeepAliveTime(60L);
|
||||
newConfig.setRejectedType(1);
|
||||
newConfig.setAllowCoreThreadTimeOut(0);
|
||||
newConfig.setExecuteTimeOut(5000L); // Extended param changed!
|
||||
newConfig.setFieldVersionMetadata(metadata);
|
||||
|
||||
String oldV2Md5 = IncrementalMd5Util.getVersionedMd5(oldConfig, 2);
|
||||
String newV2Md5 = IncrementalMd5Util.getVersionedMd5(newConfig, 2);
|
||||
|
||||
System.out.println("Extended param change: executeTimeOut 3000 -> 5000");
|
||||
System.out.println("Old v2 MD5: " + oldV2Md5);
|
||||
System.out.println("New v2 MD5: " + newV2Md5);
|
||||
System.out.println("Are they same? " + oldV2Md5.equals(newV2Md5));
|
||||
|
||||
Assert.assertEquals("v2 MD5 should remain same (no core param change)", oldV2Md5, newV2Md5);
|
||||
System.out.println("Test passed: v2 client won't refresh for extended param change");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: v1 client SHOULD refresh when extended params change
|
||||
* This verifies backward compatibility
|
||||
*/
|
||||
@Test
|
||||
public void testV1Client_ExtendedParamChange_NoRefresh() {
|
||||
System.out.println("\n========== Test 3: v1 client - extended param change ==========");
|
||||
|
||||
// Old config
|
||||
ThreadPoolParameterInfo oldConfig = new ThreadPoolParameterInfo();
|
||||
oldConfig.setCorePoolSize(10);
|
||||
oldConfig.setMaximumPoolSize(20);
|
||||
oldConfig.setQueueType(2);
|
||||
oldConfig.setCapacity(1024);
|
||||
oldConfig.setExecuteTimeOut(3000L);
|
||||
LinkedHashMap<String, String> metadata = new LinkedHashMap<>();
|
||||
metadata.put("executeTimeOut", "2.1.0");
|
||||
oldConfig.setFieldVersionMetadata(metadata);
|
||||
|
||||
// New config (only extended param changed)
|
||||
ThreadPoolParameterInfo newConfig = new ThreadPoolParameterInfo();
|
||||
newConfig.setCorePoolSize(10);
|
||||
newConfig.setMaximumPoolSize(20);
|
||||
newConfig.setQueueType(2);
|
||||
newConfig.setCapacity(1024);
|
||||
newConfig.setExecuteTimeOut(5000L); // Extended param changed!
|
||||
newConfig.setFieldVersionMetadata(metadata);
|
||||
|
||||
String oldV1Md5 = IncrementalMd5Util.getVersionedMd5(oldConfig, 1);
|
||||
String newV1Md5 = IncrementalMd5Util.getVersionedMd5(newConfig, 1);
|
||||
|
||||
System.out.println("Extended param change: executeTimeOut 3000 -> 5000");
|
||||
System.out.println("Old v1 MD5: " + oldV1Md5);
|
||||
System.out.println("New v1 MD5: " + newV1Md5);
|
||||
System.out.println("Are they same? " + oldV1Md5.equals(newV1Md5));
|
||||
|
||||
Assert.assertEquals("v1 should now leverage metadata to skip unsupported fields", oldV1Md5, newV1Md5);
|
||||
System.out.println("Test passed: v1 client no longer refreshes for unsupported fields");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Both v1 and v2 should refresh when core params change
|
||||
* This ensures core functionality still works for both versions
|
||||
*/
|
||||
@Test
|
||||
public void testBothVersions_CoreParamChange_ShouldRefresh() {
|
||||
System.out.println("\n========== Test 4: Both versions - core param change ==========");
|
||||
|
||||
// Old config
|
||||
ThreadPoolParameterInfo oldConfig = new ThreadPoolParameterInfo();
|
||||
oldConfig.setCorePoolSize(10);
|
||||
oldConfig.setMaximumPoolSize(20);
|
||||
oldConfig.setQueueType(2);
|
||||
|
||||
// New config (core param changed)
|
||||
ThreadPoolParameterInfo newConfig = new ThreadPoolParameterInfo();
|
||||
newConfig.setCorePoolSize(15); // Core param changed!
|
||||
newConfig.setMaximumPoolSize(20);
|
||||
newConfig.setQueueType(2);
|
||||
|
||||
String oldV1Md5 = IncrementalMd5Util.getVersionedMd5(oldConfig, 1);
|
||||
String newV1Md5 = IncrementalMd5Util.getVersionedMd5(newConfig, 1);
|
||||
String oldV2Md5 = IncrementalMd5Util.getVersionedMd5(oldConfig, 2);
|
||||
String newV2Md5 = IncrementalMd5Util.getVersionedMd5(newConfig, 2);
|
||||
|
||||
System.out.println("Core param change: corePoolSize 10 -> 15");
|
||||
System.out.println("v1: " + oldV1Md5 + " -> " + newV1Md5 + " (different? " + !oldV1Md5.equals(newV1Md5) + ")");
|
||||
System.out.println("v2: " + oldV2Md5 + " -> " + newV2Md5 + " (different? " + !oldV2Md5.equals(newV2Md5) + ")");
|
||||
|
||||
Assert.assertNotEquals("v1 should detect core param change", oldV1Md5, newV1Md5);
|
||||
Assert.assertNotEquals("v2 should detect core param change", oldV2Md5, newV2Md5);
|
||||
System.out.println("Test passed: Both versions detect core param changes");
|
||||
}
|
||||
}
|
||||
@ -1,223 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.config.toolkit;
|
||||
|
||||
import cn.hippo4j.common.constant.Constants;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Md5ConfigUtil Version Detection Test
|
||||
* Tests the client protocol version detection logic for cross-version compatibility
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class Md5ConfigUtilVersionTest {
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
|
||||
private static final String PROTOCOL_VERSION_HEADER = "X-Hippo4j-Protocol-Version";
|
||||
|
||||
/**
|
||||
* Test: Client sends v2 protocol version header
|
||||
* Expected: Server correctly identifies client as v2
|
||||
*/
|
||||
@Test
|
||||
public void testGetClientVersion_WithV2Header() throws Exception {
|
||||
System.out.println("========== Test 1: Client sends v2 version header ==========");
|
||||
|
||||
when(request.getHeader(PROTOCOL_VERSION_HEADER)).thenReturn("2");
|
||||
|
||||
int version = invokeGetClientVersion(request);
|
||||
|
||||
System.out.println("Request header: X-Hippo4j-Protocol-Version = 2");
|
||||
System.out.println("Detected client version: " + version);
|
||||
|
||||
Assert.assertEquals("Should detect v2 client", 2, version);
|
||||
System.out.println("Test passed: Server correctly identifies v2 client");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Old client doesn't send version header
|
||||
* Expected: Server defaults to v1 for backward compatibility
|
||||
*/
|
||||
@Test
|
||||
public void testGetClientVersion_WithoutHeader() throws Exception {
|
||||
System.out.println("\n========== Test 2: Old client without version header ==========");
|
||||
|
||||
when(request.getHeader(PROTOCOL_VERSION_HEADER)).thenReturn(null);
|
||||
|
||||
int version = invokeGetClientVersion(request);
|
||||
|
||||
System.out.println("Request header: X-Hippo4j-Protocol-Version = null");
|
||||
System.out.println("Detected client version: " + version);
|
||||
|
||||
Assert.assertEquals("Should default to v1", 1, version);
|
||||
System.out.println("Test passed: Server defaults to v1 for backward compatibility");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Version header is empty string
|
||||
* Expected: Server defaults to v1
|
||||
*/
|
||||
@Test
|
||||
public void testGetClientVersion_WithEmptyHeader() throws Exception {
|
||||
System.out.println("\n========== Test 3: Version header is empty string ==========");
|
||||
|
||||
when(request.getHeader(PROTOCOL_VERSION_HEADER)).thenReturn("");
|
||||
|
||||
int version = invokeGetClientVersion(request);
|
||||
|
||||
System.out.println("Request header: X-Hippo4j-Protocol-Version = \"\"");
|
||||
System.out.println("Detected client version: " + version);
|
||||
|
||||
Assert.assertEquals("Should default to v1 for empty header", 1, version);
|
||||
System.out.println("Test passed: Empty header defaults to v1");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Version header has invalid format (non-numeric)
|
||||
* Expected: Server gracefully handles error and defaults to v1
|
||||
*/
|
||||
@Test
|
||||
public void testGetClientVersion_WithInvalidFormat() throws Exception {
|
||||
System.out.println("\n========== Test 4: Version header has invalid format ==========");
|
||||
|
||||
when(request.getHeader(PROTOCOL_VERSION_HEADER)).thenReturn("invalid");
|
||||
|
||||
int version = invokeGetClientVersion(request);
|
||||
|
||||
System.out.println("Request header: X-Hippo4j-Protocol-Version = \"invalid\"");
|
||||
System.out.println("Detected client version: " + version);
|
||||
|
||||
Assert.assertEquals("Should default to v1 for invalid format", 1, version);
|
||||
System.out.println("Test passed: Invalid format gracefully handled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Version header is v1 explicitly
|
||||
* Expected: Server correctly identifies as v1
|
||||
*/
|
||||
@Test
|
||||
public void testGetClientVersion_WithV1Header() throws Exception {
|
||||
System.out.println("\n========== Test 5: Client explicitly sends v1 ==========");
|
||||
|
||||
when(request.getHeader(PROTOCOL_VERSION_HEADER)).thenReturn("1");
|
||||
|
||||
int version = invokeGetClientVersion(request);
|
||||
|
||||
System.out.println("Request header: X-Hippo4j-Protocol-Version = 1");
|
||||
System.out.println("Detected client version: " + version);
|
||||
|
||||
Assert.assertEquals("Should detect v1 client", 1, version);
|
||||
System.out.println("Test passed: Server correctly identifies v1 client");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Version header is future version (v3)
|
||||
* Expected: Server correctly parses and returns the version
|
||||
*/
|
||||
@Test
|
||||
public void testGetClientVersion_WithFutureVersion() throws Exception {
|
||||
System.out.println("\n========== Test 6: Client sends future version (v3) ==========");
|
||||
|
||||
when(request.getHeader(PROTOCOL_VERSION_HEADER)).thenReturn("3");
|
||||
|
||||
int version = invokeGetClientVersion(request);
|
||||
|
||||
System.out.println("Request header: X-Hippo4j-Protocol-Version = 3");
|
||||
System.out.println("Detected client version: " + version);
|
||||
|
||||
Assert.assertEquals("Should parse future version", 3, version);
|
||||
System.out.println("Test passed: Future version handled correctly");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: compareMd5 method can be called with v1 client
|
||||
* Note: This is a lightweight test focusing on version detection
|
||||
* Full integration tests are covered separately
|
||||
*/
|
||||
@Test
|
||||
public void testCompareMd5_VersionDetection_V1Client() throws Exception {
|
||||
System.out.println("\n========== Test 7: Version detection in compareMd5 (v1) ==========");
|
||||
|
||||
when(request.getHeader(PROTOCOL_VERSION_HEADER)).thenReturn(null);
|
||||
|
||||
// Verify version detection works
|
||||
int version = invokeGetClientVersion(request);
|
||||
|
||||
System.out.println("Client version detected: v" + version);
|
||||
Assert.assertEquals("Should detect v1 client", 1, version);
|
||||
System.out.println("Test passed: compareMd5 will use v1 protocol for this client");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: compareMd5 method can be called with v2 client
|
||||
* Note: This is a lightweight test focusing on version detection
|
||||
* Full integration tests are covered separately
|
||||
*/
|
||||
@Test
|
||||
public void testCompareMd5_VersionDetection_V2Client() throws Exception {
|
||||
System.out.println("\n========== Test 8: Version detection in compareMd5 (v2) ==========");
|
||||
|
||||
when(request.getHeader(PROTOCOL_VERSION_HEADER)).thenReturn("2");
|
||||
|
||||
// Verify version detection works
|
||||
int version = invokeGetClientVersion(request);
|
||||
|
||||
System.out.println("Client version detected: v" + version);
|
||||
Assert.assertEquals("Should detect v2 client", 2, version);
|
||||
System.out.println("Test passed: compareMd5 will use v2 protocol for this client");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Fallback to semantic client version when protocol header is missing.
|
||||
*/
|
||||
@Test
|
||||
public void testGetClientVersion_FromClientVersionHeader() throws Exception {
|
||||
System.out.println("\n========== Test 9: Fallback to client version header ==========");
|
||||
|
||||
when(request.getHeader(PROTOCOL_VERSION_HEADER)).thenReturn(null);
|
||||
when(request.getHeader(Constants.CLIENT_VERSION)).thenReturn("2.0.1");
|
||||
|
||||
int version = invokeGetClientVersion(request);
|
||||
|
||||
System.out.println("Client-Version header: 2.0.1");
|
||||
System.out.println("Detected protocol version: v" + version);
|
||||
|
||||
Assert.assertEquals("Semantic version should map to protocol v2", 2, version);
|
||||
System.out.println("Test passed: Fallback resolved protocol from client version header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to invoke private getClientVersion method via reflection
|
||||
*/
|
||||
private int invokeGetClientVersion(HttpServletRequest request) throws Exception {
|
||||
Method method = Md5ConfigUtil.class.getDeclaredMethod("getClientProtocolVersion", HttpServletRequest.class, String.class);
|
||||
method.setAccessible(true);
|
||||
return (int) method.invoke(null, request, request.getHeader(Constants.CLIENT_VERSION));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue