Merge lp:~javier.collado/utah/bug1178367 into lp:utah

Proposed by Javier Collado
Status: Merged
Merged at revision: 904
Proposed branch: lp:~javier.collado/utah/bug1178367
Merge into: lp:utah
Diff against target: 680 lines (+78/-348)
6 files modified
debian/changelog (+2/-0)
debian/control (+1/-9)
debian/rules (+1/-9)
examples/run_utah_tests.py (+2/-108)
tests/test_parser.py (+72/-0)
utah/parser.py (+0/-222)
To merge this branch: bzr merge lp:~javier.collado/utah/bug1178367
Reviewer Review Type Date Requested Status
Andy Doan (community) Approve
Review via email: mp+163339@code.launchpad.net

Description of the change

This branch fixes the parsing of the gigabytes option and adds a few test cases
to verify this.

Besides this, the `utah.parser` module and the `utah-parser` package are
removed since they aren't used anymore. The `utah.parser` module is now used to
have there the parser for the utah server script since that makes unit testing
easier.

To post a comment you must log in.
Revision history for this message
Andy Doan (doanac) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2013-05-09 23:36:07 +0000
3+++ debian/changelog 2013-05-10 16:56:25 +0000
4@@ -8,6 +8,8 @@
5 * Apply retry strategy to install UTAH client package (LP: #1175732)
6 * Added phoenix manpage (LP: #1067704)
7 * Apply all overrides in tslist.run to the test cases (LP: #1178238)
8+ * Set disksizes default directly instead of via argparse (LP:
9+ #1178367)
10
11 -- Javier Collado <javier.collado@canonical.com> Tue, 07 May 2013 16:06:48 +0200
12
13
14=== modified file 'debian/control'
15--- debian/control 2013-05-08 14:45:47 +0000
16+++ debian/control 2013-05-10 16:56:25 +0000
17@@ -23,8 +23,7 @@
18
19 Package: utah-all
20 Architecture: all
21-Depends: ${misc:Depends}, ${python:Depends}, utah-bamboofeeder, utah-cobbler,
22- utah-parser
23+Depends: ${misc:Depends}, ${python:Depends}, utah-bamboofeeder, utah-cobbler
24 Description: Ubuntu Test Automation Harness Complete Package
25 Automation framework for testing in Ubuntu, all sections
26
27@@ -59,10 +58,3 @@
28 Depends: ${misc:Depends}, ${python:Depends}
29 Description: Ubuntu Test Automation Harness Common Files
30 Automation framework for testing in Ubuntu, common files
31-
32-Package: utah-parser
33-Architecture: all
34-Depends: ${misc:Depends}, ${python:Depends},
35- python-jsonschema (>= 1.3~), python-yaml, utah-common
36-Description: Ubuntu Test Automation Harness Parser
37- Automation framework for testing in Ubuntu, result parser
38
39=== modified file 'debian/rules'
40--- debian/rules 2013-05-08 13:28:00 +0000
41+++ debian/rules 2013-05-10 16:56:25 +0000
42@@ -34,18 +34,14 @@
43
44 override_dh_auto_install:
45 # utah and utah-client both live in the utah directory
46- # utah-parser lives in that tree as well
47 # utah should only install the provisioning subdirectory, and utah-client should install everything else
48- # except parser.py, which is now its own package
49- # and __init__.py, which is now in the common package
50+ # except __init__.py, which is now in the common package
51 # The baremetal subdirectory in the provisioning directory is now 3 packages
52 # If we just use dh_auto_install, all packages will get everything
53 # We start by building the whole thing
54 set -e && for pyvers in $(PYVERS); do python$$pyvers setup.py install --install-layout=deb --root=$(CURDIR); done
55 # Next, we move the built provisioning directory aside for later use
56 mv build/*/utah/provisioning .
57- # Same with parser.py
58- mv build/*/utah/parser.py .
59 # And __init__.py
60 mv build/*/utah/__init__.py .
61 # Now we install into the utah-client directory, since provisioning is removed, using --skip-build to not rebuild it
62@@ -58,10 +54,6 @@
63 mv build/*/utah/provisioning/baremetal .
64 # Now we install just the provisioning directory, again using --skip-build into the utah package tree
65 set -e && for pyvers in $(PYVERS); do python$$pyvers setup.py install --skip-build --install-layout=deb --root=$(CURDIR)/debian/utah; done
66- # And now we put back the parser and install that
67- rm -r build/*/utah/*
68- mv parser.py build/*/utah
69- set -e && for pyvers in $(PYVERS); do python$$pyvers setup.py install --skip-build --install-layout=deb --root=$(CURDIR)/debian/utah-parser; done
70 # And now we put back the init file and install that
71 rm -r build/*/utah/*
72 mv __init__.py build/*/utah
73
74=== modified file 'examples/run_utah_tests.py'
75--- examples/run_utah_tests.py 2013-05-01 23:57:13 +0000
76+++ examples/run_utah_tests.py 2013-05-10 16:56:25 +0000
77@@ -17,8 +17,6 @@
78
79 """Provision a machine a run a test."""
80
81-
82-import argparse
83 import logging
84 import os
85 import sys
86@@ -31,16 +29,15 @@
87 from utah.cleanup import cleanup
88 from utah.exceptions import UTAHException
89 from utah.group import check_user_group, print_group_error_message
90+from utah.parser import get_parser, parse_args # NOQA
91 from utah.provisioning.ssh import ProvisionedMachine
92 from utah.provisioning.vm import TinySQLiteInventory
93 from utah.run import (
94 configure_logging,
95- master_runlist_argument,
96 run_tests,
97 ReturnCodes,
98 )
99 from utah.timeout import timeout, UTAHTimeout
100-from utah.url import url_argument
101
102
103 MISSING = []
104@@ -59,108 +56,6 @@
105 MISSING.append('baremetal')
106
107
108-def get_parser():
109- parser = argparse.ArgumentParser(
110- description=('Provision a machine '
111- 'and run one or more UTAH runlists there.\n\n'
112- 'The appropriate run_*.py script will be called, '
113- 'depending on the parameters passed.'),
114- epilog=("For example:\n"
115- "Provision a VM using a precise server image "
116- "with i386 architecture and run the given runlist\n"
117- "\t%(prog)s -s precise -t server -a i386 \\\n"
118- "\t\t/usr/share/utah/client/examples/master.run"),
119- formatter_class=argparse.RawDescriptionHelpFormatter)
120- parser.add_argument('-m', '--machinetype', metavar='MACHINETYPE',
121- choices=('physical', 'virtual'),
122- default=config.machinetype,
123- help='Type of machine to provision (%(choices)s) '
124- '(Default is %(default)s)')
125- parser.add_argument('-v', '--variant',
126- default=config.variant,
127- help='Variant of architecture, i.e., armel, armhf')
128- parser.add_argument('--skip-provisioning', action='store_true',
129- help='Reuse a system that is already provisioned '
130- '(name argument must be passed)')
131- parser.add_argument('runlist', metavar='runlist',
132- type=master_runlist_argument,
133- help='URLs of runlist files to run')
134- parser.add_argument('-s', '--series', metavar='SERIES',
135- choices=config.serieschoices,
136- default=config.series,
137- help='Series to use for installation (%(choices)s) '
138- '(Default is %(default)s)')
139- parser.add_argument('-t', '--type', metavar='TYPE',
140- choices=('desktop', 'server', 'mini', 'alternate'),
141- default=config.installtype,
142- help='Install type to use for installation '
143- '(%(choices)s) (Default is %(default)s)')
144- parser.add_argument('-a', '--arch', metavar='ARCH',
145- choices=('i386', 'amd64', 'arm'),
146- default=config.arch,
147- help='Architecture to use for installation '
148- '(%(choices)s) (Default is %(default)s)')
149- parser.add_argument('-n', '--no-destroy', action='store_true',
150- help='Preserve VM after tests have run')
151- parser.add_argument('-d', '--debug', action='store_true',
152- help='Enable debug logging')
153- parser.add_argument('-j', '--json', action='store_true',
154- help='Enable json logging (default is YAML)')
155- parser.add_argument('-f', '--files', action='append',
156- help='File or directory to copy from test system ')
157- parser.add_argument('-o', '--outdir',
158- help=('Directory to store locally copied files '
159- '(Default is {}/machine-name)'
160- .format(config.logpath)))
161- parser.add_argument('--dumplogs', action='store_true',
162- help='Write client output logs to standard out')
163- parser.add_argument('--outputpreseed', action='store_true',
164- help='Copy preseed to logs directory and list as '
165- 'log file in output')
166- parser.add_argument('-i', '--image', type=url_argument,
167- default=config.image,
168- help='Image/ISO file to use for installation')
169- parser.add_argument('-p', '--preseed', type=url_argument,
170- default=config.preseed,
171- help='Preseed file to use for installation')
172- parser.add_argument('-b', '--boot',
173- default=config.boot,
174- help='Boot arguments for initial installation')
175- parser.add_argument('--rewrite',
176- choices=('all', 'minimal', 'casperonly', 'none'),
177- default=config.rewrite,
178- help='Set level of automatic configuration rewriting '
179- '(Default is %(default)s)')
180- parser.add_argument('-k', '--kernel', type=url_argument,
181- default=config.kernel,
182- help='Kernel file to use for installation')
183- parser.add_argument('-r', '--initrd', type=url_argument,
184- default=config.initrd,
185- help='InitRD file to use for installation')
186- parser.add_argument('--name',
187- default=config.name,
188- help='Name of machine to provision')
189- parser.add_argument('-e', '--emulator',
190- default=config.emulator,
191- help='Emulator to use (kvm and qemu are supported, '
192- 'kvm will be favored if available)')
193- parser.add_argument('-x', '--xml', type=url_argument,
194- default=config.xml,
195- help='XML VM definition file '
196- '(Default is %(default)s)')
197- parser.add_argument('-g', '--gigabytes', action='append',
198- default=config.disksizes,
199- help='Size in gigabytes of virtual disk, '
200- 'specify more than once for multiple disks '
201- '(Default is %(default)s)')
202- parser.add_argument('--diskbus', metavar='DISKBUS',
203- choices=('virtio', 'sata', 'ide'),
204- default=config.diskbus,
205- help='Disk bus to use for customvm installation '
206- '(%(choices)s) (Default is %(default)s)')
207- return parser
208-
209-
210 def _get_machine(args):
211 if args.skip_provisioning:
212 # TBD: Inventory should be used to verify machine
213@@ -210,8 +105,7 @@
214
215
216 def run_utah_tests(args=None):
217- if args is None:
218- args = get_parser().parse_args()
219+ args = parse_args()
220
221 if not check_user_group():
222 print_group_error_message(__file__)
223
224=== added file 'tests/test_parser.py'
225--- tests/test_parser.py 1970-01-01 00:00:00 +0000
226+++ tests/test_parser.py 2013-05-10 16:56:25 +0000
227@@ -0,0 +1,72 @@
228+# Ubuntu Testing Automation Harness
229+# Copyright 2013 Canonical Ltd.
230+
231+# This program is free software: you can redistribute it and/or modify it
232+# under the terms of the GNU General Public License version 3, as published
233+# by the Free Software Foundation.
234+
235+# This program is distributed in the hope that it will be useful, but
236+# WITHOUT ANY WARRANTY; without even the implied warranties of
237+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
238+# PURPOSE. See the GNU General Public License for more details.
239+
240+# You should have received a copy of the GNU General Public License along
241+# with this program. If not, see <http://www.gnu.org/licenses/>.
242+
243+"""Unit tests for the utah.parser module."""
244+
245+import unittest
246+
247+from mock import patch, DEFAULT
248+
249+from utah import config
250+from utah.parser import parse_args
251+
252+
253+class TestParser(unittest.TestCase):
254+
255+ """Tests that command line parsing works as expected."""
256+
257+ def parse_args_wrapper(self, argv):
258+ """A wrapper to ensure that runlist argument passes validation.
259+
260+ :param argv: Command line arguments to be tested
261+ :type argv: list
262+ :returns: Parse arguments
263+ :rtype: `argparse.Namespace`
264+
265+ """
266+ with patch.multiple('utah.run',
267+ url_argument=DEFAULT,
268+ parse_yaml_file=DEFAULT) as patches:
269+ patches['url_argument'].return_value = '<local_runlist_file>'
270+ patches['parse_yaml_file'].return_value = {
271+ 'testsuites': [
272+ {'name': 'test_suite_name',
273+ 'fetch_method': 'dev',
274+ 'fetch_location': '<fetch_location>',
275+ },
276+ ]
277+ }
278+ return parse_args(argv)
279+
280+ def test_gigabytes_default(self):
281+ """Verify that gigabytes is set to default value if not passed."""
282+ args = self.parse_args_wrapper(['<runlist_file>'])
283+ self.assertEqual(args.gigabytes, config.disksizes)
284+
285+ def test_gigabytes_one_argument(self):
286+ """Verify that gigabytes is set to the argument passed."""
287+ gigabytes = '3'
288+ args = self.parse_args_wrapper(['--gigabytes', gigabytes,
289+ '<runlist_file>'])
290+ self.assertEqual(args.gigabytes, [gigabytes])
291+
292+ def test_gigabytes_multiple_arguments(self):
293+ """Verify that gigabytes is set to the arguments passed."""
294+ gigabytes = ['3', '5', '7']
295+ args = self.parse_args_wrapper(['--gigabytes', gigabytes[0],
296+ '--gigabytes', gigabytes[1],
297+ '--gigabytes', gigabytes[2],
298+ '<runlist_file>'])
299+ self.assertEqual(args.gigabytes, gigabytes)
300
301=== added file 'utah/parser.py'
302--- utah/parser.py 1970-01-01 00:00:00 +0000
303+++ utah/parser.py 2013-05-10 16:56:25 +0000
304@@ -0,0 +1,149 @@
305+# Ubuntu Testing Automation Harness
306+# Copyright 2012 Canonical Ltd.
307+
308+# This program is free software: you can redistribute it and/or modify it
309+# under the terms of the GNU General Public License version 3, as published
310+# by the Free Software Foundation.
311+
312+# This program is distributed in the hope that it will be useful, but
313+# WITHOUT ANY WARRANTY; without even the implied warranties of
314+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
315+# PURPOSE. See the GNU General Public License for more details.
316+
317+# You should have received a copy of the GNU General Public License along
318+# with this program. If not, see <http://www.gnu.org/licenses/>.
319+
320+"""Command line parser for the utah server script."""
321+
322+import argparse
323+import sys
324+
325+from utah import config
326+from utah.run import master_runlist_argument
327+from utah.url import url_argument
328+
329+
330+def parse_args(argv=None):
331+ """Parse command line arguments.
332+
333+ :param argv: Command line arguments to be parsed
334+ :type argv: list
335+ :returns: Parse arguments
336+ :rtype: `argparse.Namespace`
337+
338+ """
339+
340+ if argv is None:
341+ argv = sys.argv[1:]
342+
343+ args = get_parser().parse_args(argv)
344+ if args.gigabytes is None:
345+ args.gigabytes = config.disksizes
346+ return args
347+
348+
349+def get_parser():
350+ """Get command line parser.
351+
352+ :returns: Parser object
353+ :rtype: `argparse.ArgumentParser`
354+
355+ """
356+ parser = argparse.ArgumentParser(
357+ description=('Provision a machine '
358+ 'and run one or more UTAH runlists there.\n\n'
359+ 'The appropriate run_*.py script will be called, '
360+ 'depending on the parameters passed.'),
361+ epilog=("For example:\n"
362+ "Provision a VM using a precise server image "
363+ "with i386 architecture and run the given runlist\n"
364+ "\t%(prog)s -s precise -t server -a i386 \\\n"
365+ "\t\t/usr/share/utah/client/examples/master.run"),
366+ formatter_class=argparse.RawDescriptionHelpFormatter)
367+ parser.add_argument('-m', '--machinetype', metavar='MACHINETYPE',
368+ choices=('physical', 'virtual'),
369+ default=config.machinetype,
370+ help='Type of machine to provision (%(choices)s) '
371+ '(Default is %(default)s)')
372+ parser.add_argument('-v', '--variant',
373+ default=config.variant,
374+ help='Variant of architecture, i.e., armel, armhf')
375+ parser.add_argument('--skip-provisioning', action='store_true',
376+ help='Reuse a system that is already provisioned '
377+ '(name argument must be passed)')
378+ parser.add_argument('runlist', metavar='runlist',
379+ type=master_runlist_argument,
380+ help='URLs of runlist files to run')
381+ parser.add_argument('-s', '--series', metavar='SERIES',
382+ choices=config.serieschoices,
383+ default=config.series,
384+ help='Series to use for installation (%(choices)s) '
385+ '(Default is %(default)s)')
386+ parser.add_argument('-t', '--type', metavar='TYPE',
387+ choices=('desktop', 'server', 'mini', 'alternate'),
388+ default=config.installtype,
389+ help='Install type to use for installation '
390+ '(%(choices)s) (Default is %(default)s)')
391+ parser.add_argument('-a', '--arch', metavar='ARCH',
392+ choices=('i386', 'amd64', 'arm'),
393+ default=config.arch,
394+ help='Architecture to use for installation '
395+ '(%(choices)s) (Default is %(default)s)')
396+ parser.add_argument('-n', '--no-destroy', action='store_true',
397+ help='Preserve VM after tests have run')
398+ parser.add_argument('-d', '--debug', action='store_true',
399+ help='Enable debug logging')
400+ parser.add_argument('-j', '--json', action='store_true',
401+ help='Enable json logging (default is YAML)')
402+ parser.add_argument('-f', '--files', action='append',
403+ help='File or directory to copy from test system ')
404+ parser.add_argument('-o', '--outdir',
405+ help=('Directory to store locally copied files '
406+ '(Default is {}/machine-name)'
407+ .format(config.logpath)))
408+ parser.add_argument('--dumplogs', action='store_true',
409+ help='Write client output logs to standard out')
410+ parser.add_argument('--outputpreseed', action='store_true',
411+ help='Copy preseed to logs directory and list as '
412+ 'log file in output')
413+ parser.add_argument('-i', '--image', type=url_argument,
414+ default=config.image,
415+ help='Image/ISO file to use for installation')
416+ parser.add_argument('-p', '--preseed', type=url_argument,
417+ default=config.preseed,
418+ help='Preseed file to use for installation')
419+ parser.add_argument('-b', '--boot',
420+ default=config.boot,
421+ help='Boot arguments for initial installation')
422+ parser.add_argument('--rewrite',
423+ choices=('all', 'minimal', 'casperonly', 'none'),
424+ default=config.rewrite,
425+ help='Set level of automatic configuration rewriting '
426+ '(Default is %(default)s)')
427+ parser.add_argument('-k', '--kernel', type=url_argument,
428+ default=config.kernel,
429+ help='Kernel file to use for installation')
430+ parser.add_argument('-r', '--initrd', type=url_argument,
431+ default=config.initrd,
432+ help='InitRD file to use for installation')
433+ parser.add_argument('--name',
434+ default=config.name,
435+ help='Name of machine to provision')
436+ parser.add_argument('-e', '--emulator',
437+ default=config.emulator,
438+ help='Emulator to use (kvm and qemu are supported, '
439+ 'kvm will be favored if available)')
440+ parser.add_argument('-x', '--xml', type=url_argument,
441+ default=config.xml,
442+ help='XML VM definition file '
443+ '(Default is %(default)s)')
444+ parser.add_argument('-g', '--gigabytes', action='append',
445+ help='Size in gigabytes of virtual disk, '
446+ 'specify more than once for multiple disks '
447+ '(Default is {})'.format(config.disksizes))
448+ parser.add_argument('--diskbus', metavar='DISKBUS',
449+ choices=('virtio', 'sata', 'ide'),
450+ default=config.diskbus,
451+ help='Disk bus to use for customvm installation '
452+ '(%(choices)s) (Default is %(default)s)')
453+ return parser
454
455=== removed file 'utah/parser.py'
456--- utah/parser.py 2013-04-03 21:17:26 +0000
457+++ utah/parser.py 1970-01-01 00:00:00 +0000
458@@ -1,222 +0,0 @@
459-# Ubuntu Testing Automation Harness
460-# Copyright 2012 Canonical Ltd.
461-
462-# This program is free software: you can redistribute it and/or modify it
463-# under the terms of the GNU General Public License version 3, as published
464-# by the Free Software Foundation.
465-
466-# This program is distributed in the hope that it will be useful, but
467-# WITHOUT ANY WARRANTY; without even the implied warranties of
468-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
469-# PURPOSE. See the GNU General Public License for more details.
470-
471-# You should have received a copy of the GNU General Public License along
472-# with this program. If not, see <http://www.gnu.org/licenses/>.
473-
474-"""UTAH Client log parser."""
475-
476-
477-import argparse
478-import jsonschema
479-import logging
480-import urllib2
481-import yaml
482-
483-
484-class ParserError(Exception):
485-
486- """Module level parse error exception."""
487-
488- pass
489-
490-
491-class UTAHParser(object):
492-
493- """UTAH Client result parser class."""
494-
495- COMMAND_SCHEMA = {
496- 'type': 'object',
497- 'properties': {
498- 'cmd_type': {'type': 'string'},
499- 'command': {'type': 'string'},
500- 'returncode': {'type': 'integer'},
501- 'start_time': {'type': 'string'},
502- 'stderr': {'type': 'string'},
503- 'stdout': {'type': 'string'},
504- 'testcase': {'type': 'string'},
505- 'testsuite': {'type': 'string'},
506- 'time_delta': {'type': 'string'},
507- 'user': {'type': 'string'},
508- },
509- }
510-
511- CLIENT_OUTPUT_SCHEMA = {
512- 'type': 'object',
513- 'properties': {
514- 'runlist': {
515- 'type': 'string',
516- 'required': True,
517- },
518- 'ran_at': {
519- 'type': 'string',
520- 'required': True,
521- },
522- 'commands': {
523- 'type': 'array',
524- 'items': {'type': COMMAND_SCHEMA},
525- 'required': True,
526- },
527- 'fetch_errors': {
528- 'type': 'integer',
529- 'required': True,
530- },
531- 'errors': {
532- 'type': 'integer',
533- 'required': True,
534- },
535- 'failures': {
536- 'type': 'integer',
537- 'required': True,
538- },
539- 'passes': {
540- 'type': 'integer',
541- 'required': True,
542- },
543- 'uname': {
544- 'type': 'array',
545- 'items': {'type': 'string'},
546- 'required': True,
547- },
548- 'media-info': {
549- 'type': 'string',
550- 'required': True,
551- },
552- 'install_type': {
553- 'type': 'string',
554- 'required': True,
555- },
556- 'arch': {
557- 'type': 'string',
558- 'required': True,
559- },
560- 'release': {
561- 'type': 'string',
562- 'required': True,
563- },
564- 'build_number': {
565- 'type': 'string',
566- 'required': True,
567- },
568- },
569- }
570-
571- def parse(self, logdata, as_string=False):
572- """Parse utah client results.
573-
574- :param logdata:
575- should be either a filename or a handle to a file object.
576-
577- :returns: the parsed yaml data or None.
578-
579- :raises: ParserError on exceptions.
580-
581- """
582-
583- if as_string:
584- return self._parse_string(logdata)
585- elif isinstance(logdata, str):
586- return self._parse_logfile(logdata)
587- else:
588- return self._parse_stream(logdata)
589-
590- def _parse_stream(self, stream):
591- """Parse client output from stream.
592-
593- :returns: validated decoded YAML data.
594-
595- :raises: ParseError
596-
597- """
598- try:
599- data = yaml.load(stream)
600- except yaml.YAMLError as e:
601- logging.error(e)
602- raise ParserError(e.message)
603-
604- # Allow empty yaml files
605- if data is None:
606- return data
607-
608- try:
609- jsonschema.validate(data, self.CLIENT_OUTPUT_SCHEMA)
610- except jsonschema.ValidationError as e:
611- logging.error(e)
612- raise ParserError(e.message)
613-
614- return data
615-
616- def _parse_logfile(self, logfile):
617- """Parse client output log.
618-
619- :returns: validated decoded YAML data.
620-
621- :raises: ParseError
622-
623- """
624- data = None
625-
626- if logfile.startswith('http'):
627- try:
628- fp = urllib2.urlopen(logfile)
629- except IOError as err:
630- raise ParserError(
631- 'IOError when downloading {}: {}'
632- .format(logfile, err))
633- except urllib2.ContentTooShortError as err:
634- raise ParserError(
635- 'Error when downloading {} (probably interrupted): {}'
636- .format(logfile, err))
637- data = self._parse_stream(fp)
638- else:
639- with open(logfile, 'r') as fp:
640- data = self._parse_stream(fp)
641-
642- return data
643-
644- def _parse_string(self, log_data):
645- """Parse client data from a string.
646-
647- :returns: validated decoded YAML data.
648-
649- :raises: ParseError
650-
651- """
652- try:
653- data = yaml.load(log_data)
654-
655- # Allow empty yaml files
656- if data is None:
657- return data
658- except yaml.YAMLError as e:
659- logging.error(e)
660- raise ParserError(e.message)
661-
662- try:
663- jsonschema.validate(data, self.CLIENT_OUTPUT_SCHEMA)
664- except jsonschema.ValidationError as e:
665- logging.error(e)
666- raise ParserError(e.message)
667-
668- return data
669-
670-
671-if __name__ == "__main__":
672- arg_parser = argparse.ArgumentParser(description='phoenix bootstrapper')
673- arg_parser.add_argument('logfile', metavar='LOGFILE', type=str,
674- help='log file to parse')
675-
676- args = arg_parser.parse_args()
677-
678- parser = UTAHParser()
679- data = parser.parse(args.logfile)
680- print(data)

Subscribers

People subscribed via source and target branches