pymtt
 All Classes Namespaces Files Functions Variables Groups
IUDatabase.py
Go to the documentation of this file.
1 # -*- coding: utf-8; tab-width: 4; indent-tabs-mode: f; python-indent: 4 -*-
2 #
3 # Copyright (c) 2015-2018 Intel, Inc. All rights reserved.
4 # Copyright (c) 2017 IBM Corporation. All rights reserved.
5 # $COPYRIGHT$
6 #
7 # Additional copyrights may follow
8 #
9 # $HEADER$
10 #
11 
12 from __future__ import print_function
13 import os
14 import pwd
15 import requests
16 import json
17 import pprint
18 import re
19 from datetime import datetime
20 from requests.auth import HTTPBasicAuth
21 
22 from ReporterMTTStage import *
23 
24 from requests.packages.urllib3.exceptions import InsecureRequestWarning
25 requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
26 
27 ## @addtogroup Stages
28 # @{
29 # @addtogroup Reporter
30 # @section IUDatabase
31 # MTT Database reporter plugin for the legacy IU submission server
32 # @param realm Database name
33 # @param username Username to be used for submitting data
34 # @param password Password for that username
35 # @param pwfile File where password can be found
36 # @param platform Name of the platform (cluster) upon which the tests were run
37 # @param hostname Name of the hosts involved in the tests (may be regular expression)
38 # @param url URL of the database server
39 # @param debug_filename Debug output file for server interaction information
40 # @param keep_debug_files Retain reporter debug output after execution
41 # @param debug_server Ask the server to return its debug output as well
42 # @param email Email to which errors are to be sent
43 # @}
45 
46  def __init__(self):
47  # initialise parent class
48  ReporterMTTStage.__init__(self)
49  self.options = {}
50  self.options['realm'] = (None, "Database name")
51  self.options['username'] = (None, "Username to be used for submitting data")
52  self.options['password'] = (None, "Password for that username")
53  self.options['pwfile'] = (None, "File where password can be found")
54  self.options['platform'] = (None, "Name of the platform (cluster) upon which the tests were run")
55  self.options['hostname'] = (None, "Name of the hosts involved in the tests (may be regular expression)")
56  self.options['url'] = (None, "URL of the database server")
57  self.options['debug_filename'] = (None, "Debug output file for server interaction information")
58  self.options['keep_debug_files'] = (False, "Retain reporter debug output after execution")
59  self.options['debug_server'] = (False, "Ask the server to return its debug output as well")
60  self.options['email'] = (None, "Email to which errors are to be sent")
61 
62  def activate(self):
63  # get the automatic procedure from IPlugin
64  IPlugin.activate(self)
65  return
66 
67 
68  def deactivate(self):
69  IPlugin.deactivate(self)
70  return
71 
72  def print_name(self):
73  return "IUDatabase"
74 
75  def print_options(self, testDef, prefix):
76  lines = testDef.printOptions(self.options)
77  for line in lines:
78  print(prefix + line)
79  return
80 
81  def execute(self, log, keyvals, testDef):
82  # parse the provided keyvals against our options
83  cmds = {}
84  testDef.parseOptions(log, self.options, keyvals, cmds)
85 
86  # quick sanity check
87  sanity = 0
88  if cmds['username'] is not None:
89  sanity += 1
90  if cmds['password'] is not None or cmds['pwfile'] is not None:
91  sanity += 1
92  if cmds['realm'] is not None:
93  sanity += 1
94  if 0 < sanity and sanity != 3:
95  log['status'] = 1
96  log['stderr'] = "MTTDatabase Reporter section",log['section'] + ": if password, username, or realm is specified, they all must be specified."
97  return
98  try:
99  if cmds['pwfile'] is not None:
100  if os.path.exists(cmds['pwfile']):
101  f = open(cmds['pwfile'], 'r')
102  password = f.readline().strip()
103  f.close()
104  else:
105  log['status'] = 1;
106  log['stderr'] = "Password file " + cmds['pwfile'] + " does not exist"
107  return
108  elif cmds['password'] is not None:
109  password = cmds['password']
110  except KeyError:
111  try:
112  if cmds['password'] is not None:
113  password = cmds['password']
114  except KeyError:
115  pass
116  #
117  # Setup the JSON data structure
118  #
119  s = requests.Session()
120  url = cmds['url'] + "/submit"
121  if 0 < sanity:
122  www_auth = HTTPBasicAuth(cmds['username'], password)
123  else:
124  www_auth = None
125 
126  # Get a client serial number
127  client_serial = self._get_client_serial(s, cmds['url'], www_auth)
128  if client_serial < 0:
129  print("Error: Unable to get a client serial (rtn=%d)" % (client_serial))
130 
131  headers = {}
132  headers['content-type'] = 'application/json'
133 
134  data = {}
135 
136  profile = testDef.logger.getLog('Profile:Installed')
137  metadata = {}
138  metadata['client_serial'] = client_serial
139  metadata['hostname'] = "\n".join(profile['profile']['nodeName'])
140  metadata['http_username'] = cmds['username']
141  metadata['local_username'] = pwd.getpwuid(os.getuid()).pw_name
142  metadata['mtt_client_version'] = '4.0a1'
143  metadata['platform_name'] = self._extract_param(testDef.logger, 'MTTDefaults', 'platform')
144  trl = self._extract_param(testDef.logger, 'MTTDefaults', 'trial')
145  if trl and trl.lower() != "false":
146  metadata['trial'] = 1
147  else:
148  metadata['trial'] = 0
149 
150  # Strategy:
151  # For each Test Run section
152  # - Find 'parent' Test Build
153  # - Find 'middleware' MiddlewareBuild (MPI Install)
154  # - Submit MPI Install phase
155  # - Submit Test Build phase
156  # - for each test run result
157  # - Submit Test Run phase
158 
159  # get the entire log of results
160  fullLog = testDef.logger.getLog(None)
161  pp = pprint.PrettyPrinter(indent=4)
162 
163  #
164  # Dump the entire log
165  #
166  print("<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>")
167  for lg in fullLog:
168  print("----------------- Section (%s) " % (lg['section']))
169  pp.pprint(lg)
170  print("<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>")
171 
172  #
173  # Process the test run sections
174  #
175  for lg in fullLog:
176  # Find sections prefixed with 'TestRun'
177  if re.match("TestRun", lg['section']):
178  rtn = self._submit_test_run(testDef.logger, lg, metadata, s, url, www_auth)
179 
180  log['status'] = 0
181  return
182 
183  def _merge_dict(self, x, y):
184  z = x.copy()
185  z.update(y)
186  return z
187 
188  def _submit_test_run(self, logger, lg, metadata, s, url, httpauth=None):
189  print("----------------- Test Run (%s) " % (lg['section']))
190 
191  pp = pprint.PrettyPrinter(indent=4)
192  pp.pprint(lg)
193 
194  # Find 'parent' Test Build - submit
195  test_info = self._submit_test_build(logger,
196  logger.getLog(self._extract_param(logger, lg['section'], 'parent')),
197  metadata,
198  s, url, httpauth)
199 
200  if test_info is None:
201  return None
202 
203  # get the options used to do the run
204  try:
205  options = lg['options']
206  except KeyError:
207  return None
208 
209  #
210  # Prepare to submit
211  # JJH Todo fill these fields in
212  #
213  metadata['phase'] = 'Test Run'
214 
215  common_data = {}
216  #common_data['mpi_install_id'] = None
217  # For now assume that we only had one test_build submitted
218  # and all of the tests that follow are from that test_build
219  common_data['test_build_id'] = test_info['test_build_id']
220 
221  for trun in (lg['testresults'] if 'testresults' in lg else [lg]):
222  data = {}
223 
224  #data['mpi_install_id'] = common_data['mpi_install_id']
225  data['test_build_id'] = common_data['test_build_id']
226 
227  try:
228  data['launcher'] = options['command']
229  except KeyError:
230  data['launcher'] = None
231 
232  if 'testresults' in lg:
233  data['test_name'] = trun['test'].split('/')[-1]
234  else:
235  data['test_name'] = trun['options']['command'].split('/')[-1]
236 
237  # Number of processes field
238 
239  try:
240  if 'testresults' in lg:
241  data['np'] = lg['np']
242  else:
243  data['np'] = 1
244  except KeyError:
245  data['np'] = None
246 
247  if 'testresults' in lg:
248  data['command'] = trun['cmd']
249  else:
250  data['command'] = trun['options']['command']
251 
252  # For now just mark the time when submitted
253  data['start_timestamp'] = datetime.utcnow().strftime("%c")
254 
255  try:
256  status = trun['status']
257  except KeyError:
258  status = -1
259  if status == 0:
260  data['result_message'] = "Success"
261  data['test_result'] = 1
262  data['exit_value'] = 0
263  elif status == 1:
264  data['result_message'] = "Failed"
265  data['test_result'] = 0
266  if 'stderr' in lg:
267  # the log should be a list, but it is possible
268  # that it got joined into a single string
269  # somewhere along the way - so handle both
270  # cases here
271  if type(lg['stderr']) is list:
272  lgerr = '\n'.join(lg['stderr'])
273  else:
274  lgerr = lg['stderr']
275  if '[Errno' in lgerr:
276  try:
277  data['exit_value'] = int(lgerr.split("[Errno ")[1].split("]")[0])
278  except:
279  data['exit_value'] = -1
280  else:
281  data['exit_value'] = -1
282  else:
283  data['result_message'] = "Failed"
284  data['test_result'] = -1
285  if 'stderr' in lg:
286  if type(lg['stderr']) is list:
287  lgerr = '\n'.join(lg['stderr'])
288  else:
289  lgerr = lg['stderr']
290  if '[Errno' in lgerr:
291  try:
292  data['exit_value'] = int(lgerr.split("[Errno ")[1].split("]")[0])
293  except:
294  data['exit_value'] = -1
295  else:
296  data['exit_value'] = -1
297  else:
298  data['exit_value'] = -1
299 
300  # Optional
301  # data['duration'] = None
302 
303  # data['exit_signal'] = None
304 
305  # data['resource_manager'] = None
306  # data['parameters'] = None
307  # data['network'] = None
308 
309  # data['latency_bandwidth'] = None
310  # data['message_size'] = None
311  # data['latency_min'] = None
312  # data['latency_avg'] = None
313  # data['latency_max'] = None
314  # data['bandwidth_min'] = None
315  # data['bandwidth_avg'] = None
316  # data['bandwidth_max'] = None
317 
318  # data['description'] = None
319  data['description'] = self._extract_param(logger, 'MTTDefaults', 'description')
320  # data['environment'] = None
321  environment = {}
322  for lgentry in logger.getLog(None):
323  if 'environ' in lgentry:
324  environment.update(lgentry['environ'])
325  data['environment'] = "\n".join([str(k) + "=" + str(v) for k,v in environment.items()])
326 
327 
328  # BIOS table
329  bios = {}
330  for lgentry in logger.getLog(None):
331  if 'bios' in lgentry:
332  bios.update(lgentry['bios'])
333  try:
334  data['bios_nodelist'] = bios['nodelist']
335  data['bios_params'] = bios['params']
336  data['bios_values'] = bios['values']
337  except KeyError:
338  pass
339 
340  # Firmware table (TODO: may want to grab whole cfg file)
341  firmware = {}
342  for lgentry in logger.getLog(None):
343  if 'firmware' in lgentry:
344  firmware.update(lgentry['firmware'])
345  try:
346  data['flashupdt_cfg'] = firmware['flashupdt_cfg']
347  data['firmware_nodelist'] = firmware['nodelist']
348  except KeyError:
349  pass
350 
351  # Provision table
352  provisioning = {}
353  for lgentry in logger.getLog(None):
354  if 'provisioning' in lgentry:
355  provisioning.update(lgentry['provisioning'])
356  try:
357  data['targets'] = provisioning['target']
358  data['image'] = provisioning['image']
359  data['controllers'] = provisioning['controller']
360  data['bootstrap'] = provisioning['bootstrap']
361  except KeyError:
362  pass
363 
364  # Harasser table
365  harasser = {}
366  for lgentry in logger.getLog(None):
367  if 'harasser' in lgentry:
368  harasser.update(lgentry['harasser'])
369  try:
370  data['harasser_seed'] = harasser['seed']
371  data['inject_script'] = harasser['inject_script']
372  data['cleanup_script'] = harasser['cleanup_script']
373  data['check_script'] = harasser['check_script']
374  except KeyError:
375  pass
376 
377 
378  try:
379  if options['merge_stdout_stderr']:
380  data['merge_stdout_stderr'] = 1
381  else:
382  data['merge_stdout_stderr'] = 0
383  except KeyError:
384  data['merge_stdout_stderr'] = None
385 
386  try:
387  data['result_stdout'] = '\n'.join(trun['stdout'] if trun['stdout'] is not None else "")
388  except KeyError:
389  data['result_stdout'] = None
390 
391  try:
392  if type(trun['stderr']) is list:
393  data['result_stderr'] = '\n'.join(trun['stderr'] if trun['stderr'] is not None else "")
394  else:
395  data['result_stderr'] = (trun['stderr'] if trun['stderr'] is not None else "")
396  except KeyError:
397  data['result_stderr'] = None
398 
399  #
400  # Submit
401  #
402  payload = {}
403  payload['metadata'] = metadata
404  payload['data'] = [data]
405 
406  data = self._submit_json_data(payload, s, url, httpauth)
407  if data is None:
408  return None
409  if data['status'] is not 0:
410  return None
411 
412  return True
413 
414  def _submit_test_build(self, logger, lg, metadata, s, url, httpauth=None):
415  print("----------------- Test Build (%s) " % (lg['section']))
416 
417  pp = pprint.PrettyPrinter(indent=4)
418  pp.pprint(lg)
419 
420  # Find 'parent' Test Get (not needed)
421  # Find 'middleware' MiddlewareBuild (MPI Install)
422  install_info = self._submit_install(logger,
423  lg,
424  metadata,
425  s, url, httpauth)
426  if install_info is None:
427  return None
428 
429  # get the options used to do the run
430  try:
431  options = lg['options']
432  except KeyError:
433  return None
434 
435  #
436  # Prepare to submit
437  # JJH Todo fill these fields in
438  #
439  data = {}
440  metadata['phase'] = 'Test Build'
441 
442  # For now assume that we only had one mpi_install submitted
443  data['mpi_install_id'] = install_info['mpi_install_id']
444 
445  try:
446  data['compiler_name'] = lg['compiler']['compiler']
447 # data['compiler_version'] = "\n".join(lg['compiler']['version'])
448  data['compiler_version'] = lg['compiler']['version']
449  except KeyError:
450  full_log = logger.getLog(None)
451  for entry in full_log:
452  if 'compiler' in entry:
453  data['compiler_name'] = entry['compiler']['compiler']
454 # data['compiler_version'] = "\n".join(entry['compiler']['version'])
455  data['compiler_version'] = entry['compiler']['version']
456  break
457  else:
458  data['compiler_name'] = None
459  data['compiler_version'] = None
460 
461  data['suite_name'] = lg['section']
462 
463  # For now just mark the time when submitted
464  data['start_timestamp'] = datetime.utcnow().strftime("%c")
465 
466  try:
467  status = lg['status']
468  except KeyError:
469  status = -1
470  if status == 0:
471  data['result_message'] = "Success"
472  data['test_result'] = 1
473  data['exit_value'] = 0
474  elif status == 1:
475  data['result_message'] = "Failed"
476  data['test_result'] = 0
477  if 'stderr' in lg:
478  # the log should be a list, but it is possible
479  # that it got joined into a single string
480  # somewhere along the way - so handle both
481  # cases here
482  if type(lg['stderr']) is list:
483  lgerr = '\n'.join(lg['stderr'])
484  else:
485  lgerr = lg['stderr']
486  if '[Errno' in lgerr:
487  try:
488  data['exit_value'] = int(lgerr.split("[Errno ")[1].split("]")[0])
489  except:
490  data['exit_value'] = -1
491  else:
492  data['exit_value'] = -1
493  else:
494  data['exit_value'] = -1
495  else:
496  data['result_message'] = "Failed"
497  data['test_result'] = -1
498  if 'stderr' in lg:
499  # the log should be a list, but it is possible
500  # that it got joined into a single string
501  # somewhere along the way - so handle both
502  # cases here
503  if type(lg['stderr']) is list:
504  lgerr = '\n'.join(lg['stderr'])
505  else:
506  lgerr = lg['stderr']
507  if '[Errno' in lgerr:
508  try:
509  data['exit_value'] = int(lgerr.split("[Errno ")[1].split("]")[0])
510  except:
511  data['exit_value'] = -1
512  else:
513  data['exit_value'] = -1
514  else:
515  data['exit_value'] = -1
516 
517  # Optional
518  #data['duration'] = None
519 
520  #data['exit_signal'] = None
521  #data['description'] = None
522  data['description'] = self._extract_param(logger, 'MTTDefaults', 'description')
523  #data['environment'] = None
524  environment = {}
525  for lgentry in logger.getLog(None):
526  if 'environ' in lgentry:
527  environment.update(lgentry['environ'])
528  data['environment'] = "\n".join([str(k) + "=" + str(v) for k,v in environment.items()])
529 
530  try:
531  if options['merge_stdout_stderr']:
532  data['merge_stdout_stderr'] = 1
533  else:
534  data['merge_stdout_stderr'] = 0
535  except KeyError:
536  data['merge_stdout_stderr'] = None
537 
538  try:
539  data['result_stdout'] = '\n'.join(lg['stdout'])
540  except KeyError:
541  data['result_stdout'] = None
542 
543  try:
544  if type(lg['stderr']) is list:
545  data['result_stderr'] = '\n'.join(lg['stderr'])
546  else:
547  data['result_stderr'] = lg['stderr']
548  except KeyError:
549  data['result_stderr'] = None
550 
551  #
552  # Submit
553  #
554  payload = {}
555  payload['metadata'] = metadata
556  payload['data'] = [data]
557 
558  data = self._submit_json_data(payload, s, url, httpauth)
559  if data is None:
560  return None
561  if data['status'] is not 0:
562  return None
563 
564  # Extract ID
565  return self._merge_dict( {'test_build_id':data['ids'][0]['test_build_id']},
566  install_info)
567 
568  def _submit_install(self, logger, lg, metadata, s, url, httpauth=None):
569 
570  print("----------------- MPI Install (%s) " % (lg['section']))
571  pp = pprint.PrettyPrinter(indent=4)
572  pp.pprint(lg)
573 
574  # Find 'parent' MiddlewareGet (MPI Get) (not needed?)
575 
576  # get the options used to do the run
577  # no options for MPI Install (?)
578  # try:
579  # options = lg['options']
580  # except KeyError:
581  # print "Error: Failed to get 'options'"
582  # return None
583  options = None
584 
585  # get the system profile
586 
587  profile = logger.getLog('Profile:Installed')['profile']
588  if profile is None:
589  print("Error: Failed to get 'profile'")
590  return None
591 
592  #
593  # Prepare to submit
594  # JJH Todo fill these fields in
595  #
596  data = {}
597  metadata['phase'] = 'MPI Install'
598 
599  try:
600  data['platform_hardware'] = "\n".join(profile['machineName'])
601  except KeyError:
602  data['platform_hardware'] = None
603 
604  try:
605  data['platform_type'] = "\n".join(profile['processorType'])
606  except KeyError:
607  data['platform_type'] = None
608 
609  try:
610  data['os_name'] = "\n".join(profile['kernelName'])
611  except KeyError:
612  data['os_name'] = None
613 
614  try:
615  data['os_version'] = "\n".join(profile['kernelRelease'])
616  except KeyError:
617  data['os_version'] = None
618 
619  try:
620  data['compiler_name'] = lg['compiler']['compiler']
621 # data['compiler_version'] = "\n".join(lg['compiler']['version'])
622  data['compiler_version'] = lg['compiler']['version']
623  except KeyError:
624  full_log = logger.getLog(None)
625  for entry in full_log:
626  if 'compiler' in entry:
627  data['compiler_name'] = entry['compiler']['compiler']
628 # data['compiler_version'] = "\n".join(entry['compiler']['version'])
629  data['compiler_version'] = entry['compiler']['version']
630  break
631  else:
632  data['compiler_name'] = None
633  data['compiler_version'] = None
634 
635  try:
636  data['mpi_name'] = lg['mpi_info']['name']
637  data['mpi_version'] = lg['mpi_info']['version']
638  except KeyError:
639  full_log = logger.getLog(None)
640  for entry in full_log:
641  if 'mpi_info' in entry:
642  data['mpi_name'] = entry['mpi_info']['name']
643  data['mpi_version'] = entry['mpi_info']['version']
644  break
645  else:
646  data['mpi_name'] = None
647  data['mpi_version'] = None
648 
649  try:
650  data['configure_arguments'] = logger.getLog(lg['middleware'])['configure_options']
651  except (KeyError, TypeError):
652  data['configure_arguments'] = None
653 
654  # For now just mark the time when submitted
655  data['start_timestamp'] = datetime.utcnow().strftime("%c")
656 
657  try:
658  status = lg['status']
659  except KeyError:
660  status = -1
661  if status == 0:
662  data['result_message'] = "Success"
663  data['test_result'] = 1
664  data['exit_value'] = 0
665  elif status == 1:
666  data['result_message'] = "Failed"
667  data['test_result'] = 0
668  if 'stderr' in lg:
669  # the log should be a list, but it is possible
670  # that it got joined into a single string
671  # somewhere along the way - so handle both
672  # cases here
673  if type(lg['stderr']) is list:
674  lgerr = '\n'.join(lg['stderr'])
675  else:
676  lgerr = lg['stderr']
677  if '[Errno' in lgerr:
678  try:
679  data['exit_value'] = int(lgerr.split("[Errno ")[1].split("]")[0])
680  except:
681  data['exit_value'] = -1
682  else:
683  data['exit_value'] = -1
684  else:
685  data['exit_value'] = -1
686  else:
687  data['result_message'] = "Failed"
688  data['test_result'] = -1
689  if 'stderr' in lg:
690  # the log should be a list, but it is possible
691  # that it got joined into a single string
692  # somewhere along the way - so handle both
693  # cases here
694  if type(lg['stderr']) is list:
695  lgerr = '\n'.join(lg['stderr'])
696  else:
697  lgerr = lg['stderr']
698  if '[Errno' in lgerr:
699  try:
700  data['exit_value'] = int(lgerr.split("[Errno ")[1].split("]")[0])
701  except:
702  data['exit_value'] = -1
703  else:
704  data['exit_value'] = -1
705  else:
706  data['exit_value'] = -1
707 
708  # Optional
709  # data['duration'] = None
710 
711  # data['vpath_mode'] = None
712  # data['bitness'] = None
713  # data['endian'] = None
714 
715  #data['exit_signal'] = None
716  #data['description'] = None
717  data['description'] = self._extract_param(logger, 'MTTDefaults', 'description')
718  #data['environment'] = None
719  environment = {}
720  for lgentry in logger.getLog(None):
721  if 'environ' in lgentry:
722  environment.update(lgentry['environ'])
723  data['environment'] = "\n".join([str(k) + "=" + str(v) for k,v in environment.items()])
724 
725  try:
726  if options is not None and options['merge_stdout_stderr']:
727  data['merge_stdout_stderr'] = 1
728  else:
729  data['merge_stdout_stderr'] = 0
730  except KeyError:
731  data['merge_stdout_stderr'] = None
732 
733  try:
734  data['result_stdout'] = '\n'.join(lg['stdout'])
735  except KeyError:
736  data['result_stdout'] = None
737 
738  try:
739  if type(lg['stderr']) is list:
740  data['result_stderr'] = '\n'.join(lg['stderr'])
741  else:
742  data['result_stderr'] = lg['stderr']
743  except KeyError:
744  data['result_stderr'] = None
745 
746  #
747  # Submit
748  #
749  payload = {}
750  payload['metadata'] = metadata
751  payload['data'] = [data]
752 
753  data = self._submit_json_data(payload, s, url, httpauth)
754  if data is None:
755  return None
756  if data['status'] is not 0:
757  return None
758 
759  # Extract ID
760  return {'mpi_install_id':data['ids'][0]['mpi_install_id']}
761 
762  def _submit_json_data(self, payload, s, url, httpauth=None):
763  headers = {}
764  headers['content-type'] = 'application/json'
765 
766  print("<<<<<<<---------------- Payload (Start) -------------------------->>>>>>")
767  print(json.dumps(payload, sort_keys=True, indent=4, separators=(',',': ')))
768  print("<<<<<<<---------------- Payload (End ) -------------------------->>>>>>")
769 
770  r = s.post(url,
771  data=json.dumps(payload),
772  headers=headers,
773  auth=httpauth,
774  verify=False)
775 
776  print("<<<<<<<---------------- Response -------------------------->>>>>>")
777  print("Result: %d: %s" % (r.status_code, r.headers['content-type']))
778  print(r.headers)
779  print(r.reason)
780  print("<<<<<<<---------------- Raw Output (Start) ---------------->>>>>>")
781  print(r.text)
782  print("<<<<<<<---------------- Raw Output (End ) ---------------->>>>>>")
783 
784  if r.status_code != 200:
785  return None
786 
787  return r.json()
788 
789  def _extract_param(self, logger, section, parameter):
790  found = logger.getLog(section)
791  if found is None:
792  print("_extract_param: Section (%s) Not Found! [param=%s]" % (section, parameter))
793  return None
794 
795  try:
796  params = found['parameters']
797  except KeyError:
798  print("_extract_param: Section (%s) did not contain a parameters entry! [param=%s]" % (section, parameter))
799  return None
800  for p in params:
801  if p[0] == parameter:
802  return p[1]
803 
804  def _get_client_serial(self, session, url, httpauth=None):
805  url = url + "/serial"
806 
807  headers = {}
808  headers['content-type'] = 'application/json'
809 
810  payload = {}
811  payload['serial'] = 'serial'
812 
813  data = self._submit_json_data(payload, session, url, httpauth)
814  if data is None:
815  return -1
816 
817  if data['status'] is not 0:
818  return -2
819 
820  return data['client_serial']