log reserved resources

On non-debug log level, show something like this at the beginning of
each suite:

 03:45:49.439720 tst handover:sysmo+secondbts-trx-b200: RESERVED RESOURCES for handover:
 bts
   sysmoBTS 1002
   Ettus B200
 ip_address
   10.42.42.2
   10.42.42.3
   10.42.42.4
   10.42.42.5
   10.42.42.6
   10.42.42.7
 modem
   sierra_1st
   sierra_2nd

Change-Id: Ic23556eafee654c93d13c5ef405028da09bd51d7
diff --git a/selftest/suite_test/suite_test.ok b/selftest/suite_test/suite_test.ok
index 9d0493d..dfc8d41 100644
--- a/selftest/suite_test/suite_test.ok
+++ b/selftest/suite_test/suite_test.ok
@@ -145,6 +145,16 @@
   label: m7802
   path: /wavecom_1
 tst test_suite: DBG: FileWatch: unscheduling watch <ObservedWatch: path=[PATH]/selftest/suite_test/test_work/state_dir, is_recursive=False>
+tst test_suite: RESERVED RESOURCES for test_suite:
+bts
+  sysmoCell 5000
+  sysmoCell 5000
+  sysmoBTS 1002
+ip_address
+  10.42.42.1
+modem
+  m7801
+  m7802
 
 ----------------------------------------------
 trial test_suite hello_world.py
@@ -364,6 +374,16 @@
   path: /wavecom_1
   [resource.py:[LINENR]]
 tst test_suite: DBG: FileWatch: unscheduling watch <ObservedWatch: path=[PATH]/selftest/suite_test/test_work/state_dir, is_recursive=False>  [util.py:[LINENR]]
+tst test_suite: RESERVED RESOURCES for test_suite:
+bts
+  sysmoCell 5000
+  sysmoCell 5000
+  sysmoBTS 1002
+ip_address
+  10.42.42.1
+modem
+  m7801
+  m7802  [suite.py:[LINENR]]
 
 ----------------------------------------------
 trial test_suite hello_world.py
@@ -509,6 +529,16 @@
   path: /wavecom_1
   [resource.py:[LINENR]]
 tst test_suite: DBG: FileWatch: unscheduling watch <ObservedWatch: path=[PATH]/selftest/suite_test/test_work/state_dir, is_recursive=False>  [util.py:[LINENR]]
+tst test_suite: RESERVED RESOURCES for test_suite:
+bts
+  sysmoCell 5000
+  sysmoCell 5000
+  sysmoBTS 1002
+ip_address
+  10.42.42.1
+modem
+  m7801
+  m7802  [suite.py:[LINENR]]
 
 ----------------------------------------------
 trial test_suite hello_world.py
@@ -650,6 +680,16 @@
   path: /wavecom_1
   [resource.py:[LINENR]]
 tst test_suite: DBG: FileWatch: unscheduling watch <ObservedWatch: path=[PATH]/selftest/suite_test/test_work/state_dir, is_recursive=False>  [util.py:[LINENR]]
+tst test_suite: RESERVED RESOURCES for test_suite:
+bts
+  sysmoCell 5000
+  sysmoCell 5000
+  sysmoBTS 1002
+ip_address
+  10.42.42.1
+modem
+  m7801
+  m7802  [suite.py:[LINENR]]
 resources(test_suite)={'bts': [{'_hash': 'a59640b8ba6a373552b24a6f9f65cadd2347bace',
           '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]',
           'addr': '10.42.42.53',
@@ -841,6 +881,16 @@
   path: /wavecom_1
   [resource.py:[LINENR]]
 tst test_suite: DBG: FileWatch: unscheduling watch <ObservedWatch: path=[PATH]/selftest/suite_test/test_work/state_dir, is_recursive=False>  [util.py:[LINENR]]
+tst test_suite: RESERVED RESOURCES for test_suite:
+bts
+  sysmoCell 5000
+  sysmoCell 5000
+  sysmoBTS 1002
+ip_address
+  10.42.42.1
+modem
+  m7801
+  m7802  [suite.py:[LINENR]]
 resources(test_suite)={'bts': [{'_hash': 'a59640b8ba6a373552b24a6f9f65cadd2347bace',
           '_reserved_by': 'test_suite-[ID_NUM]-[ID_NUM]',
           'addr': '10.42.42.53',
@@ -944,6 +994,9 @@
   addr: 10.42.42.2
   [resource.py:[LINENR]]
 tst suiteC: DBG: FileWatch: unscheduling watch <ObservedWatch: path=[PATH]/selftest/suite_test/test_work/state_dir, is_recursive=False>  [util.py:[LINENR]]
+tst suiteC: RESERVED RESOURCES for suiteC:
+ip_address
+  10.42.42.2  [suite.py:[LINENR]]
 
 ----------------------------------------------
 trial suiteC test_template_overlay.py
diff --git a/src/osmo_gsm_tester/core/resource.py b/src/osmo_gsm_tester/core/resource.py
index 621522b..223a8f9 100644
--- a/src/osmo_gsm_tester/core/resource.py
+++ b/src/osmo_gsm_tester/core/resource.py
@@ -485,6 +485,18 @@
     def __repr__(self):
         return 'resources(%s)=%s' % (self.origin.name(), pprint.pformat(self.reserved))
 
+    def __str__(self):
+        return repr(self)
+
+    def summary_str(self, prefix=''):
+        lines = []
+        for key, reserved_list in sorted(self.reserved.items()):
+            lines.append(key)
+            for item in reserved_list:
+                label = item.get('label') or item.get('addr') or item.get('type') or item.get('_hash') or '?'
+                lines.append('  ' + label)
+        return prefix + ('\n' + prefix).join(lines)
+
     def get(self, kind, specifics=None):
         if specifics is None:
             specifics = {}
diff --git a/src/osmo_gsm_tester/core/suite.py b/src/osmo_gsm_tester/core/suite.py
index 3860d19..3e9ecbf 100644
--- a/src/osmo_gsm_tester/core/suite.py
+++ b/src/osmo_gsm_tester/core/suite.py
@@ -160,6 +160,8 @@
             raise RuntimeError('Attempt to reserve resources twice for a SuiteRun')
         self.log('reserving resources in', self.resources_pool.state_dir, '...')
         self.reserved_resources = self.resources_pool.reserve(self, self.resource_requirements(), self.resource_modifiers())
+        # short summary of labels
+        self.log('RESERVED RESOURCES for ' + self.suite_name() + ':\n' + self.reserved_resources.summary_str())
 
     def get_reserved_resource(self, resource_class_str, specifics):
         return self.reserved_resources.get(resource_class_str, specifics=specifics)