Repository: amwa-tv/nmos-testing
Issue: KeyError in IS0502 test for park resource test

Line 604 of park_resource in IS05_Utils, when a response fails to include the 'transport_params' key in its response.

May indicate a need for a more general catching of KeyErrors to ensure a 'FAIL' is presented rather than a traceback.

```
 * Running test_07_rx_nmos_updates_sub
 * ERROR: 'transport_params'
192.168.200.24 - - [15/Jan/2019 14:30:35] "POST / HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.5/dist-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.5/dist-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/ipstudio-admin/nmos-testing/nmos-test.py", line 218, in index_page
    raise ex
  File "/home/ipstudio-admin/nmos-testing/nmos-test.py", line 215, in index_page
    result = test_obj.run_tests(test_selection)
  File "/home/ipstudio-admin/nmos-testing/GenericTest.py", line 133, in run_tests
    self.execute_tests(test_name)
  File "/home/ipstudio-admin/nmos-testing/GenericTest.py", line 101, in execute_tests
    self.result.append(method())
  File "/home/ipstudio-admin/nmos-testing/IS0502Test.py", line 401, in test_07_rx_nmos_updates_sub
    valid, response = self.activate_check_parked(resource_type)
  File "/home/ipstudio-admin/nmos-testing/IS0502Test.py", line 161, in activate_check_parked
    valid, response = self.is05_utils.park_resource(resource_type, is05_resource)
  File "/home/ipstudio-admin/nmos-testing/IS05Utils.py", line 604, in park_resource
    staged_params = response['transport_params']
KeyError: 'transport_params'

```

Changed files:
GenericTest.py, IS05Utils.py

diff --git a/GenericTest.py b/GenericTest.py
index 899fd38..101a30a 100644
--- a/GenericTest.py
+++ b/GenericTest.py
@@ -17,6 +17,7 @@ import json
 import git
 import jsonschema
 import TestHelper
+import traceback
 
 from Specification import Specification
 from TestResult import Test
@@ -101,6 +102,8 @@ class GenericTest(object):
                             self.result.append(method())
                         except NMOSTestException as e:
                             self.result.append(e.args[0])
+                        except Exception as e:
+                            self.result.append(self.uncaught_exception(method_name, e))
 
         # Run a single test
         if test_name != "auto" and test_name != "all":
@@ -111,6 +114,15 @@ class GenericTest(object):
                     self.result.append(method())
                 except NMOSTestException as e:
                     self.result.append(e.args[0])
+                except Exception as e:
+                    self.result.append(self.uncaught_exception(test_name, e))
+
+    def uncaught_exception(self, test_name, exception):
+        """Print a traceback and provide a test FAIL result for uncaught exceptions"""
+        traceback.print_exc()
+        test = Test("Error executing {}".format(test_name))
+        return test.FAIL("Uncaught exception. Please report the traceback from the terminal to "
+                         "https://github.com/amwa-tv/nmos-testing/issues. {}".format(exception))
 
     def set_up_tests(self):
         """Called before a set of tests is run. Override this method with setup code."""
diff --git a/IS05Utils.py b/IS05Utils.py
index c3e5142..03d3301 100644
--- a/IS05Utils.py
+++ b/IS05Utils.py
@@ -601,7 +601,10 @@ class IS05Utils(NMOSUtils):
         data = {"master_enable": False}
         valid, response = self.checkCleanRequestJSON("PATCH", url, data=data)
         if valid:
-            staged_params = response['transport_params']
+            try:
+                staged_params = response['transport_params']
+            except KeyError:
+                return False, "Staged resource did not return 'transport_params' in PATCH response"
             valid2, response2 = self.check_perform_immediate_activation(resource_type.rstrip("s"),
                                                                         resource_id,
                                                                         staged_params)