fix
This commit is contained in:
@@ -35,6 +35,7 @@ class ConfigLogicTest {
|
||||
- id: p1
|
||||
url: "https://x.ru/api/v1"
|
||||
key: "k"
|
||||
max_concurrency: 4
|
||||
patch:
|
||||
provider:
|
||||
allow_fallbacks: false
|
||||
@@ -61,6 +62,7 @@ class ConfigLogicTest {
|
||||
|
||||
assertEquals(1, cfg.providers.size)
|
||||
assertEquals("https://x.ru/api/v1", cfg.providers[0].url)
|
||||
assertEquals(4, cfg.providers[0].max_concurrency)
|
||||
assertEquals(2, cfg.upstreams.size)
|
||||
assertEquals(2, cfg.upstreams[0].max_concurrency)
|
||||
assertEquals(listOf("u1", "bad"), cfg.models[0].upstreams)
|
||||
@@ -70,6 +72,53 @@ class ConfigLogicTest {
|
||||
assertEquals("""{"reasoning":{"enabled":false}}""", cfg.models[0].patch.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parseConfigReadsServerBlock() {
|
||||
val yaml = """
|
||||
server:
|
||||
host: 127.0.0.1
|
||||
port: 9200
|
||||
models:
|
||||
- name: m1
|
||||
upstreams: []
|
||||
""".trimIndent()
|
||||
|
||||
val cfg = parseConfig(Yaml.decodeYamlFromString(yaml))
|
||||
|
||||
assertEquals("127.0.0.1", cfg.server.host)
|
||||
assertEquals(9200, cfg.server.port)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parseConfigServerDefaultsWhenBlockAbsent() {
|
||||
val yaml = """
|
||||
models:
|
||||
- name: m1
|
||||
upstreams: []
|
||||
""".trimIndent()
|
||||
|
||||
val cfg = parseConfig(Yaml.decodeYamlFromString(yaml))
|
||||
|
||||
assertEquals("0.0.0.0", cfg.server.host)
|
||||
assertEquals(8100, cfg.server.port)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parseConfigServerFieldDefaultsPerField() {
|
||||
val yaml = """
|
||||
server:
|
||||
host: 192.168.88.10
|
||||
models:
|
||||
- name: m1
|
||||
upstreams: []
|
||||
""".trimIndent()
|
||||
|
||||
val cfg = parseConfig(Yaml.decodeYamlFromString(yaml))
|
||||
|
||||
assertEquals("192.168.88.10", cfg.server.host)
|
||||
assertEquals(8100, cfg.server.port)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parseConfigOmitsPatchWhenAbsent() {
|
||||
val yaml = """
|
||||
@@ -93,7 +142,7 @@ class ConfigLogicTest {
|
||||
@Test
|
||||
fun buildBodySubstitutesModelAndAppliesLayersInOrder() {
|
||||
val provider = ProviderConf(
|
||||
"p1", "https://x", "",
|
||||
"p1", "https://x", "", null,
|
||||
Json.parseToJsonElement("""{"provider":{"allow_fallbacks":false}}""").jsonObject,
|
||||
)
|
||||
val up = UpstreamConf(
|
||||
@@ -133,7 +182,7 @@ class ConfigLogicTest {
|
||||
|
||||
@Test
|
||||
fun tryClaimRespectsMaxConcurrencyAndReleaseFreesSlot() {
|
||||
val active = mapOf("u1" to UpstreamCounter(0))
|
||||
val active = mapOf("u1" to UpstreamCounter(1))
|
||||
val up = UpstreamConf("u1", "p", "m", 1, null)
|
||||
assertTrue(tryClaim(up, active))
|
||||
assertFalse(tryClaim(up, active))
|
||||
@@ -143,15 +192,37 @@ class ConfigLogicTest {
|
||||
|
||||
@Test
|
||||
fun tryClaimUnlimitedWhenMaxConcurrencyIsNull() {
|
||||
val active = mapOf("u2" to UpstreamCounter(0))
|
||||
val active = mapOf("u2" to UpstreamCounter(Int.MAX_VALUE))
|
||||
val up = UpstreamConf("u2", "p", "m", null, null)
|
||||
assertTrue(tryClaim(up, active))
|
||||
assertTrue(tryClaim(up, active))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun effectiveConcurrencyLimitPrefersUpstreamThenProvider() {
|
||||
val providerWithLimit = ProviderConf("p1", "https://x", "", 3, null)
|
||||
val providerWithoutLimit = ProviderConf("p2", "https://x", "", null, null)
|
||||
assertEquals(
|
||||
2,
|
||||
effectiveConcurrencyLimit(UpstreamConf("u1", "p1", "m", 2, null), providerWithLimit),
|
||||
)
|
||||
assertEquals(
|
||||
3,
|
||||
effectiveConcurrencyLimit(UpstreamConf("u1", "p1", "m", null, null), providerWithLimit),
|
||||
)
|
||||
assertEquals(
|
||||
Int.MAX_VALUE,
|
||||
effectiveConcurrencyLimit(UpstreamConf("u1", "p2", "m", null, null), providerWithoutLimit),
|
||||
)
|
||||
assertEquals(
|
||||
Int.MAX_VALUE,
|
||||
effectiveConcurrencyLimit(UpstreamConf("u1", "missing", "m", null, null), null),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun pickFreeUpstreamReturnsFirstFreeInDeclarationOrder() {
|
||||
val active = mapOf("u1" to UpstreamCounter(0), "u2" to UpstreamCounter(0))
|
||||
val active = mapOf("u1" to UpstreamCounter(1), "u2" to UpstreamCounter(2))
|
||||
val pool = listOf(
|
||||
UpstreamConf("u1", "p", "m", 1, null),
|
||||
UpstreamConf("u2", "p", "m", 2, null),
|
||||
@@ -164,7 +235,7 @@ class ConfigLogicTest {
|
||||
|
||||
@Test
|
||||
fun pickFreeUpstreamSkipsExcluded() {
|
||||
val active = mapOf("u1" to UpstreamCounter(0), "u2" to UpstreamCounter(0))
|
||||
val active = mapOf("u1" to UpstreamCounter(1), "u2" to UpstreamCounter(2))
|
||||
val pool = listOf(
|
||||
UpstreamConf("u1", "p", "m", 1, null),
|
||||
UpstreamConf("u2", "p", "m", 2, null),
|
||||
@@ -183,7 +254,7 @@ class ConfigLogicTest {
|
||||
@Test
|
||||
fun pickFreeUpstreamImplementsFailoverOrder() {
|
||||
// dead исключён (упал ранее) — выбирается следующий живой u1
|
||||
val active = mapOf("dead" to UpstreamCounter(0), "u1" to UpstreamCounter(0))
|
||||
val active = mapOf("dead" to UpstreamCounter(1), "u1" to UpstreamCounter(1))
|
||||
val pool = listOf(
|
||||
UpstreamConf("dead", "p", "m", 1, null),
|
||||
UpstreamConf("u1", "p", "m", 1, null),
|
||||
@@ -194,7 +265,7 @@ class ConfigLogicTest {
|
||||
|
||||
@Test
|
||||
fun pickFreeUpstreamExhaustsConcurrencyThenReturnsNull() {
|
||||
val active = mapOf("u1" to UpstreamCounter(0), "u2" to UpstreamCounter(0))
|
||||
val active = mapOf("u1" to UpstreamCounter(1), "u2" to UpstreamCounter(1))
|
||||
val pool = listOf(
|
||||
UpstreamConf("u1", "p", "m", 1, null),
|
||||
UpstreamConf("u2", "p", "m", 1, null),
|
||||
|
||||
Reference in New Issue
Block a user