blob: e01d47e474f6e90608b99172dcbdf3a8cdc59e93 [file] [log] [blame]
import unittest
from mock import Mock
import os, sys
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts", "support"))
from run_bundler import ConfigLine
from run_bundler import CopyFileConfigLine
from run_bundler import JOSHUA_PATH
from run_bundler import abs_file_path
from run_bundler import clear_non_empty_dir
from run_bundler import config_line_factory
from run_bundler import filter_through_copy_config_script
from run_bundler import handle_args
from run_bundler import main
from run_bundler import make_dest_dir
from run_bundler import processed_config_line
class TestRunBundler_cli(unittest.TestCase):
def test_force(self):
args = handle_args(["--force",
"/dev/null",
"/dev/null",
"haitian5-bundle"])
self.assertIsInstance(args.config, file)
def test_no_force(self):
args = handle_args(["/dev/null",
"/dev/null",
"haitian5-bundle"])
self.assertIsInstance(args.config, file)
def test_copy_config_options(self):
"""
For --copy_config_options, Space-separated options surrounded by a pair
of quotes should not be split.
"""
args = handle_args(["/dev/null",
"/dev/null",
"haitian5-bundle",
"--copy-config-options",
"-grammar grammar.gz"])
self.assertIsInstance(args.config, file)
self.assertEqual("-grammar grammar.gz", args.copy_config_options)
def test_copy_config_options__empty(self):
"""
An error should result from --copy-config-options with no options.
"""
with self.assertRaises(SystemExit):
handle_args(["/dev/null",
"/dev/null",
"haitian5-bundle",
"--copy-config-options"])
class TestRunBundler_bundle_dir(unittest.TestCase):
def setUp(self):
self.test_dest_dir = "newdir"
self.config_line_abs = 'tm = thrax pt 12 /home/hltcoe/lorland/expts/haitian-creole-sms/runs/5/data/test/grammar.filtered.gz'
self.config_line_rel = 'lm = berkeleylm 5 false false 100 lm.berkeleylm'
# Create the destination directory an put a file in it.
if not os.path.exists(self.test_dest_dir):
os.mkdir(self.test_dest_dir)
temp_file_path = os.path.join(self.test_dest_dir, 'temp')
open(temp_file_path, 'w').write('test text')
def tearDown(self):
if os.path.exists(self.test_dest_dir):
clear_non_empty_dir(self.test_dest_dir)
pass
def test_clear_non_empty_dir(self):
clear_non_empty_dir(self.test_dest_dir)
self.assertFalse(os.path.exists(self.test_dest_dir))
def test_force_make_dest_dir__extant_not_empty(self):
# The existing directory should be removed and a new empty directory
# should be in its place.
make_dest_dir(self.test_dest_dir, True)
self.assertTrue(os.path.exists(self.test_dest_dir))
self.assertEqual([], os.listdir(self.test_dest_dir))
def test_make_dest_dir__non_extant(self):
# Set up by removing (existing) directory.
clear_non_empty_dir(self.test_dest_dir)
# A new empty directory should be created.
make_dest_dir(self.test_dest_dir, False)
self.assertTrue(os.path.exists(self.test_dest_dir))
class TestProcessedConfigLine_blank(unittest.TestCase):
def setUp(self):
self.args = handle_args(['/dev/null', '/dev/null', '/dev/null'])
def test_output_is_input(self):
"""
The resulting processed config line of a comment line is that same
comment line.
"""
cl_object = processed_config_line('', self.args)
expect = ''
actual = cl_object.result()
self.assertEqual(expect, actual)
class TestProcessedConfigLine_comment(unittest.TestCase):
def setUp(self):
self.line = '# This is the location of the file containing model weights.'
self.args = handle_args(['/dev/null', '/dev/null', '/dev/null'])
def test_line_type(self):
cl_object = processed_config_line(self.line, self.args)
self.assertIsInstance(cl_object, ConfigLine)
def test_output_is_input(self):
"""
The resulting processed config line of a comment line is that same
comment line.
"""
expect = '# This is the location of the file containing model weights.'
actual = processed_config_line(expect, self.args).result()
self.assertEqual(expect, actual)
class TestProcessedConfigLine_copy1(unittest.TestCase):
def setUp(self):
self.line = 'weights-file = test/parser/weights # foo bar'
self.args = Mock()
self.args.origdir = JOSHUA_PATH
self.args.destdir = '/tmp/testdestdir'
if os.path.exists(self.args.destdir):
clear_non_empty_dir(self.args.destdir)
os.mkdir(self.args.destdir)
def tearDown(self):
if os.path.exists(self.args.destdir):
clear_non_empty_dir(self.args.destdir)
def test_line_type(self):
cl_object = config_line_factory(self.line, self.args)
self.assertIsInstance(cl_object, ConfigLine)
def test_output_is_input(self):
"""
The resulting processed config line of a comment line is that same
comment line.
"""
expect = '# This is the location of the file containing model weights.'
actual = processed_config_line(expect, self.args).result()
self.assertEqual(expect, actual)
class TestProcessedConfigLine_copy2(unittest.TestCase):
def setUp(self):
self.line = 'weights-file = test/parser/weights # foo bar'
args = Mock()
self.args = args
args.origdir = JOSHUA_PATH
args.destdir = './testdestdir'
self.destdir = args.destdir
# Create the destination directory.
if not os.path.exists(args.destdir):
os.mkdir(args.destdir)
self.cl_object = processed_config_line(self.line, args)
self.expected_source_file_path = os.path.abspath(os.path.join(args.origdir,
'test', 'parser', 'weights'))
self.expected_dest_file_path = os.path.abspath(os.path.join(args.destdir, 'weights'))
CopyFileConfigLine.clear_file_name_counts()
def tearDown(self):
if not os.path.exists(self.destdir):
os.mkdir(self.destdir)
def test_line_source_path(self):
actual = self.cl_object.source_file_path
self.assertEqual(self.expected_source_file_path, actual)
def test_line_parts(self):
cl_object = processed_config_line(self.line, self.args)
expect = {"command": ['weights-file', '=', 'test/parser/weights'],
"comment": '# foo bar'}
actual = cl_object.line_parts
self.assertEqual(expect["command"], actual["command"])
def test_line_dest_path(self):
actual = self.cl_object.dest_file_path
self.assertEqual(self.expected_dest_file_path, actual)
def test_line_copy_file(self):
self.assertTrue(os.path.exists(self.cl_object.dest_file_path))
class TestProcessedConfigLine_copy_dirtree(unittest.TestCase):
def setUp(self):
# N.B. specify a path to copytree that is not inside you application.
# Otherwise it ends with an infinite recursion.
self.line = 'tm = thrax pt 12 example # foo bar'
self.args = Mock()
self.args.origdir = os.path.join(JOSHUA_PATH, 'examples')
self.args.destdir = './testdestdir'
# Create the destination directory.
if os.path.exists(self.args.destdir):
clear_non_empty_dir(self.args.destdir)
os.mkdir(self.args.destdir)
CopyFileConfigLine.clear_file_name_counts()
def tearDown(self):
if os.path.exists(self.args.destdir):
clear_non_empty_dir(self.args.destdir)
def test_line_parts(self):
cl_object = processed_config_line(self.line, self.args)
expect = {"command": ['tm', '=', 'thrax', 'pt', '12', 'example'],
"comment": '# foo bar'}
actual = cl_object.line_parts
self.assertEqual(expect["command"], actual["command"])
def test_line_copy_dirtree(self):
processed_config_line(self.line, self.args)
expect = os.path.join(self.args.destdir, 'example', 'joshua.config')
self.assertTrue(os.path.exists(expect))
def test_line_copy_dirtree_result(self):
cl_object = processed_config_line(self.line, self.args)
expect = 'tm = thrax pt 12 example # foo bar'
actual = cl_object.result()
self.assertEqual(expect, actual)
class TestMain(unittest.TestCase):
def setUp(self):
CopyFileConfigLine.clear_file_name_counts()
self.line = 'weights-file = weights # foo bar\noutput-format = %1'
self.origdir = '/tmp/testorigdir'
self.destdir = '/tmp/testdestdir'
for d in [self.origdir, self.destdir]:
if os.path.exists(d):
clear_non_empty_dir(d)
# Create the destination directory.
os.mkdir(self.origdir)
os.mkdir(self.destdir)
# Write the files to be processed.
config_file = os.path.join(self.origdir, 'joshua.config')
with open(config_file, 'w') as fh:
fh.write(self.line)
with open(os.path.join(self.origdir, 'weights'), 'w') as fh:
fh.write("grammar data\n")
self.args = ['thisprogram', '-f', config_file, self.origdir,
self.destdir]
def tearDown(self):
for d in [self.origdir, self.destdir]:
if os.path.exists(d):
clear_non_empty_dir(d)
def test_main(self):
main(self.args)
actual = os.path.exists(os.path.join(self.destdir, 'weights'))
self.assertTrue(actual)
with open(os.path.join(self.destdir, 'joshua.config')) as fh:
actual = fh.read().splitlines()
expect = ['weights-file = weights # foo bar', 'output-format = %1']
self.assertEqual(expect, actual)
def test_main_with_copy_config_options(self):
"""
For --copy_config_options, Space-separated options surrounded by a pair
of quotes should not be split.
"""
main(self.args + ["--copy-config-options", "-topn 1"])
with open(os.path.join(self.destdir, 'joshua.config')) as fh:
actual = fh.read().splitlines()
expect = ['weights-file = weights # foo bar', 'output-format = %1',
"topn = 1"]
self.assertEqual(expect, actual)
self.assertEqual(3, len(actual))
class TestFilterThroughCopyConfigScript(unittest.TestCase):
def test_method(self):
expect = ["# hello", "topn = 1"]
actual = filter_through_copy_config_script(["# hello"], "-topn 1")
self.assertEqual(expect, actual)
class TestAbsFilePath(unittest.TestCase):
def test_abs_file_path_path_in_file_token_1(self):
"""
A file token that is already an absolute path outside the origdir should not be changed.
"""
dir_path = '/foo'
file_token = '/bar/file.txt'
expect = file_token
actual = abs_file_path(dir_path, file_token)
self.assertEqual(expect, actual)
def test_abs_file_path_path_in_file_token_2(self):
"""
A file token that is already an absolute path inside the origdir should not be changed.
"""
dir_path = '/bar'
file_token = '/bar/file.txt'
expect = file_token
actual = abs_file_path(dir_path, file_token)
self.assertEqual(expect, actual)
def test_rel_file_path_path_in_file_token_2(self):
"""
Relative file path should get the dir_path prepended.
"""
dir_path = '/foo'
file_token = 'bar/file.txt'
expect = '/foo/bar/file.txt'
actual = abs_file_path(dir_path, file_token)
self.assertEqual(expect, actual)
class TestUniqueFileNames(unittest.TestCase):
def setUp(self):
self.args = Mock()
self.args.origdir = '/dev/null'
self.args.destdir = '/dev/null'
CopyFileConfigLine.clear_file_name_counts()
def test_2_files_same_name__without_filename_extension(self):
line = 'weights-file = weights'
cl = config_line_factory(line, self.args)
self.assertEqual('weights-file = weights', cl.result())
# Another file with the same name appears.
line = 'weights-file = otherdir/weights'
cl = config_line_factory(line, self.args)
self.assertEqual('weights-file = weights-1', cl.result())
def test_2_files_same_name__with_filename_extension(self):
line = 'tm = blah blah blah grammar.packed'
cl = config_line_factory(line, self.args)
self.assertEqual('tm = blah blah blah grammar.packed', cl.result())
# Another file with the same name appears.
line = 'tm = blah blah blah otherdir/grammar.packed'
cl = config_line_factory(line, self.args)
self.assertEqual('tm = blah blah blah grammar-1.packed', cl.result())
def test_clear_file_name_counts(self):
line = 'tm = blah blah blah grammar.packed'
cl = config_line_factory(line, self.args)
cl = config_line_factory(line, self.args)
CopyFileConfigLine.clear_file_name_counts()
cl = config_line_factory(line, self.args)
self.assertEqual('tm = blah blah blah grammar.packed', cl.result())