Skip to content

Commit a5e0909

Browse files
authored
Azdev Fixes to work with Azure-CLI CI (#36)
* Pin pytest version. * Fix linter to use long or short formats. Remove --ci flag. * Split out version checking from updating setup.py. * Make azdev test run all tests by default. Improve FileNotFound handling. * Fix #14. * CI fixes.
1 parent 8b82b18 commit a5e0909

File tree

10 files changed

+205
-113
lines changed

10 files changed

+205
-113
lines changed

azdev/commands.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ def operation_group(name):
2727

2828
with CommandGroup(self, 'verify', operation_group('pypi')) as g:
2929
g.command('history', 'check_history')
30-
g.command('version', 'verify_versions')
30+
31+
with CommandGroup(self, 'cli', operation_group('pypi')) as g:
32+
g.command('check-versions', 'verify_versions')
33+
g.command('update-setup', 'update_setup_py')
3134

3235
with CommandGroup(self, 'verify', operation_group('help')) as g:
3336
g.command('document-map', 'check_document_map')

azdev/help.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,33 @@
2929
"""
3030

3131

32+
helps['cli'] = """
33+
short-summary: Commands for working with CLI modules.
34+
"""
35+
36+
helps['cli check-versions'] = """
37+
short-summary: Verify package versions against those hosted on PyPI and/or in the azure-cli setup.py file.
38+
long-summary: >
39+
This is used to ensure the correct module versions are bumped prior to release.
40+
examples:
41+
- name: Verify all versions and audit them against azure-cli's setup.py ONLY.
42+
text: azdev cli check-versions
43+
44+
- name: Verify all versions and update azure-cli's setup.py with each module's verison.
45+
text: azdev cli check-versions --update --pin
46+
"""
47+
48+
helps['cli update-setup'] = """
49+
short-summary: Update the azure-cli setup.py file.
50+
examples:
51+
- name: Update azure-cli's setup.py with unpinned module verions.
52+
text: azdev cli update-setup
53+
54+
- name: Update azure-cli's setup.py with pinned module versions.
55+
text: azdev cli update-setup --pin
56+
"""
57+
58+
3259
helps['configure'] = """
3360
short-summary: Configure azdev for use without installing anything.
3461
"""
@@ -80,20 +107,6 @@
80107
"""
81108

82109

83-
helps['verify version'] = """
84-
short-summary: Verify package versions against those hosted on PyPI and/or in the azure-cli setup.py file.
85-
long-summary: >
86-
This is used to ensure the correct module versions are bumped prior to release and that all
87-
module versions are present in the azure-cli setup.py with their versions pinned.
88-
examples:
89-
- name: Verify all versions and audit them against azure-cli's setup.py ONLY.
90-
text: azdev verify version
91-
92-
- name: Verify all versions and update azure-cli's setup.py with each module's verison.
93-
text: azdev verify version --update
94-
"""
95-
96-
97110
helps['style'] = """
98111
short-summary: Check code style (pylint and PEP8).
99112
"""

azdev/operations/linter/__init__.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727

2828
# pylint:disable=too-many-locals
29-
def run_linter(modules=None, rule_types=None, rules=None, ci_mode=False):
29+
def run_linter(modules=None, rule_types=None, rules=None):
3030

3131
require_azure_cli()
3232

@@ -39,12 +39,18 @@ def run_linter(modules=None, rule_types=None, rules=None, ci_mode=False):
3939
# needed to remove helps from azdev
4040
azdev_helps = helps.copy()
4141
exclusions = {}
42-
path_table = get_path_table(include_only=modules)
42+
selected_modules = get_path_table(include_only=modules)
4343

44-
selected_mod_names = list(path_table['mod'].keys()) + list(path_table['core'].keys()) + \
45-
list(path_table['ext'].keys())
46-
selected_mod_paths = list(path_table['mod'].values()) + list(path_table['core'].values()) + \
47-
list(path_table['ext'].values())
44+
if not selected_modules:
45+
raise CLIError('No modules selected.')
46+
47+
selected_mod_names = list(selected_modules['mod'].keys()) + list(selected_modules['core'].keys()) + \
48+
list(selected_modules['ext'].keys())
49+
selected_mod_paths = list(selected_modules['mod'].values()) + list(selected_modules['core'].values()) + \
50+
list(selected_modules['ext'].values())
51+
52+
if selected_mod_names:
53+
display('Modules: {}\n'.format(', '.join(selected_mod_names)))
4854

4955
# collect all rule exclusions
5056
for path in selected_mod_paths:
@@ -99,6 +105,5 @@ def run_linter(modules=None, rule_types=None, rules=None, ci_mode=False):
99105
run_params=not rule_types or 'params' in rule_types,
100106
run_commands=not rule_types or 'commands' in rule_types,
101107
run_command_groups=not rule_types or 'command_groups'in rule_types,
102-
run_help_files_entries=not rule_types or 'help_entries' in rule_types,
103-
ci=ci_mode)
108+
run_help_files_entries=not rule_types or 'help_entries' in rule_types)
104109
sys.exit(exit_code)

