1+ RSpec . describe Unleash ::StreamingClientExecutor do
2+ unless RUBY_ENGINE == 'jruby'
3+ before do
4+ Unleash . configure do |config |
5+ config . url = 'http://streaming-test-url/'
6+ config . app_name = 'streaming-test-app'
7+ config . instance_id = 'rspec/streaming'
8+ config . disable_metrics = true
9+ config . experimental_mode = { type : 'streaming' }
10+ end
11+
12+ WebMock . stub_request ( :post , "http://streaming-test-url/client/register" )
13+ . to_return ( status : 200 , body : "" , headers : { } )
14+
15+ Unleash . logger = Unleash . configuration . logger
16+ end
17+
18+ after do
19+ WebMock . reset!
20+ File . delete ( Unleash . configuration . backup_file ) if File . exist? ( Unleash . configuration . backup_file )
21+
22+ # Reset configuration to prevent interference with other tests
23+ Unleash . configuration . bootstrap_config = nil
24+ Unleash . configuration . experimental_mode = nil
25+ Unleash . configuration . disable_metrics = false
26+ end
27+
28+ describe '.new' do
29+ let ( :engine ) { YggdrasilEngine . new }
30+ let ( :executor_name ) { 'streaming_client_executor_spec' }
31+
32+ context 'when there are problems connecting to streaming endpoint' do
33+ let ( :backup_toggles ) do
34+ {
35+ version : 1 ,
36+ features : [
37+ {
38+ name : "backup-feature" ,
39+ description : "Feature from backup" ,
40+ enabled : true ,
41+ strategies : [ {
42+ "name" : "default"
43+ } ]
44+ }
45+ ]
46+ }
47+ end
48+
49+ let ( :streaming_executor ) { described_class . new ( executor_name , engine ) }
50+
51+ before do
52+ backup_file = Unleash . configuration . backup_file
53+
54+ # manually create a stub cache on disk, so we can test that we read it correctly later.
55+ File . open ( backup_file , "w" ) do |file |
56+ file . write ( backup_toggles . to_json )
57+ end
58+
59+ # Simulate streaming connection failure
60+ WebMock . stub_request ( :get , "http://streaming-test-url/client/streaming" )
61+ . to_return ( status : 500 , body : "Internal Server Error" , headers : { } )
62+
63+ streaming_executor
64+ end
65+
66+ it 'reads the backup file for values' do
67+ enabled = engine . enabled? ( 'backup-feature' , { } )
68+ expect ( enabled ) . to eq ( true )
69+ end
70+ end
71+
72+ context 'when bootstrap is configured' do
73+ let ( :bootstrap_data ) do
74+ {
75+ version : 1 ,
76+ features : [
77+ {
78+ name : "bootstrap-feature" ,
79+ enabled : true ,
80+ strategies : [ { name : "default" } ]
81+ }
82+ ]
83+ }
84+ end
85+
86+ let ( :bootstrap_config ) do
87+ Unleash ::Bootstrap ::Configuration . new ( {
88+ 'data' => bootstrap_data . to_json
89+ } )
90+ end
91+
92+ let ( :streaming_executor ) { described_class . new ( executor_name , engine ) }
93+
94+ before do
95+ Unleash . configuration . bootstrap_config = bootstrap_config
96+
97+ # Streaming connection might succeed or fail, doesn't matter for bootstrap
98+ WebMock . stub_request ( :get , "http://streaming-test-url/client/streaming" )
99+ . to_return ( status : 200 , body : "" , headers : { } )
100+
101+ streaming_executor
102+ end
103+
104+ after do
105+ Unleash . configuration . bootstrap_config = nil
106+ end
107+
108+ it 'uses bootstrap data on initialization' do
109+ enabled = engine . enabled? ( 'bootstrap-feature' , { } )
110+ expect ( enabled ) . to eq ( true )
111+ end
112+
113+ it 'clears bootstrap config after use' do
114+ expect ( Unleash . configuration . bootstrap_config ) . to be_nil
115+ end
116+ end
117+
118+ context 'when bootstrap fails and backup file exists' do
119+ let ( :invalid_bootstrap_config ) do
120+ Unleash ::Bootstrap ::Configuration . new ( {
121+ 'data' => 'invalid json'
122+ } )
123+ end
124+
125+ let ( :fallback_toggles ) do
126+ {
127+ version : 1 ,
128+ features : [
129+ {
130+ name : "fallback-feature" ,
131+ enabled : true ,
132+ strategies : [ { name : "default" } ]
133+ }
134+ ]
135+ }
136+ end
137+
138+ let ( :streaming_executor ) { described_class . new ( executor_name , engine ) }
139+
140+ before do
141+ backup_file = Unleash . configuration . backup_file
142+
143+ File . open ( backup_file , "w" ) do |file |
144+ file . write ( fallback_toggles . to_json )
145+ end
146+
147+ Unleash . configuration . bootstrap_config = invalid_bootstrap_config
148+
149+ # Streaming connection failure doesn't matter here
150+ WebMock . stub_request ( :get , "http://streaming-test-url/client/streaming" )
151+ . to_return ( status : 500 , body : "" , headers : { } )
152+
153+ streaming_executor
154+ end
155+
156+ after do
157+ Unleash . configuration . bootstrap_config = nil
158+ end
159+
160+ it 'falls back to reading backup file when bootstrap fails' do
161+ enabled = engine . enabled? ( 'fallback-feature' , { } )
162+ expect ( enabled ) . to eq ( true )
163+ end
164+ end
165+ end
166+ end
167+ end
0 commit comments