Skip to content

Test mlc tests #303

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Mar 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/scripts/process_individual_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@
ret = mlc.access(ii)
if ret['return'] > 0:
raise Exception(r['error'])
ii = {'action': 'rm', 'target': 'cache', 'f': True}
ret = mlc.access(ii)
2 changes: 0 additions & 2 deletions .github/workflows/check-broken-links.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
name: "Check .md README files for broken links"

on:
pull_request:
branches:
Expand All @@ -13,7 +12,6 @@ jobs:
steps:
- uses: actions/checkout@v4


# Checks the status of hyperlinks in .md files in verbose mode
- name: Check links
uses: gaurav-nelson/github-action-markdown-link-check@v1
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/test-mlc-script-features.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ jobs:
mlc search cache --tags=get,dataset,preprocessed,imagenet,-_NCHW
mlc search cache --tags=get,dataset,preprocessed,imagenet,-_NHWC
# Tests run-scripts on windows,ubuntu,macos
mlcr get,wkhtmltopdf

- name: Test native script name variants
run: |
mlcr get,wkhtmltopdf --quiet

- name: Test versions
continue-on-error: true
Expand Down
285 changes: 29 additions & 256 deletions automation/script/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,8 +502,7 @@ def _run(self, i):
ii = {}
ii['tags'] = tags_string
ii['out'] = None
for key in ["automation", "parsed_automation",
"artifact", "parsed_artifact"]:
for key in ["automation", "artifact", "item", "details"]:
if i.get(key):
ii[key] = i[key]

Expand Down Expand Up @@ -2792,13 +2791,19 @@ def search(self, i):
# Find MLC script(s) based on thier tags to get their meta (can be more than 1)
# Then check if variations exists inside meta

i['tags'] = ','.join(script_tags)
ii = {}
ii['tags'] = ','.join(script_tags)

i['out'] = None
i['common'] = True
ii['out'] = None
ii['common'] = True

ii['target'] = "script"
for key in ["automation", "item",
"artifact", "details"]:
if i.get(key):
ii[key] = i[key]

i['target_name'] = "script"
r = super(ScriptAutomation, self).search(i)
r = super(ScriptAutomation, self).search(ii)
if r['return'] > 0:
return r

Expand Down Expand Up @@ -2901,7 +2906,6 @@ def test(self, i):
# Find script item(s)
i['out'] = None
r = self.search(i)

if r['return'] > 0:
return r

Expand All @@ -2910,7 +2914,6 @@ def test(self, i):
for script_item in lst:
path = script_item.path
meta = script_item.meta
original_meta = script_item.original_meta

alias = meta.get('alias', '')
uid = meta.get('uid', '')
Expand Down Expand Up @@ -2970,14 +2973,14 @@ def test(self, i):
if given_variations:
v_split = []
run_variations = []
for i, v in enumerate(given_variations):
for v in given_variations:
v_split = v.split(",")
for t in v_split:
for index, t in enumerate(v_split):
if not t.startswith("_"):
# variations must begin with _. We
# support both with and without _
# in the meta
given_variations[i] = f"_{t}"
v_split[index] = f"_{t}"
if v_split:
run_variations.append(
",".join(v_split))
Expand Down Expand Up @@ -3018,7 +3021,8 @@ def test(self, i):
r = self.action_object.access(ii)
if r['return'] > 0:
return r

if is_true(i.get('docker_prune', '')):
docker_prune()
return {'return': 0, 'list': lst}

############################################################
Expand Down Expand Up @@ -3097,250 +3101,8 @@ def native_run(self, i):

return {'return': 0, 'return_code': rc}

############################################################
def add(self, i):
"""
Add MLC script

Args:
(MLC input dict):

(out) (str): if 'con', output to console

parsed_artifact (list): prepared in MLC CLI or MLC access function
[ (artifact alias, artifact UID) ] or
[ (artifact alias, artifact UID), (artifact repo alias, artifact repo UID) ]

(tags) (str): tags to find an MLC script (MLC artifact)

(script_name) (str): name of script (it will be copied to the new entry and added to the meta)

(tags) (string or list): tags to be added to meta

(new_tags) (string or list): new tags to be added to meta (the same as tags)

(json) (bool): if True, record JSON meta instead of YAML

(meta) (dict): preloaded meta

(template) (string): template to use (python)
(python) (bool): template=python
(pytorch) (bool): template=pytorch
...

Returns:
(MLC return dict):

* return (int): return code == 0 if no error and >0 if error
* (error) (str): error string if return>0

"""

import shutil

console = i.get('out') == 'con'
logger = self.action_object.logger

# Try to find script artifact by alias and/or tags
# ii = utils.sub_input(i, self.cmind.cfg['artifact_keys'])
ii = {}
ii['tags'] = tags_string
ii['out'] = None

for key in ["automation", "parsed_automation",
"artifact", "parsed_artifact"]:
if i.get(key):
ii[key] = i[key]

parsed_artifact = i.get('parsed_artifact', [])

artifact_obj = parsed_artifact[0] if len(parsed_artifact) > 0 else None
artifact_repo = parsed_artifact[1] if len(
parsed_artifact) > 1 else None

script_name = ''
if 'script_name' in i:
script_name = i.get('script_name', '').strip()
del (i['script_name'])

