File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / rsync / testhelp / maketree.py
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Fri Feb 17 15:09:30 2012 UTC (12 years, 5 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: #! /usr/bin/python2.2
    2: 
    3: # Copyright (C) 2002 by Martin Pool <mbp@samba.org>
    4: 
    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.
    8: #
    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.
   13: # 
   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.
   17: 
   18: # Populate a tree with pseudo-randomly distributed files to test
   19: # rsync.
   20: 
   21: from __future__ import generators
   22: import random, string, os, os.path
   23: 
   24: nfiles = 10000
   25: depth = 5
   26: n_children = 20
   27: n_files = 20
   28: n_symlinks = 10
   29: 
   30: name_chars = string.digits + string.letters
   31: 
   32: abuffer = 'a' * 1024
   33: 
   34: def random_name_chars():
   35:     a = ""
   36:     for i in range(10):
   37:         a = a + random.choice(name_chars)
   38:     return a
   39: 
   40:     
   41: def generate_names():
   42:     n = 0
   43:     while 1:
   44:         yield "%05d_%s" % (n, random_name_chars())
   45:         n += 1
   46: 
   47: 
   48: class TreeBuilder:
   49:     def __init__(self):
   50:         self.n_children = 20
   51:         self.n_files = 100
   52:         self.total_entries = 100000 # long(1e8)
   53:         self.actual_size = 0
   54:         self.name_gen = generate_names()
   55:         self.all_files = []
   56:         self.all_dirs = []
   57:         self.all_symlinks = []
   58: 
   59: 
   60:     def random_size(self):
   61:         return random.lognormvariate(4, 4)
   62: 
   63: 
   64:     def random_symlink_target(self):
   65:         what = random.choice(['directory', 'file', 'symlink', 'none'])
   66:         try:
   67:             if what == 'directory':
   68:                 return random.choice(self.all_dirs)
   69:             elif what == 'file':
   70:                 return random.choice(self.all_files)
   71:             elif what == 'symlink':
   72:                 return random.choice(self.all_symlinks)
   73:             elif what == 'none':
   74:                 return self.name_gen.next()
   75:         except IndexError:
   76:             return self.name_gen.next()
   77: 
   78: 
   79:     def can_continue(self):
   80:         self.total_entries -= 1
   81:         return self.total_entries > 0
   82: 
   83:         
   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():
   91:                     return
   92:                 name = os.path.join(prefix, self.name_gen.next())
   93:                 function(name, depth)
   94: 
   95: 
   96:     def print_summary(self):
   97:         print "total bytes: %d" % self.actual_size
   98: 
   99: 
  100:     def make_child_recurse(self, dname, depth):
  101:         if depth > 1:
  102:             self.make_dir(dname)
  103:             self.build_tree(dname, depth-1)
  104: 
  105: 
  106:     def make_dir(self, dname, depth='ignore'):
  107:         print "%s/" % (dname)
  108:         os.mkdir(dname)
  109:         self.all_dirs.append(dname)
  110: 
  111: 
  112:     def make_symlink(self, lname, depth='ignore'):
  113:         print "%s -> %s" % (lname, self.random_symlink_target())
  114: 
  115: 
  116:     def make_file(self, fname, depth='ignore'):
  117:         size = long(self.random_size())
  118:         print "%-70s %d" % (fname, size)
  119:         f = open(fname, 'w')
  120:         f.truncate(size)
  121:         self.fill_file(f, size)
  122:         self.all_files.append(fname)
  123:         self.actual_size += size
  124: 
  125:     def fill_file(self, f, size):
  126:         while size > 0:
  127:             f.write(abuffer[:size])
  128:             size -= len(abuffer)
  129: 
  130:     
  131: tb = TreeBuilder()
  132: tb.build_tree('/tmp/foo', 3)
  133: tb.print_summary()

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>