def test_clone(self): self.call('python -m signac init ProjectA'.split()) project_a = signac.Project() project_b = signac.init_project('ProjectB', os.path.join(self.tmpdir.name, 'b')) job = project_a.open_job({'a': 0}) job.init() assert len(project_a) == 1 assert len(project_b) == 0 self.call("python -m signac clone {} {}".format( os.path.join(self.tmpdir.name, 'b'), job.id).split()) assert len(project_a) == 1 assert job in project_a assert len(project_b) == 1 assert job in project_b # cloning a job that exist at both source and destination err = self.call("python -m signac clone {} {}".format( os.path.join(self.tmpdir.name, 'b'), job.id).split(), error=True) assert 'Destination already exists' in err assert len(project_a) == 1 assert job in project_a assert len(project_b) == 1 assert job in project_b # checking for id that does not exit at source with pytest.raises(ExitCodeError): self.call("python -m signac clone {} 9bfd29df07674bc5".format( os.path.join(self.tmpdir.name, 'b')).split()) assert len(project_a) == 1 assert len(project_b) == 1
def test_sync_file(self): self.call("python -m signac init ProjectA".split()) project_a = signac.Project() project_b = signac.init_project("ProjectB", os.path.join(self.tmpdir.name, "b")) job_src = project_a.open_job({"a": 0}).init() job_dst = project_b.open_job({"a": 0}).init() for i, job in enumerate([job_src, job_dst]): with open(job.fn("test"), "w") as file: file.write("x" * (i + 1)) # FileSyncConflict with pytest.raises(ExitCodeError): self.call( "python -m signac sync {} {}".format( os.path.join(self.tmpdir.name, "b"), self.tmpdir.name ).split() ) self.call( "python -m signac sync {} {} --strategy never".format( os.path.join(self.tmpdir.name, "b"), self.tmpdir.name ).split() ) with open(job_dst.fn("test")) as file: assert file.read() == "xx" with pytest.raises(ExitCodeError): self.call( "python -m signac sync {} {}".format( os.path.join(self.tmpdir.name, "b"), self.tmpdir.name ).split() ) self.call( "python -m signac sync {} {} --update".format( os.path.join(self.tmpdir.name, "b"), self.tmpdir.name ).split() )
def test_sync_merge(self): project_b = signac.init_project('ProjectB', os.path.join(self.tmpdir.name, 'b')) self.call('python -m signac init ProjectA'.split()) project_a = signac.Project() for i in range(4): project_a.open_job({'a': i}).init() project_b.open_job({'a': i}).init() project_a.open_job({'c': 1}).init() project_b.open_job({'b': 1}).init() project_b.open_job({'a': 4}).init() assert len(project_a) == 5 assert len(project_b) == 6 # sync with projects having diffent schema with pytest.raises(ExitCodeError): self.call('python -m signac sync {} {}'.format( os.path.join(self.tmpdir.name, 'b'), self.tmpdir.name).split()) assert len(project_a) == 5 assert len(project_b) == 6 self.call('python -m signac sync {} {} --merge'.format( os.path.join(self.tmpdir.name, 'b'), self.tmpdir.name).split()) assert len(project_a) == 7 assert len(project_b) == 6
def test_import_sync(self): project_b = signac.init_project('ProjectB', os.path.join(self.tmpdir.name, 'b')) self.call('python -m signac init ProjectA'.split()) prefix_data = os.path.join(self.tmpdir.name, 'data') project_a = signac.Project() for i in range(4): project_a.open_job({'a': i}).init() project_b.open_job({'a': i}).init() job_dst = project_a.open_job({'a': 0}) job_src = project_b.open_job({'a': 0}) job_src.document['a'] = 0 project_b.export_to(prefix_data) err = self.call( "python -m signac import {}".format(prefix_data).split(), error=True) assert "Import failed" in err self.call( "python -m signac import {} --sync".format(prefix_data).split(), error=True) assert len(project_a) == 4 assert 'a' in job_dst.document assert job_dst.document['a'] == 0 out = self.call('python -m signac import {} --sync-interactive'.format( prefix_data), 'print(str(tmp_project), len(tmp_project)); exit()', shell=True) assert 'ProjectA' in out assert '4' in out
def test_import(self): self.call('python -m signac init my_project'.split()) project = signac.Project() prefix_data = os.path.join(self.tmpdir.name, 'data') err = self.call("python -m signac import {}".format( self.tmpdir.name).split(), error=True) assert 'Nothing to import.' in err for i in range(10): project.open_job({'a': i}).init() job_ids = list(project.find_job_ids()) assert len(project) == 10 project.export_to(target=prefix_data, copytree=os.replace) assert len(project) == 0 self.call("python -m signac import {}".format(prefix_data).split()) assert len(project) == 10 assert list(project.find_job_ids()) == job_ids # invalid combination with pytest.raises(ExitCodeError): self.call( 'python -m signac import {} --sync-interactive --move'.format( prefix_data).split())
def test_import_sync(self): project_b = signac.init_project("ProjectB", os.path.join(self.tmpdir.name, "b")) self.call("python -m signac init ProjectA".split()) prefix_data = os.path.join(self.tmpdir.name, "data") project_a = signac.Project() for i in range(4): project_a.open_job({"a": i}).init() project_b.open_job({"a": i}).init() job_dst = project_a.open_job({"a": 0}) job_src = project_b.open_job({"a": 0}) job_src.document["a"] = 0 project_b.export_to(prefix_data) err = self.call(f"python -m signac import {prefix_data}".split(), error=True) assert "Import failed" in err self.call(f"python -m signac import {prefix_data} --sync".split(), error=True) assert len(project_a) == 4 assert "a" in job_dst.document assert job_dst.document["a"] == 0 out = self.call( f"python -m signac import {prefix_data} --sync-interactive", "print(str(tmp_project), len(tmp_project)); exit()", shell=True, ) assert "ProjectA" in out assert "4" in out
def test_statepoint(self): self.call('python -m signac init my_project'.split()) self.call(['python', '-m', 'signac', 'job', '--create', '{"a": 0}']) project = signac.Project() for job in project: sp = self.call('python -m signac statepoint {}'.format(job).split()) assert project.open_job(json.loads(sp)) == job
def test_shell(self): self.call('python -m signac init my_project'.split()) project = signac.Project() out = self.call( 'python -m signac shell', 'print(str(project), job, len(list(jobs))); exit()', shell=True) assert out.strip() == '>>> {} None {}'.format(project, len(project))
def test_sync_merge(self): project_b = signac.init_project("ProjectB", os.path.join(self.tmpdir.name, "b")) self.call("python -m signac init ProjectA".split()) project_a = signac.Project() for i in range(4): project_a.open_job({"a": i}).init() project_b.open_job({"a": i}).init() project_a.open_job({"c": 1}).init() project_b.open_job({"b": 1}).init() project_b.open_job({"a": 4}).init() assert len(project_a) == 5 assert len(project_b) == 6 # sync with projects having diffent schema with pytest.raises(ExitCodeError): self.call("python -m signac sync {} {}".format( os.path.join(self.tmpdir.name, "b"), self.tmpdir.name).split()) assert len(project_a) == 5 assert len(project_b) == 6 self.call("python -m signac sync {} {} --merge".format( os.path.join(self.tmpdir.name, "b"), self.tmpdir.name).split()) assert len(project_a) == 7 assert len(project_b) == 6
def test_import(self): self.call("python -m signac init my_project".split()) project = signac.Project() prefix_data = os.path.join(self.tmpdir.name, "data") err = self.call( f"python -m signac import {self.tmpdir.name}".split(), error=True ) assert "Nothing to import." in err for i in range(10): project.open_job({"a": i}).init() jobs_before_export = {job.id for job in project.find_jobs()} assert len(project) == 10 project.export_to(target=prefix_data, copytree=os.replace) assert len(project) == 0 self.call(f"python -m signac import {prefix_data}".split()) assert len(project) == 10 assert {job.id for job in project.find_jobs()} == jobs_before_export # invalid combination with pytest.raises(ExitCodeError): self.call( f"python -m signac import {prefix_data} --sync-interactive --move".split() )
def test_move(self): self.call('python -m signac init ProjectA'.split()) project_a = signac.Project() project_b = signac.init_project('ProjectB', os.path.join(self.tmpdir.name, 'b')) job = project_a.open_job({'a': 0}) job.init() assert len(project_a) == 1 assert len(project_b) == 0 self.call("python -m signac move {} {}".format( os.path.join(self.tmpdir.name, 'b'), job.id).split()) assert len(project_a) == 0 assert job not in project_a assert len(project_b) == 1 assert job in project_b # moving a job that already exists at destination project_a.open_job({'a': 0}).init() err = self.call("python -m signac move {} {}".format( os.path.join(self.tmpdir.name, 'b'), job.id).split(), error=True) assert 'Destination already exists' in err assert len(project_a) == 1 assert job in project_a assert len(project_b) == 1 assert job in project_b # moving a job that does not exits with pytest.raises(ExitCodeError): self.call("python -m signac move {} 9bfd29df07674bc5".format( os.path.join(self.tmpdir.name, 'b')).split()) assert len(project_a) == 1 assert len(project_b) == 1
def test_shell(self): self.call('python -m signac init my_project'.split()) project = signac.Project() out = self.call( 'python -m signac shell', 'from __future__ import print_function;' 'print(str(project), job, len(list(jobs))); exit()', shell=True) self.assertEqual(out.strip(), '>>> {} None {}'.format(project, len(project)))
def test_shell_with_jobs(self): self.call('python -m signac init my_project'.split()) project = signac.Project() for i in range(3): project.open_job(dict(a=i)).init() assert len(project) out = self.call( 'python -m signac shell', 'print(str(project), job, len(list(jobs))); exit()', shell=True) assert out.strip() == '>>> {} None {}'.format(project, len(project))
def test_diff(self): self.call("python -m signac init ProjectA".split()) project = signac.Project() job_a = project.open_job({"a": 0, "b": 1}) job_a.init() job_b = project.open_job({"a": 0, "b": 0}) job_b.init() out = self.call(f"python -m signac diff {job_a.id} {job_b.id}".split()) expected = [str(job_a.id), "{'b': 1}", str(job_b.id), "{'b': 0}"] outputs = out.strip().split(os.linesep) assert set(expected) == set(outputs)
def test_shell_with_jobs_and_selection_only_one_job(self): self.call('python -m signac init my_project'.split()) project = signac.Project() for i in range(3): project.open_job(dict(a=i)).init() assert len(project) out = self.call( 'python -m signac shell -f a 0', 'print(str(project), job, len(list(jobs))); exit()', shell=True) job = list(project.find_jobs({'a': 0}))[0] assert out.strip() == '>>> {} {} 1'.format(project, job)
def test_shell_with_jobs_and_selection(self): self.call('python -m signac init my_project'.split()) project = signac.Project() for i in range(3): project.open_job(dict(a=i)).init() assert len(project) out = self.call(r'python -m signac shell -f a.\$gt 0', 'from __future__ import print_function;' 'print(str(project), job, len(list(jobs))); exit()', shell=True) n = len(project.find_jobs({'a': {'$gt': 0}})) self.assertEqual(out.strip(), '>>> {} None {}'.format(project, n))
def test_shell_with_jobs_and_selection(self): self.call('python -m signac init my_project'.split()) project = signac.Project() for i in range(3): project.open_job(dict(a=i)).init() assert len(project) python_command = 'python -m signac shell -f a.{}gt 0'.format('$' if WINDOWS else r'\$') out = self.call( python_command, 'print(str(project), job, len(list(jobs))); exit()', shell=True) n = len(project.find_jobs({'a': {'$gt': 0}})) assert out.strip() == '>>> {} None {}'.format(project, n)
def test_sync_document(self): self.call('python -m signac init ProjectA'.split()) project_a = signac.Project() project_b = signac.init_project('ProjectB', os.path.join(self.tmpdir.name, 'b')) job_src = project_a.open_job({'a': 0}) job_dst = project_b.open_job({'a': 0}) def reset(): job_src.document['a'] = 0 job_src.document['nested'] = dict(a=1) job_dst.document['a'] = 1 job_dst.document['nested'] = dict(a=2) # DocumentSyncConflict without any doc-strategy reset() assert job_dst.document != job_src.document with pytest.raises(ExitCodeError): self.call('python -m signac sync {} {}'.format( os.path.join(self.tmpdir.name, 'b'), self.tmpdir.name).split()) assert job_dst.document != job_src.document # don't sync any key self.call('python -m signac sync {} {} --no-key'.format( os.path.join(self.tmpdir.name, 'b'), self.tmpdir.name).split()) assert job_dst.document != job_src.document assert job_dst.document['a'] != job_src.document['a'] assert job_dst.document['nested'] != job_src.document['nested'] # only sync a reset() self.call('python -m signac sync {} {} --key a'.format( os.path.join(self.tmpdir.name, 'b'), self.tmpdir.name).split()) assert job_dst.document != job_src.document assert job_dst.document['nested'] != job_src.document['nested'] assert job_dst.document['a'] == job_src.document['a'] # only sync nested reset() self.call('python -m signac sync {} {} --key nested'.format( os.path.join(self.tmpdir.name, 'b'), self.tmpdir.name).split()) assert job_dst.document != job_src.document assert job_dst.document['a'] != job_src.document['a'] assert job_dst.document['nested'] == job_src.document['nested'] # sync both reset() self.call('python -m signac sync {} {} --all-key'.format( os.path.join(self.tmpdir.name, 'b'), self.tmpdir.name).split()) assert job_dst.document == job_src.document assert job_dst.document['nested'] == job_src.document['nested'] assert job_dst.document['a'] == job_src.document['a'] # invalid input with pytest.raises(ExitCodeError): self.call('python -m signac sync {} {} --all-key --no-key'.format( os.path.join(self.tmpdir.name, 'b'), self.tmpdir.name).split())
def test_view(self): self.call('python -m signac init my_project'.split()) project = signac.Project() sps = [{'a': i} for i in range(3)] for sp in sps: project.open_job(sp).init() os.mkdir('view') self.call('python -m signac view'.split()) for sp in sps: assert os.path.isdir('view/a/{}'.format(sp['a'])) assert os.path.isdir('view/a/{}/job'.format(sp['a'])) assert os.path.realpath('view/a/{}/job'.format(sp['a'])) == \ os.path.realpath(project.open_job(sp).workspace())
def test_view_single(self): """Check whether command line views work for single job workspaces.""" self.call('python -m signac init my_project'.split()) project = signac.Project() sps = [{'a': i} for i in range(1)] for sp in sps: project.open_job(sp).init() os.mkdir('view') self.call('python -m signac view'.split()) for sp in sps: assert os.path.isdir('view/job') assert os.path.realpath('view/job') == \ os.path.realpath(project.open_job(sp).workspace())
def test_update_cache(self): self.call('python -m signac init ProjectA'.split()) project_a = signac.Project() assert not os.path.isfile(project_a.FN_CACHE) for i in range(4): project_a.open_job({'a': i}).init() err = self.call('python -m signac update-cache'.split(), error=True) assert os.path.isfile(project_a.FN_CACHE) assert 'Updated cache' in err err = self.call('python -m signac update-cache'.split(), error=True) assert 'Cache is up to date' in err
def test_shell_with_jobs_and_selection_only_one_job(self): self.call("python -m signac init my_project".split()) project = signac.Project() for i in range(3): project.open_job(dict(a=i)).init() assert len(project) == 3 out = self.call( "python -m signac shell -f a 0", "print(str(project), job, len(list(jobs))); exit()", shell=True, ) job = list(project.find_jobs({"a": 0}))[0] assert out.strip() == f">>> {project} {job} 1"
def test_view(self): self.call("python -m signac init my_project".split()) project = signac.Project() sps = [{"a": i} for i in range(3)] for sp in sps: project.open_job(sp).init() os.mkdir("view") self.call("python -m signac view".split()) for sp in sps: assert os.path.isdir("view/a/{}".format(sp["a"])) assert os.path.isdir("view/a/{}/job".format(sp["a"])) assert os.path.realpath("view/a/{}/job".format( sp["a"])) == os.path.realpath( project.open_job(sp).workspace())
def test_find(self): self.call("python -m signac init my_project".split()) project = signac.Project() sps = [{"a": i} for i in range(3)] for sp in sps: project.open_job(sp).init() out = self.call("python -m signac find".split()) job_ids = out.split(os.linesep)[:-1] with pytest.deprecated_call(): assert set(job_ids) == set(project.find_job_ids()) assert (self.call("python -m signac find".split() + ['{"a": 0}']).strip() == list( project.find_job_ids({"a": 0}))[0]) job = project.open_job({"a": 0}) out = self.call("python -m signac find a 0 --sp".split()).strip() assert out.strip().split( os.linesep) == [str(job.id), str(job.statepoint())] out = self.call("python -m signac find a 0 --sp a".split()).strip() assert out.strip().split( os.linesep) == [str(job.id), str(job.statepoint())] out = self.call("python -m signac find a 0 --sp b".split()).strip() assert out.strip().split(os.linesep) == [str(job.id), "{}"] job.document["a"] = 2 out = self.call("python -m signac find a 0 --doc".split()).strip() assert out.strip().split( os.linesep) == [str(job.id), str(job.document)] out = self.call("python -m signac find a 0 --doc a".split()).strip() assert out.strip().split( os.linesep) == [str(job.id), str(job.document)] out = self.call("python -m signac find a 0 --doc b".split()).strip() assert out.strip().split(os.linesep) == [str(job.id), "{}"] out = self.call( "python -m signac find a 0 --show --one-line".split()).strip() assert str(job.id) in out assert '{"a": 0}' in out assert '{"a": 2}' in out # Test the doc_filter for job in project.find_jobs(): job.document["a"] = job.statepoint()["a"] with pytest.deprecated_call(): for i in range(3): assert ( self.call("python -m signac find --doc-filter".split() + ['{"a": ' + str(i) + "}"]).strip() == list( project.find_job_ids( doc_filter={"a": i}))[0])
def test_statepoint(self): self.call("python -m signac init my_project".split()) self.call(["python", "-m", "signac", "job", "--create", '{"a": 0}']) project = signac.Project() assert len(project) == 1 job = project.open_job({"a": 0}) sp = self.call(f"python -m signac statepoint {job.id}".split()) assert project.open_job(json.loads(sp)) == job assert len(project) == 1 sp = self.call("python -m signac statepoint".split()) assert project.open_job(json.loads(sp)) == job assert len(project) == 1 sp = self.call("python -m signac statepoint --pretty".split()) assert "{'a': 0}" in sp assert len(project) == 1
def test_shell(self): self.call("python -m signac init my_project".split()) project = signac.Project() out = self.call( "python -m signac shell", "print(str(project), job, len(list(jobs))); exit()", shell=True, ) assert out.strip() == ">>> {} None {}".format(project, len(project)) cmd = "python -m signac shell -c".split() + [ "print(str(project), len(list(jobs)))" ] out = self.call(cmd) assert out.strip() == "{} {}".format(project, len(project))
def test_shell_with_jobs(self): out = self.call("python -m signac shell", shell=True) assert "No project within this directory" in out self.call("python -m signac init my_project".split()) project = signac.Project() for i in range(3): project.open_job(dict(a=i)).init() assert len(project) out = self.call( "python -m signac shell", "print(str(project), job, len(list(jobs))); exit()", shell=True, ) assert out.strip() == ">>> {} None {}".format(project, len(project))
def test_shell_with_jobs_and_selection(self): self.call("python -m signac init my_project".split()) project = signac.Project() for i in range(3): project.open_job(dict(a=i)).init() assert len(project) python_command = "python -m signac shell -f a.{}gt 0".format( "$" if WINDOWS else r"\$") out = self.call( python_command, "print(str(project), job, len(list(jobs))); exit()", shell=True, ) n = len(project.find_jobs({"a": {"$gt": 0}})) assert out.strip() == f">>> {project} None {n}"
def test_statepoint(self): self.call('python -m signac init my_project'.split()) self.call(['python', '-m', 'signac', 'job', '--create', '{"a": 0}']) project = signac.Project() assert len(project) == 1 job = project.open_job({'a': 0}) sp = self.call('python -m signac statepoint {}'.format(job.id).split()) assert project.open_job(json.loads(sp)) == job assert len(project) == 1 sp = self.call('python -m signac statepoint'.split()) assert project.open_job(json.loads(sp)) == job assert len(project) == 1 sp = self.call('python -m signac statepoint --pretty'.split()) assert "{'a': 0}" in sp assert len(project) == 1
def test_remove(self): self.call('python -m signac init my_project'.split()) project = signac.Project() sps = [{'a': i} for i in range(3)] for sp in sps: project.open_job(sp).init() job_to_remove = project.open_job({'a': 1}) job_to_remove.doc.a = 0 self.assertIn(job_to_remove, project) self.assertEqual(job_to_remove.doc.a, 0) self.assertEqual(len(job_to_remove.doc), 1) self.call('python -m signac rm --clear {}'.format(job_to_remove.get_id()).split()) self.assertIn(job_to_remove, project) self.assertEqual(len(job_to_remove.doc), 0) self.call('python -m signac rm {}'.format(job_to_remove.get_id()).split()) self.assertNotIn(job_to_remove, project)