diff --git a/.github/workflows/tests.sh b/.github/workflows/tests.sh index 169ca71525..5fcc682769 100755 --- a/.github/workflows/tests.sh +++ b/.github/workflows/tests.sh @@ -22,7 +22,10 @@ verdi daemon stop pytest --noconftest .ci/test_test_manager.py pytest --noconftest .ci/test_profile_manager.py python .ci/test_plugin_testcase.py # uses custom unittest test runner -AIIDA_TEST_PROFILE=test_$AIIDA_TEST_BACKEND pytest .ci/pytest + +# Until the `.ci/pytest` tests are moved within `tests` we have to run them separately and pass in the path to the +# `conftest.py` explicitly, because otherwise it won't be able to find the fixtures it provides +AIIDA_TEST_PROFILE=test_$AIIDA_TEST_BACKEND pytest tests/conftest.py .ci/pytest # main aiida-core tests AIIDA_TEST_PROFILE=test_$AIIDA_TEST_BACKEND pytest tests diff --git a/bin/runaiida b/bin/runaiida deleted file mode 100755 index d5c1c951c5..0000000000 --- a/bin/runaiida +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -# Pass all parameters to 'verdi run' -# This is useful to use in a shebang line: i.e., you can put -# the following line as the first line in a file: - -#!/usr/bin/env runaiida - -# and the script will be run with 'verdi run' upon execution -# (if it has the correct execution bits set, i.e. using -# chmod +x ...) - -# With "$@", each parameter is correctly escaped -verdi run "$@" - diff --git a/examples/__init__.py b/examples/__init__.py deleted file mode 100644 index 2776a55f97..0000000000 --- a/examples/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -########################################################################### -# Copyright (c), The AiiDA team. All rights reserved. # -# This file is part of the AiiDA code. # -# # -# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # -# For further information on the license, see the LICENSE.txt file # -# For further information please visit http://www.aiida.net # -########################################################################### diff --git a/examples/work/__init__.py b/examples/work/__init__.py deleted file mode 100644 index 2776a55f97..0000000000 --- a/examples/work/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -########################################################################### -# Copyright (c), The AiiDA team. All rights reserved. # -# This file is part of the AiiDA code. # -# # -# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # -# For further information on the license, see the LICENSE.txt file # -# For further information please visit http://www.aiida.net # -########################################################################### diff --git a/examples/work/workchain.py b/examples/work/workchain.py deleted file mode 100755 index 6894ef3876..0000000000 --- a/examples/work/workchain.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env runaiida -# -*- coding: utf-8 -*- -########################################################################### -# Copyright (c), The AiiDA team. All rights reserved. # -# This file is part of the AiiDA code. # -# # -# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # -# For further information on the license, see the LICENSE.txt file # -# For further information please visit http://www.aiida.net # -########################################################################### -""" -This example illustrates in a very minimal way how a WorkChain can be defined and how it can be run. This mostly -illustrates how the spec of the WorkChain is defined and how functions in the outline of the spec have to be defined. -""" - -from aiida.engine import WorkChain, run -from aiida.orm import NumericType, Float, Int - - -class SumWorkChain(WorkChain): - - @classmethod - def define(cls, spec): - super().define(spec) - spec.input('a', valid_type=NumericType) - spec.input('b', valid_type=NumericType) - spec.outline( - cls.sum - ) - spec.output('sum', valid_type=NumericType) - - def sum(self): - self.out('sum', self.inputs.a + self.inputs.b) - - -class ProductWorkChain(WorkChain): - - @classmethod - def define(cls, spec): - super().define(spec) - spec.input('a', valid_type=NumericType) - spec.input('b', valid_type=NumericType) - spec.outline( - cls.product - ) - spec.output('product', valid_type=NumericType) - - def product(self): - self.out('product', self.inputs.a * self.inputs.b) - - -class SumProductWorkChain(WorkChain): - - @classmethod - def define(cls, spec): - super().define(spec) - spec.input('a', valid_type=NumericType) - spec.input('b', valid_type=NumericType) - spec.input('c', valid_type=NumericType) - spec.outline( - cls.sum, - cls.product - ) - spec.output('sumproduct', valid_type=NumericType) - - def sum(self): - self.ctx.sum = self.inputs.a + self.inputs.b - - def product(self): - self.out('sumproduct', self.ctx.sum * self.inputs.c) - - -def main(): - inputs = { - 'a': Float(3.14), - 'b': Int(4), - 'c': Int(6) - } - - results = run(SumWorkChain, **inputs) - print('Result of SumWorkChain: {}'.format(results)) - - results = run(ProductWorkChain, **inputs) - print('Result of ProductWorkChain: {}'.format(results)) - - results = run(SumProductWorkChain, **inputs) - print('Result of SumProductWorkChain: {}'.format(results)) - - -if __name__ == '__main__': - main() diff --git a/examples/work/workchain_outline.py b/examples/work/workchain_outline.py deleted file mode 100755 index d82a6cca43..0000000000 --- a/examples/work/workchain_outline.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env runaiida -# -*- coding: utf-8 -*- -########################################################################### -# Copyright (c), The AiiDA team. All rights reserved. # -# This file is part of the AiiDA code. # -# # -# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # -# For further information on the license, see the LICENSE.txt file # -# For further information please visit http://www.aiida.net # -########################################################################### -""" -This WorkChain example is a very contrived implementation of the infamous FizzBuzz problem, that serves to illustrate -the various logical blocks that one can incorporate into the outline of the workchain's spec. -""" - -from aiida.engine import WorkChain, run, while_, if_ -from aiida.orm import Int - - -class OutlineWorkChain(WorkChain): - - @classmethod - def define(cls, spec): - super().define(spec) - spec.input('a', valid_type=Int) - spec.outline( - cls.setup, - while_(cls.not_finished)( - if_(cls.if_multiple_of_three_and_five)( - cls.report_fizz_buzz - ).elif_(cls.if_multiple_of_five)( - cls.report_buzz - ).elif_(cls.if_multiple_of_three)( - cls.report_fizz - ).else_( - cls.report_number - ), - cls.decrement - ) - ) - - def setup(self): - self.ctx.counter = abs(self.inputs.a.value) - - def not_finished(self): - return self.ctx.counter > 0 - - def if_multiple_of_three_and_five(self): - return (self.ctx.counter % 3 == 0 and self.ctx.counter % 5 == 0) - - def if_multiple_of_five(self): - return self.ctx.counter % 5 == 0 - - def if_multiple_of_three(self): - return self.ctx.counter % 3 == 0 - - def report_fizz_buzz(self): - print('FizzBuzz') - - def report_fizz(self): - print('Fizz') - - def report_buzz(self): - print('Buzz') - - def report_number(self): - print(self.ctx.counter) - - def decrement(self): - self.ctx.counter -= 1 - - -def main(): - run(OutlineWorkChain, a=Int(16)) - - -if __name__ == '__main__': - main() diff --git a/examples/work/workfunction.py b/examples/work/workfunction.py deleted file mode 100755 index d36a2c66c0..0000000000 --- a/examples/work/workfunction.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env runaiida -# -*- coding: utf-8 -*- -########################################################################### -# Copyright (c), The AiiDA team. All rights reserved. # -# This file is part of the AiiDA code. # -# # -# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # -# For further information on the license, see the LICENSE.txt file # -# For further information please visit http://www.aiida.net # -########################################################################### -""" -This example implements exactly the same functionality as seen in the basic WorkChain example, except in this case it -utilizes calcfunctions instead of workchains. -""" - -from aiida.engine import calcfunction -from aiida.orm import Float, Int - - -@calcfunction -def sum(a, b): - return a + b - - -@calcfunction -def product(a, b): - return a * b - - -@calcfunction -def sumproduct(a, b, c): - return product(sum(a, b), c) - - -def main(): - a = Float(3.14) - b = Int(4) - c = Int(6) - - results = sum(a, b) - print('Result of sum: {}'.format(results)) - - results = product(a, b) - print('Result of product: {}'.format(results)) - - results = sumproduct(a, b, c) - print('Result of sumproduct: {}'.format(results)) - - -if __name__ == '__main__': - main() diff --git a/setup.json b/setup.json index 53f1d1a310..de5f83b295 100644 --- a/setup.json +++ b/setup.json @@ -112,7 +112,8 @@ "reentry_register": true, "entry_points": { "console_scripts": [ - "verdi=aiida.cmdline.commands.cmd_verdi:verdi" + "verdi=aiida.cmdline.commands.cmd_verdi:verdi", + "runaiida=aiida.cmdline.commands.cmd_run:run" ], "aiida.calculations": [ "arithmetic.add = aiida.calculations.plugins.arithmetic.add:ArithmeticAddCalculation", @@ -201,8 +202,5 @@ "realhydrogen = aiida.tools.data.orbital.realhydrogen:RealhydrogenOrbital" ], "aiida.workflows": [] - }, - "scripts": [ - "bin/runaiida" - ] + } } diff --git a/conftest.py b/tests/conftest.py similarity index 99% rename from conftest.py rename to tests/conftest.py index 1d2336820d..29210b7305 100644 --- a/conftest.py +++ b/tests/conftest.py @@ -8,7 +8,6 @@ # For further information please visit http://www.aiida.net # ########################################################################### """Configuration file for pytest tests.""" - import pytest # pylint: disable=unused-import pytest_plugins = ['aiida.manage.tests.pytest_fixtures'] # pylint: disable=invalid-name diff --git a/utils/plugin_tpl/calculation.tpl b/utils/plugin_tpl/calculation.tpl deleted file mode 100644 index 5cab031e0f..0000000000 --- a/utils/plugin_tpl/calculation.tpl +++ /dev/null @@ -1,126 +0,0 @@ -#-*- coding: utf8 -*- -""" -defines {{classname}} -""" -from aiida.orm import JobCalculation - - -class {{classname}}(JobCalculation): - """TODO: describe the calculation""" - - def _init_internal_params(self): - """Initialize internal parameters""" - super()._init_internal_params() - - self._INPUT_FILE_NAME = '{{ifilename}}' - self._OUTPUT_FILE_NAME = '{{ofilename}}' - self._default_parser = '{{parser}}' - - @classproperty - def _use_methods(cls): - """ - input node declaration hook - """ - - ''' - Start by getting the _use_methods from super and update the dictionary - before returning it. - - Each entry should look like this:: - - '': { # the input will be set with calc.use_(Data) - 'valid_types': , - 'additional_parameter': , - # -> use__(Data) - 'linkname': - # The name attached to the link in the db between the input - # and the calculation. Will be used for queries. - 'docstring': - } - ''' - retdict = super()._use_methods - retdict.update({ - {% for item in inputs %} - '{{item.name}}: { - 'valid_types': {{item.types}}, - 'additional_parameter': {{item.adn_par}}, - 'linkname': '{{item.get("lname", item.name)}}' - 'docstring': '{{item.docstring}}' - }, - {% endfor %} - }) - return retdict - - def _prepare_for_submission(self, tempfolder, inputdict): - """ - Hook for the deamon to create input files and do everything - else necessary before submitting the calculation to the computer. - - :param tempfolder: all input files should be put into this :py:class:`aiida.common.folders.Folder` subclass - :param inputdict: a dictionary containing all the inputs, keys are link names - """ - self.verify_inputs(self, inputdict) - - self._write_inputfiles(self, tempfolder, inputdict) - - calcinfo = CalcInfo() - calcinfo.uuid = self.uuid - '''list of files to copy to the computer''' - calcinfo.local_copy_list = [] # [('', '')] - calcinfo.remote_copy_list = [] # [('', '', '')] - calcinfo.retrieve_list = [self._OUTPUT_FILE_NAME] # add all files to be parsed - - code = inputdict['code'] - codeinfo = CodeInfo() - codeinfo.cmdline_params = [] # example: ['-i {}'.format(self._INPUT_FILE_NAME)] - codeinfo.code_uuid = code.uuid - - calcinfo.codes_info = [codeinfo] - - return calcinfo - - def verify_inputs(self, inputdict): - """ - ensure required input nodes are given, of the right type and nothing else - - raise ValidationError() otherwise - - example required node:: - - try: - param_name = inputdict.pop(self.get_linkname(param_name)) - except KeyError: - raise InputValidationError("Missing: param_name") - - if not isinstance(param_name, param_type(s)): - raise InputValidationError("Wrong type: param_name") - - example no superfluous nodes:: - - # after pop() - ing all expected nodes - if inputdict: - raise ValidationError("Superflous input nodes!") - """ - - '''TODO: implement input checks''' - - def _write_input_files(self, tempfolder, inputdict): - """ - write inputfiles to a temporary folder in preparation to submitting - - example using json input format:: - - # Dict input nodes - input_params = inputdict['param_name'].get_dict() - secondary_params = inputdict['secondary_name'].get_dict() - - input_filename = tempfolder.get_abs_path(self._INPUT_FILE_NAME) - with open(input_filename, 'w') as infile: - json.dump(input_params, infile) - - secondary_input_filename = tempfolder.get_abs_path('secondary.inp') - with open(secondary_input_filename, 'w') as infile: - json.dump(secondary_params, infile) - """ - - '''TODO: implement input file writing