6
"path/filepath"
7
"testing"
8
9
+ "github.com/ipfs/kubo/config"
10
"github.com/ipfs/kubo/test/cli/harness"
11
"github.com/stretchr/testify/assert"
12
"github.com/stretchr/testify/require"
179
assert.NotContains(t, lsRes.Stdout.String(), "test-dir")
180
})
181
}
182
+
183
+func TestFilesNoFlushLimit(t *testing.T) {
184
+ t.Parallel()
185
+
186
+ t.Run("reaches default limit of 256 operations", func(t *testing.T) {
187
+ t.Parallel()
188
+ node := harness.NewT(t).NewNode().Init().StartDaemon()
189
+
190
+ // Perform 256 operations with --flush=false (should succeed)
191
+ for i := 0; i < 256; i++ {
192
+ res := node.IPFS("files", "mkdir", "--flush=false", fmt.Sprintf("/dir%d", i))
193
+ assert.NoError(t, res.Err, "operation %d should succeed", i+1)
194
+ }
195
+
196
+ // 257th operation should fail
197
+ res := node.RunIPFS("files", "mkdir", "--flush=false", "/dir256")
198
+ require.NotNil(t, res.ExitErr, "command should have failed")
199
+ assert.NotEqual(t, 0, res.ExitErr.ExitCode())
200
+ assert.Contains(t, res.Stderr.String(), "reached limit of 256 unflushed MFS operations")
201
+ assert.Contains(t, res.Stderr.String(), "run 'ipfs files flush'")
202
+ assert.Contains(t, res.Stderr.String(), "use --flush=true")
203
+ assert.Contains(t, res.Stderr.String(), "increase Internal.MFSNoFlushLimit")
204
+ })
205
+
206
+ t.Run("custom limit via config", func(t *testing.T) {
207
+ t.Parallel()
208
+ node := harness.NewT(t).NewNode().Init()
209
+
210
+ // Set custom limit to 5
211
+ node.UpdateConfig(func(cfg *config.Config) {
212
+ limit := config.NewOptionalInteger(5)
213
+ cfg.Internal.MFSNoFlushLimit = limit
214
+ })
215
+
216
+ node.StartDaemon()
217
+
218
+ // Perform 5 operations (should succeed)
219
+ for i := 0; i < 5; i++ {
220
+ res := node.IPFS("files", "mkdir", "--flush=false", fmt.Sprintf("/dir%d", i))
221
+ assert.NoError(t, res.Err, "operation %d should succeed", i+1)
222
+ }
223
+
224
+ // 6th operation should fail
225
+ res := node.RunIPFS("files", "mkdir", "--flush=false", "/dir5")
226
+ require.NotNil(t, res.ExitErr, "command should have failed")
227
+ assert.NotEqual(t, 0, res.ExitErr.ExitCode())
228
+ assert.Contains(t, res.Stderr.String(), "reached limit of 5 unflushed MFS operations")
229
+ })
230
+
231
+ t.Run("flush=true resets counter", func(t *testing.T) {
232
+ t.Parallel()
233
+ node := harness.NewT(t).NewNode().Init()
234
+
235
+ // Set limit to 3 for faster testing
236
+ node.UpdateConfig(func(cfg *config.Config) {
237
+ limit := config.NewOptionalInteger(3)
238
+ cfg.Internal.MFSNoFlushLimit = limit
239
+ })
240
+
241
+ node.StartDaemon()
242
+
243
+ // Do 2 operations with --flush=false
244
+ node.IPFS("files", "mkdir", "--flush=false", "/dir1")
245
+ node.IPFS("files", "mkdir", "--flush=false", "/dir2")
246
+
247
+ // Operation with --flush=true should reset counter
248
+ node.IPFS("files", "mkdir", "--flush=true", "/dir3")
249
+
250
+ // Now we should be able to do 3 more operations with --flush=false
251
+ for i := 4; i <= 6; i++ {
252
+ res := node.IPFS("files", "mkdir", "--flush=false", fmt.Sprintf("/dir%d", i))
253
+ assert.NoError(t, res.Err, "operation after flush should succeed")
254
+ }
255
+
256
+ // 4th operation after reset should fail
257
+ res := node.RunIPFS("files", "mkdir", "--flush=false", "/dir7")
258
+ require.NotNil(t, res.ExitErr, "command should have failed")
259
+ assert.NotEqual(t, 0, res.ExitErr.ExitCode())
260
+ assert.Contains(t, res.Stderr.String(), "reached limit of 3 unflushed MFS operations")
261
+ })
262
+
263
+ t.Run("explicit flush command resets counter", func(t *testing.T) {
264
+ t.Parallel()
265
+ node := harness.NewT(t).NewNode().Init()
266
+
267
+ // Set limit to 3 for faster testing
268
+ node.UpdateConfig(func(cfg *config.Config) {
269
+ limit := config.NewOptionalInteger(3)
270
+ cfg.Internal.MFSNoFlushLimit = limit
271
+ })
272
+
273
+ node.StartDaemon()
274
+
275
+ // Do 2 operations with --flush=false
276
+ node.IPFS("files", "mkdir", "--flush=false", "/dir1")
277
+ node.IPFS("files", "mkdir", "--flush=false", "/dir2")
278
+
279
+ // Explicit flush should reset counter
280
+ node.IPFS("files", "flush")
281
+
282
+ // Now we should be able to do 3 more operations
283
+ for i := 3; i <= 5; i++ {
284
+ res := node.IPFS("files", "mkdir", "--flush=false", fmt.Sprintf("/dir%d", i))
285
+ assert.NoError(t, res.Err, "operation after flush should succeed")
286
+ }
287
+
288
+ // 4th operation should fail
289
+ res := node.RunIPFS("files", "mkdir", "--flush=false", "/dir6")
290
+ require.NotNil(t, res.ExitErr, "command should have failed")
291
+ assert.NotEqual(t, 0, res.ExitErr.ExitCode())
292
+ assert.Contains(t, res.Stderr.String(), "reached limit of 3 unflushed MFS operations")
293
+ })
294
+
295
+ t.Run("limit=0 disables the feature", func(t *testing.T) {
296
+ t.Parallel()
297
+ node := harness.NewT(t).NewNode().Init()
298
+
299
+ // Set limit to 0 (disabled)
300
+ node.UpdateConfig(func(cfg *config.Config) {
301
+ limit := config.NewOptionalInteger(0)
302
+ cfg.Internal.MFSNoFlushLimit = limit
303
+ })
304
+
305
+ node.StartDaemon()
306
+
307
+ // Should be able to do many operations without error
308
+ for i := 0; i < 300; i++ {
309
+ res := node.IPFS("files", "mkdir", "--flush=false", fmt.Sprintf("/dir%d", i))
310
+ assert.NoError(t, res.Err, "operation %d should succeed with limit disabled", i+1)
311
+ }
312
+ })
313
+
314
+ t.Run("different MFS commands count towards limit", func(t *testing.T) {
315
+ t.Parallel()
316
+ node := harness.NewT(t).NewNode().Init()
317
+
318
+ // Set limit to 5 for testing
319
+ node.UpdateConfig(func(cfg *config.Config) {
320
+ limit := config.NewOptionalInteger(5)
321
+ cfg.Internal.MFSNoFlushLimit = limit
322
+ })
323
+
324
+ node.StartDaemon()
325
+
326
+ // Mix of different MFS operations (5 operations to hit the limit)
327
+ node.IPFS("files", "mkdir", "--flush=false", "/testdir")
328
+ // Create a file first, then copy it
329
+ testCid := node.IPFSAddStr("test content")
330
+ node.IPFS("files", "cp", "--flush=false", fmt.Sprintf("/ipfs/%s", testCid), "/testfile")
331
+ node.IPFS("files", "cp", "--flush=false", "/testfile", "/testfile2")
332
+ node.IPFS("files", "mv", "--flush=false", "/testfile2", "/testfile3")
333
+ node.IPFS("files", "mkdir", "--flush=false", "/anotherdir")
334
+
335
+ // 6th operation should fail
336
+ res := node.RunIPFS("files", "mkdir", "--flush=false", "/another")
337
+ require.NotNil(t, res.ExitErr, "command should have failed")
338
+ assert.NotEqual(t, 0, res.ExitErr.ExitCode())
339
+ assert.Contains(t, res.Stderr.String(), "reached limit of 5 unflushed MFS operations")
340
+ })
341
+}