if script_name != '' and not os.path.isfile(script_name):
return {'return': 1,
'error': 'file {} not found'.format(script_name)}

# Move tags from input to meta of the newly created script artifact
res = utils.convert_tags_to_list(i['tags'])
if res['return'] > 0:
return res
tags_list = res['tags']
if 'tags' in i:
del (i['tags'])

if len(tags_list) == 0:
if console:
x = input(
'Please specify a combination of unique tags separated by comma for this script: ')
x = x.strip()
if x != '':
tags_list = x.split(',')

if len(tags_list) == 0:
return {
'return': 1, 'error': 'you must specify a combination of unique tags separate by comman using "--new_tags"'}

# Add placeholder (use common action)
ii['out'] = 'con'
# Avoid recursion - use internal MLC add function to add the script
# artifact
ii['common'] = True

# Check template path
template_dir = 'template'

template = i.get('template', '')

if template == '':
if i.get('python', False):
template = 'python'
elif i.get('pytorch', False):
template = 'pytorch'

if template != '':
template_dir += '-' + template

template_path = os.path.join(self.path, template_dir)

if not os.path.isdir(template_path):
return {'return': 1, 'error': 'template path {} not found'.format(
template_path)}

# Check if preloaded meta exists
meta = {
'cache': False
# 20240127: Grigori commented that because newly created script meta looks ugly
# 'new_env_keys':[],
# 'new_state_keys':[],
# 'input_mapping':{},
# 'docker_input_mapping':{},
# 'deps':[],
# 'prehook_deps':[],
# 'posthook_deps':[],
# 'post_deps':[],
# 'versions':{},
# 'variations':{},
# 'input_description':{}
}

fmeta = os.path.join(
template_path,
self.action_object.cfg['file_cmeta'])

r = utils.load_yaml_and_json(fmeta)
if r['return'] == 0:
utils.merge_dicts({'dict1': meta,
'dict2': r['meta'],
'append_lists': True,
'append_unique': True})

# Check meta from CMD
xmeta = i.get('meta', {})

if len(xmeta) > 0:
utils.merge_dicts({'dict1': meta, 'dict2': xmeta,
'append_lists': True, 'append_unique': True})

meta['automation_alias'] = self.meta['alias']
meta['automation_uid'] = self.meta['uid']
meta['tags'] = tags_list

script_name_base = script_name
script_name_ext = ''
if script_name != '':
# separate name and extension
j = script_name.rfind('.')
if j >= 0:
script_name_base = script_name[:j]
script_name_ext = script_name[j:]

meta['script_name'] = script_name_base

ii['meta'] = meta
ii['action'] = 'add'

use_yaml = True if not i.get('json', False) else False

if use_yaml:
ii['yaml'] = True

ii['automation'] = 'script,5b4e0237da074764'

for k in ['parsed_automation', 'parsed_artifact']:
if k in ii:
del ii[k]

if artifact_repo is not None:
ii['artifact'] = utils.assemble_object2(
artifact_repo) + ':' + utils.assemble_object2(artifact_obj)

r_obj = self.action_object.access(ii)
if r_obj['return'] > 0:
return r_obj

new_script_path = r_obj['path']

if console:
logger.info('Created script in {}'.format(new_script_path))

# Copy files from template (only if exist)
files = [
(template_path, 'README-extra.md', ''),
(template_path, 'customize.py', ''),
(template_path, 'main.py', ''),
(template_path, 'requirements.txt', ''),
(template_path, 'install_deps.bat', ''),
(template_path, 'install_deps.sh', ''),
(template_path, 'plot.bat', ''),
(template_path, 'plot.sh', ''),
(template_path, 'analyze.bat', ''),
(template_path, 'analyze.sh', ''),
(template_path, 'validate.bat', ''),
(template_path, 'validate.sh', '')
]

if script_name == '':
files += [(template_path, 'run.bat', ''),
(template_path, 'run.sh', '')]
else:
if script_name_ext == '.bat':
files += [(template_path, 'run.sh', script_name_base + '.sh')]
files += [('', script_name, script_name)]

else:
files += [(template_path, 'run.bat',
script_name_base + '.bat')]
files += [('', script_name, script_name_base + '.sh')]

for x in files:
path = x[0]
f1 = x[1]
f2 = x[2]

if f2 == '':
f2 = f1

if path != '':
f1 = os.path.join(path, f1)

if os.path.isfile(f1):
f2 = os.path.join(new_script_path, f2)

if console:
logger.info(' * Copying {} to {}'.format(f1, f2))

shutil.copyfile(f1, f2)

return r_obj

##########################################################################

def _get_name_for_dynamic_variation_tag(script, variation_tag):
'''
Returns the variation name in meta for the dynamic_variation_tag
Expand Down Expand Up @@ -5101,6 +4863,17 @@ def _update_env(env, key=None, value=None):
return {'return': 0}


def docker_prune():
try:
# Run the docker prune command with -a (removes all unused images, not
# just dangling ones)
result = subprocess.run(["docker", "system", "prune", "-a", "-f"],
capture_output=True, text=True, check=True)
print("Docker prune output:\n", result.stdout)
except subprocess.CalledProcessError as e:
print("Error while running Docker prune:\n", e.stderr)


##########################################################################
def update_env_with_values(env, fail_on_not_found=False, extra_env=None):
"""
Expand Down
Loading
Loading