clawsql 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/api/routes/instances.d.ts.map +1 -1
  2. package/dist/api/routes/instances.js +9 -6
  3. package/dist/api/routes/instances.js.map +1 -1
  4. package/dist/api/schemas/index.d.ts +142 -142
  5. package/dist/bin/clawsql.js +0 -0
  6. package/dist/cli/commands/cleanup.d.ts.map +1 -1
  7. package/dist/cli/commands/cleanup.js +40 -44
  8. package/dist/cli/commands/cleanup.js.map +1 -1
  9. package/dist/cli/commands/start.d.ts.map +1 -1
  10. package/dist/cli/commands/start.js +16 -36
  11. package/dist/cli/commands/start.js.map +1 -1
  12. package/dist/cli/commands/stop.d.ts.map +1 -1
  13. package/dist/cli/commands/stop.js +18 -35
  14. package/dist/cli/commands/stop.js.map +1 -1
  15. package/dist/cli/utils/command-executor.d.ts +62 -0
  16. package/dist/cli/utils/command-executor.d.ts.map +1 -0
  17. package/dist/cli/utils/command-executor.js +224 -0
  18. package/dist/cli/utils/command-executor.js.map +1 -0
  19. package/dist/core/discovery/topology.d.ts.map +1 -1
  20. package/dist/core/discovery/topology.js +4 -1
  21. package/dist/core/discovery/topology.js.map +1 -1
  22. package/docker/Dockerfile.allinone +37 -28
  23. package/docker-compose.yml +3 -0
  24. package/init/metadata.sql +11 -0
  25. package/init/replica.sql +12 -2
  26. package/package.json +1 -1
  27. package/dist/__tests__/config/settings.test.d.ts +0 -5
  28. package/dist/__tests__/config/settings.test.d.ts.map +0 -1
  29. package/dist/__tests__/config/settings.test.js +0 -154
  30. package/dist/__tests__/config/settings.test.js.map +0 -1
  31. package/dist/__tests__/core/discovery/topology.test.d.ts +0 -5
  32. package/dist/__tests__/core/discovery/topology.test.d.ts.map +0 -1
  33. package/dist/__tests__/core/discovery/topology.test.js +0 -191
  34. package/dist/__tests__/core/discovery/topology.test.js.map +0 -1
  35. package/dist/__tests__/core/failover/executor.test.d.ts +0 -5
  36. package/dist/__tests__/core/failover/executor.test.d.ts.map +0 -1
  37. package/dist/__tests__/core/failover/executor.test.js +0 -256
  38. package/dist/__tests__/core/failover/executor.test.js.map +0 -1
  39. package/dist/__tests__/core/monitoring/collector.test.d.ts +0 -5
  40. package/dist/__tests__/core/monitoring/collector.test.d.ts.map +0 -1
  41. package/dist/__tests__/core/monitoring/collector.test.js +0 -131
  42. package/dist/__tests__/core/monitoring/collector.test.js.map +0 -1
  43. package/dist/__tests__/core/monitoring/exporters.test.d.ts +0 -5
  44. package/dist/__tests__/core/monitoring/exporters.test.d.ts.map +0 -1
  45. package/dist/__tests__/core/monitoring/exporters.test.js +0 -90
  46. package/dist/__tests__/core/monitoring/exporters.test.js.map +0 -1
  47. package/dist/__tests__/core/routing/proxysql-manager.test.d.ts +0 -5
  48. package/dist/__tests__/core/routing/proxysql-manager.test.d.ts.map +0 -1
  49. package/dist/__tests__/core/routing/proxysql-manager.test.js +0 -155
  50. package/dist/__tests__/core/routing/proxysql-manager.test.js.map +0 -1
  51. package/dist/__tests__/types/index.test.d.ts +0 -5
  52. package/dist/__tests__/types/index.test.d.ts.map +0 -1
  53. package/dist/__tests__/types/index.test.js +0 -290
  54. package/dist/__tests__/types/index.test.js.map +0 -1
  55. package/dist/__tests__/utils/exceptions.test.d.ts +0 -5
  56. package/dist/__tests__/utils/exceptions.test.d.ts.map +0 -1
  57. package/dist/__tests__/utils/exceptions.test.js +0 -142
  58. package/dist/__tests__/utils/exceptions.test.js.map +0 -1
  59. package/dist/cli/commands/health.d.ts +0 -12
  60. package/dist/cli/commands/health.d.ts.map +0 -1
  61. package/dist/cli/commands/health.js +0 -125
  62. package/dist/cli/commands/health.js.map +0 -1
