populse / capsul

Collaborative Analysis Platform : Simple, Unifying, Lean
Other
7 stars 14 forks source link

failing test in v3: test_nipype_wrap with SPM config #282

Closed denisri closed 1 year ago

denisri commented 1 year ago

When running tests in capsul v3, I see one failing: capsul.process.test.test_nipype_wrap run via:

python -m capsul.test -k test_nipype_wrap

Compared to the tests running on github, the difference is that I have SPM standalone installed and detected in the test. The error is the following:

________________________________________ TestNipypeWrap.test_nipype_spm_exec _________________________________________

self = <capsul.process.test.test_nipype_wrap.TestNipypeWrap testMethod=test_nipype_spm_exec>

    @unittest.skipIf(not init_spm_config(),
                     'SPM is not configured to run this test')
    def test_nipype_spm_exec(self):
        # we must do this again because when multiple tests are run, the init
        # function may be called at the wrong time (too early, at import), then
        # other tests will run and define a different Capsul object
        init_spm_config()

        c = Capsul()

        template_dirs = ['spm12_mcr/spm12/spm12',
                         'spm12_mcr/spm12',
                         'spm12']
        for template_dir_s in template_dirs:
            template_dir = osp.join(
>               c.config.builtin.spm.spm12_standalone.directory, template_dir_s)

process/test/test_nipype_wrap.py:136: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = EngineConfiguration(dataset=undefined, config_modules=undefined, python_modules=undefined, database='builtin', start_workers={'type': 'builtin', 'count': 2})
name = 'spm'

    def __getattr__(self, name):
        if name != '_dyn_fields':
            dyn_fields = getattr(self, '_dyn_fields', None)
            if dyn_fields:
                field = dyn_fields.get(name)
                if field:
                    result = getattr(field, name)
                    return result
>       raise AttributeError('{} object has no attribute {}'.format(repr(self.__class__), repr(name)))
E       AttributeError: <class 'capsul.config.configuration.EngineConfiguration'> object has no attribute 'spm'

/casa/host/build/python/soma/controller/controller.py:454: AttributeError

Getting more closely into it, it seems to be a config issue: in init_spm_config(), things are done this way (I simplify to get a minimal example):

from capsul.config.configuration import ApplicationConfiguration

spm_dir = '/host/usr/local/spm12-standalone'   # (for me)
mcr_dir = '/host/usr/local/spm12-standalone/mcr/v97'
user_conf_dict = {
    'builtin': {
        'spm': {
            'spm12_standalone': {
                'directory': spm_dir,
                'standalone': True,
                'version': '12'},
            },
        'nipype': {
            'nipype': {},
        },
        'matlab': {
            'matlab_mcr': {
                'mcr_directory': mcr_dir,
            },
        },
    }
}
config = ApplicationConfiguration('capsul_test_nipype_spm')
print(config.user)

output:

ConfigurationLayer(databases={'builtin': {'type': 'redis+socket', 'path': '/tmp/capsul_engine_database.rdb'}}, builtin=...)
config.user = user_conf_dict
print(config.user)

output:

ConfigurationLayer()

The ConfigurationLayer object is now empty, the config options didn't get into it. If I replace the = operation with:

config.user.import_dict(user_conf_dict)

then the configuration is properly set, and the test goes further. It fails later but this is a different issue. Thus the = operation in ApplicationConfiguration doesn't work as expected (the doc shows a pretty similar example), and I think it used to work some time ago. The problem is probably in Controller however.