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)