3 # Copyright (C) 2002 by Martin Pool <mbp@samba.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License version
7 # 2 as published by the Free Software Foundation.
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this program; if not, write to the Free Software
16 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 # Populate a tree with pseudo-randomly distributed files to test
21 from __future__
import generators
22 import random
, string
, os
, os
.path
30 name_chars
= string
.digits
+ string
.letters
34 def random_name_chars():
37 a
= a
+ random
.choice(name_chars
)
44 yield "%05d_%s" % (n
, random_name_chars())
52 self
.total_entries
= 100000 # long(1e8)
54 self
.name_gen
= generate_names()
57 self
.all_symlinks
= []
60 def random_size(self
):
61 return random
.lognormvariate(4, 4)
64 def random_symlink_target(self
):
65 what
= random
.choice(['directory', 'file', 'symlink', 'none'])
67 if what
== 'directory':
68 return random
.choice(self
.all_dirs
)
70 return random
.choice(self
.all_files
)
71 elif what
== 'symlink':
72 return random
.choice(self
.all_symlinks
)
74 return self
.name_gen
.next()
76 return self
.name_gen
.next()
79 def can_continue(self
):
80 self
.total_entries
-= 1
81 return self
.total_entries
> 0
84 def build_tree(self
, prefix
, depth
):
85 """Generate a breadth-first tree"""
86 for count
, function
in [[n_files
, self
.make_file
],
87 [n_children
, self
.make_child_recurse
],
88 [n_symlinks
, self
.make_symlink
]]:
89 for i
in range(count
):
90 if not self
.can_continue():
92 name
= os
.path
.join(prefix
, self
.name_gen
.next())
96 def print_summary(self
):
97 print "total bytes: %d" % self
.actual_size
100 def make_child_recurse(self
, dname
, depth
):
103 self
.build_tree(dname
, depth
-1)
106 def make_dir(self
, dname
, depth
='ignore'):
107 print "%s/" % (dname
)
109 self
.all_dirs
.append(dname
)
112 def make_symlink(self
, lname
, depth
='ignore'):
113 print "%s -> %s" % (lname
, self
.random_symlink_target())
116 def make_file(self
, fname
, depth
='ignore'):
117 size
= long(self
.random_size())
118 print "%-70s %d" % (fname
, size
)
121 self
.fill_file(f
, size
)
122 self
.all_files
.append(fname
)
123 self
.actual_size
+= size
125 def fill_file(self
, f
, size
):
127 f
.write(abuffer
[:size
])
132 tb
.build_tree('/tmp/foo', 3)