def test_unit_test_with_deps(self): app_dir = join(self.test_dir, 'test_app') dep_dir = join(app_dir, 'deps') set_deps( app_dir, # root project depends on dep1 [{ 'name': 'dep1', 'url': 'https://github.com/comtihon/dep1', 'tag': '1.0.0' }]) create(dep_dir, {'<name>': 'dep1'}) # dep1 has dep_api:test/0 with open(join(dep_dir, 'dep1', 'src', 'dep_api.erl'), 'w') as test: test.write(''' -module(dep_api). -export([test/0]). test() -> true.''') app_test_dir = join(app_dir, 'test') ensure_dir(app_test_dir) # dep_api:test/0 is used in unit test of root project with open(join(app_test_dir, 'common.erl'), 'w') as test: test.write(''' -module(common). -include_lib("eunit/include/eunit.hrl"). run_test() -> ?assertEqual(true, dep_api:test()).''') # Compile dep. I only do it in test, as in real life deps will be compiled and linked before running unit. dep = Package.from_path(join(dep_dir, 'dep1')) self.assertEqual(True, EnotCompiler(dep).compile()) package = Package.from_path(app_dir) compiler = EnotCompiler(package) self.assertEqual(True, compiler.unit())
def compile(self, override_config: ConfigFile or None = None, params: list or None = None, erts: str or None = None) -> bool: ensure_dir(join(self.package.path, 'rel')) ensure_empty(join(self.package.path, '_rel')) resave_relconf, relconf_path, relconf = self.__modify_resource( 'relx.config') resave_vmargs, vmargs_path, vmargs = self.__modify_resource( 'vm.args', 'rel') resave_sysconf, sysconf_path, sysconf = self.__modify_resource( 'sys.config', 'rel') env_vars = dict(os.environ) if params is not None: cmd = [self.executable] + params else: cmd = self.executable if erts is not None: env_vars = RelxCompiler.__add_path(env_vars, erts) try: return run_cmd(cmd, self.project_name, self.root_path, env_vars=env_vars, output=None) finally: # Return previous file values, if were changed. if resave_vmargs: write_file(vmargs_path, vmargs) if resave_relconf: write_file(relconf_path, relconf) if resave_sysconf: write_file(sysconf_path, sysconf)
def add_package(self, package: Package, rewrite=False) -> bool: full_dir = join(self.path, self.get_package_path(package, True)) ensure_dir(full_dir) info('add ' + package.fullname) path = package.path LocalCache.__copy_data(rewrite, full_dir, path, 'ebin') LocalCache.__copy_include(rewrite, full_dir, path) if package.config.with_source: LocalCache.__copy_data(rewrite, full_dir, path, 'src') if package.config.with_source and package.has_nifs: LocalCache.__copy_data(rewrite, full_dir, path, 'c_src') if os.path.exists(join(path, 'priv')): LocalCache.__copy_data(rewrite, full_dir, path, 'priv') enot_package = join(path, package.name + '.ep') if not os.path.isfile(enot_package): debug('generate missing package') package.generate_package() copy_file(join(path, 'enot_config.json'), join(full_dir, 'enot_config.json')) copy_file(enot_package, join(full_dir, package.name + '.ep')) resource = resource_filename(Requirement.parse(enot.APPNAME), 'enot/resources/EmptyMakefile') debug('copy ' + resource + ' to ' + join(full_dir, 'Makefile')) copy_file(resource, join(full_dir, 'Makefile')) package.path = full_dir # update package's dir to point to cache return True
def test_app_creating_duplucates(self): ensure_dir(self.src_dir) with open(join(self.src_dir, 'test.app.src'), 'w') as w: w.write(get_application(['test_dep1', 'test_dep2'])) with open(join(self.test_dir, 'enot_config.json'), 'w') as w: w.write(get_package_conf([{'name': 'test_dep1', 'url': "http://github/comtihon/test_dep1", 'tag': "test_vsn"}, {'name': 'test_dep3', 'url': "http://github/comtihon/test_dep3", 'tag': "test_vsn"}])) package = Package.from_path(self.test_dir) package_deps = [dep.name for dep in package.deps] self.assertEqual(2, len(package_deps)) self.assertEqual(True, 'test_dep1' in package_deps) self.assertEqual(True, 'test_dep3' in package_deps) applications = package.app_config.applications self.assertEqual(2, len(package_deps)) self.assertEqual(True, 'test_dep1' in applications) self.assertEqual(True, 'test_dep2' in applications) apps = package.apps self.assertEqual(3, len(apps)) # test_dep1, test_dep2, test_dep3 self.assertEqual(True, 'test_dep1' in apps) self.assertEqual(True, 'test_dep2' in apps) self.assertEqual(True, 'test_dep3' in apps)
def test_error_compilation(self): ensure_dir(self.src_dir) with open(join(self.src_dir, 'proper.c'), 'w') as w: w.write(''' #include "erl_nif.h" static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1) // error here, forget terminator } static ErlNifFunc nif_funcs[] = { {"hello", 0, hello} }; ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL) ''') config = EnotConfig({'name': 'proper'}) package = Package(self.test_dir, config, None) compiler = CCompiler(package) self.assertEqual(False, compiler.compile()) self.assertEqual( False, os.path.exists(join(self.output_dir, self.test_name + '.so')))
def test_collecting_units_recurse(self): test_dir = join(self.test_dir, 'test_app', 'test') ensure_dir(test_dir) with open(join(test_dir, 'level1.erl'), 'w') as test: test.write(''' -module(level1). -include_lib("eunit/include/eunit.hrl"). run_test() -> ?_assert(true).''') subdir = join(test_dir, 'sub') ensure_dir(subdir) with open(join(subdir, 'level2.erl'), 'w') as test: test.write(''' -module(level2). -include_lib("eunit/include/eunit.hrl"). run_test() -> ?_assert(true).''') package = Package.from_path(join(self.test_dir, 'test_app')) compiler = EnotCompiler(package) files = compiler._EnotCompiler__get_all_files(compiler.test_path, 'erl') self.assertEqual({ 'level1': test_dir, 'level2': join(test_dir, 'sub') }, files)
def init_config(source: str, path: str, file: str): cache_dir = user_cache_dir(enot.APPNAME, enot.APPAUTHOR) ensure_dir(path) ensure_dir(cache_dir) with open(source, 'r') as r: content = r.read() with open(join(path, file), 'w') as f: f.write( Template(content).render(local_cache=cache_dir, temp_dir=temp_dir()))
def test_app_creating_new_app(self): ensure_dir(self.src_dir) with open(join(self.src_dir, 'test.app.src'), 'w') as w: w.write(get_application(['mnesia'])) with open(join(self.test_dir, 'enot_config.json'), 'w') as w: w.write(get_package_conf([])) package = Package.from_path(self.test_dir) self.assertEqual([], package.deps) # no package deps self.assertEqual(['mnesia'], package.apps) # mnesia in applications to be inserted in app (from apps) self.assertEqual(['mnesia'], package.app_config.applications) # mnesia in package apps (from app.src conf)
def __compose_ct_call(self, log_dir: str) -> list: cmd = ['ct_run', '-no_auto_compile', '-noinput'] cmd += ['-pa', self.output_path] cmd += ['-pa', join(self.deps_path, '*/ebin')] cmd += ['-pa', self.test_path] cmd += ['-dir', self.test_path] logs = join(self.root_path, log_dir) ensure_dir(logs) cmd += ['-logdir', logs] return cmd
def create(path: str, arguments: dict): name = arguments['<name>'] project_dir = join(path, name) src_dir = join(project_dir, 'src') ensure_dir(project_dir) ensure_dir(src_dir) __ensure_template(src_dir, name, '_app.erl') __ensure_template(src_dir, name, '_sup.erl') __ensure_template(src_dir, name, '.app.src') __ensure_template(project_dir, name, 'enot_config.json', True) return True
def __init__(self, temp_dir: str, default_erlang: str, conf): cache_url = conf['url'] path = cache_url[7:] super().__init__(conf['name'], temp_dir, path, default_erlang, CacheType.LOCAL) if not os.path.exists(path): os.makedirs(path) ensure_dir(temp_dir) ensure_dir(self.tool_dir) self._locks = {} self.__fill_locks()
def unit( self ) -> bool: # TODO run unit tests only for modules with include eunit lib? info('unit tests for ' + self.project_name) debug('run eunit in ' + self.test_path) all_src = self.__get_all_files(self.test_path, 'erl') ensure_dir(self.output_path) if self.__do_compile(all_src, output=self.test_path): modules, test_dirs = self.__get_test_directories( all_src, drop_extension='_SUITE') return self.__do_unit_test(modules, test_dirs) return False
def test_unit_test_fail(self): test_dir = join(self.test_dir, 'test_app', 'test') ensure_dir(test_dir) with open(join(test_dir, 'simple.erl'), 'w') as test: test.write(''' -module(simple). -include_lib("eunit/include/eunit.hrl"). run_test() -> ?assertEqual(true, false).''') package = Package.from_path(join(self.test_dir, 'test_app')) compiler = EnotCompiler(package) self.assertEqual(False, compiler.unit())
def test_app_creating_new_dep(self): ensure_dir(self.src_dir) with open(join(self.src_dir, 'test.app.src'), 'w') as w: w.write(get_application([])) with open(join(self.test_dir, 'enot_config.json'), 'w') as w: w.write(get_package_conf([{'name': 'test_dep', 'url': "http://github/comtihon/test_dep", 'tag': "test_vsn"}])) package = Package.from_path(self.test_dir) # test_dep in package deps (from package conf) self.assertEqual(['test_dep'], [dep.name for dep in package.deps]) self.assertEqual(['test_dep'], package.apps) # test_dep in applications to be inserted in app (from deps) self.assertEqual([], package.app_config.applications) # no applications in app.src
def link_package(self, package: Package, dest_path: str) -> bool: if not dest_path: dest_path = os.getcwd() cache_path = join(self.path, self.get_package_path(package)) dep_dir = join(dest_path, 'deps', package.name) ensure_dir(dep_dir) debug('link ' + package.name) changed = [] for file in listdir(cache_path): if file != package.name + '.ep': changed.append( LocalCache.link(cache_path, dest_path, package.name, file)) return all(changed) # if all links were changed - it is a new version
def test_proper_project_compilation(self): create(self.test_dir, {'<name>': 'proper'}) project_dir = join(self.test_dir, 'proper') ensure_dir(join(project_dir, 'c_src')) with open(join(project_dir, 'c_src/proper.c'), 'w') as w: w.write(''' #include "erl_nif.h" static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1); } static ErlNifFunc nif_funcs[] = { {"hello", 0, hello} }; ERL_NIF_INIT(proper,nif_funcs,NULL,NULL,NULL,NULL) ''') with open(join(project_dir, 'src/proper.erl'), 'w') as w: w.write(''' -module(proper). -export([init/0, hello/0]). init() -> erlang:load_nif("priv/proper", 0), io:format("~p~n", [hello()]). hello() -> "NIF library not loaded". ''') package = Package.from_path(project_dir) compiler = EnotCompiler(package) self.assertEqual(True, compiler.compile()) self.assertEqual(True, os.path.exists(join(project_dir, 'priv/proper.so'))) self.assertEqual(True, os.path.exists(join(project_dir, 'ebin/proper.beam'))) p = subprocess.Popen([ 'erl', '-pa', 'ebin', '-run', 'proper', 'init', '-run', 'init', 'stop', '-noshell' ], stdout=PIPE, cwd=project_dir) self.assertEqual(0, p.wait(5000)) self.assertEqual('"Hello world!"\n', p.stdout.read().decode('utf8'))
def test_app_creating_new_app_and_dep(self): ensure_dir(self.src_dir) with open(join(self.src_dir, 'test.app.src'), 'w') as w: w.write(get_application(['mnesia'])) with open(join(self.test_dir, 'enot_config.json'), 'w') as w: w.write(get_package_conf([{'name': 'test_dep', 'url': "http://github/comtihon/test_dep", 'tag': "test_vsn"}])) package = Package.from_path(self.test_dir) # test_dep in package deps (from package conf) self.assertEqual(['test_dep'], [dep.name for dep in package.deps]) self.assertEqual(['mnesia'], package.app_config.applications) # mnesia in package apps (from app.src conf) apps = package.apps self.assertEqual(2, len(apps)) # mnesia and test_dep will go to app file self.assertEqual(True, 'test_dep' in apps) self.assertEqual(True, 'mnesia' in apps)
def test_error_compilation(self, mock_compiler): mock_compiler.return_value = True ensure_dir(self.src_dir) with open(join(self.src_dir, 'improper.erl'), 'w') as w: w.write(''' -module(proper). -export([test/0]). test() -> syntax error here. do_smth(A) -> A + 1. ''') config = EnotConfig({'name': 'test'}) package = Package(self.test_dir, config, None) compiler = EnotCompiler(package) self.assertEqual(False, compiler.compile()) self.assertEqual(False, os.path.exists(join(self.ebin_dir, 'improper.beam')))
def test_in_cache(self, mock_conf, mock_get_cmd): mock_conf.return_value = self.conf_file mock_get_cmd.return_value = False ensure_dir(join(self.cache_dir, 'tool')) with open(join(self.cache_dir, 'tool', 'rebar'), 'w') as outfile: # 'load' tool to cache outfile.write('some content') enot.__main__.create(self.test_dir, {'<name>': 'test'}) project_dir = join(self.test_dir, 'test') builder = Builder.init_from_path(project_dir) compiler = RebarCompiler(builder.project) compiler.ensure_tool(builder.system_config.cache.local_cache) self.assertEqual(True, os.path.islink(join( project_dir, 'rebar'))) # linked to current project self.assertEqual(True, builder.system_config.cache.local_cache.tool_exists( 'rebar')) # and available in cache
def test_common_test_fail(self): test_dir = join(self.test_dir, 'test_app', 'test') ensure_dir(test_dir) with open(join(test_dir, 'common_SUITE.erl'), 'w') as test: test.write(''' -module(common_SUITE). -include_lib("common_test/include/ct.hrl"). -export([all/0]). -export([test/1]). all() -> [test]. test(_Config) -> 1 = 2.''') package = Package.from_path(join(self.test_dir, 'test_app')) compiler = EnotCompiler(package) self.assertEqual(False, compiler.common('test/logs'))
def test_write_app_file_from_src(self): ensure_dir(self.src_dir) with open(join(self.src_dir, 'proper.erl'), 'w') as w: w.write(''' -module(proper). -export([test/0]). test() -> do_smth(1). do_smth(A) -> A + 1. ''') with open(join(self.src_dir, 'proper.app.src'), 'w') as w: w.write(''' {application, proper, [ {description, ""}, {vsn, "{{ app.vsn }}"}, {registered, []}, {modules, {{ modules }}}, {applications, {{ app.std_apps + app.apps }}}, {mod, {proper_app, []}}, {env, []} ]}. ''') with open(join(self.test_dir, 'enot_config.json'), 'w') as w: w.write('''{ \"name\":\"proper\", \"app_vsn\":\"1.0.0\", \"deps\": [{\"name\": \"test_dep\", \"url\": \"http://github/comtihon/test_dep\", \"tag\": \"test_vsn\"}] }''') package = Package.from_path(self.test_dir) compiler = EnotCompiler(package) self.assertEqual(True, compiler.compile()) self.assertEqual(True, os.path.exists(self.ebin_dir)) ls = listdir(self.ebin_dir) self.assertEqual(True, 'proper.beam' in ls) self.assertEqual(True, 'proper.app' in ls) self.assertEqual(2, len(ls)) (name, vsn, deps, _) = parse_app_config(self.ebin_dir, '.app') self.assertEqual('proper', name) self.assertEqual('1.0.0', vsn) self.assertEqual(deps, ['kernel', 'stdlib', 'test_dep'])
def test_missing(self, mock_conf, mock_get_cmd, mock_http_read): mock_conf.return_value = self.conf_file mock_get_cmd.return_value = False ensure_dir(self.tmp_dir) mock_http_read.return_value = b'some rebar binary content' enot.__main__.create(self.test_dir, {'<name>': 'test'}) project_dir = join(self.test_dir, 'test') builder = Builder.init_from_path(project_dir) compiler = RebarCompiler(builder.project) compiler.ensure_tool(builder.system_config.cache.local_cache) self.assertEqual(True, os.path.exists(join( self.tmp_dir, 'rebar'))) # tool should be downloaded to tempdir self.assertEqual(True, os.path.exists(join(self.cache_dir, 'tool', 'rebar'))) # added to cache self.assertEqual(True, os.path.islink(join( project_dir, 'rebar'))) # linked to current project self.assertEqual(True, builder.system_config.cache.local_cache.tool_exists( 'rebar')) # and available in cache
def test_error_project_compilation(self): create(self.test_dir, {'<name>': 'proper'}) project_dir = join(self.test_dir, 'proper') ensure_dir(join(project_dir, 'c_src')) with open(join(project_dir, 'c_src/proper.c'), 'w') as w: w.write(''' #include "erl_nif.h" static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1) // error here } static ErlNifFunc nif_funcs[] = { {"hello", 0, hello} }; ERL_NIF_INIT(proper,nif_funcs,NULL,NULL,NULL,NULL) ''') with open(join(project_dir, 'src/proper.erl'), 'w') as w: w.write(''' -module(proper). -export([init/0, hello/0]). init() -> erlang:load_nif("priv/proper", 0), io:format("~p~n", [hello()]). hello() -> "NIF library not loaded". ''') package = Package.from_path(project_dir) compiler = EnotCompiler(package) self.assertEqual(False, compiler.compile()) self.assertEqual(False, os.path.exists(join(project_dir, 'priv/proper.so'))) self.assertEqual(False, os.path.exists(join(project_dir, 'ebin/proper.beam')))
def test_unit_multiple_test_ok(self, ): test_dir = join(self.test_dir, 'test_app', 'test') ensure_dir(test_dir) with open(join(test_dir, 'simple.erl'), 'w') as test: test.write(''' -module(simple). -include_lib("eunit/include/eunit.hrl"). run_test() -> ?_assert(true).''') subdir = join(test_dir, 'sub') ensure_dir(subdir) with open(join(subdir, 'level2.erl'), 'w') as test: test.write(''' -module(level2). -include_lib("eunit/include/eunit.hrl"). run_test() -> ?_assert(true).''') package = Package.from_path(join(self.test_dir, 'test_app')) compiler = EnotCompiler(package) self.assertEqual(True, compiler.unit())
def test_collecting_units(self): test_dir = join(self.test_dir, 'test_app', 'test') ensure_dir(test_dir) with open(join(test_dir, 'first.erl'), 'w') as test: test.write(''' -module(first). -include_lib("eunit/include/eunit.hrl"). run_test() -> ?_assert(true).''') with open(join(test_dir, 'second.erl'), 'w') as test: test.write(''' -module(second). -include_lib("eunit/include/eunit.hrl"). run_test() -> ?_assert(true).''') package = Package.from_path(join(self.test_dir, 'test_app')) compiler = EnotCompiler(package) files = compiler._EnotCompiler__get_all_files(compiler.test_path, 'erl') self.assertEqual({'first': test_dir, 'second': test_dir}, files)
def compile(self, override_config: ConfigFile or None = None) -> bool: info('Enot build ' + self.project_name) self.__run_prebuild(override_config) all_files = self.__get_all_files(self.src_path, 'erl') first_compiled = self.form_compilation_order(all_files) debug('ensure ' + self.output_path) ensure_dir(self.output_path) res = True if self.package.has_nifs: res = CCompiler( self.package).compile(override_config=override_config) if res and first_compiled is not {}: res = self.__do_compile(first_compiled, override=override_config) [ all_files.pop(key) for key in first_compiled if first_compiled[key] == all_files[key] ] if res: res = self.__do_compile(all_files, override=override_config) if res: self.__write_app_file(list(all_files.keys())) return res
def test_release_non_otp_dep(self, mock_conf, _): mock_conf.return_value = self.conf_file pack_path = join(self.test_dir, 'test_app') set_deps(pack_path, [ {'name': 'dep', 'url': 'https://github.com/comtihon/dep', 'tag': '1.0.0'} ]) create(self.tmp_dir, {'<name>': 'dep'}) dep_dir = join(self.tmp_dir, 'dep') ensure_dir(join(dep_dir, 'src')) with open(join(dep_dir, 'src', 'dep.erl'), 'w') as f: f.write(''' -module(dep). -export([test/0]). test() -> ok. ''') with open(join(dep_dir, 'src', 'dep.app.src'), 'w') as f: f.write(''' {application, dep, [ {description, ""}, {vsn, "0.0.1"}, {registered, []}, {applications, {{ app.std_apps + app.apps }}}, {modules, {{ modules }}} ]}. ''') builder = Builder.init_from_path(pack_path) builder.populate() self.assertEqual(True, builder.build()) path = ensure_tool(RelxTool()) builder.system_config.cache.local_cache.add_tool('relx', path) self.assertEqual(True, builder.release()) lib_dir = join(pack_path, '_rel', 'test_app', 'lib') self.assertEqual(True, os.path.exists(join(lib_dir, 'dep-0.0.1')))
def test_defines_setting(self, mock_compiler): mock_compiler.return_value = True ensure_dir(self.src_dir) with open(join(self.src_dir, 'proper.erl'), 'w') as w: w.write(''' -module(proper). -export([test/0]). test() -> io:format("~p~n", [?TEST_DEFINE]). ''') config = EnotConfig({'name': 'test'}) package = Package(self.test_dir, config, None) compiler = EnotCompiler(package, 'TEST_DEFINE=test') self.assertEqual(True, compiler.compile()) self.assertEqual(True, os.path.exists(join(self.ebin_dir, 'proper.beam'))) p = subprocess.Popen([ 'erl', '-pa', 'ebin', '-run', 'proper', 'test', '-run', 'init', 'stop', '-noshell' ], stdout=subprocess.PIPE, cwd=self.ebin_dir) self.assertEqual(0, p.wait(5000)) self.assertEqual('test\n', p.stdout.read().decode('utf8'))
def compile(self, override_config: ConfigFile or None = None) -> bool: ensure_dir(self.output_path) ensure_makefile(self.src_path) env_vars = self.__get_env_vars(override_config) return run_cmd([self.executable, '-C', 'c_src'], self.project_name, self.root_path, env_vars)
def setUp(self): super().setUp() ensure_dir(join(self.test_dir, 'conf'))