azdev/operations/linter/linter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ def exclusions(self):
188188
def exit_code(self):
189189
return self._exit_code
190190

191-
def run(self, run_params=None, run_commands=None, run_command_groups=None, run_help_files_entries=None, ci=False):
192-
self._ci = ci
191+
def run(self, run_params=None, run_commands=None, run_command_groups=None, run_help_files_entries=None):
192+
self._ci = os.environ.get('CI', False)
193193
paths = import_module('{}.rules'.format(PACAKGE_NAME)).__path__
194194

195195
if paths:

azdev/operations/linter/util.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
from knack.log import get_logger
1111

12+
from azdev.utilities import COMMAND_MODULE_PREFIX
13+
1214

1315
logger = get_logger(__name__)
1416

@@ -38,6 +40,7 @@ def exclude_commands(command_loader, help_file_entries, module_exclusions):
3840

3941
def _filter_mods(command_loader, help_file_entries, modules=None, exclude=False):
4042
modules = modules or []
43+
modules = [x.replace(COMMAND_MODULE_PREFIX, '') for x in modules]
4144

4245
# command tables and help entries must be copied to allow for seperate linter scope
4346
command_table = command_loader.command_table.copy()
@@ -64,6 +67,7 @@ def _filter_mods(command_loader, help_file_entries, modules=None, exclude=False)
6467
# Remove unneeded command groups
6568
retained_command_groups = {' '.join(x.split(' ')[:-1]) for x in command_loader.command_table}
6669
excluded_command_groups = set(command_loader.command_group_table.keys()) - retained_command_groups
70+
6771
for group_name in excluded_command_groups:
6872
command_loader.command_group_table.pop(group_name, None)
6973
help_file_entries.pop(group_name, None)

azdev/operations/performance.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,23 @@
1515
logger = get_logger(__name__)
1616

1717
TOTAL = 'ALL'
18+
TOTAL_THRESHOLD = 300
1819
DEFAULT_THRESHOLD = 10
19-
20-
# TODO: Treat everything as bubble instead of specific modules
21-
# explicit thresholds that deviate from the default
2220
THRESHOLDS = {
23-
'network': 30,
24-
'vm': 30,
25-
'batch': 30,
26-
'storage': 50,
27-
TOTAL: 300
21+
# threshold value: num of exceptions allowed
22+
50: 1,
23+
30: 4
2824
}
2925

3026

27+
# pylint: disable=too-many-statements
3128
def check_load_time(runs=3):
3229

3330
require_azure_cli()
3431

3532
heading('Module Load Performance')
3633

37-
regex = r"[^']*'([^']*)'[\D]*([\d\.]*)"
34+
regex = r"[^']*'(?P<mod>[^']*)'[\D]*(?P<val>[\d\.]*)"
3835

3936
results = {TOTAL: []}
4037
# Time the module loading X times
@@ -52,8 +49,8 @@ def check_load_time(runs=3):
5249
for line in lines:
5350
if line.startswith('DEBUG: Loaded module'):
5451
matches = re.match(regex, line)
55-
mod = matches.group(1)
56-
val = float(matches.group(2)) * 1000
52+
mod = matches.group('mod')
53+
val = float(matches.group('val')) * 1000
5754
total_time = total_time + val
5855
if mod in results:
5956
results[mod].append(val)
@@ -64,24 +61,33 @@ def check_load_time(runs=3):
6461
passed_mods = {}
6562
failed_mods = {}
6663

64+
def _claim_higher_threshold(val):
65+
avail_thresholds = {k: v for k, v in THRESHOLDS.items() if v}
66+
new_threshold = None
67+
for threshold in sorted(avail_thresholds):
68+
if val < threshold:
69+
THRESHOLDS[threshold] = THRESHOLDS[threshold] - 1
70+
new_threshold = threshold
71+
break
72+
return new_threshold
73+
6774
mods = sorted(results.keys())
68-
bubble_found = False
6975
for mod in mods:
7076
val = results[mod]
7177
mean_val = mean(val)
7278
stdev_val = pstdev(val)
73-
threshold = THRESHOLDS.get(mod) or DEFAULT_THRESHOLD
79+
threshold = TOTAL_THRESHOLD if mod == TOTAL else DEFAULT_THRESHOLD
7480
statistics = {
7581
'average': mean_val,
7682
'stdev': stdev_val,
7783
'threshold': threshold,
7884
'values': val
7985
}
8086
if mean_val > threshold:
81-
if not bubble_found and mean_val < 30:
82-
# This temporary measure allows one floating performance
83-
# failure up to 30 ms. See issue #6224 and #6218.
84-
bubble_found = True
87+
# claim a threshold exception if available
88+
new_threshold = _claim_higher_threshold(mean_val)
89+
if new_threshold:
90+
statistics['threshold'] = new_threshold
8591
passed_mods[mod] = statistics
8692
else:
8793
failed_mods[mod] = statistics

0 commit comments

Comments
 (0)