#!/usr/bin/env python # -*- coding: UTF-8 -*- # Copyright (c) 2017 Orange and others. # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 """This module manages calls to Energy recording API.""" import json import logging import urllib import requests import functest.utils.functest_utils as ft_utils def enable_recording(method): """ Decorator to record energy during "method" exection. param method: Method to suround with start and stop :type method: function .. note:: "method" should belong to a class having a "case_name" attribute """ def wrapper(*args): """Wrapper for decorator to handle method arguments.""" EnergyRecorder.start(args[0].case_name) return_value = method(*args) EnergyRecorder.stop() return return_value return wrapper # Class to manage energy recording sessions class EnergyRecorder(object): """Manage Energy recording session.""" logger = logging.getLogger(__name__) # Energy recording API connectivity settings # see load_config method energy_recorder_api = None # Default initial step INITIAL_STEP = "starting" @staticmethod def load_config(): """ Load connectivity settings from yaml. Load connectivity settings to Energy recording API Use functest global config yaml file (see functest_utils.get_functest_config) """ # Singleton pattern for energy_recorder_api static member # Load only if not previouly done if EnergyRecorder.energy_recorder_api is None: environment = ft_utils.get_pod_name() # API URL energy_recorder_uri = ft_utils.get_functest_config( "energy_recorder.api_url") assert energy_recorder_uri assert environment energy_recorder_uri += "/recorders/environment/" energy_recorder_uri += urllib.quote_plus(environment) EnergyRecorder.logger.debug( "API recorder at: " + energy_recorder_uri) # Creds user = ft_utils.get_functest_config( "energy_recorder.api_user") password = ft_utils.get_functest_config( "energy_recorder.api_password") if user != "" and password != "": energy_recorder_api_auth = (user, password) else: energy_recorder_api_auth = None # Final config EnergyRecorder.energy_recorder_api = { "uri": energy_recorder_uri, "auth": energy_recorder_api_auth } @staticmethod def start(scenario): """ Start a recording session for scenario. param scenario: Starting scenario :type scenario: string """ return_status = True try: EnergyRecorder.logger.debug("Starting recording") # Ensure that connectyvity settings are loaded EnergyRecorder.load_config() # Create API payload payload = { "step": EnergyRecorder.INITIAL_STEP, "scenario": scenario } # Call API to start energy recording response = requests.post( EnergyRecorder.energy_recorder_api["uri"], data=json.dumps(payload), auth=EnergyRecorder.energy_recorder_api["auth"], headers={ 'content-type': 'application/json' } ) if response.status_code != 200: log_msg = "Error while starting energy recording session\n{}" log_msg = log_msg.format(response.text) EnergyRecorder.logger.info(log_msg) return_status = False except Exception: # pylint: disable=broad-except # Default exception handler to ensure that method # is safe for caller EnergyRecorder.logger.exception( "Error while starting energy recorder API" ) return_status = False return return_status @staticmethod def stop(): """Stop current recording session.""" EnergyRecorder.logger.debug("Stopping recording") return_status = True try: # Ensure that connectyvity settings are loaded EnergyRecorder.load_config() # Call API to stop energy recording response = requests.delete( EnergyRecorder.energy_recorder_api["uri"], auth=EnergyRecorder.energy_recorder_api["auth"], headers={ 'content-type': 'application/json' } ) if response.status_code != 200: log_msg = "Error while stating energy recording session\n{}" log_msg = log_msg.format(response.text) EnergyRecorder.logger.error(log_msg) return_status = False except Exception: # pylint: disable=broad-except # Default exception handler to ensure that method # is safe for caller EnergyRecorder.logger.exception( "Error while stoping energy recorder API" ) return_status = False return return_status @staticmethod def set_step(step): """Notify energy recording service of current step of the testcase.""" EnergyRecorder.logger.debug("Setting step") return_status = True try: # Ensure that connectyvity settings are loaded EnergyRecorder.load_config() # Create API payload payload = { "step": step, } # Call API to define step response = requests.post( EnergyRecorder.energy_recorder_api["uri"] + "/step", data=json.dumps(payload), auth=EnergyRecorder.energy_recorder_api["auth"], headers={ 'content-type': 'application/json' } ) if response.status_code != 200: log_msg = "Error while setting current step of testcase\n{}" log_msg = log_msg.format(response.text) EnergyRecorder.logger.error(log_msg) return_status = False except Exception: # pylint: disable=broad-except # Default exception handler to ensure that method # is safe for caller EnergyRecorder.logger.exception( "Error while setting step on energy recorder API" ) return_status = False return return_status