@@ -1,154 +0,0 @@
1
- "use strict";
2
- /**
3
- * Tests for ClawSQL configuration settings
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- // Store original env
7
- const originalEnv = { ...process.env };
8
- // Mock dotenv to prevent loading .env
9
- jest.mock('dotenv', () => ({
10
- config: jest.fn(),
11
- }));
12
- const settings_1 = require("../../config/settings");
13
- describe('Settings', () => {
14
- beforeEach(() => {
15
- // Clear all env vars that affect settings
16
- delete process.env.API_PORT;
17
- delete process.env.DB_TYPE;
18
- delete process.env.AUTO_FAILOVER_ENABLED;
19
- delete process.env.PROXYSQL_ADMIN_USER;
20
- delete process.env.PROXYSQL_ADMIN_PASSWORD;
21
- delete process.env.API_TOKEN_SECRET;
22
- delete process.env.MYSQL_MONITOR_PASSWORD;
23
- // Reset settings cache before each test
24
- (0, settings_1.resetSettings)();
25
- });
26
- afterEach(() => {
27
- // Restore original env
28
- process.env = { ...originalEnv };
29
- (0, settings_1.resetSettings)();
30
- });
31
- describe('getSettings', () => {
32
- it('should return default settings when no env vars set', () => {
33
- const settings = (0, settings_1.getSettings)();
34
- expect(settings.appName).toBe('ClawSQL');
35
- expect(settings.appVersion).toBe('0.1.0');
36
- expect(settings.debug).toBe(false);
37
- });
38
- it('should return cached settings on subsequent calls', () => {
39
- const settings1 = (0, settings_1.getSettings)();
40
- const settings2 = (0, settings_1.getSettings)();
41
- expect(settings1).toBe(settings2);
42
- });
43
- it('should load new settings after reset', () => {
44
- const settings1 = (0, settings_1.getSettings)();
45
- (0, settings_1.resetSettings)();
46
- const settings2 = (0, settings_1.getSettings)();
47
- // Different object references but same values
48
- expect(settings1).not.toBe(settings2);
49
- expect(settings1.appName).toBe(settings2.appName);
50
- });
51
- });
52
- describe('DatabaseSettings', () => {
53
- it('should have correct defaults', () => {
54
- const settings = (0, settings_1.getSettings)();
55
- expect(settings.database.type).toBe('sqlite');
56
- expect(settings.database.sqlitePath).toBe('/data/clawsql.db');
57
- expect(settings.database.host).toBe('localhost');
58
- expect(settings.database.port).toBe(3306);
59
- expect(settings.database.name).toBe('clawsql');
60
- expect(settings.database.user).toBe('clawsql');
61
- expect(settings.database.poolSize).toBe(10);
62
- });
63
- });
64
- describe('OrchestratorSettings', () => {
65
- it('should have correct defaults', () => {
66
- const settings = (0, settings_1.getSettings)();
67
- expect(settings.orchestrator.url).toBe('http://orchestrator:3000');
68
- expect(settings.orchestrator.timeout).toBe(30);
69
- expect(settings.orchestrator.tlsEnabled).toBe(false);
70
- });
71
- });
72
- describe('ProxySQLSettings', () => {
73
- it('should have correct defaults', () => {
74
- const settings = (0, settings_1.getSettings)();
75
- expect(settings.proxysql.host).toBe('proxysql');
76
- expect(settings.proxysql.adminPort).toBe(6032);
77
- expect(settings.proxysql.mysqlPort).toBe(6033);
78
- expect(settings.proxysql.adminUser).toBe('clawsql');
79
- expect(settings.proxysql.adminPassword).toBe('clawsql');
80
- });
81
- });
82
- describe('PrometheusSettings', () => {
83
- it('should have correct defaults', () => {
84
- const settings = (0, settings_1.getSettings)();
85
- expect(settings.prometheus.url).toBe('http://prometheus:9090');
86
- expect(settings.prometheus.retentionDays).toBe(15);
87
- });
88
- });
89
- describe('MonitoringSettings', () => {
90
- it('should have correct defaults', () => {
91
- const settings = (0, settings_1.getSettings)();
92
- expect(settings.monitoring.collectionInterval).toBe(15);
93
- expect(settings.monitoring.healthCheckInterval).toBe(10);
94
- expect(settings.monitoring.alertCooldownMinutes).toBe(5);
95
- });
96
- });
97
- describe('FailoverSettings', () => {
98
- it('should have correct defaults', () => {
99
- const settings = (0, settings_1.getSettings)();
100
- expect(settings.failover.autoFailoverEnabled).toBe(true);
101
- expect(settings.failover.timeoutSeconds).toBe(30);
102
- expect(settings.failover.minReplicasForFailover).toBe(2);
103
- expect(settings.failover.confirmationChecks).toBe(3);
104
- });
105
- });
106
- describe('DiscoverySettings', () => {
107
- it('should have correct defaults', () => {
108
- const settings = (0, settings_1.getSettings)();
109
- expect(settings.discovery.networkSegments).toBe('172.18.0.0/24');
110
- expect(settings.discovery.portRangeStart).toBe(3306);
111
- expect(settings.discovery.portRangeEnd).toBe(3306);
112
- expect(settings.discovery.timeout).toBe(2);
113
- expect(settings.discovery.maxConcurrent).toBe(100);
114
- });
115
- });
116
- describe('APISettings', () => {
117
- it('should have correct defaults', () => {
118
- const settings = (0, settings_1.getSettings)();
119
- expect(settings.api.host).toBe('0.0.0.0');
120
- expect(settings.api.port).toBe(8080);
121
- expect(settings.api.tokenSecret).toBe('change-me-in-production');
122
- expect(settings.api.tokenExpiryHours).toBe(24);
123
- });
124
- });
125
- describe('MySQLCredentials', () => {
126
- it('should have correct defaults', () => {
127
- const settings = (0, settings_1.getSettings)();
128
- expect(settings.mysql.monitorUser).toBe('monitor');
129
- expect(settings.mysql.monitorPassword).toBe('');
130
- expect(settings.mysql.replicationUser).toBe('repl');
131
- expect(settings.mysql.replicationPassword).toBe('');
132
- });
133
- });
134
- describe('LogSettings', () => {
135
- it('should have correct defaults', () => {
136
- const settings = (0, settings_1.getSettings)();
137
- expect(settings.logging.level).toBe('INFO');
138
- expect(settings.logging.format).toBe('json');
139
- });
140
- });
141
- describe('Environment variable loading', () => {
142
- it('should load settings from environment variables', () => {
143
- process.env.API_PORT = '9090';
144
- process.env.DB_TYPE = 'mysql';
145
- process.env.AUTO_FAILOVER_ENABLED = 'false';
146
- (0, settings_1.resetSettings)();
147
- const settings = (0, settings_1.getSettings)();
148
- expect(settings.api.port).toBe(9090);
149
- expect(settings.database.type).toBe('mysql');
150
- expect(settings.failover.autoFailoverEnabled).toBe(false);
151
- });
152
- });
153
- });
154
- //# sourceMappingURL=settings.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"settings.test.js","sourceRoot":"","sources":["../../../src/__tests__/config/settings.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Tests for Orchestrator client
3
- */
4
- export {};
5
- //# sourceMappingURL=topology.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"topology.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/core/discovery/topology.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -1,191 +0,0 @@
1
- "use strict";
2
- /**
3
- * Tests for Orchestrator client
4
- */
5
- var __importDefault = (this && this.__importDefault) || function (mod) {
6
- return (mod && mod.__esModule) ? mod : { "default": mod };
7
- };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const topology_js_1 = require("../../../core/discovery/topology.js");
10
- const index_js_1 = require("../../../types/index.js");
11
- const exceptions_js_1 = require("../../../utils/exceptions.js");
12
- const axios_1 = __importDefault(require("axios"));
13
- // Mock axios
14
- jest.mock('axios');
15
- const mockedAxios = axios_1.default;
16
- describe('OrchestratorClient', () => {
17
- let client;
18
- let mockAxiosInstance;
19
- beforeEach(() => {
20
- mockAxiosInstance = {
21
- get: jest.fn(),
22
- post: jest.fn(),
23
- };
24
- mockedAxios.create.mockReturnValue(mockAxiosInstance);
25
- client = new topology_js_1.OrchestratorClient({
26
- url: 'http://orchestrator:3000',
27
- timeout: 30,
28
- });
29
- });
30
- afterEach(() => {
31
- jest.clearAllMocks();
32
- });
33
- describe('constructor', () => {
34
- it('should create axios client with correct config', () => {
35
- expect(mockedAxios.create).toHaveBeenCalledWith({
36
- baseURL: 'http://orchestrator:3000',
37
- timeout: 30000,
38
- headers: {
39
- 'Content-Type': 'application/json',
40
- },
41
- });
42
- });
43
- it('should use default settings when not provided', () => {
44
- new topology_js_1.OrchestratorClient();
45
- expect(mockedAxios.create).toHaveBeenCalledWith(expect.objectContaining({
46
- baseURL: 'http://orchestrator:3000',
47
- }));
48
- });
49
- it('should strip trailing slash from URL', () => {
50
- new topology_js_1.OrchestratorClient({
51
- url: 'http://orchestrator:3000/',
52
- timeout: 30,
53
- });
54
- expect(mockedAxios.create).toHaveBeenCalledWith(expect.objectContaining({
55
- baseURL: 'http://orchestrator:3000',
56
- }));
57
- });
58
- });
59
- describe('healthCheck', () => {
60
- it('should return true when health check succeeds', async () => {
61
- mockAxiosInstance.get.mockResolvedValue({ status: 200 });
62
- const result = await client.healthCheck();
63
- expect(result).toBe(true);
64
- expect(mockAxiosInstance.get).toHaveBeenCalledWith('/api/health');
65
- });
66
- it('should return false when health check fails', async () => {
67
- mockAxiosInstance.get.mockRejectedValue(new Error('Connection refused'));
68
- const result = await client.healthCheck();
69
- expect(result).toBe(false);
70
- });
71
- });
72
- describe('getClusters', () => {
73
- it('should return cluster names', async () => {
74
- mockAxiosInstance.get.mockResolvedValue({
75
- data: ['cluster1', 'cluster2'],
76
- });
77
- const clusters = await client.getClusters();
78
- expect(clusters).toEqual(['cluster1', 'cluster2']);
79
- expect(mockAxiosInstance.get).toHaveBeenCalledWith('/api/clusters');
80
- });
81
- it('should throw OrchestratorError on failure', async () => {
82
- mockAxiosInstance.get.mockRejectedValue(new Error('Network error'));
83
- await expect(client.getClusters()).rejects.toThrow(exceptions_js_1.OrchestratorError);
84
- });
85
- });
86
- describe('getTopology', () => {
87
- it('should return parsed cluster topology', async () => {
88
- mockAxiosInstance.get.mockResolvedValue({
89
- data: {
90
- Alias: 'primary',
91
- Hostname: 'mysql-primary',
92
- Port: 3306,
93
- IsPrimary: true,
94
- IsLastCheckValid: true,
95
- ServerID: 1,
96
- Version: '8.0.32',
97
- ClusterName: 'test-cluster',
98
- Child: [
99
- {
100
- Alias: 'replica1',
101
- Hostname: 'mysql-replica-1',
102
- Port: 3306,
103
- IsReplica: true,
104
- IsLastCheckValid: true,
105
- ReplicationLagSeconds: 0,
106
- },
107
- ],
108
- },
109
- });
110
- const cluster = await client.getTopology('test-cluster');
111
- expect(cluster).not.toBeNull();
112
- expect(cluster?.clusterId).toBe('test-cluster');
113
- expect(cluster?.primary?.host).toBe('mysql-primary');
114
- expect(cluster?.primary?.role).toBe(index_js_1.InstanceRole.PRIMARY);
115
- expect(cluster?.primary?.state).toBe(index_js_1.InstanceState.ONLINE);
116
- expect(cluster?.replicas).toHaveLength(1);
117
- });
118
- it('should return null when cluster not found', async () => {
119
- const axiosError = {
120
- response: { status: 404 },
121
- isAxiosError: true,
122
- };
123
- mockAxiosInstance.get.mockRejectedValue(axiosError);
124
- // Need to mock isAxiosError to return true
125
- mockedAxios.isAxiosError = jest.fn().mockReturnValue(true);
126
- const cluster = await client.getTopology('nonexistent');
127
- expect(cluster).toBeNull();
128
- });
129
- it('should throw OrchestratorError on other failures', async () => {
130
- mockAxiosInstance.get.mockRejectedValue(new Error('Network error'));
131
- await expect(client.getTopology('test-cluster')).rejects.toThrow(exceptions_js_1.OrchestratorError);
132
- });
133
- });
134
- describe('getInstance', () => {
135
- it('should return parsed instance', async () => {
136
- mockAxiosInstance.get.mockResolvedValue({
137
- data: {
138
- Hostname: 'mysql-primary',
139
- Port: 3306,
140
- IsPrimary: true,
141
- IsLastCheckValid: true,
142
- ServerID: 1,
143
- Version: '8.0.32',
144
- },
145
- });
146
- const instance = await client.getInstance('mysql-primary', 3306);
147
- expect(instance).not.toBeNull();
148
- expect(instance?.host).toBe('mysql-primary');
149
- expect(instance?.port).toBe(3306);
150
- expect(instance?.role).toBe(index_js_1.InstanceRole.PRIMARY);
151
- });
152
- it('should return null when instance not found', async () => {
153
- const axiosError = {
154
- response: { status: 404 },
155
- isAxiosError: true,
156
- };
157
- mockAxiosInstance.get.mockRejectedValue(axiosError);
158
- // Need to mock isAxiosError to return true
159
- mockedAxios.isAxiosError = jest.fn().mockReturnValue(true);
160
- const instance = await client.getInstance('nonexistent', 3306);
161
- expect(instance).toBeNull();
162
- });
163
- });
164
- describe('discoverInstance', () => {
165
- it('should return true on successful discovery', async () => {
166
- mockAxiosInstance.post.mockResolvedValue({});
167
- const result = await client.discoverInstance('mysql-primary', 3306);
168
- expect(result).toBe(true);
169
- });
170
- it('should return false on failure', async () => {
171
- mockAxiosInstance.post.mockRejectedValue(new Error('Failed'));
172
- const result = await client.discoverInstance('mysql-primary', 3306);
173
- expect(result).toBe(false);
174
- });
175
- });
176
- describe('requestFailover', () => {
177
- it('should request failover without destination', async () => {
178
- mockAxiosInstance.post.mockResolvedValue({ data: { success: true } });
179
- const result = await client.requestFailover('mysql-replica-1', 3306);
180
- expect(result).toEqual({ success: true });
181
- });
182
- });
183
- });
184
- describe('getOrchestratorClient', () => {
185
- it('should return singleton instance', () => {
186
- const client1 = (0, topology_js_1.getOrchestratorClient)();
187
- const client2 = (0, topology_js_1.getOrchestratorClient)();
188
- expect(client1).toBe(client2);
189
- });
190
- });
191
- //# sourceMappingURL=topology.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"topology.test.js","sourceRoot":"","sources":["../../../../src/__tests__/core/discovery/topology.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Tests for Failover Executor
3
- */
4
- export {};
5
- //# sourceMappingURL=executor.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"executor.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/core/failover/executor.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -1,256 +0,0 @@
1
- "use strict";
2
- /**
3
- * Tests for Failover Executor
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const executor_js_1 = require("../../../core/failover/executor.js");
7
- const index_js_1 = require("../../../types/index.js");
8
- // Mock dependencies
9
- jest.mock('../../../core/discovery/topology.js');
10
- jest.mock('../../../core/routing/proxysql-manager.js');
11
- describe('FailoverExecutor', () => {
12
- let executor;
13
- let mockOrchestrator;
14
- let mockProxySQL;
15
- beforeEach(() => {
16
- mockOrchestrator = {
17
- healthCheck: jest.fn(),
18
- getClusters: jest.fn(),
19
- getTopology: jest.fn(),
20
- getInstance: jest.fn(),
21
- discoverInstance: jest.fn(),
22
- forgetInstance: jest.fn(),
23
- beginMaintenance: jest.fn(),
24
- endMaintenance: jest.fn(),
25
- getReplicationAnalysis: jest.fn(),
26
- requestFailover: jest.fn(),
27
- relocateReplicas: jest.fn(),
28
- };
29
- mockProxySQL = {
30
- connect: jest.fn(),
31
- close: jest.fn(),
32
- setMonitorCredentials: jest.fn(),
33
- addServer: jest.fn(),
34
- registerInstance: jest.fn(),
35
- removeServer: jest.fn(),
36
- setupReadWriteSplit: jest.fn(),
37
- syncCluster: jest.fn(),
38
- removeCluster: jest.fn(),
39
- loadConfigToRuntime: jest.fn(),
40
- saveConfigToDisk: jest.fn(),
41
- getServers: jest.fn(),
42
- getConfigSummary: jest.fn(),
43
- };
44
- executor = new executor_js_1.FailoverExecutor(mockOrchestrator, mockProxySQL);
45
- });
46
- afterEach(() => {
47
- jest.clearAllMocks();
48
- });
49
- describe('constructor', () => {
50
- it('should create executor with dependencies', () => {
51
- expect(executor).toBeDefined();
52
- });
53
- });
54
- describe('selectCandidate', () => {
55
- it('should return null when no replicas', async () => {
56
- const cluster = (0, index_js_1.createMySQLCluster)('cluster-1', 'test');
57
- const candidate = await executor.selectCandidate(cluster);
58
- expect(candidate).toBeNull();
59
- });
60
- it('should return null when all replicas are offline', async () => {
61
- const primary = (0, index_js_1.createMySQLInstance)('primary', 3306, { role: index_js_1.InstanceRole.PRIMARY });
62
- const replica = (0, index_js_1.createMySQLInstance)('replica', 3306, {
63
- role: index_js_1.InstanceRole.REPLICA,
64
- state: index_js_1.InstanceState.OFFLINE,
65
- });
66
- const cluster = (0, index_js_1.createMySQLCluster)('cluster-1', 'test', {
67
- primary,
68
- replicas: [replica],
69
- });
70
- const candidate = await executor.selectCandidate(cluster);
71
- expect(candidate).toBeNull();
72
- });
73
- it('should select replica with lowest replication lag', async () => {
74
- const primary = (0, index_js_1.createMySQLInstance)('primary', 3306, {
75
- role: index_js_1.InstanceRole.PRIMARY,
76
- state: index_js_1.InstanceState.ONLINE,
77
- });
78
- const replica1 = (0, index_js_1.createMySQLInstance)('replica1', 3306, {
79
- role: index_js_1.InstanceRole.REPLICA,
80
- state: index_js_1.InstanceState.ONLINE,
81
- replicationLag: 10,
82
- });
83
- const replica2 = (0, index_js_1.createMySQLInstance)('replica2', 3306, {
84
- role: index_js_1.InstanceRole.REPLICA,
85
- state: index_js_1.InstanceState.ONLINE,
86
- replicationLag: 2,
87
- });
88
- const cluster = (0, index_js_1.createMySQLCluster)('cluster-1', 'test', {
89
- primary,
90
- replicas: [replica1, replica2],
91
- });
92
- const candidate = await executor.selectCandidate(cluster);
93
- expect(candidate?.host).toBe('replica2');
94
- });
95
- it('should skip replicas in maintenance', async () => {
96
- const primary = (0, index_js_1.createMySQLInstance)('primary', 3306, { role: index_js_1.InstanceRole.PRIMARY });
97
- const replica1 = (0, index_js_1.createMySQLInstance)('replica1', 3306, {
98
- role: index_js_1.InstanceRole.REPLICA,
99
- state: index_js_1.InstanceState.MAINTENANCE,
100
- replicationLag: 0,
101
- });
102
- const replica2 = (0, index_js_1.createMySQLInstance)('replica2', 3306, {
103
- role: index_js_1.InstanceRole.REPLICA,
104
- state: index_js_1.InstanceState.ONLINE,
105
- replicationLag: 5,
106
- });
107
- const cluster = (0, index_js_1.createMySQLCluster)('cluster-1', 'test', {
108
- primary,
109
- replicas: [replica1, replica2],
110
- });
111
- const candidate = await executor.selectCandidate(cluster);
112
- expect(candidate?.host).toBe('replica2');
113
- });
114
- });
115
- describe('promoteInstance', () => {
116
- it('should promote instance successfully', async () => {
117
- mockOrchestrator.requestFailover.mockResolvedValue({ success: true });
118
- const primary = (0, index_js_1.createMySQLInstance)('primary', 3306, { role: index_js_1.InstanceRole.PRIMARY });
119
- const newPrimary = (0, index_js_1.createMySQLInstance)('new-primary', 3306, { role: index_js_1.InstanceRole.REPLICA });
120
- const cluster = (0, index_js_1.createMySQLCluster)('cluster-1', 'test', { primary });
121
- const result = await executor.promoteInstance(newPrimary, cluster);
122
- expect(result).toBe(true);
123
- });
124
- it('should return false on failure', async () => {
125
- mockOrchestrator.requestFailover.mockRejectedValue(new Error('Failed'));
126
- const primary = (0, index_js_1.createMySQLInstance)('primary', 3306, { role: index_js_1.InstanceRole.PRIMARY });
127
- const newPrimary = (0, index_js_1.createMySQLInstance)('new-primary', 3306, { role: index_js_1.InstanceRole.REPLICA });
128
- const cluster = (0, index_js_1.createMySQLCluster)('cluster-1', 'test', { primary });
129
- const result = await executor.promoteInstance(newPrimary, cluster);
130
- expect(result).toBe(false);
131
- });
132
- });
133
- describe('reconfigureReplicas', () => {
134
- it('should reconfigure replicas to follow new primary', async () => {
135
- mockOrchestrator.relocateReplicas.mockResolvedValue(true);
136
- const newPrimary = (0, index_js_1.createMySQLInstance)('new-primary', 3306);
137
- const replica = (0, index_js_1.createMySQLInstance)('replica', 3306);
138
- const result = await executor.reconfigureReplicas(newPrimary, [replica]);
139
- expect(result).toBe(true);
140
- });
141
- });
142
- describe('executeManualFailover', () => {
143
- it('should execute manual failover', async () => {
144
- mockOrchestrator.requestFailover.mockResolvedValue({ success: true });
145
- mockOrchestrator.relocateReplicas.mockResolvedValue(true);
146
- mockProxySQL.syncCluster.mockResolvedValue({
147
- clusterId: 'cluster-1',
148
- serversAdded: 2,
149
- serversRemoved: 0,
150
- hostgroups: { writer: 10, reader: 20 },
151
- success: true,
152
- errors: [],
153
- });
154
- const primary = (0, index_js_1.createMySQLInstance)('primary', 3306, {
155
- role: index_js_1.InstanceRole.PRIMARY,
156
- state: index_js_1.InstanceState.ONLINE,
157
- });
158
- const replica = (0, index_js_1.createMySQLInstance)('replica', 3306, {
159
- role: index_js_1.InstanceRole.REPLICA,
160
- state: index_js_1.InstanceState.ONLINE,
161
- });
162
- const cluster = (0, index_js_1.createMySQLCluster)('cluster-1', 'test', {
163
- primary,
164
- replicas: [replica],
165
- });
166
- const operation = await executor.executeManualFailover(cluster, 'replica:3306', 'Planned maintenance');
167
- expect(operation.state).toBe(index_js_1.FailoverState.COMPLETED);
168
- expect(operation.manual).toBe(true);
169
- });
170
- });
171
- describe('executeAutomaticFailover', () => {
172
- it('should execute automatic failover', async () => {
173
- mockOrchestrator.requestFailover.mockResolvedValue({ success: true });
174
- mockOrchestrator.relocateReplicas.mockResolvedValue(true);
175
- mockProxySQL.syncCluster.mockResolvedValue({
176
- clusterId: 'cluster-1',
177
- serversAdded: 2,
178
- serversRemoved: 0,
179
- hostgroups: { writer: 10, reader: 20 },
180
- success: true,
181
- errors: [],
182
- });
183
- const primary = (0, index_js_1.createMySQLInstance)('primary', 3306, {
184
- role: index_js_1.InstanceRole.PRIMARY,
185
- state: index_js_1.InstanceState.FAILED,
186
- });
187
- const replica = (0, index_js_1.createMySQLInstance)('replica', 3306, {
188
- role: index_js_1.InstanceRole.REPLICA,
189
- state: index_js_1.InstanceState.ONLINE,
190
- });
191
- const cluster = (0, index_js_1.createMySQLCluster)('cluster-1', 'test', {
192
- primary,
193
- replicas: [replica],
194
- });
195
- const failureEvent = {
196
- eventId: 'event-1',
197
- failureType: index_js_1.FailureType.PRIMARY_UNREACHABLE,
198
- instanceId: 'primary:3306',
199
- clusterId: 'cluster-1',
200
- detectedAt: new Date(),
201
- confirmed: true,
202
- confirmationCount: 3,
203
- details: {},
204
- };
205
- const operation = await executor.executeAutomaticFailover(failureEvent, cluster);
206
- expect(operation.state).toBe(index_js_1.FailoverState.COMPLETED);
207
- expect(operation.manual).toBe(false);
208
- });
209
- it('should fail when no suitable candidate', async () => {
210
- const primary = (0, index_js_1.createMySQLInstance)('primary', 3306, {
211
- role: index_js_1.InstanceRole.PRIMARY,
212
- state: index_js_1.InstanceState.FAILED,
213
- });
214
- const replica = (0, index_js_1.createMySQLInstance)('replica', 3306, {
215
- role: index_js_1.InstanceRole.REPLICA,
216
- state: index_js_1.InstanceState.OFFLINE,
217
- });
218
- const cluster = (0, index_js_1.createMySQLCluster)('cluster-1', 'test', {
219
- primary,
220
- replicas: [replica],
221
- });
222
- const failureEvent = {
223
- eventId: 'event-1',
224
- failureType: index_js_1.FailureType.PRIMARY_UNREACHABLE,
225
- instanceId: 'primary:3306',
226
- clusterId: 'cluster-1',
227
- detectedAt: new Date(),
228
- confirmed: true,
229
- confirmationCount: 3,
230
- details: {},
231
- };
232
- const operation = await executor.executeAutomaticFailover(failureEvent, cluster);
233
- expect(operation.state).toBe(index_js_1.FailoverState.FAILED);
234
- expect(operation.error).toContain('No suitable candidate');
235
- });
236
- });
237
- describe('getCurrentOperation', () => {
238
- it('should return null when no operation in progress', () => {
239
- expect(executor.getCurrentOperation()).toBeNull();
240
- });
241
- });
242
- describe('getOperationHistory', () => {
243
- it('should return empty array initially', () => {
244
- const history = executor.getOperationHistory();
245
- expect(history).toEqual([]);
246
- });
247
- });
248
- });
249
- describe('getFailoverExecutor', () => {
250
- it('should return singleton instance', () => {
251
- const e1 = (0, executor_js_1.getFailoverExecutor)();
252
- const e2 = (0, executor_js_1.getFailoverExecutor)();
253
- expect(e1).toBe(e2);
254
- });
255
- });
256
- //# sourceMappingURL=executor.test.js.map