From 958cff43f3fed57973bc7c8ff5f34ca8b176af14 Mon Sep 17 00:00:00 2001 From: joyc-bq Date: Tue, 17 Dec 2024 21:42:16 -0800 Subject: [PATCH 1/5] fix: connection tracker update after failover --- .../connection_string_host_list_provider.ts | 2 +- .../host_list_provider/host_list_provider.ts | 2 +- .../rds_host_list_provider.ts | 8 ++--- common/lib/plugin_service.ts | 2 +- .../aurora_connection_tracker_plugin.ts | 3 +- .../lib/plugins/failover/failover_plugin.ts | 20 +++++++++-- .../failover/reader_failover_handler.ts | 33 ++++++++++--------- common/lib/utils/locales/en.json | 4 ++- pg/lib/dialect/aurora_pg_database_dialect.ts | 2 +- 9 files changed, 49 insertions(+), 27 deletions(-) diff --git a/common/lib/host_list_provider/connection_string_host_list_provider.ts b/common/lib/host_list_provider/connection_string_host_list_provider.ts index 85eb27e1..cd5f1a59 100644 --- a/common/lib/host_list_provider/connection_string_host_list_provider.ts +++ b/common/lib/host_list_provider/connection_string_host_list_provider.ts @@ -81,7 +81,7 @@ export class ConnectionStringHostListProvider implements StaticHostListProvider return Promise.resolve(this.hostList); } - getHostRole(client: AwsClient): Promise { + getHostRole(client: ClientWrapper): Promise { throw new AwsWrapperError("ConnectionStringHostListProvider does not support getHostRole."); } diff --git a/common/lib/host_list_provider/host_list_provider.ts b/common/lib/host_list_provider/host_list_provider.ts index fcd29857..801577f6 100644 --- a/common/lib/host_list_provider/host_list_provider.ts +++ b/common/lib/host_list_provider/host_list_provider.ts @@ -33,7 +33,7 @@ export interface HostListProvider { forceRefresh(client: ClientWrapper): Promise; - getHostRole(client: AwsClient, dialect: DatabaseDialect): Promise; + getHostRole(client: ClientWrapper, dialect: DatabaseDialect): Promise; identifyConnection(targetClient: ClientWrapper, dialect: DatabaseDialect): Promise; diff --git a/common/lib/host_list_provider/rds_host_list_provider.ts b/common/lib/host_list_provider/rds_host_list_provider.ts index 1099f9a2..9bc970bb 100644 --- a/common/lib/host_list_provider/rds_host_list_provider.ts +++ b/common/lib/host_list_provider/rds_host_list_provider.ts @@ -137,15 +137,15 @@ export class RdsHostListProvider implements DynamicHostListProvider { throw new AwsWrapperError("Could not retrieve targetClient."); } - async getHostRole(client: AwsClient, dialect: DatabaseDialect): Promise { + async getHostRole(client: ClientWrapper, dialect: DatabaseDialect): Promise { if (!this.isTopologyAwareDatabaseDialect(dialect)) { throw new TypeError(Messages.get("RdsHostListProvider.incorrectDialect")); } - if (client.targetClient) { - return dialect.getHostRole(client.targetClient); + if (client) { + return await dialect.getHostRole(client); } else { - throw new AwsWrapperError(Messages.get("AwsClient targetClient not defined.")); + throw new AwsWrapperError(Messages.get("AwsClient.targetClientNotDefined")); } } diff --git a/common/lib/plugin_service.ts b/common/lib/plugin_service.ts index f4ea810a..c31ace82 100644 --- a/common/lib/plugin_service.ts +++ b/common/lib/plugin_service.ts @@ -40,7 +40,7 @@ import { ClientWrapper } from "./client_wrapper"; import { logger } from "../logutils"; import { Messages } from "./utils/messages"; import { DatabaseDialectCodes } from "./database_dialect/database_dialect_codes"; -import { getWriter } from "./utils/utils"; +import { getWriter, logTopology } from "./utils/utils"; import { TelemetryFactory } from "./utils/telemetry/telemetry_factory"; import { DriverDialect } from "./driver_dialect/driver_dialect"; import { ConfigurationProfile } from "./profile/configuration_profile"; diff --git a/common/lib/plugins/connection_tracker/aurora_connection_tracker_plugin.ts b/common/lib/plugins/connection_tracker/aurora_connection_tracker_plugin.ts index 3c2c2ec7..85c42d94 100644 --- a/common/lib/plugins/connection_tracker/aurora_connection_tracker_plugin.ts +++ b/common/lib/plugins/connection_tracker/aurora_connection_tracker_plugin.ts @@ -100,7 +100,6 @@ export class AuroraConnectionTrackerPlugin extends AbstractConnectionPlugin impl private async checkWriterChanged(): Promise { const hostInfoAfterFailover = this.getWriter(this.pluginService.getHosts()); - if (this.currentWriter === null) { this.currentWriter = hostInfoAfterFailover; this.needUpdateCurrentWriter = false; @@ -127,10 +126,12 @@ export class AuroraConnectionTrackerPlugin extends AbstractConnectionPlugin impl async notifyHostListChanged(changes: Map>): Promise { for (const [key, _] of changes.entries()) { const hostChanges = changes.get(key); + if (hostChanges) { if (hostChanges.has(HostChangeOptions.PROMOTED_TO_READER)) { await this.tracker.invalidateAllConnectionsMultipleHosts(key); } + if (hostChanges.has(HostChangeOptions.PROMOTED_TO_WRITER)) { this.needUpdateCurrentWriter = true; } diff --git a/common/lib/plugins/failover/failover_plugin.ts b/common/lib/plugins/failover/failover_plugin.ts index ac4209a9..80c59a07 100644 --- a/common/lib/plugins/failover/failover_plugin.ts +++ b/common/lib/plugins/failover/failover_plugin.ts @@ -48,6 +48,7 @@ export class FailoverPlugin extends AbstractConnectionPlugin { private static readonly TELEMETRY_WRITER_FAILOVER = "failover to writer instance"; private static readonly TELEMETRY_READER_FAILOVER = "failover to replica"; private static readonly METHOD_END = "end"; + private static readonly subscribedMethods: Set = new Set([ "initHostProvider", "connect", @@ -392,7 +393,7 @@ export class FailoverPlugin extends AbstractConnectionPlugin { await this.pluginService.setCurrentClient(result.client, result.newHost); this.pluginService.getCurrentHostInfo()?.removeAlias(Array.from(oldAliases)); await this.updateTopology(true); - this.failoverReaderSuccessCounter.inc(); + await this.throwFailoverSuccessError(); } catch (error: any) { this.failoverReaderFailedCounter.inc(); throw error; @@ -405,6 +406,21 @@ export class FailoverPlugin extends AbstractConnectionPlugin { } } + async throwFailoverSuccessError() { + if (this._isInTransaction || this.pluginService.isInTransaction()) { + this.pluginService.setInTransaction(false); + + // "Transaction resolution unknown. Please re-configure session state if required and try + // restarting transaction." + logger.debug(Messages.get("Failover.transactionResolutionUnknownError")); + throw new TransactionResolutionUnknownError(Messages.get("Failover.transactionResolutionUnknownError")); + } else { + // "The active SQL connection has changed due to a connection failure. Please re-configure + // session state if required." + throw new FailoverSuccessError(Messages.get("Failover.connectionChangedError")); + } + } + async failoverWriter() { logger.debug(Messages.get("Failover.startWriterFailover")); @@ -439,7 +455,7 @@ export class FailoverPlugin extends AbstractConnectionPlugin { await this.pluginService.setCurrentClient(result.client, writerHostInfo); logger.debug(Messages.get("Failover.establishedConnection", this.pluginService.getCurrentHostInfo()?.host ?? "")); await this.pluginService.refreshHostList(); - this.failoverWriterSuccessCounter.inc(); + await this.throwFailoverSuccessError(); } catch (error: any) { this.failoverWriterFailedCounter.inc(); throw error; diff --git a/common/lib/plugins/failover/reader_failover_handler.ts b/common/lib/plugins/failover/reader_failover_handler.ts index 8ddf031f..7fb10c29 100644 --- a/common/lib/plugins/failover/reader_failover_handler.ts +++ b/common/lib/plugins/failover/reader_failover_handler.ts @@ -113,23 +113,14 @@ export class ClusterAwareReaderFailoverHandler implements ReaderFailoverHandler // ensure new connection is to a reader host await this.pluginService.refreshHostList(); const topology = this.pluginService.getHosts(); - - for (let i = 0; i < topology.length; i++) { - const host = topology[i]; - if (host.host === result.newHost.host) { - // found new connection host in the latest topology - if (host.role === HostRole.READER) { - return result; - } + try { + if ((await this.pluginService.getHostRole(result.client)) !== HostRole.READER) { + return result; } + } catch (error) { + logger.debug(Messages.get("ClusterAwareReaderFailoverHandler.errorGettingHostRole", error.message)); } - // New host is not found in the latest topology. There are few possible reasons for that. - // - Host is not yet presented in the topology due to failover process in progress - // - Host is in the topology but its role isn't a - // READER (that is not acceptable option due to this.strictReader setting) - // Need to continue this loop and to make another try to connect to a reader. - try { await this.pluginService.abortTargetClient(result.client); } catch (error) { @@ -276,7 +267,9 @@ export class ClusterAwareReaderFailoverHandler implements ReaderFailoverHandler const hostsByPriority: HostInfo[] = [...activeReaders]; const numReaders: number = activeReaders.length + downHostList.length; - if (writerHost && (!this.enableFailoverStrictReader || numReaders === 0)) { + // Since the writer instance may change during failover, the original writer is likely now a reader. We will include + // it and then verify the role once connected if using "strict-reader". + if (writerHost || numReaders === 0) { hostsByPriority.push(writerHost); } hostsByPriority.push(...downHostList); @@ -322,6 +315,16 @@ class ConnectionAttemptTask { ); try { this.targetClient = await this.pluginService.forceConnect(this.newHost, copy); + + // Ensure that new connection is a connection to a reader host + try { + if ((await this.pluginService.getHostRole(this.targetClient)) === HostRole.READER) { + return this.targetClient; + } + } catch (error: any) { + logger.debug(Messages.get("ClusterAwareReaderFailoverHandler.errorGettingHostRole", error.message)); + } + this.pluginService.setAvailability(this.newHost.allAliases, HostAvailability.AVAILABLE); logger.info(Messages.get("ClusterAwareReaderFailoverHandler.successfulReaderConnection", this.newHost.host)); if (this.taskHandler.getSelectedConnectionAttemptTask(this.failoverTaskId) === -1) { diff --git a/common/lib/utils/locales/en.json b/common/lib/utils/locales/en.json index 1dd52e36..2c48b105 100644 --- a/common/lib/utils/locales/en.json +++ b/common/lib/utils/locales/en.json @@ -48,6 +48,7 @@ "ClusterAwareWriterFailoverHandler.standaloneHost": "[TaskB] Host %s is not yet connected to a cluster. The cluster is still being reconfigured.", "ClusterAwareWriterFailoverHandler.taskBAttemptConnectionToNewWriter": "[TaskB] Trying to connect to a new writer: '%s'", "ClusterAwareWriterFailoverHandler.alreadyWriter": "Current reader connection is actually a new writer connection.", + "ClusterAwareReaderFailoverHandler.errorGettingHostRole": "An error occurred while trying to determine the role of the reader candidate: %s.", "Failover.TransactionResolutionUnknownError": "Transaction resolution unknown. Please re-configure session state if required and try restarting the transaction.", "Failover.connectionChangedError": "The active SQL connection has changed due to a connection failure. Please re-configure session state if required.", "Failover.parameterValue": "%s = %s", @@ -193,5 +194,6 @@ "ConfigurationProfileBuilder.notFound": "Configuration profile '%s' not found.", "ConfigurationProfileBuilder.profileNameRequired": "Profile name is required.", "ConfigurationProfileBuilder.canNotUpdateKnownPreset": "Can't add or update a built-in preset configuration profile '%s'.", - "AwsClient.configurationProfileNotFound": "Configuration profile '%s' not found." + "AwsClient.configurationProfileNotFound": "Configuration profile '%s' not found.", + "AwsClient.targetClientNotDefined": "AwsClient targetClient not defined." } diff --git a/pg/lib/dialect/aurora_pg_database_dialect.ts b/pg/lib/dialect/aurora_pg_database_dialect.ts index 17463fca..a2b73e06 100644 --- a/pg/lib/dialect/aurora_pg_database_dialect.ts +++ b/pg/lib/dialect/aurora_pg_database_dialect.ts @@ -67,7 +67,7 @@ export class AuroraPgDatabaseDialect extends PgDatabaseDialect implements Topolo async getHostRole(targetClient: ClientWrapper): Promise { const res = await targetClient.query(AuroraPgDatabaseDialect.IS_READER_QUERY); - return Promise.resolve(res.rows[0]["is_reader"] === "true" ? HostRole.READER : HostRole.WRITER); + return Promise.resolve(res.rows[0]["is_reader"] === true ? HostRole.READER : HostRole.WRITER); } async isDialect(targetClient: ClientWrapper): Promise { From 9b5f978759fcfc965a035dd345637c94063049b2 Mon Sep 17 00:00:00 2001 From: joyc-bq Date: Tue, 7 Jan 2025 10:30:27 -0800 Subject: [PATCH 2/5] fix failover update topology --- .../plugins/failover/reader_failover_handler.ts | 14 ++------------ tests/unit/reader_failover_handler.test.ts | 4 ++++ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/common/lib/plugins/failover/reader_failover_handler.ts b/common/lib/plugins/failover/reader_failover_handler.ts index 7fb10c29..568146a2 100644 --- a/common/lib/plugins/failover/reader_failover_handler.ts +++ b/common/lib/plugins/failover/reader_failover_handler.ts @@ -17,7 +17,7 @@ import { HostInfo } from "../../host_info"; import { PluginService } from "../../plugin_service"; import { ReaderFailoverResult } from "./reader_failover_result"; -import { getTimeoutTask, maskProperties, shuffleList, sleep } from "../../utils/utils"; +import { getTimeoutTask, logAndThrowError, maskProperties, shuffleList, sleep } from "../../utils/utils"; import { HostRole } from "../../host_role"; import { HostAvailability } from "../../host_availability/host_availability"; import { AwsWrapperError, InternalQueryTimeoutError } from "../../utils/errors"; @@ -110,9 +110,8 @@ export class ClusterAwareReaderFailoverHandler implements ReaderFailoverHandler return result; // connection to any host is acceptable } - // ensure new connection is to a reader host + // Ensure new connection is to a reader host await this.pluginService.refreshHostList(); - const topology = this.pluginService.getHosts(); try { if ((await this.pluginService.getHostRole(result.client)) !== HostRole.READER) { return result; @@ -316,15 +315,6 @@ class ConnectionAttemptTask { try { this.targetClient = await this.pluginService.forceConnect(this.newHost, copy); - // Ensure that new connection is a connection to a reader host - try { - if ((await this.pluginService.getHostRole(this.targetClient)) === HostRole.READER) { - return this.targetClient; - } - } catch (error: any) { - logger.debug(Messages.get("ClusterAwareReaderFailoverHandler.errorGettingHostRole", error.message)); - } - this.pluginService.setAvailability(this.newHost.allAliases, HostAvailability.AVAILABLE); logger.info(Messages.get("ClusterAwareReaderFailoverHandler.successfulReaderConnection", this.newHost.host)); if (this.taskHandler.getSelectedConnectionAttemptTask(this.failoverTaskId) === -1) { diff --git a/tests/unit/reader_failover_handler.test.ts b/tests/unit/reader_failover_handler.test.ts index 3e2cf3f5..29407f9a 100644 --- a/tests/unit/reader_failover_handler.test.ts +++ b/tests/unit/reader_failover_handler.test.ts @@ -57,6 +57,8 @@ describe("reader failover handler", () => { const successHostIndex = 3; when(mockPluginService.getHosts()).thenReturn(hosts); + when(await mockPluginService.getHostRole(anything())).thenReturn(HostRole.READER); + for (let i = 0; i < hosts.length; i++) { if (i !== successHostIndex) { when(mockPluginService.forceConnect(hosts[i], anything())).thenThrow(new AwsWrapperError("Rejecting test")); @@ -326,6 +328,8 @@ describe("reader failover handler", () => { const reader = new HostInfo("reader", 1234, HostRole.READER); const hosts = [writer, reader]; when(mockPluginService.getHosts()).thenReturn(hosts); + when(await mockPluginService.getHostRole(anything())).thenReturn(HostRole.READER); + const mockPluginServiceInstance = instance(mockPluginService); const target = new ClusterAwareReaderFailoverHandler( From 999c40495fb1ada819e8773e618f3016240e13c8 Mon Sep 17 00:00:00 2001 From: joyc-bq Date: Tue, 7 Jan 2025 12:02:34 -0800 Subject: [PATCH 3/5] unit test --- tests/unit/failover_plugin.test.ts | 1 + tests/unit/reader_failover_handler.test.ts | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/unit/failover_plugin.test.ts b/tests/unit/failover_plugin.test.ts index 71df54d3..a4a87b95 100644 --- a/tests/unit/failover_plugin.test.ts +++ b/tests/unit/failover_plugin.test.ts @@ -199,6 +199,7 @@ describe("reader failover handler", () => { when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "aslias2"])); when(mockHostInfo.getRawAvailability()).thenReturn(HostAvailability.AVAILABLE); when(mockPluginService.getHosts()).thenReturn(hosts); + when(await mockPluginService.getHostRole(anything())).thenReturn(HostRole.WRITER); when(mockReaderResult.isConnected).thenReturn(true); when(mockReaderResult.client).thenReturn(mockClientWrapper); diff --git a/tests/unit/reader_failover_handler.test.ts b/tests/unit/reader_failover_handler.test.ts index 29407f9a..19e72641 100644 --- a/tests/unit/reader_failover_handler.test.ts +++ b/tests/unit/reader_failover_handler.test.ts @@ -328,8 +328,9 @@ describe("reader failover handler", () => { const reader = new HostInfo("reader", 1234, HostRole.READER); const hosts = [writer, reader]; when(mockPluginService.getHosts()).thenReturn(hosts); - when(await mockPluginService.getHostRole(anything())).thenReturn(HostRole.READER); - + when(await mockPluginService.getHostRole(anything())) + .thenReturn(HostRole.READER) + .thenReturn(HostRole.WRITER); const mockPluginServiceInstance = instance(mockPluginService); const target = new ClusterAwareReaderFailoverHandler( @@ -342,13 +343,13 @@ describe("reader failover handler", () => { // We expect only reader nodes to be chosen. let hostsByPriority = target.getHostsByPriority(hosts); - expect(hostsByPriority).toStrictEqual([reader]); + expect(hostsByPriority).toStrictEqual([reader, writer]); // Should pick the reader even if unavailable. reader.setAvailability(HostAvailability.NOT_AVAILABLE); hostsByPriority = target.getHostsByPriority(hosts); - expect(hostsByPriority).toStrictEqual([reader]); + expect(hostsByPriority).toStrictEqual([writer, reader]); // Writer node will only be picked if it is the only node in topology; hostsByPriority = target.getHostsByPriority([writer]); From 9a226f72dcdd1a523baa5841d8d24c3c28684c18 Mon Sep 17 00:00:00 2001 From: joyc-bq Date: Tue, 7 Jan 2025 13:31:30 -0800 Subject: [PATCH 4/5] throw failover success --- .../lib/plugins/failover/failover_plugin.ts | 19 +++++-------------- tests/unit/failover_plugin.test.ts | 13 +++++++------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/common/lib/plugins/failover/failover_plugin.ts b/common/lib/plugins/failover/failover_plugin.ts index 80c59a07..638c3ee4 100644 --- a/common/lib/plugins/failover/failover_plugin.ts +++ b/common/lib/plugins/failover/failover_plugin.ts @@ -345,17 +345,7 @@ export class FailoverPlugin extends AbstractConnectionPlugin { } else { await this.failoverReader(failedHost); } - - if (this._isInTransaction || this.pluginService.isInTransaction()) { - // "Transaction resolution unknown. Please re-configure session state if required and try - // restarting transaction." - logger.debug(Messages.get("Failover.transactionResolutionUnknownError")); - throw new TransactionResolutionUnknownError(Messages.get("Failover.transactionResolutionUnknownError")); - } else { - // "The active SQL connection has changed due to a connection failure. Please re-configure - // session state if required." - throw new FailoverSuccessError(Messages.get("Failover.connectionChangedError")); - } + this.throwFailoverSuccessError(); } async failoverReader(failedHostInfo: HostInfo) { @@ -393,7 +383,7 @@ export class FailoverPlugin extends AbstractConnectionPlugin { await this.pluginService.setCurrentClient(result.client, result.newHost); this.pluginService.getCurrentHostInfo()?.removeAlias(Array.from(oldAliases)); await this.updateTopology(true); - await this.throwFailoverSuccessError(); + this.failoverWriterSuccessCounter.inc(); } catch (error: any) { this.failoverReaderFailedCounter.inc(); throw error; @@ -406,7 +396,7 @@ export class FailoverPlugin extends AbstractConnectionPlugin { } } - async throwFailoverSuccessError() { + throwFailoverSuccessError() { if (this._isInTransaction || this.pluginService.isInTransaction()) { this.pluginService.setInTransaction(false); @@ -455,7 +445,8 @@ export class FailoverPlugin extends AbstractConnectionPlugin { await this.pluginService.setCurrentClient(result.client, writerHostInfo); logger.debug(Messages.get("Failover.establishedConnection", this.pluginService.getCurrentHostInfo()?.host ?? "")); await this.pluginService.refreshHostList(); - await this.throwFailoverSuccessError(); + this.throwFailoverSuccessError(); + this.failoverWriterSuccessCounter.inc(); } catch (error: any) { this.failoverWriterFailedCounter.inc(); throw error; diff --git a/tests/unit/failover_plugin.test.ts b/tests/unit/failover_plugin.test.ts index a4a87b95..7a0c98c8 100644 --- a/tests/unit/failover_plugin.test.ts +++ b/tests/unit/failover_plugin.test.ts @@ -36,9 +36,10 @@ import { AwsMySQLClient } from "../../mysql/lib"; import { anything, instance, mock, reset, resetCalls, spy, verify, when } from "ts-mockito"; import { Messages } from "../../common/lib/utils/messages"; import { HostChangeOptions } from "../../common/lib/host_change_options"; -import { ClientWrapper } from "../../common/lib/client_wrapper"; import { NullTelemetryFactory } from "../../common/lib/utils/telemetry/null_telemetry_factory"; import { MySQLClientWrapper } from "../../common/lib/mysql_client_wrapper"; +import { DriverDialect } from "../../common/lib/driver_dialect/driver_dialect"; +import { MySQL2DriverDialect } from "../../mysql/lib/dialect/mysql2_driver_dialect"; const builder = new HostInfoBuilder({ hostAvailabilityStrategy: new SimpleHostAvailabilityStrategy() }); @@ -196,7 +197,7 @@ describe("reader failover handler", () => { const hostInfo = builder.withHost("hostA").build(); const hosts = [hostInfo]; - when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "aslias2"])); + when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "alias2"])); when(mockHostInfo.getRawAvailability()).thenReturn(HostAvailability.AVAILABLE); when(mockPluginService.getHosts()).thenReturn(hosts); when(await mockPluginService.getHostRole(anything())).thenReturn(HostRole.WRITER); @@ -231,7 +232,7 @@ describe("reader failover handler", () => { const hosts = [hostInfo]; const test = new AwsWrapperError("test"); - when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "aslias2"])); + when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "alias2"])); when(mockHostInfo.getRawAvailability()).thenReturn(HostAvailability.AVAILABLE); when(mockPluginService.getHosts()).thenReturn(hosts); when(mockReaderResult.exception).thenReturn(test); @@ -255,7 +256,7 @@ describe("reader failover handler", () => { const hosts = [hostInfo]; const test = new AwsWrapperError("test"); - when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "aslias2"])); + when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "alias2"])); when(mockPluginService.getHosts()).thenReturn(hosts); when(mockWriterResult.exception).thenReturn(test); when(mockWriterFailoverHandler.failover(anything())).thenResolve(instance(mockWriterResult)); @@ -276,7 +277,7 @@ describe("reader failover handler", () => { const hostInfo = builder.withHost("hostA").build(); const hosts = [hostInfo]; - when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "aslias2"])); + when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "alias2"])); when(mockPluginService.getHosts()).thenReturn(hosts); when(mockWriterResult.isConnected).thenReturn(false); when(mockWriterFailoverHandler.failover(anything())).thenResolve(instance(mockWriterResult)); @@ -306,7 +307,7 @@ describe("reader failover handler", () => { const hostInfo = builder.withHost("hostA").build(); const hosts = [hostInfo]; - when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "aslias2"])); + when(mockHostInfo.allAliases).thenReturn(new Set(["alias1", "alias2"])); when(mockPluginService.getHosts()).thenReturn(hosts); when(mockWriterResult.isConnected).thenReturn(false); when(mockWriterResult.topology).thenReturn(hosts); From 88417b82899289ab2acc5afccd428321f0dad408 Mon Sep 17 00:00:00 2001 From: joyc-bq Date: Wed, 8 Jan 2025 10:38:42 -0800 Subject: [PATCH 5/5] imports --- tests/unit/failover_plugin.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/unit/failover_plugin.test.ts b/tests/unit/failover_plugin.test.ts index 7a0c98c8..3fa1c141 100644 --- a/tests/unit/failover_plugin.test.ts +++ b/tests/unit/failover_plugin.test.ts @@ -38,8 +38,6 @@ import { Messages } from "../../common/lib/utils/messages"; import { HostChangeOptions } from "../../common/lib/host_change_options"; import { NullTelemetryFactory } from "../../common/lib/utils/telemetry/null_telemetry_factory"; import { MySQLClientWrapper } from "../../common/lib/mysql_client_wrapper"; -import { DriverDialect } from "../../common/lib/driver_dialect/driver_dialect"; -import { MySQL2DriverDialect } from "../../mysql/lib/dialect/mysql2_driver_dialect"; const builder = new HostInfoBuilder({ hostAvailabilityStrategy: new SimpleHostAvailabilityStrategy() });