Skip to content

Commit 803be0b

Browse files
authored
Merge pull request #673 from hyperweb-io/anmol/verify-cli
feature: initial setup for adding verify command to starship cli
2 parents 7357cda + 7286932 commit 803be0b

File tree

15 files changed

+1601
-1
lines changed

15 files changed

+1601
-1
lines changed

clients/js/packages/cli/src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ async function main() {
112112
case 'undeploy':
113113
client.deleteHelm();
114114
break;
115+
case 'verify':
116+
client.verify().catch((err: any) => {
117+
console.error('An error occurred during verification:', err);
118+
process.exit(1);
119+
});
120+
break;
115121
default:
116122
console.log(`Unknown command: ${command}`);
117123
displayUsage();

clients/js/packages/cli/src/utils.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,17 @@ Commands:
7878
delete Delete a specific Helm release.
7979
get-pods Get the list of pods for the Helm release.
8080
clean Perform a clean operation to tidy up resources.
81+
verify Verify the status of deployed services and endpoints.
82+
Checks:
83+
- Chain REST endpoints (supply)
84+
- Chain RPC endpoints (block height)
85+
- Chain Faucet endpoints (chain ID)
86+
- Chain Exposer endpoints (node ID)
87+
- Ethereum REST endpoints (sync status)
88+
- Ethereum RPC endpoints (sync status)
89+
- Registry service (chain list)
90+
- Explorer service (dashboard)
91+
- Relayer service (version)
8192
version, -v Display the version of the Starship Client.
8293
8394
Configuration File:
@@ -95,6 +106,8 @@ Command-line Options:
95106
Examples:
96107
$ starship start --config ./config/two-chain.yaml
97108
$ starship stop --config ./config/two-chain.yaml
109+
$ starship verify --config ./config/two-chain.yaml
110+
$ starship verify --config ./config/two-chain.yaml --name my-starship
98111
99112
If you want to setup starship for the first time
100113
$ starship setup
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`StarshipClient verify should handle explorer verification failure 1`] = `
4+
"Call: setConfig({"name":"osmojs","version":"v0.2.3","chains":[{"id":"osmosis-1","name":"osmosis","image":"pyramation/osmosis:v16.1.0","numValidators":1,"ports":{"rest":1317,"rpc":26657,"faucet":8007}},{"id":"cosmos-2","name":"cosmos","numValidators":1,"ports":{"rest":1313,"rpc":26653,"faucet":8003}}],"relayers":[{"name":"osmos-cosmos","type":"hermes","replicas":1,"chains":["osmosis-1","cosmos-2"]}],"registry":{"enabled":true,"ports":{"rest":8081,"grpc":9091}}})
5+
Log: config again: [object Object]
6+
Call: verify()
7+
Log: Verifying services...
8+
Log: FAILURE chain-osmosis-1 (rest): Unhandled URL in mock: http://localhost:1317/cosmos/bank/v1beta1/supply
9+
Log: FAILURE chain-osmosis-1 (rpc): Unhandled URL in mock: http://localhost:26657/status
10+
Log: FAILURE chain-osmosis-1 (faucet): Unhandled URL in mock: http://localhost:8007/status
11+
Log: SKIPPED chain-osmosis-1 (exposer): Port not found
12+
Log: FAILURE chain-cosmos-2 (rest): Unhandled URL in mock: http://localhost:1313/cosmos/bank/v1beta1/supply
13+
Log: FAILURE chain-cosmos-2 (rpc): Unhandled URL in mock: http://localhost:26653/status
14+
Log: FAILURE chain-cosmos-2 (faucet): Unhandled URL in mock: http://localhost:8003/status
15+
Log: SKIPPED chain-cosmos-2 (exposer): Port not found
16+
Log: SKIPPED relayer-osmos-cosmos (rest): Port not found
17+
Log: SKIPPED relayer-osmos-cosmos (exposer): Port not found
18+
Log: FAILURE registry (rest): Unhandled URL in mock: http://localhost:8081/chains
19+
Log⬇
20+
21+
Some services failed verification. Please check the logs above.
22+
EndLog⬆"
23+
`;
24+
25+
exports[`StarshipClient verify should handle explorer verification failure 2`] = `""`;
26+
27+
exports[`StarshipClient verify should handle registry verification failure 1`] = `
28+
"Call: setConfig({"name":"osmojs","version":"v0.2.3","chains":[{"id":"osmosis-1","name":"osmosis","image":"pyramation/osmosis:v16.1.0","numValidators":1,"ports":{"rest":1317,"rpc":26657,"faucet":8007}},{"id":"cosmos-2","name":"cosmos","numValidators":1,"ports":{"rest":1313,"rpc":26653,"faucet":8003}}],"relayers":[{"name":"osmos-cosmos","type":"hermes","replicas":1,"chains":["osmosis-1","cosmos-2"]}],"registry":{"enabled":true,"ports":{"rest":8081,"grpc":9091}}})
29+
Log: config again: [object Object]
30+
Call: verify()
31+
Log: Verifying services...
32+
Log: FAILURE chain-osmosis-1 (rest): Unhandled URL in mock: http://localhost:1317/cosmos/bank/v1beta1/supply
33+
Log: FAILURE chain-osmosis-1 (rpc): Unhandled URL in mock: http://localhost:26657/status
34+
Log: FAILURE chain-osmosis-1 (faucet): Unhandled URL in mock: http://localhost:8007/status
35+
Log: SKIPPED chain-osmosis-1 (exposer): Port not found
36+
Log: FAILURE chain-cosmos-2 (rest): Unhandled URL in mock: http://localhost:1313/cosmos/bank/v1beta1/supply
37+
Log: FAILURE chain-cosmos-2 (rpc): Unhandled URL in mock: http://localhost:26653/status
38+
Log: FAILURE chain-cosmos-2 (faucet): Unhandled URL in mock: http://localhost:8003/status
39+
Log: SKIPPED chain-cosmos-2 (exposer): Port not found
40+
Log: SKIPPED relayer-osmos-cosmos (rest): Port not found
41+
Log: SKIPPED relayer-osmos-cosmos (exposer): Port not found
42+
Log: FAILURE registry (rest): Registry not available
43+
Log⬇
44+
45+
Some services failed verification. Please check the logs above.
46+
EndLog⬆"
47+
`;
48+
49+
exports[`StarshipClient verify should handle registry verification failure 2`] = `""`;
50+
51+
exports[`StarshipClient verify should handle relayer verification failure 1`] = `
52+
"Call: setConfig({"name":"osmojs","version":"v0.2.3","chains":[{"id":"osmosis-1","name":"osmosis","image":"pyramation/osmosis:v16.1.0","numValidators":1,"ports":{"rest":1317,"rpc":26657,"faucet":8007}},{"id":"cosmos-2","name":"cosmos","numValidators":1,"ports":{"rest":1313,"rpc":26653,"faucet":8003}}],"relayers":[{"name":"osmos-cosmos","type":"hermes","replicas":1,"chains":["osmosis-1","cosmos-2"]}],"registry":{"enabled":true,"ports":{"rest":8081,"grpc":9091}}})
53+
Log: config again: [object Object]
54+
Call: verify()
55+
Log: Verifying services...
56+
Log: FAILURE chain-osmosis-1 (rest): Unhandled URL in mock: http://localhost:1317/cosmos/bank/v1beta1/supply
57+
Log: FAILURE chain-osmosis-1 (rpc): Unhandled URL in mock: http://localhost:26657/status
58+
Log: FAILURE chain-osmosis-1 (faucet): Unhandled URL in mock: http://localhost:8007/status
59+
Log: SKIPPED chain-osmosis-1 (exposer): Port not found
60+
Log: FAILURE chain-cosmos-2 (rest): Unhandled URL in mock: http://localhost:1313/cosmos/bank/v1beta1/supply
61+
Log: FAILURE chain-cosmos-2 (rpc): Unhandled URL in mock: http://localhost:26653/status
62+
Log: FAILURE chain-cosmos-2 (faucet): Unhandled URL in mock: http://localhost:8003/status
63+
Log: SKIPPED chain-cosmos-2 (exposer): Port not found
64+
Log: SKIPPED relayer-osmos-cosmos (rest): Port not found
65+
Log: SKIPPED relayer-osmos-cosmos (exposer): Port not found
66+
Log: FAILURE registry (rest): Unhandled URL in mock: http://localhost:8081/chains
67+
Log⬇
68+
69+
Some services failed verification. Please check the logs above.
70+
EndLog⬆"
71+
`;
72+
73+
exports[`StarshipClient verify should handle relayer verification failure 2`] = `""`;
74+
75+
exports[`StarshipClient verify should skip disabled services 1`] = `
76+
"Call: setConfig({"name":"osmojs","version":"v0.2.3","chains":[{"id":"osmosis-1","name":"osmosis","image":"pyramation/osmosis:v16.1.0","numValidators":1,"ports":{"rest":1317,"rpc":26657,"faucet":8007}},{"id":"cosmos-2","name":"cosmos","numValidators":1,"ports":{"rest":1313,"rpc":26653,"faucet":8003}}],"relayers":[{"name":"osmos-cosmos","type":"hermes","replicas":1,"chains":["osmosis-1","cosmos-2"]}],"registry":{"enabled":false,"ports":{"rest":8081,"grpc":9091}},"explorer":{"enabled":false}})
77+
Log: config again: [object Object]
78+
Call: verify()
79+
Log: Verifying services...
80+
Log: SUCCESS chain-osmosis-1 (rest): Chain supply is greater than 0
81+
Log: SUCCESS chain-osmosis-1 (rpc): Chain is synced
82+
Log: SUCCESS chain-osmosis-1 (faucet): Chain faucet is working
83+
Log: SKIPPED chain-osmosis-1 (exposer): Port not found
84+
Log: SUCCESS chain-cosmos-2 (rest): Chain supply is greater than 0
85+
Log: SUCCESS chain-cosmos-2 (rpc): Chain is synced
86+
Log: SUCCESS chain-cosmos-2 (faucet): Chain faucet is working
87+
Log: SKIPPED chain-cosmos-2 (exposer): Port not found
88+
Log: SKIPPED relayer-osmos-cosmos (rest): Port not found
89+
Log: SKIPPED relayer-osmos-cosmos (exposer): Port not found
90+
Log⬇
91+
92+
All services verified successfully!
93+
EndLog⬆"
94+
`;
95+
96+
exports[`StarshipClient verify should skip disabled services 2`] = `""`;
97+
98+
exports[`StarshipClient verify should verify all services successfully 1`] = `
99+
"Call: setConfig({"name":"starship","version":"v0.2.3","chains":[{"id":"osmosis-1","name":"osmosis","image":"pyramation/osmosis:v16.1.0","numValidators":1,"ports":{"rest":1317,"rpc":26657,"faucet":8007}},{"id":"cosmos-2","name":"cosmos","numValidators":1,"ports":{"rest":1313,"rpc":26653,"faucet":8003}}],"relayers":[{"name":"osmos-cosmos","type":"hermes","replicas":1,"chains":["osmosis-1","cosmos-2"]}],"registry":{"enabled":true,"ports":{"rest":8081,"grpc":9091}}})
100+
Log: config again: [object Object]
101+
Call: verify()
102+
Log: Verifying services...
103+
Log: SUCCESS chain-osmosis-1 (rest): Chain supply is greater than 0
104+
Log: SUCCESS chain-osmosis-1 (rpc): Chain is synced
105+
Log: SUCCESS chain-osmosis-1 (faucet): Chain faucet is working
106+
Log: SKIPPED chain-osmosis-1 (exposer): Port not found
107+
Log: SUCCESS chain-cosmos-2 (rest): Chain supply is greater than 0
108+
Log: SUCCESS chain-cosmos-2 (rpc): Chain is synced
109+
Log: SUCCESS chain-cosmos-2 (faucet): Chain faucet is working
110+
Log: SKIPPED chain-cosmos-2 (exposer): Port not found
111+
Log: SKIPPED relayer-osmos-cosmos (rest): Port not found
112+
Log: SKIPPED relayer-osmos-cosmos (exposer): Port not found
113+
Log: SUCCESS registry (rest): Registry is working
114+
Log⬇
115+
116+
All services verified successfully!
117+
EndLog⬆"
118+
`;
119+
120+
exports[`StarshipClient verify should verify all services successfully 2`] = `""`;
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
import axios from 'axios';
2+
3+
import { StarshipConfig } from '../src/config';
4+
import { createClient, expectClient } from '../test-utils/client';
5+
import { config } from '../test-utils/config';
6+
7+
jest.mock('axios');
8+
const mockedAxios = axios as jest.Mocked<typeof axios>;
9+
10+
describe('StarshipClient verify', () => {
11+
beforeEach(() => {
12+
jest.clearAllMocks();
13+
});
14+
15+
it('should verify all services successfully', async () => {
16+
const { client, ctx } = createClient();
17+
client.dependencies.forEach((dep) => (dep.installed = true));
18+
client.setConfig(config.config);
19+
20+
// Mock successful responses for all services
21+
mockedAxios.get.mockImplementation((url) => {
22+
// Chain REST check (port 1317, 1313)
23+
if (url.includes('/cosmos/bank/v1beta1/supply')) {
24+
return Promise.resolve({
25+
status: 200,
26+
data: {
27+
supply: [{ amount: '1000000' }]
28+
}
29+
});
30+
}
31+
32+
// Chain RPC check (port 26657, 26653)
33+
if (
34+
url.includes('/status') &&
35+
(url.includes('26657') || url.includes('26653'))
36+
) {
37+
return Promise.resolve({
38+
status: 200,
39+
data: {
40+
result: {
41+
sync_info: {
42+
latest_block_height: '100'
43+
}
44+
}
45+
}
46+
});
47+
}
48+
49+
// Chain faucet check (port 8007, 8003)
50+
if (
51+
url.includes('/status') &&
52+
(url.includes('8007') || url.includes('8003'))
53+
) {
54+
// Extract port from URL
55+
const port = url.includes('8007') ? 8007 : 8003;
56+
// Find the chain ID based on the port
57+
const chain = config.config.chains?.find(
58+
(chain) => chain.ports?.faucet === port
59+
);
60+
return Promise.resolve({
61+
status: 200,
62+
data: {
63+
chainId: chain?.id || 'unknown'
64+
}
65+
});
66+
}
67+
68+
// Registry check (port 8081)
69+
if (url.includes('/chains')) {
70+
return Promise.resolve({
71+
status: 200,
72+
data: {
73+
chains: config.config.chains?.map((chain) => chain.id) || []
74+
}
75+
});
76+
}
77+
78+
// Explorer check (port 8080)
79+
if (url.includes('8080')) {
80+
return Promise.resolve({
81+
status: 200,
82+
data: '<html><body>Ping Dashboard</body></html>'
83+
});
84+
}
85+
86+
// Throw error for unhandled URLs
87+
throw new Error(`Unhandled URL in mock: ${url}`);
88+
});
89+
90+
await client.verify();
91+
expectClient(ctx, 0);
92+
});
93+
94+
it('should handle registry verification failure', async () => {
95+
const { client, ctx } = createClient();
96+
client.dependencies.forEach((dep) => (dep.installed = true));
97+
client.setConfig(config.config);
98+
99+
// Mock registry failure
100+
mockedAxios.get.mockImplementation((url) => {
101+
if (url.includes('/chains')) {
102+
return Promise.reject(new Error('Registry not available'));
103+
}
104+
105+
// Throw error for unhandled URLs
106+
throw new Error(`Unhandled URL in mock: ${url}`);
107+
});
108+
109+
await client.verify();
110+
expectClient(ctx, 1);
111+
});
112+
113+
it('should handle explorer verification failure', async () => {
114+
const { client, ctx } = createClient();
115+
client.dependencies.forEach((dep) => (dep.installed = true));
116+
client.setConfig(config.config);
117+
118+
// Mock explorer failure
119+
mockedAxios.get.mockImplementation((url) => {
120+
if (url.includes('8080')) {
121+
return Promise.reject(new Error('Explorer not available'));
122+
}
123+
124+
// Throw error for unhandled URLs
125+
throw new Error(`Unhandled URL in mock: ${url}`);
126+
});
127+
128+
await client.verify();
129+
expectClient(ctx, 1);
130+
});
131+
132+
it('should handle relayer verification failure', async () => {
133+
const { client, ctx } = createClient();
134+
client.dependencies.forEach((dep) => (dep.installed = true));
135+
client.setConfig(config.config);
136+
137+
// Mock relayer failure
138+
mockedAxios.get.mockImplementation((url) => {
139+
if (url.includes('/version')) {
140+
return Promise.reject(new Error('Relayer not available'));
141+
}
142+
143+
// Throw error for unhandled URLs
144+
throw new Error(`Unhandled URL in mock: ${url}`);
145+
});
146+
147+
await client.verify();
148+
expectClient(ctx, 1);
149+
});
150+
151+
it('should skip disabled services', async () => {
152+
const { client, ctx } = createClient();
153+
client.dependencies.forEach((dep) => (dep.installed = true));
154+
155+
// Create config with disabled services
156+
const disabledConfig: StarshipConfig = {
157+
...config.config,
158+
explorer: {
159+
...config.config.explorer,
160+
enabled: false
161+
},
162+
registry: {
163+
...config.config.registry,
164+
enabled: false
165+
}
166+
};
167+
client.setConfig(disabledConfig);
168+
169+
// Mock successful responses for enabled services
170+
mockedAxios.get.mockImplementation((url) => {
171+
// Chain REST check (port 1317, 1313)
172+
if (url.includes('/cosmos/bank/v1beta1/supply')) {
173+
return Promise.resolve({
174+
status: 200,
175+
data: {
176+
supply: [{ amount: '1000000' }]
177+
}
178+
});
179+
}
180+
181+
// Chain RPC check (port 26657, 26653)
182+
if (
183+
url.includes('/status') &&
184+
(url.includes('26657') || url.includes('26653'))
185+
) {
186+
return Promise.resolve({
187+
status: 200,
188+
data: {
189+
result: {
190+
sync_info: {
191+
latest_block_height: '100'
192+
}
193+
}
194+
}
195+
});
196+
}
197+
198+
// Chain faucet check (port 8007, 8003)
199+
if (
200+
url.includes('/status') &&
201+
(url.includes('8007') || url.includes('8003'))
202+
) {
203+
// Extract port from URL
204+
const port = url.includes('8007') ? 8007 : 8003;
205+
// Find the chain ID based on the port
206+
const chain = disabledConfig.chains?.find(
207+
(chain) => chain.ports?.faucet === port
208+
);
209+
return Promise.resolve({
210+
status: 200,
211+
data: {
212+
chainId: chain?.id || 'unknown'
213+
}
214+
});
215+
}
216+
217+
// Throw error for unhandled URLs
218+
throw new Error(`Unhandled URL in mock: ${url}`);
219+
});
220+
221+
await client.verify();
222+
expectClient(ctx, 0);
223+
});
224+
});

clients/js/packages/client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"interchain"
4848
],
4949
"dependencies": {
50+
"axios": "^1.6.7",
5051
"chalk": "^4.1.0",
5152
"deepmerge": "^4.3.1",
5253
"js-yaml": "^4.1.0",

0 commit comments

Comments
 (0)