github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/test/qr_test.go (about)

     1  // Copyright 2016 Keybase Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD
     3  // license that can be found in the LICENSE file.
     4  
     5  // These tests exercise quota reclamation.
     6  
     7  package test
     8  
     9  import (
    10  	"fmt"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  // Check that simple quota reclamation works
    16  func TestQRSimple(t *testing.T) {
    17  	test(t,
    18  		users("alice"),
    19  		as(alice,
    20  			addTime(1*time.Minute),
    21  			mkfile("a", "hello"),
    22  			rm("a"),
    23  			addTime(2*time.Minute),
    24  			forceQuotaReclamation(),
    25  		),
    26  	)
    27  }
    28  
    29  // Check that quota reclamation works, eventually, after enough iterations.
    30  func TestQRLargePointerSet(t *testing.T) {
    31  	var busyWork []fileOp
    32  	iters := 100
    33  	for i := 0; i < iters; i++ {
    34  		name := fmt.Sprintf("a%d", i)
    35  		busyWork = append(busyWork, mkfile(name, "hello"), rm(name))
    36  	}
    37  	// 5 unreferenced pointers per iteration -- 3 updates to the root
    38  	// block, one empty file written to, and one non-empty file
    39  	// deleted.
    40  	ptrsPerIter := 5
    41  	var qrOps []optionOp
    42  	// Each reclamation needs a sync after it (e.g., a new "as"
    43  	// clause) to ensure it completes before the next force
    44  	// reclamation.
    45  	for i := 0; i < ptrsPerIter*iters/100; i++ {
    46  		qrOps = append(qrOps, as(alice,
    47  			addTime(2*time.Minute),
    48  			forceQuotaReclamation(),
    49  		))
    50  	}
    51  	totalOps := []optionOp{users("alice"), as(alice, busyWork...)}
    52  	totalOps = append(totalOps, qrOps...)
    53  	test(t, totalOps...)
    54  }
    55  
    56  // Test that quota reclamation handles conflict resolution correctly.
    57  func TestQRAfterCR(t *testing.T) {
    58  	test(t,
    59  		users("alice", "bob"),
    60  		as(alice,
    61  			mkfile("a/b", "hello"),
    62  		),
    63  		as(bob,
    64  			disableUpdates(),
    65  		),
    66  		as(alice,
    67  			write("a/c", "world"),
    68  		),
    69  		as(bob, noSync(),
    70  			rm("a/b"),
    71  			reenableUpdates(),
    72  		),
    73  		as(alice,
    74  			addTime(2*time.Minute),
    75  			forceQuotaReclamation(),
    76  		),
    77  	)
    78  }
    79  
    80  // Check that quota reclamation after two syncOps CR leaves the TLF in
    81  // a readable state.  Regression test for KBFS-1562.
    82  func TestQRAfterCRWithTwoSyncOps(t *testing.T) {
    83  	test(t,
    84  		users("alice", "bob"),
    85  		as(alice,
    86  			mkfile("a/b", "hello"),
    87  		),
    88  		as(bob,
    89  			disableUpdates(),
    90  		),
    91  		as(alice,
    92  			write("a/c", "hello2"),
    93  		),
    94  		as(bob, noSync(),
    95  			write("a/b", "hello world"),
    96  			write("a/b", "hello world etc"),
    97  			reenableUpdates(),
    98  		),
    99  		as(alice,
   100  			addTime(2*time.Minute),
   101  			forceQuotaReclamation(),
   102  			read("a/b", "hello world etc"),
   103  			read("a/c", "hello2"),
   104  		),
   105  	)
   106  }
   107  
   108  // Check that quota reclamation works on multi-block files
   109  func TestQRWithMultiBlockFiles(t *testing.T) {
   110  	test(t,
   111  		blockSize(20), users("alice"),
   112  		as(alice,
   113  			addTime(1*time.Minute),
   114  			mkfile("a", ntimesString(15, "0123456789")),
   115  			rm("a"),
   116  			addTime(2*time.Minute),
   117  			forceQuotaReclamation(),
   118  		),
   119  	)
   120  }
   121  
   122  // Test that conflict resolution works gracefully after quota
   123  // reclamation deletes a modified+deleted directory from the merged
   124  // branch.  Regression for KBFS-1202.
   125  func TestCRAfterRmdirAndQR(t *testing.T) {
   126  	test(t,
   127  		users("alice", "bob"),
   128  		as(alice,
   129  			mkdir("a/b"),
   130  			mkfile("a/b/c", "world"),
   131  		),
   132  		as(bob,
   133  			disableUpdates(),
   134  		),
   135  		as(alice,
   136  			mkfile("a/b/d", "world2"),
   137  			rm("a/b/c"),
   138  			rm("a/b/d"),
   139  			rmdir("a/b"),
   140  		),
   141  		as(bob, noSync(),
   142  			setmtime("a/b/c", time.Now().Add(1*time.Minute)),
   143  			rm("a/b/c"),
   144  			rmdir("a/b"),
   145  		),
   146  		as(alice,
   147  			addTime(2*time.Minute),
   148  			// Force rmd.data.Dir.MTime to something recent. TODO: remove me.
   149  			mkfile("c", "test"),
   150  			forceQuotaReclamation(),
   151  		),
   152  		as(bob, noSync(),
   153  			reenableUpdates(),
   154  			lsdir("a/", m{}),
   155  		),
   156  		as(alice,
   157  			lsdir("a/", m{}),
   158  		),
   159  	)
   160  }