Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@ __pycache__/
# Sphinx documentation
docs/_build/

# Build files
venv/

# Temporary files
_.*
/output/
/tests/_scratch/
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
default: example

example:
./venv/bin/python3 run_example.py -d .

test:
@./venv/bin/python3 -m unittest
18 changes: 17 additions & 1 deletion ddhf/ddhf/decorated_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,29 @@ def from_argv(self):
"AUTOARCHAEOLOGIST_BITSTORE_CACHE": "ddhf_bitstore_cache",
}

def main(job, html_subdir="tmp", **kwargs):
def parse_arguments(argv=None):
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--out', default='/tmp/_autoarchaologist')

args = parser.parse_args(args=argv)
if args.out == '.':
args.out = os.path.join(os.getcwd(), "_autoarchaologist")
return args

def main(job, html_subdir, **kwargs):
args = parse_arguments()
kwargs["html_dir"] = args.out

''' A standard main routine to reduce boiler-plate '''
for key in os.environ:
i = OK_ENVS.get(key)
if i:
kwargs[i] = os.environ[key]

if 'html_dir' not in kwargs:
raise AttributeError("missing: html_dir")


kwargs['html_dir'] = os.path.join(kwargs['html_dir'], html_subdir)
kwargs.setdefault('download_links', True)
kwargs.setdefault('download_limit', 1 << 20)
Expand Down
Empty file added output/.gitkeep
Empty file.
48 changes: 48 additions & 0 deletions run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import argparse
import os
import sys

from autoarchaeologist import Excavation

def parse_arguments(argv=None):
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--dir", default="/tmp/_autoarchaologist")
parser.add_argument('filename')

return parser.parse_args(args=argv)

def process_arguments(args):
if args.dir == ".":
args.dir = os.path.join(os.getcwd(), "output", "_autoarchaologist")
if args.filename is not None:
args.filename = os.path.abspath(args.filename)
else:
raise ValueError()

return args

def perform_excavation(args, action_tuple):
match action_tuple:
case "excavator", AnExcavation:
assert issubclass(AnExcavation, Excavation)
ctx = AnExcavation(html_dir=args.dir)
case action, _:
raise NotImplementedError(f"action: {action}")

ff = ctx.add_file_artifact(args.filename)

ctx.start_examination()

return ctx

if __name__ == "__main__":
args = process_arguments(parse_arguments())

try:
os.mkdir(args.dir)
except FileExistsError:
pass

ctx = perform_excavation(args, ("none", None))
ctx.produce_html()
print("Now point your browser at", ctx.filename_for(ctx).link)
38 changes: 19 additions & 19 deletions run_example.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@

import os
import sys
from types import SimpleNamespace

import autoarchaeologist

from autoarchaeologist.generic.bigdigits import BigDigits
from run import parse_arguments, process_arguments, perform_excavation
from autoarchaeologist.base.excavation import Excavation
from autoarchaeologist.generic.bigtext import BigText
from autoarchaeologist.generic.samesame import SameSame
from autoarchaeologist.data_general.absbin import AbsBin
from autoarchaeologist.data_general.papertapechecksum import DGC_PaperTapeCheckSum


if __name__ == "__main__":

ctx = autoarchaeologist.Excavation()

ctx.add_examiner(BigDigits)
ctx.add_examiner(AbsBin)
ctx.add_examiner(DGC_PaperTapeCheckSum)
ctx.add_examiner(SameSame)
class ExampleExcavation(Excavation):
def __init__(self, **kwargs):
super().__init__(**kwargs)

ff = ctx.add_file_artifact("examples/30001393.bin")
self.add_examiner(BigText)
self.add_examiner(AbsBin)
self.add_examiner(DGC_PaperTapeCheckSum)
self.add_examiner(SameSame)

ctx.start_examination()

try:
os.mkdir("/tmp/_autoarchaologist")
except FileExistsError:
pass
if __name__ == "__main__":
argv = sys.argv[1:]
# force the example as the filename
argv.append("examples/30001393.bin")
args = process_arguments(parse_arguments(argv=argv))

ctx.produce_html(html_dir="/tmp/_autoarchaologist")
ctx = perform_excavation(args, ("excavator", ExampleExcavation))
ctx.produce_html()

