github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/fs/dirtree/dirtree_test.go (about)

     1  package dirtree
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/rclone/rclone/fstest/mockdir"
     8  	"github.com/rclone/rclone/fstest/mockobject"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestNew(t *testing.T) {
    14  	dt := New()
    15  	assert.Equal(t, "", dt.String())
    16  }
    17  
    18  func TestParentDir(t *testing.T) {
    19  	assert.Equal(t, "root/parent", parentDir("root/parent/file"))
    20  	assert.Equal(t, "parent", parentDir("parent/file"))
    21  	assert.Equal(t, "", parentDir("parent"))
    22  	assert.Equal(t, "", parentDir(""))
    23  }
    24  
    25  func TestDirTreeAdd(t *testing.T) {
    26  	dt := New()
    27  	o := mockobject.New("potato")
    28  	dt.Add(o)
    29  	assert.Equal(t, `/
    30    potato
    31  `, dt.String())
    32  	o = mockobject.New("dir/subdir/sausage")
    33  	dt.Add(o)
    34  	assert.Equal(t, `/
    35    potato
    36  dir/subdir/
    37    sausage
    38  `, dt.String())
    39  }
    40  
    41  func TestDirTreeAddDir(t *testing.T) {
    42  	dt := New()
    43  	d := mockdir.New("potato")
    44  	dt.Add(d)
    45  	assert.Equal(t, `/
    46    potato/
    47  `, dt.String())
    48  	d = mockdir.New("dir/subdir/sausage")
    49  	dt.AddDir(d)
    50  	assert.Equal(t, `/
    51    potato/
    52  dir/subdir/
    53    sausage/
    54  dir/subdir/sausage/
    55  `, dt.String())
    56  	d = mockdir.New("")
    57  	dt.AddDir(d)
    58  	assert.Equal(t, `/
    59    potato/
    60  dir/subdir/
    61    sausage/
    62  dir/subdir/sausage/
    63  `, dt.String())
    64  }
    65  
    66  func TestDirTreeAddEntry(t *testing.T) {
    67  	dt := New()
    68  
    69  	d := mockdir.New("dir/subdir/sausagedir")
    70  	dt.AddEntry(d)
    71  	o := mockobject.New("dir/subdir2/sausage2")
    72  	dt.AddEntry(o)
    73  
    74  	assert.Equal(t, `/
    75    dir/
    76  dir/
    77    subdir/
    78    subdir2/
    79  dir/subdir/
    80    sausagedir/
    81  dir/subdir/sausagedir/
    82  dir/subdir2/
    83    sausage2
    84  `, dt.String())
    85  }
    86  
    87  func TestDirTreeFind(t *testing.T) {
    88  	dt := New()
    89  
    90  	parent, foundObj := dt.Find("dir/subdir/sausage")
    91  	assert.Equal(t, "dir/subdir", parent)
    92  	assert.Nil(t, foundObj)
    93  
    94  	o := mockobject.New("dir/subdir/sausage")
    95  	dt.Add(o)
    96  
    97  	parent, foundObj = dt.Find("dir/subdir/sausage")
    98  	assert.Equal(t, "dir/subdir", parent)
    99  	assert.Equal(t, o, foundObj)
   100  }
   101  
   102  func TestDirTreeCheckParent(t *testing.T) {
   103  	dt := New()
   104  
   105  	o := mockobject.New("dir/subdir/sausage")
   106  	dt.Add(o)
   107  
   108  	assert.Equal(t, `dir/subdir/
   109    sausage
   110  `, dt.String())
   111  
   112  	dt.checkParent("", "dir/subdir", nil)
   113  
   114  	assert.Equal(t, `/
   115    dir/
   116  dir/
   117    subdir/
   118  dir/subdir/
   119    sausage
   120  `, dt.String())
   121  
   122  }
   123  
   124  func TestDirTreeCheckParents(t *testing.T) {
   125  	dt := New()
   126  
   127  	dt.Add(mockobject.New("dir/subdir/sausage"))
   128  	dt.Add(mockobject.New("dir/subdir2/sausage2"))
   129  
   130  	dt.CheckParents("")
   131  	dt.Sort() // sort since the exact order of adding parents is not defined
   132  
   133  	assert.Equal(t, `/
   134    dir/
   135  dir/
   136    subdir/
   137    subdir2/
   138  dir/subdir/
   139    sausage
   140  dir/subdir2/
   141    sausage2
   142  `, dt.String())
   143  }
   144  
   145  func TestDirTreeSort(t *testing.T) {
   146  	dt := New()
   147  
   148  	dt.Add(mockobject.New("dir/subdir/B"))
   149  	dt.Add(mockobject.New("dir/subdir/A"))
   150  
   151  	assert.Equal(t, `dir/subdir/
   152    B
   153    A
   154  `, dt.String())
   155  
   156  	dt.Sort()
   157  
   158  	assert.Equal(t, `dir/subdir/
   159    A
   160    B
   161  `, dt.String())
   162  }
   163  
   164  func TestDirTreeDirs(t *testing.T) {
   165  	dt := New()
   166  
   167  	dt.Add(mockobject.New("dir/subdir/sausage"))
   168  	dt.Add(mockobject.New("dir/subdir2/sausage2"))
   169  
   170  	dt.CheckParents("")
   171  
   172  	assert.Equal(t, []string{
   173  		"",
   174  		"dir",
   175  		"dir/subdir",
   176  		"dir/subdir2",
   177  	}, dt.Dirs())
   178  }
   179  
   180  func TestDirTreePrune(t *testing.T) {
   181  	dt := New()
   182  
   183  	dt.Add(mockobject.New("file"))
   184  	dt.Add(mockobject.New("dir/subdir/sausage"))
   185  	dt.Add(mockobject.New("dir/subdir2/sausage2"))
   186  	dt.Add(mockobject.New("dir/file"))
   187  	dt.Add(mockobject.New("dir2/file"))
   188  
   189  	dt.CheckParents("")
   190  
   191  	err := dt.Prune(map[string]bool{
   192  		"dir": true,
   193  	})
   194  	require.NoError(t, err)
   195  
   196  	assert.Equal(t, `/
   197    file
   198    dir2/
   199  dir2/
   200    file
   201  `, dt.String())
   202  
   203  }
   204  
   205  func BenchmarkCheckParents(b *testing.B) {
   206  	for _, N := range []int{1e2, 1e3, 1e4, 1e5, 1e6} {
   207  		b.Run(fmt.Sprintf("%d", N), func(b *testing.B) {
   208  			b.StopTimer()
   209  			dt := New()
   210  			for i := 0; i < N; i++ {
   211  				remote := fmt.Sprintf("dir%09d/file%09d.txt", i, 1)
   212  				o := mockobject.New(remote)
   213  				dt.Add(o)
   214  			}
   215  			b.StartTimer()
   216  			for n := 0; n < b.N; n++ {
   217  				dt.CheckParents("")
   218  			}
   219  		})
   220  	}
   221  }