xmipp3-installer 1.0.1__py3-none-any.whl → 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. xmipp3_installer/__main__.py +1 -1
  2. xmipp3_installer/api_client/api_client.py +35 -34
  3. xmipp3_installer/api_client/assembler/installation_info_assembler.py +140 -145
  4. xmipp3_installer/application/cli/arguments/__init__.py +3 -2
  5. xmipp3_installer/application/cli/arguments/modes.py +112 -95
  6. xmipp3_installer/application/cli/arguments/params.py +63 -53
  7. xmipp3_installer/application/cli/cli.py +171 -190
  8. xmipp3_installer/application/cli/parsers/base_help_formatter.py +256 -235
  9. xmipp3_installer/application/cli/parsers/error_handler_parser.py +53 -53
  10. xmipp3_installer/application/cli/parsers/format.py +22 -22
  11. xmipp3_installer/application/cli/parsers/general_help_formatter.py +102 -84
  12. xmipp3_installer/application/cli/parsers/mode_help_formatter.py +144 -105
  13. xmipp3_installer/application/logger/__init__.py +5 -0
  14. xmipp3_installer/application/logger/errors.py +8 -8
  15. xmipp3_installer/application/logger/logger.py +218 -215
  16. xmipp3_installer/application/logger/predefined_messages.py +42 -35
  17. xmipp3_installer/application/user_interactions.py +6 -0
  18. xmipp3_installer/installer/constants/paths.py +6 -0
  19. xmipp3_installer/installer/handlers/cmake/cmake_handler.py +49 -53
  20. xmipp3_installer/installer/handlers/conda_handler.py +6 -6
  21. xmipp3_installer/installer/handlers/generic_package_handler.py +9 -9
  22. xmipp3_installer/installer/handlers/git_handler.py +152 -153
  23. xmipp3_installer/installer/handlers/shell_handler.py +87 -88
  24. xmipp3_installer/installer/handlers/versions_manager.py +20 -6
  25. xmipp3_installer/installer/installer_service.py +22 -8
  26. xmipp3_installer/installer/modes/mode_all_executor.py +61 -51
  27. xmipp3_installer/installer/modes/mode_clean/mode_clean_all_executor.py +44 -36
  28. xmipp3_installer/installer/modes/mode_clean/mode_clean_bin_executor.py +84 -74
  29. xmipp3_installer/installer/modes/mode_clean/mode_clean_executor.py +48 -34
  30. xmipp3_installer/installer/modes/mode_cmake/mode_cmake_executor.py +60 -47
  31. xmipp3_installer/installer/modes/mode_cmake/mode_compile_and_install_executor.py +52 -39
  32. xmipp3_installer/installer/modes/mode_cmake/mode_config_build_executor.py +68 -49
  33. xmipp3_installer/installer/modes/mode_config_executor.py +44 -33
  34. xmipp3_installer/installer/modes/mode_executor.py +14 -13
  35. xmipp3_installer/installer/modes/mode_get_sources_executor.py +121 -112
  36. xmipp3_installer/installer/modes/mode_git_executor.py +43 -31
  37. xmipp3_installer/installer/modes/mode_selector.py +6 -0
  38. xmipp3_installer/installer/modes/mode_sync/mode_add_model_executor.py +97 -83
  39. xmipp3_installer/installer/modes/mode_sync/mode_get_models_executor.py +53 -41
  40. xmipp3_installer/installer/modes/mode_sync/mode_sync_executor.py +41 -35
  41. xmipp3_installer/installer/modes/mode_sync/mode_test_executor.py +144 -77
  42. xmipp3_installer/installer/modes/mode_version_executor.py +161 -150
  43. xmipp3_installer/installer/orquestrator.py +24 -24
  44. xmipp3_installer/installer/urls.py +4 -3
  45. xmipp3_installer/repository/config.py +225 -227
  46. xmipp3_installer/repository/config_vars/__init__.py +5 -0
  47. xmipp3_installer/repository/config_vars/config_values_adapter.py +97 -91
  48. xmipp3_installer/repository/config_vars/default_values.py +24 -24
  49. xmipp3_installer/repository/config_vars/variables.py +9 -9
  50. xmipp3_installer/repository/invalid_config_line.py +17 -0
  51. xmipp3_installer/shared/file_operations.py +14 -12
  52. xmipp3_installer/shared/singleton.py +16 -17
  53. xmipp3_installer-1.1.0.dist-info/METADATA +86 -0
  54. xmipp3_installer-1.1.0.dist-info/RECORD +70 -0
  55. {xmipp3_installer-1.0.1.dist-info → xmipp3_installer-1.1.0.dist-info}/WHEEL +1 -1
  56. xmipp3_installer-1.0.1.dist-info/METADATA +0 -729
  57. xmipp3_installer-1.0.1.dist-info/RECORD +0 -70
  58. {xmipp3_installer-1.0.1.dist-info → xmipp3_installer-1.1.0.dist-info}/entry_points.txt +0 -0
  59. /xmipp3_installer-1.0.1.dist-info/LICENSE → /xmipp3_installer-1.1.0.dist-info/licenses/LICENSE.txt +0 -0
  60. {xmipp3_installer-1.0.1.dist-info → xmipp3_installer-1.1.0.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,9 @@
1
+ """
2
+ ### Mode Add Model Executor Module.
3
+
4
+ This module contains the class to upload models to the remote server.
5
+ """
6
+
1
7
  import os
2
8
  import tarfile
3
9
  from typing import Dict, Tuple
@@ -11,94 +17,102 @@ from xmipp3_installer.installer.handlers import shell_handler
11
17
  from xmipp3_installer.installer.modes.mode_sync.mode_sync_executor import ModeSyncExecutor
12
18
 
13
19
  class ModeAddModelExecutor(ModeSyncExecutor):
14
- def __init__(self, context: Dict):
15
- """
16
- ### Constructor.
17
-
18
- #### Params:
19
- - context (dict): Dictionary containing the installation context variables.
20
- """
21
- super().__init__(context)
22
- self.login = context.pop(params.PARAM_LOGIN)
23
- self.model_path = context.pop(params.PARAM_MODEL_PATH)
24
- self.update = context.pop(params.PARAM_UPDATE)
25
- self.model_dir = os.path.dirname(self.model_path)
26
- self.model_name = os.path.basename(self.model_path)
27
- self.tar_file_name = f"xmipp_model_{self.model_name}.tgz"
28
- self.tar_file_path = os.path.join(self.model_dir, self.tar_file_name)
20
+ """
21
+ ### Mode Add Model Executor.
22
+
23
+ Uploads models to the remote server.
24
+ """
25
+
26
+ def __init__(self, context: Dict):
27
+ """
28
+ ### Constructor.
29
+
30
+ #### Params:
31
+ - context (dict): Dictionary containing the installation context variables.
32
+ """
33
+ super().__init__(context)
34
+ self.login = context.pop(params.PARAM_LOGIN)
35
+ self.model_path = context.pop(params.PARAM_MODEL_PATH)
36
+ self.update = context.pop(params.PARAM_UPDATE)
37
+ self.model_dir = os.path.dirname(self.model_path)
38
+ self.model_name = os.path.basename(self.model_path)
39
+ self.tar_file_name = f"xmipp_model_{self.model_name}.tgz"
40
+ self.tar_file_path = os.path.join(self.model_dir, self.tar_file_name)
29
41
 
30
- def _sync_operation(self) -> Tuple[int, str]:
31
- """
32
- ### Uploads the model to the remote server.
42
+ def _sync_operation(self) -> Tuple[int, str]:
43
+ """
44
+ ### Uploads the model to the remote server.
33
45
 
34
- #### Returns:
35
- - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
36
- """
37
- if not os.path.isdir(self.model_path):
38
- logger('\n'.join([
39
- logger.red(f"{self.model_path} is not a directory. Please, check the path."),
40
- logger.red("The name of the model will be the name of that folder.")
41
- ]))
42
- return errors.IO_ERROR, ""
43
-
44
- ret_code, output = self.__generate_compressed_file()
45
- if ret_code:
46
- return ret_code, output
47
-
48
- if not self.__get_confirmation():
49
- return errors.INTERRUPTED_ERROR, ""
50
-
51
- return self.__upload_model()
46
+ #### Returns:
47
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
48
+ """
49
+ if not os.path.isdir(self.model_path):
50
+ logger('\n'.join([
51
+ logger.red(f"{self.model_path} is not a directory. Please, check the path."),
52
+ logger.red("The name of the model will be the name of that folder.")
53
+ ]))
54
+ return errors.IO_ERROR, ""
55
+
56
+ ret_code, output = self.__generate_compressed_file()
57
+ if ret_code:
58
+ return ret_code, output
59
+
60
+ if not self.__get_confirmation():
61
+ return errors.INTERRUPTED_ERROR, ""
62
+
63
+ ret_code, output = self.__upload_model()
64
+ ret_code = 1 if ret_code else ret_code
65
+ return ret_code, output
52
66
 
53
- def __generate_compressed_file(self) -> Tuple[int, str]:
54
- """
55
- ### Generates the model's compressed file.
67
+ def __generate_compressed_file(self) -> Tuple[int, str]:
68
+ """
69
+ ### Generates the model's compressed file.
56
70
 
57
- #### Returns:
58
- - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
59
- """
60
- logger(f"Creating the {self.tar_file_name} model.")
61
- try:
62
- with tarfile.open(self.tar_file_path, "w:gz") as tar:
63
- tar.add(self.model_path, arcname=self.model_name)
64
- except (tarfile.ReadError, tarfile.CompressionError) as ex:
65
- return errors.IO_ERROR, str(ex)
66
- return 0, ""
71
+ #### Returns:
72
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
73
+ """
74
+ logger(f"Creating the {self.tar_file_name} model.")
75
+ try:
76
+ with tarfile.open(self.tar_file_path, "w:gz") as tar:
77
+ tar.add(self.model_path, arcname=self.model_name)
78
+ except (tarfile.ReadError, tarfile.CompressionError) as ex:
79
+ return errors.IO_ERROR, str(ex)
80
+ return 0, ""
67
81
 
68
- def __get_confirmation(self) -> bool:
69
- """
70
- ### Asks the user for confirmation.
82
+ def __get_confirmation(self) -> bool:
83
+ """
84
+ ### Asks the user for confirmation.
71
85
 
72
- #### Returns:
73
- - (bool): True if the user confirms, False otherwise.
74
- """
75
- logger('\n'.join([
76
- logger.yellow("Warning: Uploading, please BE CAREFUL! This can be dangerous."),
77
- f"You are going to be connected to {self.login} to write in folder {paths.SCIPION_SOFTWARE_EM}.",
78
- "Continue? YES/no (case sensitive)"
79
- ]))
80
- return user_interactions.get_user_confirmation("YES")
86
+ #### Returns:
87
+ - (bool): True if the user confirms, False otherwise.
88
+ """
89
+ logger('\n'.join([
90
+ logger.yellow("Warning: Uploading, please BE CAREFUL! This can be dangerous."),
91
+ f"You are going to be connected to {self.login} to write in folder {paths.SCIPION_SOFTWARE_EM}.",
92
+ "Continue? YES/no (case sensitive)"
93
+ ]))
94
+ return user_interactions.get_user_confirmation("YES")
81
95
 
82
- def __upload_model(self) -> Tuple[int, str]:
83
- """
84
- ### Uploads the model to the remote server.
96
+ def __upload_model(self) -> Tuple[int, str]:
97
+ """
98
+ ### Uploads the model to the remote server.
85
99
 
86
- #### Returns:
87
- - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
88
- """
89
- update = '--update' if self.update else ''
90
- args = f"{self.login}, {os.path.abspath(self.tar_file_path)}, {paths.SCIPION_SOFTWARE_EM}, {update}"
91
- logger(f"Trying to upload the model using {self.login} as login")
92
- sync_program_relative_call = os.path.join(
93
- ".",
94
- os.path.basename(self.sync_program_path)
95
- )
96
- ret_code, output = shell_handler.run_shell_command(
97
- f"{sync_program_relative_call} upload {args}",
98
- cwd=os.path.dirname(self.sync_program_path)
99
- )
100
- if not ret_code:
101
- output = ""
102
- logger(logger.green(f"{self.model_name} model successfully uploaded! Removing the local .tgz"))
103
- os.remove(self.tar_file_path)
104
- return ret_code, output
100
+ #### Returns:
101
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
102
+ """
103
+ update = '--update' if self.update else ''
104
+ args = f"{self.login}, {os.path.abspath(self.tar_file_path)}, {paths.SCIPION_SOFTWARE_EM}, {update}"
105
+ logger(f"Trying to upload the model using {self.login} as login")
106
+ sync_program_relative_call = os.path.join(
107
+ ".",
108
+ os.path.basename(self.sync_program_path)
109
+ )
110
+ ret_code, output = shell_handler.run_shell_command(
111
+ f"{sync_program_relative_call} upload {args}",
112
+ cwd=os.path.dirname(self.sync_program_path)
113
+ )
114
+ if not ret_code:
115
+ output = ""
116
+ logger(logger.green(f"{self.model_name} model successfully uploaded! Removing the local .tgz"))
117
+ os.remove(self.tar_file_path)
118
+ return ret_code, output
@@ -1,51 +1,63 @@
1
+ """
2
+ ### Mode Get Models Executor Module.
3
+
4
+ This module contains the class to download deep learning models.
5
+ """
6
+
1
7
  import os
2
8
  from typing import Dict, Tuple
3
9
 
4
10
  from xmipp3_installer.application.cli.arguments import params
5
11
  from xmipp3_installer.application.logger.logger import logger
6
- from xmipp3_installer.installer import constants, urls
12
+ from xmipp3_installer.installer import urls
7
13
  from xmipp3_installer.installer.constants import paths
8
14
  from xmipp3_installer.installer.handlers import shell_handler
9
15
  from xmipp3_installer.installer.modes.mode_sync.mode_sync_executor import ModeSyncExecutor
10
16
 
11
17
  class ModeGetModelsExecutor(ModeSyncExecutor):
12
- def __init__(self, context: Dict):
13
- """
14
- ### Constructor.
15
-
16
- #### Params:
17
- - context (dict): Dictionary containing the installation context variables.
18
- """
19
- super().__init__(context)
20
- self.models_directory = context.pop(params.PARAM_MODELS_DIRECTORY)
21
- self.dist_path = paths.get_source_path(constants.XMIPP)
22
- if self.models_directory == self.dist_path:
23
- self.models_directory = os.path.join(self.models_directory, 'models')
24
-
25
- def _sync_operation(self) -> Tuple[int, str]:
26
- """
27
- ### Downloads deep learning models.
28
-
29
- #### Returns:
30
- - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
31
- """
32
- if os.path.isdir(self.models_directory):
33
- task = "update"
34
- in_progress_task = "Updating"
35
- completed_task = "updated"
36
- else:
37
- task = "download"
38
- in_progress_task = "Downloading"
39
- completed_task = "downloaded"
40
-
41
- logger(f"{in_progress_task} Deep Learning models (in background)")
42
- ret_code, output = shell_handler.run_shell_command(
43
- f"{self.sync_program_path} {task} {self.models_directory} {urls.MODELS_URL} DLmodels",
44
- show_command=True,
45
- show_output=True,
46
- show_error=True
47
- )
48
- if not ret_code:
49
- logger(logger.green(f"Models successfully {completed_task}!"))
50
-
51
- return ret_code, output
18
+ """
19
+ ### Mode Get Models Executor.
20
+
21
+ Downloads deep learning models for the installation.
22
+ """
23
+
24
+ def __init__(self, context: Dict):
25
+ """
26
+ ### Constructor.
27
+
28
+ #### Params:
29
+ - context (dict): Dictionary containing the installation context variables.
30
+ """
31
+ super().__init__(context)
32
+ self.models_directory = context.pop(params.PARAM_MODELS_DIRECTORY)
33
+ if self.models_directory == os.path.abspath(paths.INSTALL_PATH):
34
+ self.models_directory = os.path.join(self.models_directory, 'models')
35
+
36
+ def _sync_operation(self) -> Tuple[int, str]:
37
+ """
38
+ ### Downloads deep learning models.
39
+
40
+ #### Returns:
41
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
42
+ """
43
+ if os.path.isdir(self.models_directory):
44
+ task = "update"
45
+ in_progress_task = "Updating"
46
+ completed_task = "updated"
47
+ else:
48
+ task = "download"
49
+ in_progress_task = "Downloading"
50
+ completed_task = "downloaded"
51
+
52
+ logger(f"{in_progress_task} Deep Learning models (in background)")
53
+ ret_code = shell_handler.run_shell_command_in_streaming(
54
+ f"{self.sync_program_path} {task} {self.models_directory} {urls.MODELS_URL} DLmodels",
55
+ show_output=True,
56
+ show_error=True,
57
+ substitute=True
58
+ )
59
+ if not ret_code:
60
+ logger(logger.green(f"Models successfully {completed_task}!"))
61
+
62
+ ret_code = 1 if ret_code else ret_code
63
+ return ret_code, ""
@@ -1,3 +1,8 @@
1
+ """
2
+ ### Mode Sync Executor Module.
3
+
4
+ This module contains the base class for mode executors with sync operations.
5
+ """
1
6
  import os
2
7
  from abc import abstractmethod
3
8
  from typing import Dict, Tuple
@@ -11,38 +16,39 @@ _SYNC_PROGRAM_PATH = os.path.join(".", paths.BINARIES_PATH)
11
16
  _SYNC_PROGRAM_NAME = "xmipp_sync_data"
12
17
 
13
18
  class ModeSyncExecutor(mode_executor.ModeExecutor):
14
- """Base class for mode executors with sync operations."""
15
-
16
- def __init__(self, context: Dict):
17
- """
18
- ### Constructor.
19
-
20
- #### Params:
21
- - context (dict): Dictionary containing the installation context variables.
22
- """
23
- super().__init__(context)
24
- self.sync_program_path = os.path.join(_SYNC_PROGRAM_PATH, _SYNC_PROGRAM_NAME)
25
-
26
- def run(self) -> Tuple[int, str]:
27
- """
28
- ### Executes the sync operation.
29
-
30
- #### Returns:
31
- - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
32
- """
33
- if not os.path.exists(self.sync_program_path):
34
- logger('\n'.join([
35
- logger.red(f"{self.sync_program_path} does not exist."),
36
- logger.red("Xmipp needs to be compiled successfully before running this command!")
37
- ]))
38
- return errors.IO_ERROR, ""
39
- return self._sync_operation()
40
-
41
- @abstractmethod
42
- def _sync_operation(self) -> Tuple[int, str]:
43
- """
44
- ### Executes the specific sync operation.
45
-
46
- #### Returns:
47
- - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
48
- """
19
+ """Base class for mode executors with sync operations."""
20
+
21
+ def __init__(self, context: Dict):
22
+ """
23
+ ### Constructor.
24
+
25
+ #### Params:
26
+ - context (dict): Dictionary containing the installation context variables.
27
+ """
28
+ super().__init__(context)
29
+ self.sync_program_name = _SYNC_PROGRAM_NAME
30
+ self.sync_program_path = os.path.join(_SYNC_PROGRAM_PATH, _SYNC_PROGRAM_NAME)
31
+
32
+ def run(self) -> Tuple[int, str]:
33
+ """
34
+ ### Executes the sync operation.
35
+
36
+ #### Returns:
37
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
38
+ """
39
+ if not os.path.exists(self.sync_program_path):
40
+ logger('\n'.join([
41
+ logger.red(f"{self.sync_program_path} does not exist."),
42
+ logger.red("Xmipp needs to be compiled successfully before running this command!")
43
+ ]))
44
+ return errors.IO_ERROR, ""
45
+ return self._sync_operation()
46
+
47
+ @abstractmethod
48
+ def _sync_operation(self) -> Tuple[int, str]:
49
+ """
50
+ ### Executes the specific sync operation.
51
+
52
+ #### Returns:
53
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
54
+ """
@@ -1,8 +1,13 @@
1
+ """
2
+ ### Mode Test Executor Module.
3
+
4
+ This module contains the class to execute Xmipp tests.
5
+ """
1
6
  import os
2
- from typing import Dict, Tuple
7
+ from typing import Dict, Tuple, Any
3
8
 
4
9
  from xmipp3_installer.application.cli.arguments import params
5
- from xmipp3_installer.application.logger.logger import logger
10
+ from xmipp3_installer.application.logger.logger import logger, errors
6
11
  from xmipp3_installer.installer import urls
7
12
  from xmipp3_installer.installer.constants import paths
8
13
  from xmipp3_installer.installer.handlers import shell_handler
@@ -10,82 +15,144 @@ from xmipp3_installer.installer.modes.mode_sync.mode_sync_executor import ModeSy
10
15
  from xmipp3_installer.repository.config_vars import variables
11
16
 
12
17
  _DATASET_NAME = "xmipp_programs"
18
+ _PYTHON_TEST_SCRIPT_PATH = os.path.join(paths.SOURCES_PATH, "xmipp")
19
+ _PYTHON_TEST_SCRIPT_INTERNAL_FOLDER = "tests"
13
20
  _PYTHON_TEST_SCRIPT_NAME = "test.py"
14
- _PYTHON_TEST_SCRIPT_PATH = os.path.join(paths.BINARIES_PATH, "tests")
21
+ _PYTHON_DATA_FOLDER = 'data'
22
+ _PYTHON_TEST_SCRIPT_INTERNAL_PATH = os.path.join(
23
+ _PYTHON_TEST_SCRIPT_INTERNAL_FOLDER,
24
+ _PYTHON_TEST_SCRIPT_NAME
25
+ )
15
26
  _DEFAULT_PYTHON_HOME = "python3"
16
- _DATASET_PATH = os.path.join(_PYTHON_TEST_SCRIPT_PATH, 'data')
27
+ _DATASET_PATH = os.path.join(_PYTHON_TEST_SCRIPT_PATH, _PYTHON_TEST_SCRIPT_INTERNAL_FOLDER, _PYTHON_DATA_FOLDER)
28
+ _TEST_DATA = os.path.join(_PYTHON_TEST_SCRIPT_INTERNAL_FOLDER, _PYTHON_DATA_FOLDER)
29
+ _BASHRC_FILE_PATH = os.path.abspath(os.path.join(paths.INSTALL_PATH, "xmipp.bashrc"))
30
+ _TESTS_SEPARATOR = " "
31
+ _PARAM_MAPPER = {
32
+ params.PARAM_SHOW_TESTS: "--show",
33
+ params.PARAM_ALL_FUNCTIONS: "--allFuncs",
34
+ params.PARAM_ALL_PROGRAMS: "--allPrograms"
35
+ }
17
36
 
18
37
  class ModeTestExecutor(ModeSyncExecutor):
19
- """Class to execute Xmipp tests."""
20
-
21
- def __init__(self, context: Dict):
22
- """
23
- ### Constructor.
24
-
25
- #### Params:
26
- - context (dict): Dictionary containing the installation context variables.
27
- """
28
- super().__init__(context)
29
- self.test_names = context.pop(params.PARAM_TEST_NAMES)
30
- self.cuda = context.pop(variables.CUDA)
31
- self.show = context.pop(params.PARAM_SHOW_TESTS)
32
- python_home = context.pop(variables.PYTHON_HOME, None)
33
- self.python_home = python_home if python_home else _DEFAULT_PYTHON_HOME
34
-
35
- def run(self) -> Tuple[int, str]:
36
- """
37
- ### Runs the provided tests.
38
-
39
- #### Returns:
40
- - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
41
- """
42
- ret_code, output = super().run()
43
- if ret_code:
44
- return ret_code, output
45
- return self.__run_tests()
46
-
47
- def _sync_operation(self) -> Tuple[int, str]:
48
- """
49
- ### Executes the test operation.
50
-
51
- #### Returns:
52
- - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
53
- """
54
- if os.path.isdir(_DATASET_PATH):
55
- task_message = "Updating"
56
- task = "update"
57
- show_output = False
58
- else:
59
- task_message = "Downloading"
60
- task = "download"
61
- show_output = True
62
- logger(logger.blue(f"{task_message} the test files"))
63
-
64
- args = f"{_DATASET_PATH} {urls.SCIPION_TESTS_URL} {_DATASET_NAME}"
65
- sync_program_relative_call = os.path.join(
66
- ".",
67
- os.path.basename(self.sync_program_path)
68
- )
69
- return shell_handler.run_shell_command(
70
- f"{sync_program_relative_call} {task} {args}",
71
- cwd=os.path.dirname(self.sync_program_path),
72
- show_output=show_output
73
- )
74
-
75
- def __run_tests(self) -> Tuple[int, str]:
76
- """
77
- ### Runs the specified tests.
78
-
79
- #### Returns:
80
- - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
81
- """
82
- no_cuda_str = "--noCuda" if not self.cuda else ""
83
- show_str = "--show" if self.show else ""
84
- logger(f" Tests to run: {', '.join(self.test_names)}")
85
-
86
- return shell_handler.run_shell_command(
87
- f"{self.python_home} {_PYTHON_TEST_SCRIPT_NAME} {' '.join(self.test_names)} {no_cuda_str}{show_str}",
88
- cwd=_PYTHON_TEST_SCRIPT_PATH,
89
- show_output=True,
90
- show_error=True
91
- )
38
+ """Class to execute Xmipp tests."""
39
+
40
+ def __init__(self, context: Dict):
41
+ """
42
+ ### Constructor.
43
+
44
+ #### Params:
45
+ - context (dict): Dictionary containing the installation context variables.
46
+ """
47
+ super().__init__(context)
48
+ self.param_value = self.__get_selected_param_value(context)
49
+ self.cuda = context.pop(variables.CUDA)
50
+ python_home = context.pop(variables.PYTHON_HOME, None)
51
+ self.python_home = python_home if python_home else _DEFAULT_PYTHON_HOME
52
+
53
+ def run(self) -> Tuple[int, str]:
54
+ """
55
+ ### Runs the provided tests.
56
+
57
+ #### Returns:
58
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
59
+ """
60
+ ret_code, output = self.__load_bashrc()
61
+ if ret_code:
62
+ return ret_code, output
63
+
64
+ ret_code, output = super().run()
65
+ if ret_code:
66
+ return ret_code, output
67
+ return self.__run_tests()
68
+
69
+ def _sync_operation(self) -> Tuple[int, str]:
70
+ """
71
+ ### Executes the test operation.
72
+
73
+ #### Returns:
74
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
75
+ """
76
+ if os.path.isdir(_DATASET_PATH):
77
+ task_message = "Updating"
78
+ task = "update"
79
+ else:
80
+ task_message = "Downloading"
81
+ task = "download"
82
+ logger(logger.blue(f"{task_message} the test files"))
83
+
84
+ args = f"{_TEST_DATA} {urls.SCIPION_TESTS_URL} {_DATASET_NAME}"
85
+ ret_code = shell_handler.run_shell_command_in_streaming(
86
+ f"{self.sync_program_name} {task} {args}",
87
+ cwd=_PYTHON_TEST_SCRIPT_PATH,
88
+ show_output=True,
89
+ show_error=True,
90
+ substitute=True
91
+ )
92
+ ret_code = 1 if ret_code else ret_code
93
+ return ret_code, ""
94
+
95
+ @staticmethod
96
+ def __load_bashrc() -> Tuple[int, str]:
97
+ """
98
+ ### Loads the bashrc file.
99
+
100
+ #### Returns:
101
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
102
+ """
103
+ if not os.path.exists(_BASHRC_FILE_PATH):
104
+ return errors.IO_ERROR, f"File {_BASHRC_FILE_PATH} does not exist."
105
+
106
+ ret_code, output = shell_handler.run_shell_command(
107
+ f"bash -c 'source {_BASHRC_FILE_PATH} && env'"
108
+ )
109
+ if ret_code:
110
+ return 1, output
111
+
112
+ for line in output.splitlines():
113
+ key, _, value = line.partition("=")
114
+ os.environ[key] = value
115
+ return 0, ""
116
+
117
+ def __run_tests(self) -> Tuple[int, str]:
118
+ """
119
+ ### Runs the specified tests.
120
+
121
+ #### Returns:
122
+ - (tuple(int, str)): Tuple containing the return code and an error message if there was an error.
123
+ """
124
+ no_cuda_str = "--noCuda" if not self.cuda else ""
125
+ if self.param_value not in {
126
+ _PARAM_MAPPER[params.PARAM_SHOW_TESTS],
127
+ _PARAM_MAPPER[params.PARAM_ALL_FUNCTIONS],
128
+ _PARAM_MAPPER[params.PARAM_ALL_PROGRAMS]
129
+ }:
130
+ test_names = self.param_value.replace(_TESTS_SEPARATOR, ", ")
131
+ logger(f" Tests to run: {test_names}")
132
+ ret_code, output = shell_handler.run_shell_command(
133
+ f"{self.python_home} {_PYTHON_TEST_SCRIPT_INTERNAL_PATH} {self.param_value} {no_cuda_str}",
134
+ cwd=_PYTHON_TEST_SCRIPT_PATH,
135
+ show_output=True
136
+ )
137
+ ret_code = 1 if ret_code else 0
138
+ return ret_code, output
139
+
140
+ @staticmethod
141
+ def __get_selected_param_value(context: Dict[str, Any]) -> str:
142
+ """
143
+ ### Returns the value of the param selected to run the test execution.
144
+
145
+ #### Params:
146
+ - context (dict(str, any)): Dictionary containing the installation context variables.
147
+
148
+ #### Returns:
149
+ - (str): The value of the selected variable to use
150
+ """
151
+ for variable in {
152
+ params.PARAM_SHOW_TESTS,
153
+ params.PARAM_ALL_FUNCTIONS,
154
+ params.PARAM_ALL_PROGRAMS
155
+ }:
156
+ if context[variable]:
157
+ return _PARAM_MAPPER[variable]
158
+ return _TESTS_SEPARATOR.join(context.pop(params.PARAM_TEST_NAMES))