Skip to content

Instantly share code, notes, and snippets.

@marcsello
Last active February 17, 2022 12:07
Show Gist options
  • Save marcsello/75f88386f05943ccca988ad174bdff14 to your computer and use it in GitHub Desktop.
Save marcsello/75f88386f05943ccca988ad174bdff14 to your computer and use it in GitHub Desktop.
Create a directory with full of random files and directories. Ideal for inode related tests and benchmarks.
import sys
import os
import os.path
import random
import string
WORDS = [
"condition", "set", "against", "legislation", "solar", "dad", "rating", "machine", "swim", "distribute",
"payment", "basically", "gold", "prosecutor", "poverty", "profession", "tail", "psychological", "dimension",
"jail", "suppose", "efficient", "party", "quit", "approval", "cloud", "settle", "offer", "everywhere", "famous",
"oven", "consciousness", "literary", "part", "nobody", "procedure", "member", "CEO", "sell", "flight", "commercial",
"room", "long", "lip", "progress", "branch", "sensitive", "weekly", "depend", "title", "council", "ear", "wise",
"reduce", "limited", "access", "office", "approximately", "new", "finance", "tire", "practice"
]
MAX_PATH = os.pathconf('/', 'PC_PATH_MAX')
MAX_NAME = os.pathconf('/', 'PC_NAME_MAX')
def newname(maxlen: int, have_ext: bool = True) -> str:
assert maxlen > 0
words = []
for _ in range(random.randint(2, 5)):
word = random.choice(WORDS)
if random.random() > 0.7:
word = word.upper()
words.append(
word
)
if random.random() > 0.5:
words.insert(
random.randint(0, len(words) - 1),
str(random.randint(1000, 99999))
)
separator = random.choice(["-", "_", ".", " "])
name = separator.join(words)
if have_ext and (maxlen > 4):
name = name[:maxlen - 4]
name += "." + "".join(random.choice(string.ascii_lowercase) for _ in range(3))
else:
name = name[:maxlen]
assert len(name) <= MAX_NAME
assert len(name) <= maxlen
return name
def main():
path = os.path.abspath(sys.argv[1])
maxinodes = int(sys.argv[2])
print(f"Creating a random tree in {path} with {maxinodes} inodes!")
os.chdir(path)
cwd = os.getcwd()
inodecount = 0
while inodecount < maxinodes:
assert len(cwd) <= MAX_PATH
assert len(path) <= len(cwd) # TODO: This isn't the best check
usable_length = MAX_PATH - len(cwd) - 1 # remove one because the slash
move_up = False
if usable_length < 5:
move_up = True
else:
rnd = random.random()
if rnd < 0.15: # <- The chance of creating a dir instead of a file
newdir = newname(min(usable_length, MAX_NAME), False)
if os.path.exists(newdir):
continue
os.mkdir(newdir)
os.chdir(newdir)
cwd = os.getcwd()
inodecount += 1
print(f"[{inodecount}/{maxinodes}] (D) {cwd}")
elif 0.15 < rnd < 0.30: # <- chance of leaving this dir
move_up = True
else:
newfile = newname(min(usable_length, MAX_NAME), True)
if os.path.exists(newfile):
continue
with open(newfile, "wb") as f:
f.write(os.urandom(random.randint(128, 1024 ** 2)))
inodecount += 1
print(f"[{inodecount}/{maxinodes}] (F) {os.path.join(os.getcwd(), newfile)}")
if move_up:
if path != os.path.abspath(os.getcwd()): # if not at top level
os.chdir("..")
cwd = os.getcwd()
assert inodecount == maxinodes
print(f"Finished! Created {inodecount} inodes.")
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment