@@ -390,6 +390,73 @@ def test_exts_list(self):
390390 regex = re .compile ('EBEXTSLISTPI.*ext1-1.0,ext2-2.0' )
391391 self .assertTrue (regex .search (modtxt ), "Pattern '%s' found in: %s" % (regex .pattern , modtxt ))
392392
393+ def test_extensions_templates (self ):
394+ """Test whether templates used in exts_list are resolved properly."""
395+
396+ # put dummy source file in place to avoid download fail
397+ toy_tar_gz = os .path .join (self .test_sourcepath , 'toy' , 'toy-0.0.tar.gz' )
398+ copy_file (toy_tar_gz , os .path .join (self .test_prefix , 'toy-0.0-py3-test.tar.gz' ))
399+ toy_patch_fn = 'toy-0.0_fix-silly-typo-in-printf-statement.patch'
400+ toy_patch = os .path .join (self .test_sourcepath , 'toy' , toy_patch_fn )
401+ copy_file (toy_patch , self .test_prefix )
402+
403+ os .environ ['EASYBUILD_SOURCEPATH' ] = self .test_prefix
404+ init_config (build_options = {'silent' : True })
405+
406+ self .contents = '\n ' .join ([
407+ 'easyblock = "ConfigureMake"' ,
408+ 'name = "pi"' ,
409+ 'version = "3.14"' ,
410+ 'versionsuffix = "-test"' ,
411+ 'homepage = "http://example.com"' ,
412+ 'description = "test easyconfig"' ,
413+ 'toolchain = {"name": "dummy", "version": ""}' ,
414+ 'dependencies = [("Python", "3.6.6")]' ,
415+ 'exts_defaultclass = "EB_Toy"' ,
416+ # bogus, but useful to check whether this get resolved
417+ 'exts_default_options = {"source_urls": [PYPI_SOURCE]}' ,
418+ 'exts_list = [' ,
419+ ' ("toy", "0.0", {' ,
420+ # %(name)s and %(version_major_minor)s should be resolved using name/version of extension (not parent)
421+ # %(pymajver)s should get resolved because Python is listed as a (runtime) dep
422+ # %(versionsuffix)s should get resolved with value of parent
423+ ' "source_tmpl": "%(name)s-%(version_major_minor)s-py%(pymajver)s%(versionsuffix)s.tar.gz",' ,
424+ ' "patches": ["%(name)s-%(version)s_fix-silly-typo-in-printf-statement.patch"],' ,
425+ # use hacky prebuildopts that is picked up by 'EB_Toy' easyblock, to check whether templates are resolved
426+ ' "prebuildopts": "gcc -O2 %(name)s.c -o toy-%(version)s && mv toy-%(version)s toy #",' ,
427+ ' }),' ,
428+ ']' ,
429+ ])
430+ self .prep ()
431+ ec = EasyConfig (self .eb_file )
432+ eb = EasyBlock (ec )
433+ eb .fetch_step ()
434+
435+ # run extensions step to install 'toy' extension
436+ eb .extensions_step ()
437+
438+ # check whether template values were resolved correctly in Extension instances that were created/used
439+ toy_ext = eb .ext_instances [0 ]
440+ self .assertEqual (os .path .basename (toy_ext .src ), 'toy-0.0-py3-test.tar.gz' )
441+ self .assertEqual (toy_ext .patches , [os .path .join (self .test_prefix , toy_patch_fn )])
442+ expected = {
443+ 'patches' : ['toy-0.0_fix-silly-typo-in-printf-statement.patch' ],
444+ 'prebuildopts' : 'gcc -O2 toy.c -o toy-0.0 && mv toy-0.0 toy #' ,
445+ 'source_tmpl' : 'toy-0.0-py3-test.tar.gz' ,
446+ 'source_urls' : ['https://pypi.python.org/packages/source/t/toy' ],
447+ }
448+ self .assertEqual (toy_ext .options , expected )
449+
450+ # also .cfg of Extension instance was updated correctly
451+ self .assertEqual (toy_ext .cfg ['source_urls' ], ['https://pypi.python.org/packages/source/t/toy' ])
452+ self .assertEqual (toy_ext .cfg ['patches' ], [toy_patch_fn ])
453+ self .assertEqual (toy_ext .cfg ['prebuildopts' ], "gcc -O2 toy.c -o toy-0.0 && mv toy-0.0 toy #" )
454+
455+ # check whether files expected to be installed for 'toy' extension are in place
456+ pi_installdir = os .path .join (self .test_installpath , 'software' , 'pi' , '3.14-test' )
457+ self .assertTrue (os .path .exists (os .path .join (pi_installdir , 'bin' , 'toy' )))
458+ self .assertTrue (os .path .exists (os .path .join (pi_installdir , 'lib' , 'libtoy.a' )))
459+
393460 def test_suggestions (self ):
394461 """ If a typo is present, suggestions should be provided (if possible) """
395462 self .contents = '\n ' .join ([
@@ -2163,6 +2230,31 @@ def test_template_constant_dict(self):
21632230
21642231 self .assertEqual (res , expected )
21652232
2233+ # also check result of template_constant_dict when dict representing extension is passed
2234+ ext_dict = {
2235+ 'name' : 'foo' ,
2236+ 'version' : '1.2.3' ,
2237+ 'options' : {
2238+ 'source_urls' : ['https://example.com' ],
2239+ 'source_tmpl' : '%(name)s-%(version)s.tar.gz' ,
2240+ },
2241+ }
2242+ res = template_constant_dict (ext_dict )
2243+
2244+ self .assertTrue ('arch' in res )
2245+ arch = res .pop ('arch' )
2246+ self .assertTrue (arch_regex .match (arch ), "'%s' matches with pattern '%s'" % (arch , arch_regex .pattern ))
2247+
2248+ expected = {
2249+ 'name' : 'foo' ,
2250+ 'nameletter' : 'f' ,
2251+ 'version' : '1.2.3' ,
2252+ 'version_major' : '1' ,
2253+ 'version_major_minor' : '1.2' ,
2254+ 'version_minor' : '2'
2255+ }
2256+ self .assertEqual (res , expected )
2257+
21662258 def test_parse_deps_templates (self ):
21672259 """Test whether handling of templates defined by dependencies is done correctly."""
21682260 test_ecs = os .path .join (os .path .dirname (os .path .abspath (__file__ )), 'easyconfigs' , 'test_ecs' )
0 commit comments