@@ -14,6 +14,182 @@ const recreateRuntime = async (version: any = LatestSupportedPHPVersion) =>
1414 await loadNodeRuntime ( version ) ;
1515
1616describe ( 'rotatePHPRuntime()' , ( ) => {
17+ it ( 'Preserves the /internal directory through PHP runtime recreation' , async ( ) => {
18+ // Rotate the PHP runtime
19+ const recreateRuntimeSpy = vitest . fn ( recreateRuntime ) ;
20+
21+ const php = new PHP ( await recreateRuntime ( ) ) ;
22+ rotatePHPRuntime ( {
23+ php,
24+ cwd : '/test-root' ,
25+ recreateRuntime : recreateRuntimeSpy ,
26+ maxRequests : 10 ,
27+ } ) ;
28+
29+ // Create a temporary directory and a file in it
30+ const tempDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'temp-' ) ) ;
31+ const tempFile = path . join ( tempDir , 'file' ) ;
32+ fs . writeFileSync ( tempFile , 'playground' ) ;
33+
34+ // Mount the temporary directory
35+ php . mkdir ( '/internal/shared' ) ;
36+ php . writeFile ( '/internal/shared/test' , 'playground' ) ;
37+
38+ // Confirm the file is there
39+ expect ( php . fileExists ( '/internal/shared/test' ) ) . toBe ( true ) ;
40+
41+ // Rotate the PHP runtime
42+ for ( let i = 0 ; i < 15 ; i ++ ) {
43+ await php . run ( { code : `` } ) ;
44+ }
45+
46+ expect ( recreateRuntimeSpy ) . toHaveBeenCalledTimes ( 1 ) ;
47+
48+ // Confirm the file is still there
49+ expect ( php . fileExists ( '/internal/shared/test' ) ) . toBe ( true ) ;
50+ expect ( php . readFileAsText ( '/internal/shared/test' ) ) . toBe ( 'playground' ) ;
51+ } ) ;
52+
53+ it ( 'Preserves a single NODEFS mount through PHP runtime recreation' , async ( ) => {
54+ // Rotate the PHP runtime
55+ const recreateRuntimeSpy = vitest . fn ( recreateRuntime ) ;
56+
57+ const php = new PHP ( await recreateRuntime ( ) ) ;
58+ rotatePHPRuntime ( {
59+ php,
60+ cwd : '/test-root' ,
61+ recreateRuntime : recreateRuntimeSpy ,
62+ maxRequests : 10 ,
63+ } ) ;
64+
65+ // Create a temporary directory and a file in it
66+ const tempDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'temp-' ) ) ;
67+ const tempFile = path . join ( tempDir , 'file' ) ;
68+ fs . writeFileSync ( tempFile , 'playground' ) ;
69+
70+ // Mount the temporary directory
71+ php . mkdir ( '/test-root' ) ;
72+ await php . mount ( '/test-root' , createNodeFsMountHandler ( tempDir ) ) ;
73+
74+ // Confirm the file is still there
75+ expect ( php . readFileAsText ( '/test-root/file' ) ) . toBe ( 'playground' ) ;
76+
77+ // Rotate the PHP runtime
78+ for ( let i = 0 ; i < 15 ; i ++ ) {
79+ await php . run ( { code : `` } ) ;
80+ }
81+
82+ expect ( recreateRuntimeSpy ) . toHaveBeenCalledTimes ( 1 ) ;
83+
84+ // Confirm the local NODEFS mount is lost
85+ expect ( php . readFileAsText ( '/test-root/file' ) ) . toBe ( 'playground' ) ;
86+ } ) ;
87+
88+ it ( 'Preserves 4 WordPress plugin mounts through PHP runtime recreation' , async ( ) => {
89+ // Rotate the PHP runtime
90+ const recreateRuntimeSpy = vitest . fn ( recreateRuntime ) ;
91+
92+ const php = new PHP ( await recreateRuntime ( ) ) ;
93+ rotatePHPRuntime ( {
94+ php,
95+ cwd : '/wordpress' ,
96+ recreateRuntime : recreateRuntimeSpy ,
97+ maxRequests : 10 ,
98+ } ) ;
99+
100+ // Create temporary directories and files for plugins and uploads
101+ const tempDirs = [
102+ fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'data-liberation-' ) ) ,
103+ fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'data-liberation-markdown-' ) ) ,
104+ fs . mkdtempSync (
105+ path . join ( os . tmpdir ( ) , 'data-liberation-static-files-editor-' )
106+ ) ,
107+ fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'static-pages-' ) ) ,
108+ ] ;
109+
110+ // Add test files to each directory
111+ tempDirs . forEach ( ( dir , i ) => {
112+ fs . writeFileSync ( path . join ( dir , 'test.php' ) , `plugin-${ i } ` ) ;
113+ } ) ;
114+
115+ // Create WordPress directory structure
116+ php . mkdir ( '/wordpress/wp-content/plugins/data-liberation' ) ;
117+ php . mkdir ( '/wordpress/wp-content/plugins/z-data-liberation-markdown' ) ;
118+ php . mkdir (
119+ '/wordpress/wp-content/plugins/z-data-liberation-static-files-editor'
120+ ) ;
121+ php . mkdir ( '/wordpress/wp-content/uploads/static-pages' ) ;
122+
123+ // Mount the directories using WordPress paths
124+ await php . mount (
125+ '/wordpress/wp-content/plugins/data-liberation' ,
126+ createNodeFsMountHandler ( tempDirs [ 0 ] )
127+ ) ;
128+ await php . mount (
129+ '/wordpress/wp-content/plugins/z-data-liberation-markdown' ,
130+ createNodeFsMountHandler ( tempDirs [ 1 ] )
131+ ) ;
132+ await php . mount (
133+ '/wordpress/wp-content/plugins/z-data-liberation-static-files-editor' ,
134+ createNodeFsMountHandler ( tempDirs [ 2 ] )
135+ ) ;
136+ await php . mount (
137+ '/wordpress/wp-content/uploads/static-pages' ,
138+ createNodeFsMountHandler ( tempDirs [ 3 ] )
139+ ) ;
140+
141+ // Verify files exist
142+ expect (
143+ php . readFileAsText (
144+ '/wordpress/wp-content/plugins/data-liberation/test.php'
145+ )
146+ ) . toBe ( 'plugin-0' ) ;
147+ expect (
148+ php . readFileAsText (
149+ '/wordpress/wp-content/plugins/z-data-liberation-markdown/test.php'
150+ )
151+ ) . toBe ( 'plugin-1' ) ;
152+ expect (
153+ php . readFileAsText (
154+ '/wordpress/wp-content/plugins/z-data-liberation-static-files-editor/test.php'
155+ )
156+ ) . toBe ( 'plugin-2' ) ;
157+ expect (
158+ php . readFileAsText (
159+ '/wordpress/wp-content/uploads/static-pages/test.php'
160+ )
161+ ) . toBe ( 'plugin-3' ) ;
162+
163+ // Rotate the PHP runtime
164+ for ( let i = 0 ; i < 15 ; i ++ ) {
165+ await php . run ( { code : `` } ) ;
166+ }
167+
168+ expect ( recreateRuntimeSpy ) . toHaveBeenCalledTimes ( 1 ) ;
169+
170+ // Verify files still exist after rotation
171+ expect (
172+ php . readFileAsText (
173+ '/wordpress/wp-content/plugins/data-liberation/test.php'
174+ )
175+ ) . toBe ( 'plugin-0' ) ;
176+ expect (
177+ php . readFileAsText (
178+ '/wordpress/wp-content/plugins/z-data-liberation-markdown/test.php'
179+ )
180+ ) . toBe ( 'plugin-1' ) ;
181+ expect (
182+ php . readFileAsText (
183+ '/wordpress/wp-content/plugins/z-data-liberation-static-files-editor/test.php'
184+ )
185+ ) . toBe ( 'plugin-2' ) ;
186+ expect (
187+ php . readFileAsText (
188+ '/wordpress/wp-content/uploads/static-pages/test.php'
189+ )
190+ ) . toBe ( 'plugin-3' ) ;
191+ } ) ;
192+
17193 it ( 'Free up the available PHP memory' , async ( ) => {
18194 const freeMemory = ( php : PHP ) =>
19195 php [ __private__dont__use ] . HEAPU32 . reduce (
0 commit comments