print("Now point your browser at", ctx.filename_for(ctx).link)
Empty file added tests/__init__.py
Empty file.
119 changes: 119 additions & 0 deletions tests/test_run_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import importlib
import os
import shutil
import sys
from types import SimpleNamespace
import unittest

TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
SCRATCH_DIR = os.path.join(TESTS_DIR, "_scratch")
ROOT_DIR = os.path.normpath(os.path.join(TESTS_DIR, ".."))

sys.path.append(TESTS_DIR)

from run import perform_excavation
from run_example import ExampleExcavation
from autoarchaeologist.base.artifact import ArtifactBase, ArtifactStream


def example_arguments(output_dir):
example_arguments = SimpleNamespace()
example_arguments.dir = output_dir
example_arguments.filename = "examples/30001393.bin"
return example_arguments


class Test_RunExampleBasicHtml(unittest.TestCase):
"""
Ensure run_example produces expected HTML files for the example input.
"""

DIR_TREE = None

@classmethod
def setUpClass(cls):
args = example_arguments(SCRATCH_DIR)
shutil.rmtree(args.dir, ignore_errors=True)
os.makedirs(args.dir, exist_ok=True)
ctx = perform_excavation(args, ("excavator", ExampleExcavation))
ctx.produce_html()
cls.DIR_TREE = list(os.walk(args.dir))

def toplevel(self):
return self.__class__.DIR_TREE[0]

def toplevel_dirnames(self):
_, dirs, __ = self.toplevel()
dirs.sort()
return dirs

def toplevel_filenames(self):
_, __, filenames = self.toplevel()
return filenames

def test_produces_top_level_index(self):
toplevel_filenames = self.toplevel_filenames()
self.assertTrue("index.html" in toplevel_filenames)
self.assertTrue("index.css" in toplevel_filenames)

def test_produces_digest_directories(self):
toplevel_dirnames = self.toplevel_dirnames()
self.assertEqual(toplevel_dirnames, ['08', '79', 'fa'])


class Test_RunExampleBasicArtifacts(unittest.TestCase):
"""
Ensure run_example excavates the expected artifacts for the example input.
"""

CTX = None

@classmethod
def setUpClass(cls):
args = example_arguments(SCRATCH_DIR)
shutil.rmtree(args.dir, ignore_errors=True)
os.makedirs(args.dir, exist_ok=True)
ctx = perform_excavation(args, ("excavator", ExampleExcavation))
cls.CTX = ctx

def assertArtifactIsChild(self, artifact, parent):
assert issubclass(artifact.__class__, ArtifactBase)
self.assertEqual(list(artifact.parents), [parent])

def excavation(self):
return self.__class__.CTX

def test_excavated_three_total_artifacts(self):
arfifact_hash_keys = list(self.excavation().hashes.keys())
self.assertEqual(len(arfifact_hash_keys), 3)

def test_excavated_one_top_level_artifact(self):
excavatoin_child_count = len(self.excavation().children)
self.assertEqual(excavatoin_child_count, 1)

def test_produces_top_level_artifact(self):
excavation = self.excavation()
artifact = self.excavation().children[0]
self.assertIsInstance(artifact, ArtifactStream)
self.assertEqual(artifact.digest, '083a3d5e3098aec38ee5d9bc9f9880d3026e120ff8f058782d49ee3ccafd2a6c')
self.assertTrue(artifact.digest in excavation.hashes)

def test_produces_top_level_artifact_whose_parent_is_excavation(self):
artifact = self.excavation().children[0]
self.assertArtifactIsChild(artifact, self.excavation())

def test_produces_two_children_of_the_top_level(self):
excavation = self.excavation()
artifact = excavation.children[0]
artifact_children = sorted(artifact.children, key=lambda a: a.digest)
self.assertEqual(len(artifact_children), 2)
self.assertTrue(artifact_children[0].digest in excavation.hashes)
self.assertTrue(artifact_children[0].digest.startswith('79'))
self.assertArtifactIsChild(artifact_children[0], artifact)
self.assertTrue(artifact_children[1].digest in excavation.hashes)
self.assertTrue(artifact_children[1].digest.startswith('fa'))
self.assertArtifactIsChild(artifact_children[1], artifact)


if __name__ == '__main__':
unittest.main()