1+ import { RelayerBuilder } from '../src/builders/relayer' ;
2+ import { singleChainConfig } from './test-utils/config' ;
3+
4+ describe ( 'RelayerBuilder' , ( ) => {
5+ it ( 'should generate no manifests when no relayers are configured' , ( ) => {
6+ const config = { ...singleChainConfig } ;
7+ delete config . relayers ;
8+
9+ const builder = new RelayerBuilder ( config ) ;
10+ const manifests = builder . buildManifests ( ) ;
11+
12+ expect ( manifests ) . toEqual ( [ ] ) ;
13+ } ) ;
14+
15+ it ( 'should generate manifests for a hermes relayer' , ( ) => {
16+ const config = {
17+ ...singleChainConfig ,
18+ relayers : [
19+ {
20+ name : 'osmo-cosmos' ,
21+ type : 'hermes' as const ,
22+ replicas : 1 ,
23+ chains : [ 'osmosis-1' , 'cosmoshub-4' ] ,
24+ config : {
25+ global : { log_level : 'info' } ,
26+ mode : {
27+ clients : { enabled : true , refresh : true , misbehaviour : true } ,
28+ connections : { enabled : true } ,
29+ channels : { enabled : true } ,
30+ packets : { enabled : true , clear_interval : 100 , clear_on_start : true , tx_confirmation : true }
31+ } ,
32+ rest : { enabled : true , host : '0.0.0.0' , port : 3000 } ,
33+ telemetry : { enabled : true , host : '0.0.0.0' , port : 3001 }
34+ }
35+ }
36+ ]
37+ } ;
38+
39+ const builder = new RelayerBuilder ( config ) ;
40+ const manifests = builder . buildManifests ( ) ;
41+
42+ expect ( manifests ) . toHaveLength ( 3 ) ; // ConfigMap, Service, StatefulSet
43+
44+ const configMap = manifests . find ( m => m . kind === 'ConfigMap' ) ;
45+ const service = manifests . find ( m => m . kind === 'Service' ) ;
46+ const statefulSet = manifests . find ( m => m . kind === 'StatefulSet' ) ;
47+
48+ expect ( configMap ) . toBeDefined ( ) ;
49+ expect ( configMap . metadata . name ) . toBe ( 'hermes-osmo-cosmos' ) ;
50+ expect ( configMap . data [ 'config.toml' ] ) . toContain ( 'log_level = "info"' ) ;
51+
52+ expect ( service ) . toBeDefined ( ) ;
53+ expect ( service . metadata . name ) . toBe ( 'hermes-osmo-cosmos' ) ;
54+ expect ( service . spec . ports ) . toHaveLength ( 2 ) ; // rest and exposer
55+
56+ expect ( statefulSet ) . toBeDefined ( ) ;
57+ expect ( statefulSet . metadata . name ) . toBe ( 'hermes-osmo-cosmos' ) ;
58+ expect ( statefulSet . spec . replicas ) . toBe ( 1 ) ;
59+ } ) ;
60+
61+ it ( 'should generate manifests for a go-relayer' , ( ) => {
62+ const config = {
63+ ...singleChainConfig ,
64+ relayers : [
65+ {
66+ name : 'go-rly' ,
67+ type : 'go-relayer' as const ,
68+ replicas : 1 ,
69+ chains : [ 'osmosis-1' , 'cosmoshub-4' ]
70+ }
71+ ]
72+ } ;
73+
74+ const builder = new RelayerBuilder ( config ) ;
75+ const manifests = builder . buildManifests ( ) ;
76+
77+ expect ( manifests ) . toHaveLength ( 2 ) ; // ConfigMap, StatefulSet (no service)
78+
79+ const configMap = manifests . find ( m => m . kind === 'ConfigMap' ) ;
80+ const statefulSet = manifests . find ( m => m . kind === 'StatefulSet' ) ;
81+
82+ expect ( configMap ) . toBeDefined ( ) ;
83+ expect ( configMap . metadata . name ) . toBe ( 'go-relayer-go-rly' ) ;
84+ expect ( configMap . data [ 'path.json' ] ) . toContain ( 'osmosis-1' ) ;
85+
86+ expect ( statefulSet ) . toBeDefined ( ) ;
87+ expect ( statefulSet . metadata . name ) . toBe ( 'go-relayer-go-rly' ) ;
88+ } ) ;
89+
90+ it ( 'should generate manifests for a ts-relayer' , ( ) => {
91+ const config = {
92+ ...singleChainConfig ,
93+ relayers : [
94+ {
95+ name : 'ts-rly' ,
96+ type : 'ts-relayer' as const ,
97+ replicas : 1 ,
98+ chains : [ 'osmosis-1' , 'cosmoshub-4' ]
99+ }
100+ ]
101+ } ;
102+
103+ const builder = new RelayerBuilder ( config ) ;
104+ const manifests = builder . buildManifests ( ) ;
105+
106+ expect ( manifests ) . toHaveLength ( 2 ) ; // ConfigMap, StatefulSet (no service)
107+
108+ const configMap = manifests . find ( m => m . kind === 'ConfigMap' ) ;
109+ const statefulSet = manifests . find ( m => m . kind === 'StatefulSet' ) ;
110+
111+ expect ( configMap ) . toBeDefined ( ) ;
112+ expect ( configMap . metadata . name ) . toBe ( 'ts-relayer-ts-rly' ) ;
113+ expect ( configMap . data [ 'template-app.yaml' ] ) . toContain ( '<SRC>' ) ;
114+ expect ( configMap . data [ 'registry.yaml' ] ) . toContain ( 'osmosis-1' ) ;
115+
116+ expect ( statefulSet ) . toBeDefined ( ) ;
117+ expect ( statefulSet . metadata . name ) . toBe ( 'ts-relayer-ts-rly' ) ;
118+ } ) ;
119+
120+ it ( 'should generate manifests for a neutron-query-relayer' , ( ) => {
121+ const neutronConfig = {
122+ ...singleChainConfig ,
123+ chains : [
124+ ...singleChainConfig . chains ,
125+ {
126+ id : 'neutron-1' ,
127+ name : 'neutron' as const ,
128+ numValidators : 1 ,
129+ prefix : 'neutron' ,
130+ denom : 'untrn' ,
131+ home : '/root/.neutrond'
132+ }
133+ ] ,
134+ relayers : [
135+ {
136+ name : 'neutron-query' ,
137+ type : 'neutron-query-relayer' as const ,
138+ replicas : 1 ,
139+ chains : [ 'neutron-1' , 'osmosis-1' ] ,
140+ config : {
141+ RELAYER_NEUTRON_CHAIN_TIMEOUT : '1000s' ,
142+ RELAYER_NEUTRON_CHAIN_GAS_PRICES : '0.5untrn'
143+ }
144+ }
145+ ]
146+ } ;
147+
148+ const builder = new RelayerBuilder ( neutronConfig ) ;
149+ const manifests = builder . buildManifests ( ) ;
150+
151+ expect ( manifests ) . toHaveLength ( 3 ) ; // ConfigMap, Service, StatefulSet
152+
153+ const configMap = manifests . find ( m => m . kind === 'ConfigMap' ) ;
154+ const service = manifests . find ( m => m . kind === 'Service' ) ;
155+ const statefulSet = manifests . find ( m => m . kind === 'StatefulSet' ) ;
156+
157+ expect ( configMap ) . toBeDefined ( ) ;
158+ expect ( configMap . metadata . name ) . toBe ( 'neutron-query-relayer-neutron-query' ) ;
159+
160+ expect ( service ) . toBeDefined ( ) ;
161+ expect ( service . metadata . name ) . toBe ( 'neutron-query-relayer-neutron-query' ) ;
162+
163+ expect ( statefulSet ) . toBeDefined ( ) ;
164+ expect ( statefulSet . metadata . name ) . toBe ( 'neutron-query-relayer-neutron-query' ) ;
165+ } ) ;
166+
167+ it ( 'should handle multiple relayers' , ( ) => {
168+ const config = {
169+ ...singleChainConfig ,
170+ relayers : [
171+ {
172+ name : 'hermes-rly' ,
173+ type : 'hermes' as const ,
174+ replicas : 1 ,
175+ chains : [ 'osmosis-1' , 'cosmoshub-4' ]
176+ } ,
177+ {
178+ name : 'go-rly' ,
179+ type : 'go-relayer' as const ,
180+ replicas : 1 ,
181+ chains : [ 'osmosis-1' , 'cosmoshub-4' ]
182+ }
183+ ]
184+ } ;
185+
186+ const builder = new RelayerBuilder ( config ) ;
187+ const manifests = builder . buildManifests ( ) ;
188+
189+ expect ( manifests ) . toHaveLength ( 5 ) ; // 2 relayers: hermes (3 manifests) + go-relayer (2 manifests)
190+
191+ const hermesManifests = manifests . filter ( m =>
192+ m . metadata . name . includes ( 'hermes-rly' )
193+ ) ;
194+ const goRelayerManifests = manifests . filter ( m =>
195+ m . metadata . name . includes ( 'go-relayer-go-rly' )
196+ ) ;
197+
198+ expect ( hermesManifests ) . toHaveLength ( 3 ) ;
199+ expect ( goRelayerManifests ) . toHaveLength ( 2 ) ;
200+ } ) ;
201+
202+ it ( 'should use custom image when provided' , ( ) => {
203+ const config = {
204+ ...singleChainConfig ,
205+ relayers : [
206+ {
207+ name : 'custom-hermes' ,
208+ type : 'hermes' as const ,
209+ image : 'custom/hermes:latest' ,
210+ replicas : 1 ,
211+ chains : [ 'osmosis-1' , 'cosmoshub-4' ]
212+ }
213+ ]
214+ } ;
215+
216+ const builder = new RelayerBuilder ( config ) ;
217+ const manifests = builder . buildManifests ( ) ;
218+
219+ const statefulSet = manifests . find ( m => m . kind === 'StatefulSet' ) ;
220+ const initContainers = statefulSet . spec . template . spec . initContainers ;
221+ const containers = statefulSet . spec . template . spec . containers ;
222+
223+ const relayerInitContainer = initContainers . find ( ( c : any ) => c . name === 'init-relayer' ) ;
224+ const relayerContainer = containers . find ( ( c : any ) => c . name === 'relayer' ) ;
225+
226+ expect ( relayerInitContainer . image ) . toBe ( 'custom/hermes:latest' ) ;
227+ expect ( relayerContainer . image ) . toBe ( 'custom/hermes:latest' ) ;
228+ } ) ;
229+ } ) ;
0 commit comments