@@ -2,8 +2,12 @@ use crate::config::{Config, DownstreamProxyProtocol, TlsClientAuthConfig, TlsCli
22use crate :: reload:: { ReloadImpact , ReloadReason , classify_reload} ;
33
44fn assert_process_upgrade ( new : Config , expected : ReloadReason ) {
5+ assert_transition_requires_process_upgrade ( & Config :: default ( ) , & new, expected) ;
6+ }
7+
8+ fn assert_transition_requires_process_upgrade ( old : & Config , new : & Config , expected : ReloadReason ) {
59 assert_eq ! (
6- classify_reload( & Config :: default ( ) , & new) ,
10+ classify_reload( old , new) ,
711 ReloadImpact :: ProcessUpgrade {
812 reasons: vec![ expected] ,
913 }
@@ -90,3 +94,160 @@ fn certificate_lookup_change_remains_snapshot_safe() {
9094 ReloadImpact :: Snapshot
9195 ) ;
9296}
97+
98+ fn managed_acme_config ( ) -> Config {
99+ toml:: from_str (
100+ r#"
101+ [[vhosts]]
102+ name = "site"
103+ hosts = ["site.example.test"]
104+
105+ [vhosts.tls]
106+ enabled = true
107+
108+ [vhosts.tls.acme]
109+ enabled = true
110+ issuer = "primary"
111+ "# ,
112+ )
113+ . unwrap ( )
114+ }
115+
116+ #[ test]
117+ fn nested_acme_enablement_requires_process_upgrade ( ) {
118+ let new = managed_acme_config ( ) ;
119+ let mut old = new. clone ( ) ;
120+ old. vhosts [ 0 ] . tls . acme . enabled = false ;
121+
122+ assert_transition_requires_process_upgrade ( & old, & new, ReloadReason :: AcmeServiceChanged ) ;
123+ assert_transition_requires_process_upgrade ( & new, & old, ReloadReason :: AcmeServiceChanged ) ;
124+ }
125+
126+ #[ test]
127+ fn nested_acme_identity_and_targets_require_process_upgrade ( ) {
128+ let old = managed_acme_config ( ) ;
129+ let mut changes = Vec :: new ( ) ;
130+
131+ let mut issuer = old. clone ( ) ;
132+ issuer. vhosts [ 0 ] . tls . acme . issuer = Some ( "secondary" . to_owned ( ) ) ;
133+ changes. push ( issuer) ;
134+
135+ let mut domains = old. clone ( ) ;
136+ domains. vhosts [ 0 ] . tls . acme . domains = vec ! [ "certificate.example.test" . to_owned( ) ] ;
137+ changes. push ( domains) ;
138+
139+ let mut inherited_hosts = old. clone ( ) ;
140+ inherited_hosts. vhosts [ 0 ] . hosts = vec ! [ "renamed.example.test" . to_owned( ) ] ;
141+ changes. push ( inherited_hosts) ;
142+
143+ let mut vhost_name = old. clone ( ) ;
144+ vhost_name. vhosts [ 0 ] . name = "renamed" . to_owned ( ) ;
145+ changes. push ( vhost_name) ;
146+
147+ for new in changes {
148+ assert_transition_requires_process_upgrade ( & old, & new, ReloadReason :: AcmeServiceChanged ) ;
149+ }
150+ }
151+
152+ fn managed_php_config ( ) -> Config {
153+ toml:: from_str (
154+ r#"
155+ [[vhosts]]
156+ name = "php"
157+ hosts = ["php.example.test"]
158+
159+ [vhosts.php]
160+ enabled = true
161+
162+ [vhosts.php.fpm]
163+ mode = "managed"
164+ php_fpm_binary = "/usr/sbin/php-fpm"
165+ socket_dir = "/run/fluxheim/php"
166+ "# ,
167+ )
168+ . unwrap ( )
169+ }
170+
171+ #[ test]
172+ fn managed_php_add_remove_requires_process_upgrade ( ) {
173+ let new = managed_php_config ( ) ;
174+ let old = Config :: default ( ) ;
175+
176+ assert_transition_requires_process_upgrade ( & old, & new, ReloadReason :: ManagedPhpServiceChanged ) ;
177+ assert_transition_requires_process_upgrade ( & new, & old, ReloadReason :: ManagedPhpServiceChanged ) ;
178+ }
179+
180+ #[ test]
181+ fn managed_php_process_policy_changes_require_process_upgrade ( ) {
182+ let old = managed_php_config ( ) ;
183+ let mut changes = Vec :: new ( ) ;
184+
185+ let mut binary = old. clone ( ) ;
186+ binary. vhosts [ 0 ] . php . fpm . php_fpm_binary = Some ( "/opt/php/sbin/php-fpm" . into ( ) ) ;
187+ changes. push ( binary) ;
188+
189+ let mut identity = old. clone ( ) ;
190+ identity. vhosts [ 0 ] . php . fpm . user = Some ( "www-data" . to_owned ( ) ) ;
191+ identity. vhosts [ 0 ] . php . fpm . group = Some ( "www-data" . to_owned ( ) ) ;
192+ changes. push ( identity) ;
193+
194+ let mut environment = old. clone ( ) ;
195+ environment. vhosts [ 0 ] . php . fpm . clear_env = false ;
196+ changes. push ( environment) ;
197+
198+ let mut socket_dir = old. clone ( ) ;
199+ socket_dir. vhosts [ 0 ] . php . fpm . socket_dir = Some ( "/run/fluxheim/php-next" . into ( ) ) ;
200+ changes. push ( socket_dir) ;
201+
202+ let mut workers = old. clone ( ) ;
203+ workers. vhosts [ 0 ] . php . fpm . process_manager = crate :: config:: PhpFpmProcessManager :: Dynamic ;
204+ workers. vhosts [ 0 ] . php . fpm . workers = 8 ;
205+ workers. vhosts [ 0 ] . php . fpm . min_spare_servers = Some ( 2 ) ;
206+ workers. vhosts [ 0 ] . php . fpm . max_spare_servers = Some ( 4 ) ;
207+ changes. push ( workers) ;
208+
209+ for new in changes {
210+ assert_transition_requires_process_upgrade (
211+ & old,
212+ & new,
213+ ReloadReason :: ManagedPhpServiceChanged ,
214+ ) ;
215+ }
216+ }
217+
218+ #[ test]
219+ fn route_managed_php_addition_requires_process_upgrade ( ) {
220+ let old = Config :: default ( ) ;
221+ let new: Config = toml:: from_str (
222+ r#"
223+ [[vhosts]]
224+ name = "php"
225+ hosts = ["php.example.test"]
226+
227+ [[vhosts.routes]]
228+ name = "application"
229+ path_prefix = "/app"
230+
231+ [vhosts.routes.php]
232+ enabled = true
233+
234+ [vhosts.routes.php.fpm]
235+ mode = "managed"
236+ php_fpm_binary = "/usr/sbin/php-fpm"
237+ socket_dir = "/run/fluxheim/php-route"
238+ "# ,
239+ )
240+ . unwrap ( ) ;
241+
242+ assert_transition_requires_process_upgrade ( & old, & new, ReloadReason :: ManagedPhpServiceChanged ) ;
243+ }
244+
245+ #[ test]
246+ fn managed_php_request_policy_change_remains_snapshot_safe ( ) {
247+ let old = managed_php_config ( ) ;
248+ let mut new = old. clone ( ) ;
249+ new. vhosts [ 0 ] . php . request_timeout_secs += 1 ;
250+ new. vhosts [ 0 ] . php . fpm . read_timeout_secs = Some ( 15 ) ;
251+
252+ assert_eq ! ( classify_reload( & old, & new) , ReloadImpact :: Snapshot ) ;
253+ }
0 commit comments