@@ -14,6 +14,182 @@ const recreateRuntime = async (version: any = LatestSupportedPHPVersion) =>
14
14
await loadNodeRuntime ( version ) ;
15
15
16
16
describe ( '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
+
17
193
it ( 'Free up the available PHP memory' , async ( ) => {
18
194
const freeMemory = ( php : PHP ) =>
19
195
php [ __private__dont__use ] . HEAPU32 . reduce (
0 commit comments