Repository: RedHatInsights/insights-core

Issue:
YumRepolist parser throws an exception parsing valid repolist data
The [YumRepolist parser](https://github.com/RedHatInsights/insights-core/blob/master/insights/parsers/yum.py) throws an exception when attempting to parse valid output:

```
$ insights inspect insights.combiners.cloud_provider.CloudProvider archive
Traceback (most recent call last):
  File "/home/bfahr/work/insights/insights-core/insights/core/dr.py", line 962, in run
    result = DELEGATES[component].process(broker)
  File "/home/bfahr/work/insights/insights-core/insights/core/dr.py", line 681, in process
    return self.invoke(broker)
  File "/home/bfahr/work/insights/insights-core/insights/core/plugins.py", line 130, in invoke
    return self.component(dep_value)
  File "/home/bfahr/work/insights/insights-core/insights/core/__init__.py", line 598, in __init__
    super(CommandParser, self).__init__(context)
  File "/home/bfahr/work/insights/insights-core/insights/core/__init__.py", line 92, in __init__
    self._handle_content(context)
  File "/home/bfahr/work/insights/insights-core/insights/core/__init__.py", line 95, in _handle_content
    self.parse_content(context.content)
  File "/home/bfahr/work/insights/insights-core/insights/parsers/yum.py", line 145, in parse_content
    empty_exception=True)
  File "/home/bfahr/work/insights/insights-core/insights/parsers/__init__.py", line 342, in parse_fixed_table
    first_line = calc_offset(table_lines, heading_ignore)
  File "/home/bfahr/work/insights/insights-core/insights/parsers/__init__.py", line 276, in calc_offset
    raise ValueError("Line containing '{}' was not found in table".format(','.join(target)))
ValueError: Line containing 'repo id' was not found in table
```

Caused by output of `yum -C --noplugins repolist` having the output:

```
repolist: 0
```


Discussion:

Resolving patch:
diff --git a/insights/parsers/yum.py b/insights/parsers/yum.py
--- a/insights/parsers/yum.py
+++ b/insights/parsers/yum.py
@@ -11,7 +11,7 @@
 """
 
 from insights import parser, CommandParser
-from insights.parsers import SkipException, parse_fixed_table
+from insights.parsers import SkipException, parse_fixed_table, ParseException
 from insights.specs import Specs
 
 eus = [
@@ -127,6 +127,9 @@ def parse_content(self, content):
         if not content:
             raise SkipException('No repolist.')
 
+        if content[0].startswith('repolist:'):
+            raise SkipException('No repolist.')
+
         trailing_line_prefix = [
                 'repolist:',
                 'Uploading Enabled',
@@ -137,12 +140,16 @@ def parse_content(self, content):
 
         self.data = []
         self.repos = {}
-        self.data = parse_fixed_table(
-                content,
-                heading_ignore=['repo id'],
-                header_substitute=[('repo id', 'id     '), ('repo name', 'name     ')],
-                trailing_ignore=trailing_line_prefix,
-                empty_exception=True)
+        try:
+            self.data = parse_fixed_table(
+                    content,
+                    heading_ignore=['repo id'],
+                    header_substitute=[('repo id', 'id     '), ('repo name', 'name     ')],
+                    trailing_ignore=trailing_line_prefix,
+                    empty_exception=True)
+        except ValueError as e:
+            # ValueError raised by parse_fixed_table
+            raise ParseException('Failed to parser yum repolist: {0}'.format(str(e)))
 
         if not self.data:
             raise SkipException('No repolist.')


Test patch:
diff --git a/insights/parsers/tests/test_yum_repolist.py b/insights/parsers/tests/test_yum_repolist.py
--- a/insights/parsers/tests/test_yum_repolist.py
+++ b/insights/parsers/tests/test_yum_repolist.py
@@ -133,6 +133,16 @@
 repolist: 58096
 """.strip()
 
+# This output occurred in Bugzilla 1929384
+YUM_REPOLIST_ZERO = """
+repolist: 0
+""".strip()
+
+YUM_REPOLIST_MISSING_HEADER = """
+Loaded plugins: product-id, rhnplugin, security, subscription-manager
+Updating certificate-based repositories.
+"""
+
 
 def test_yum_repolist():
     repo_list = YumRepoList(context_wrap(YUM_REPOLIST_CONTENT))
@@ -234,3 +244,15 @@ def test_repos_without_ends():
     repo_list = YumRepoList(context_wrap(YUM_REPOLIST_CONTENT_MISSING_END))
     assert 1 == len(repo_list)
     assert 0 == len(repo_list.rhel_repos)
+
+
+def test_repolist_zero():
+    with pytest.raises(SkipException) as se:
+        YumRepoList(context_wrap(YUM_REPOLIST_ZERO))
+    assert 'No repolist.' in str(se)
+
+
+def test_repolist_missing_header():
+    with pytest.raises(ParseException) as se:
+        YumRepoList(context_wrap(YUM_REPOLIST_MISSING_HEADER))
+    assert 'Failed to parser yum repolist' in str(se)