<commit_before>import django_oauth_consumer
from django_oauth_consumer import NoAccessToken

from django.conf import settings
from django.utils import simplejson as json

CONSUMER_KEY = settings.CONSUMER_KEY
CONSUMER_SECRET = settings.CONSUMER_SECRET

NAME = 'EmOAuth'

SERVER = settings.EMOCRACY_API_SERVER
API_SERVER = SERVER + "api/"

REQUEST_TOKEN_URL = '%soauth/request_token/' % SERVER
ACCESS_TOKEN_URL = '%soauth/access_token/' % SERVER
AUTHORIZATION_URL = '%soauth/authorize/' % SERVER
REALM = 'emo.buhrer.net'
SIGNATURE_METHOD = 'oauth.signature_method.plaintext.OAuthSignatureMethod_PLAINTEXT'

class EmoOAuthConsumerApp(django_oauth_consumer.OAuthConsumerApp):

    def  __init__(self,
        name=NAME,
        consumer_key=CONSUMER_KEY,
        consumer_secret=CONSUMER_SECRET,
        request_token_url=REQUEST_TOKEN_URL,
        authorization_url=AUTHORIZATION_URL,
        access_token_url=ACCESS_TOKEN_URL,
        realm=REALM,
        signature_method=SIGNATURE_METHOD):

        super(EmoOAuthConsumerApp, self).__init__(
        name=name,
        consumer_key=consumer_key,
        consumer_secret=consumer_secret,
        request_token_url=request_token_url,
        authorization_url=authorization_url,
        access_token_url=access_token_url,
        realm=realm,
        signature_method=signature_method)

        self.response = None

    def store_access_token(self, request, token):
        if not request.user.is_anonymous():
            profile = request.user.get_profile()
            profile.access_token = token['oauth_token']
            profile.access_secret = token['oauth_token_secret']
            profile.save()
        else:
            request.session[self.ACCESS_TOKEN_NAME] = token

    def get_access_token(self, request):
        if not request.user.is_anonymous():
            profile = request.user.get_profile()
            if not profile.access_token:
                raise NoAccessToken()
            else:
                token = {}
                token['oauth_token'] = profile.access_token
                token['oauth_token_secret'] = profile.access_secret
                return token
        else:
            if self.ACCESS_TOKEN_NAME in request.session:
                return request.session[self.ACCESS_TOKEN_NAME]
            else:
                raise NoAccessToken()

    def get_resource(self, request, resource):
        try:
            token = self.get_access_token(request)
            return self.make_signed_req(url=resource, token=token, request=request)
        except NoAccessToken:
            return self.make_signed_req(url=resource)

    def ld(self):
        """Load data - parse json from last request"""
        data = self.response.read()
        return json.loads(data)

    def post_resource(self, request, resource, content=None):
        if resource==None:
            return false
        try:
            token = self.get_access_token(request)
            return self.make_signed_req(url=resource, method='POST', content=content, token=token, request=request)
        except NoAccessToken:
            raise

    def post_vote(self, request, vote_data):
        """
        Posts a vote to Emocracy Service Provider.

        `vote_data` should be a dictionary:
            { 'issue' : integer,
              'keep_private' : boolean,
              'vote' : integer,  # valid values -1, 1, 10-19 (see emocracy docs)
            }
        """
        api_url = API_SERVER+'votes/'
        self.response = self.post_resource(request, api_url, content=vote_data)
        return self.response.status

    def get_issue_list(self, request):
        api_url = API_SERVER+'issues/'
        self.response = self.get_resource(request, api_url)
        return self.ld()

    def get_issue(self, request, issue_no):
        api_url = API_SERVER+'issues/'+issue_no+'/'
        self.response = self.get_resource(request, api_url)
        return self.ld()

    def post_issue(self, request, issue_data):
        api_url = API_SERVER+'issues/'
        self.response = self.post_resource(request, api_url, content=issue_data)
        return self.response.status
<commit_msg>moved REALM to settings_local.py<commit_after>import django_oauth_consumer
from django_oauth_consumer import NoAccessToken

from django.conf import settings
from django.utils import simplejson as json

CONSUMER_KEY = settings.CONSUMER_KEY
CONSUMER_SECRET = settings.CONSUMER_SECRET

NAME = 'EmOAuth'

SERVER = settings.EMOCRACY_API_SERVER
API_SERVER = SERVER + "api/"

REQUEST_TOKEN_URL = '%soauth/request_token/' % SERVER
ACCESS_TOKEN_URL = '%soauth/access_token/' % SERVER
AUTHORIZATION_URL = '%soauth/authorize/' % SERVER
REALM = settings.REALM
SIGNATURE_METHOD = 'oauth.signature_method.plaintext.OAuthSignatureMethod_PLAINTEXT'

class EmoOAuthConsumerApp(django_oauth_consumer.OAuthConsumerApp):

    def  __init__(self,
        name=NAME,
        consumer_key=CONSUMER_KEY,
        consumer_secret=CONSUMER_SECRET,
        request_token_url=REQUEST_TOKEN_URL,
        authorization_url=AUTHORIZATION_URL,
        access_token_url=ACCESS_TOKEN_URL,
        realm=REALM,
        signature_method=SIGNATURE_METHOD):

        super(EmoOAuthConsumerApp, self).__init__(
        name=name,
        consumer_key=consumer_key,
        consumer_secret=consumer_secret,
        request_token_url=request_token_url,
        authorization_url=authorization_url,
        access_token_url=access_token_url,
        realm=realm,
        signature_method=signature_method)

        self.response = None

    def store_access_token(self, request, token):
        if not request.user.is_anonymous():
            profile = request.user.get_profile()
            profile.access_token = token['oauth_token']
            profile.access_secret = token['oauth_token_secret']
            profile.save()
        else:
            request.session[self.ACCESS_TOKEN_NAME] = token

    def get_access_token(self, request):
        if not request.user.is_anonymous():
            profile = request.user.get_profile()
            if not profile.access_token:
                raise NoAccessToken()
            else:
                token = {}
                token['oauth_token'] = profile.access_token
                token['oauth_token_secret'] = profile.access_secret
                return token
        else:
            if self.ACCESS_TOKEN_NAME in request.session:
                return request.session[self.ACCESS_TOKEN_NAME]
            else:
                raise NoAccessToken()

    def get_resource(self, request, resource):
        try:
            token = self.get_access_token(request)
            return self.make_signed_req(url=resource, token=token, request=request)
        except NoAccessToken:
            return self.make_signed_req(url=resource)

    def ld(self):
        """Load data - parse json from last request"""
        data = self.response.read()
        return json.loads(data)

    def post_resource(self, request, resource, content=None):
        if resource==None:
            return false
        try:
            token = self.get_access_token(request)
            return self.make_signed_req(url=resource, method='POST', content=content, token=token, request=request)
        except NoAccessToken:
            raise

    def post_vote(self, request, vote_data):
        """
        Posts a vote to Emocracy Service Provider.

        `vote_data` should be a dictionary:
            { 'issue' : integer,
              'keep_private' : boolean,
              'vote' : integer,  # valid values -1, 1, 10-19 (see emocracy docs)
            }
        """
        api_url = API_SERVER+'votes/'
        self.response = self.post_resource(request, api_url, content=vote_data)
        return self.response.status

    def get_issue_list(self, request):
        api_url = API_SERVER+'issues/'
        self.response = self.get_resource(request, api_url)
        return self.ld()

    def get_issue(self, request, issue_no):
        api_url = API_SERVER+'issues/'+issue_no+'/'
        self.response = self.get_resource(request, api_url)
        return self.ld()

    def post_issue(self, request, issue_data):
        api_url = API_SERVER+'issues/'
        self.response = self.post_resource(request, api_url, content=issue_data)
        return self.response.status
<|endoftext|>


<commit_before>#!/usr/bin/env python

"""
Audio Test Cases modules for unittest

"""

import os
import commands
import unittest

from igep_qa.helpers.common import is_in_path

class TestAudio(unittest.TestCase):
    """ Generic tests for audio interfaces.

    """
    def setUp(self):
        """ Ensure requirements are installed.

        """
        required = ["aplay", "arecord", "multimon"]
        files = "/opt/igep-qa/contrib/dtmf.wav"
        for req in required:
            if not is_in_path(req):
                raise Exception("Can't find %s" % req)
        if not os.path.isfile(files):
            raise Exception("Can't find %s" % files)

    def test_audio_loopback(self):
        """ Audio IN/OUT loopback

        Type: Functional

        Prerequisite commands:
            - aplay
            - arecord
            - multimon

        Prerequitsite files:
            - dtmf.wav (on contrib/dtmf.wav)

        Requirements:
            - Audio Mini jack-Stereo loopback cable.

        Description:
            - Connect the cable between Audio IN and Audio OUT connectors.
            - A sound with recorded DTMF tones is reproduced through Audio OUT
              and is simultaneously recorded via Audio IN.
            - Using demodulator multimon, it demodulates the recorded tune and
              gets the DMTF digits.

        """
        commands.getoutput("rm -f /tmp/recorded.wav")
        commands.getoutput("aplay -t wav -v /usr/share/igep_qa/contrib/dtmf.wav & arecord -t wav -c 1 "
                           "-r 8000 -f S16_LE -d 5 -v /tmp/recorded.wav")
        commands.getoutput("multimon -t wav -a DTMF recorded.wav | grep 'DTMF: 5'")
        retval = commands.getstatusoutput("multimon -t wav -a DTMF "
                                          "/tmp/recorded.wav | grep 'DTMF: 5'")

        self.failUnless(retval[0] == 0, "failed: No DTMF found in recorded "
                        "file")

if __name__ == '__main__':
    unittest.main(verbosity=2)
<commit_msg>tests/qaudio: Fix path for dtmf.wav file.<commit_after>#!/usr/bin/env python

"""
Audio Test Cases modules for unittest

"""

import os
import commands
import unittest

from igep_qa.helpers.common import is_in_path

class TestAudio(unittest.TestCase):
    """ Generic tests for audio interfaces.

    """
    def setUp(self):
        """ Ensure requirements are installed.

        """
        required = ["aplay", "arecord", "multimon"]
        files = "/usr/share/igep_qa/contrib/dtmf.wav"
        for req in required:
            if not is_in_path(req):
                raise Exception("Can't find %s" % req)
        if not os.path.isfile(files):
            raise Exception("Can't find %s" % files)

    def test_audio_loopback(self):
        """ Audio IN/OUT loopback

        Type: Functional

        Prerequisite commands:
            - aplay
            - arecord
            - multimon

        Prerequitsite files:
            - dtmf.wav (on contrib/dtmf.wav)

        Requirements:
            - Audio Mini jack-Stereo loopback cable.

        Description:
            - Connect the cable between Audio IN and Audio OUT connectors.
            - A sound with recorded DTMF tones is reproduced through Audio OUT
              and is simultaneously recorded via Audio IN.
            - Using demodulator multimon, it demodulates the recorded tune and
              gets the DMTF digits.

        """
        commands.getoutput("rm -f /tmp/recorded.wav")
        commands.getoutput("aplay -t wav -v /usr/share/igep_qa/contrib/dtmf.wav & arecord -t wav -c 1 "
                           "-r 8000 -f S16_LE -d 5 -v /tmp/recorded.wav")
        commands.getoutput("multimon -t wav -a DTMF recorded.wav | grep 'DTMF: 5'")
        retval = commands.getstatusoutput("multimon -t wav -a DTMF "
                                          "/tmp/recorded.wav | grep 'DTMF: 5'")

        self.failUnless(retval[0] == 0, "failed: No DTMF found in recorded "
                        "file")

if __name__ == '__main__':
    unittest.main(verbosity=2)
<|endoftext|>


<commit_before>#!/usr/bin/env python

'''
driver1.py
  A driver exemplifying the orchestration of the
  implemented LDFI workflow.
'''

# **************************************** #

#############
#  IMPORTS  #
#############
# standard python packages
import inspect, os, sys

# ------------------------------------------------------ #
# import sibling packages HERE!!!
packagePath  = os.path.abspath( __file__ + "/../.." )
sys.path.append( packagePath )

from dedt           import dedt, dedalusParser
from derivation     import ProvTree
from utils          import parseCommandLineInput, tools
from evaluators     import c4_evaluator, evalTools
from solvers        import EncodedProvTree_CNF, newProgGenerationTools, solverTools
from visualizations import vizTools

# **************************************** #

#############
#  GLOBALS  #
#############
DRIVER_DEBUG            = True
RUN_C4_DIRECTLY         = True
PROV_TREES_ON           = True  # toggle prov tree generation code
OUTPUT_PROV_TREES_ON    = True  # output prov tree renders
ONE_CORE_ITERATION_ONLY = False
TREE_CNF_ON             = True  # toggle provTree to CNF conversion
OUTPUT_TREE_CNF_ON      = False # toggle CNF formula renders
SOLVE_TREE_CNF_ON       = True  # toggle CNF solve

C4_DUMP_SAVEPATH        = os.path.abspath( __file__ + "/../../.." ) + "/save_data/c4Output/c4dump.txt"
FINAL_FI_SOLN_SAVEPATH  = os.path.abspath( __file__ + "/../../.." ) + "/save_data/finalFIsolns/"

################
#  PARSE ARGS  #
################
# parse arguments from the command line
def parseArgs( ) :
  argDict = {}   # empty dict

  argDict = parseCommandLineInput.parseCommandLineInput( )  # get dictionary of arguments.

  return argDict

############
#  DRIVER  #
############
def driver() :
  # get list of command line args, except prog name
  argList = sys.argv[1:]

  # print help if no args provided
  if len(argList) < 1 :
    thisFilename = os.path.basename(__file__)     # name of this file
    sys.exit( "No arguments provided. Please run 'python " + sys.argv[0] + " -h' for assistance." )

  # ----------------------------------------------- #

  # pass list to parse args, get dict of args
  argDict = parseArgs( )
  print argDict

  # check if EOT is an integer (this better pass!)
  try :
    val = int( argDict[ "EOT" ] )
  except :
    tools.bp( __name__, inspect.stack()[0][3], " Could not convert EOT into integer: EOT = " + str(eot) )

  # =================================================================== #
  # loop until find a bug (or not).

  ITER_COUNT       = 0
  runTranslator    = True
  tableListPath    = None
  datalogProgPath  = None
  irCursor         = None
  saveDB           = None
  triedSolnList    = []
  currentTriedSoln = None
  executionStatus  = None

  prevTriedSoln    = None
  while True :

    executionData   = LDFICore( argDict, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, triedSolnList, prevTriedSoln, ITER_COUNT )

    parsedResults    = executionData[0]
    runTranslator    = executionData[1] # a value indicating whether the db is appropriately populated
    tableListPath    = executionData[2]
    datalogProgPath  = executionData[3]
    irCursor         = executionData[4]
    saveDB           = executionData[5]
    triedSolnList    = executionData[6]
    currentTriedSoln = executionData[7]
    executionStatus  = executionData[8]

    #if currentTriedSoln :
    #  print "currentTriedSoln = " + str( currentTriedSoln )
    #  tools.bp( __name__, inspect.stack()[0][3], "evalTools.bugFreeExecution( parsedResults, argDict[ 'EOT' ], executionStatus ) = " + str(evalTools.bugFreeExecution( parsedResults, argDict[ 'EOT' ], executionStatus )) )

    ITER_COUNT += 1
    # ---------------------------------------------------------------------- #
    # control loop iterations
    if ONE_CORE_ITERATION_ONLY : # only run a single iteration of LDFI (good for debugging)
      break

    else :
      # sanity check pre and post must appear in the evaluation results.
      if not "pre" in parsedResults :
        dedt.cleanUp( irCursor, saveDB )
        tools.bp( __name__, inspect.stack()[0][3], "ERROR : no rule defining pre" )
      elif not "post" in parsedResults :
        dedt.cleanUp( irCursor, saveDB )
        tools.bp( __name__, inspect.stack()[0][3], "ERROR : no rule defining post" )

      # ****************************************************************** #
      #                          CHECK FOR BUG                             #
      # ****************************************************************** #
      #
      bugEval     = evalTools.bugFreeExecution( parsedResults, argDict[ 'EOT' ], executionStatus )
      isBugFree   = bugEval[0]
      explanation = bugEval[1]

      # case execution is bug free
      if isBugFree :
        pass # run another iteration in the infinite loop over LDFICore

      # case BUG EXISTS!!! *dalek accent* EXTERMINATE! EXTERMINATE!
      else :
        # place magic post processing and visualization code here. =]
        print "HIT BUGGER!!!"

        if DRIVER_DEBUG :
          print
          print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
          print "    RUNNING POST PROCESSING"
          print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
          print

        # save the solution which caused the bug and the reason why
        if DRIVER_DEBUG :
          print "isBugFree        = " + str( isBugFree )
          print "currentTriedSoln = " + str( currentTriedSoln )
          print "explanation      = " + str( explanation )

        if os.path.isdir( FINAL_FI_SOLN_SAVEPATH ) :
          save_fi_results_filename = FINAL_FI_SOLN_SAVEPATH + "fault_injection_soln.txt"
          outfile = open( save_fi_results_filename, "w" )
          outfile.write( str( currentTriedSoln ) )
          outfile.write( "\n" )
          outfile.write( explanation )
          outfile.write( "\n" )
          outfile.close()
          print "pyLDFI saved fault injection solution information in : " + save_fi_results_filename
        else :
          tools.bp( __name__, inspect.stack()[0][3], "FATAL ERROR : directory for saving files containing fault injection solution information does not exist:\n" + FINAL_FI_SOLN_SAVEPATH )

        # generate prov graphs of buggy executions.
        vizTools.generateBuggyProvGraphs( parsedResults, argDict[ "EOT" ], irCursor, ITER_COUNT )

        break # break the infinite loop over LDFICore
      # ****************************************************************** #

    # ---------------------------------------------------------------------- #

    prevTriedSoln = currentTriedSoln

  # =================================================================== #

  # -------------------------------------------- #
  # cleanUp saved db stuff
  dedt.cleanUp( irCursor, saveDB )

  # -------------------------------------------- #
  # sanity check
  print "PROGRAM EXITED SUCCESSFULLY"

###############
#  LDFI CORE  #
###############
def LDFICore( argDict, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, triedSolnList, prevTriedSoln, iter_count ) :

  print
  print "*******************************************************"
  print "                 RUNNING LDFI CORE"
  print "*******************************************************"
  print

  os.system( "rm " + C4_DUMP_SAVEPATH )

  # ----------------------------------------------- #

  # translate all input dedalus files into a single datalog program
  outputs = None
  if runTranslator :
    outputs         = dedt.translateDedalus( argDict )
    tableListPath   = outputs[0] # string of table names
    datalogProgPath = outputs[1] # path to datalog program
    irCursor        = outputs[2] # ir db cursor
    saveDB          = outputs[3] # ir db save file
    runTranslator   = False

  if DRIVER_DEBUG :
    if outputs :
      print "outputs              = " + str( outputs )
    print "table   list    path = " + tableListPath
    print "datalog program path = " + datalogProgPath

  # ----------------------------------------------- #
  # evaluate

  resultsPath = None

  # c4
  savepath = C4_DUMP_SAVEPATH
  if RUN_C4_DIRECTLY :
    resultsPath = c4_evaluator.runC4_directly( datalogProgPath, tableListPath, savepath )
  else :
    c4_evaluator.runC4_wrapper( datalogProgPath, tableListPath )

  # ----------------------------------------------- #
  # get provenance trees
  if PROV_TREES_ON :

    if DRIVER_DEBUG :
      print "\n~~~~ BUILDING PROV TREE ~~~~"

    if resultsPath :
      print "Using c4 results from : " + resultsPath
      parsedResults = tools.getEvalResults_file_c4( resultsPath )

      # initialize provenance tree structure
      provTreeComplete = ProvTree.ProvTree( "FinalState", parsedResults, irCursor )

      # grab the set of post records at EOT.
      # assume the right-most attribute/variable/field of the post schema
      # represents the last send time (aka EOT).
      eot = argDict[ "EOT" ]
      postrecords_all = parsedResults[ "post" ]
      postrecords_eot = []

      if DRIVER_DEBUG :
        print "postrecords_all = " + str(postrecords_all)

      for rec in postrecords_all :
        print "rec     = " + str(rec)
        print "rec[-1] = " + str(rec[-1])
        print "eot     = " + str(eot)

        # sanity check
        # check if last element of post record is an integer
        try :
          val = int( rec[-1] )
        except :
          tools.bp( __name__, inspect.stack()[0][3], " Could not convert last element of record " + str(rec) + ", rec[-1] = " + str(rec[-1]) + " into an integer. Therefore, cannot compare with EOT." )

        # collect eot post records only
        if int( rec[-1] ) == int( eot ) :
          postrecords_eot.append( rec )

      print "postrecords_eot = " + str(postrecords_eot)

      # !!! RETURN EARLY IF POST CONTAINS NO EOT RECORDS !!!
      if len( postrecords_eot ) < 1 :
        return ( parsedResults, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, None, prevTriedSoln, "noMoreEOTPostRecords")

      # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #
      # populate prov tree
      for seedRecord in postrecords_eot :
        if DRIVER_DEBUG :
          print " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
          print "           NEW POST RECORD "
          print "seedRecord = " + str( seedRecord )
        newProvTree = provTreeComplete.generateProvTree( "post", seedRecord )
        provTreeComplete.subtrees.append( newProvTree )
      # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

      if OUTPUT_PROV_TREES_ON :
        print "provTreeComplete :"
        provTreeComplete.createGraph( None, iter_count )

    else :
      sys.exit( "ERROR: No path to c4 results file.\nAborting..." ) # sanity check

  # -------------------------------------------- #
  # graphs to CNF

  if TREE_CNF_ON and PROV_TREES_ON :

    if DRIVER_DEBUG :
      print "\n~~~~ CONVERTING PROV TREE TO CNF ~~~~"

    provTree_fmla = EncodedProvTree_CNF.EncodedProvTree_CNF( provTreeComplete ) # get fmla with provTree_fmla.CNFFormula

    if provTree_fmla.rawformula :
      print ">>> provTree_fmla.rawformula = " + str( provTree_fmla.rawformula )
      print
      print ">>> provTree_fmla.rawformula.display() = " + str( provTree_fmla.rawformula.display() )
      print
      print ">>> provTree_fmla.cnfformula = " + str( provTree_fmla.cnfformula )
      print

      if OUTPUT_TREE_CNF_ON :
        provTree_fmla.rawformula.graph()

    else :
      tools.bp( __name__, inspect.stack()[0][3], "ERROR: provTree_fmla.rawformula is empty. Aborting execution..." )

  # -------------------------------------------- #
  # solve CNF
  finalSolnList = []
  if SOLVE_TREE_CNF_ON :
    solns = solverTools.solveCNF( provTree_fmla.cnfformula )

    # sanity check
    if DRIVER_DEBUG :
      print "***************************"
      print "*    PRINTING ALL SOLNS    "
      print "***************************"

    # +++++++++++++++++++++++++++++++++++++++++++++ #
    # collect solns and process into legible format
    if solns :
      numid    = 1

      finalStr = []
      for s in solns.solutions() :
        numsolns = solns.numsolns

        # make pretty
        for var in s :
          finalStr.append( solverTools.toggle_format_str( var, "legible" ) )

        if DRIVER_DEBUG :
          print "SOLN : " + str(numid) + " of " + str( numsolns ) + "\n" + str( finalStr )
          numid += 1

        # add soln to soln list and clear temporary save list for the next iteration
        finalSolnList.append( finalStr )
        finalStr = []

      #tools.bp( __name__, inspect.stack()[0][3], "finalSolnList = " + str(finalSolnList) )

      # duplicates are annoying.
      tmp = []
      for s in finalSolnList :
        if s : # skip empties
          if not s in tmp :
            tmp.append( s )
      finalSolnList = tmp

      # remove all solutions containing non-clock facts.
      tmp = []
      for s in finalSolnList :
        clockOnly = True
        for i in s :
          if not i.startswith( "clock(" ) :
            clockOnly = False # hit a non-clock fact
        if clockOnly :
          tmp.append( s )

      # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #
      # set final final copy of the solution list
      finalSolnList = tmp
      # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

    else :
      tools.bp( __name__, inspect.stack()[0][3], "Congratulations! No solutions exist, meaning the solver could not find a counterexample, which means your program is pyLDFI certified. =D\nAborting..." )
    # +++++++++++++++++++++++++++++++++++++++++++++ #

  # -------------------------------------------- #
  # new datalog prog
  if DRIVER_DEBUG :
    print "before: finalSolnList = " + str( finalSolnList )

  finalSolnList  = listDiff( finalSolnList, triedSolnList ) # remove triedSolns from final solution list

  if DRIVER_DEBUG :
    print "after: finalSolnList = " + str( finalSolnList )
    print "triedSolnList = " + str( triedSolnList )

  # case the finalSolnList still contains clock-only solns
  if len( finalSolnList ) > 0 :
    executionInfo    = newProgGenerationTools.buildNewProg( finalSolnList, irCursor, iter_count )
    newProgSavePath  = executionInfo[0]
    currentTriedSoln = executionInfo[1]
    triedSolnList.append( currentTriedSoln )  # add to list of tried solns

  # case no more clock-only solutions exist
  else :
    return ( parsedResults, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, triedSolnList, None, "exhaustedClockOnlySolns" )

  # -------------------------------------------- #
  return ( parsedResults, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, triedSolnList, currentTriedSoln, "GOOD" )

###############
#  LIST DIFF  #
###############
def listDiff( finalList, triedList ) :

  newFinal = []

  for item in finalList :
    if not item in triedList :
      newFinal.append( item )

  return newFinal

#########################
#  THREAD OF EXECUTION  #
#########################
driver()

#########
#  EOF  #
#########
<commit_msg>Fixed save path for FI solns to include date and time.<commit_after>#!/usr/bin/env python

'''
driver1.py
  A driver exemplifying the orchestration of the
  implemented LDFI workflow.
'''

# **************************************** #

#############
#  IMPORTS  #
#############
# standard python packages
import inspect, os, sys, time

# ------------------------------------------------------ #
# import sibling packages HERE!!!
packagePath  = os.path.abspath( __file__ + "/../.." )
sys.path.append( packagePath )

from dedt           import dedt, dedalusParser
from derivation     import ProvTree
from utils          import parseCommandLineInput, tools
from evaluators     import c4_evaluator, evalTools
from solvers        import EncodedProvTree_CNF, newProgGenerationTools, solverTools
from visualizations import vizTools

# **************************************** #

#############
#  GLOBALS  #
#############
DRIVER_DEBUG            = True
RUN_C4_DIRECTLY         = True
PROV_TREES_ON           = True  # toggle prov tree generation code
OUTPUT_PROV_TREES_ON    = True  # output prov tree renders
ONE_CORE_ITERATION_ONLY = False
TREE_CNF_ON             = True  # toggle provTree to CNF conversion
OUTPUT_TREE_CNF_ON      = False # toggle CNF formula renders
SOLVE_TREE_CNF_ON       = True  # toggle CNF solve

C4_DUMP_SAVEPATH        = os.path.abspath( __file__ + "/../../.." ) + "/save_data/c4Output/c4dump.txt"
FINAL_FI_SOLN_SAVEPATH  = os.path.abspath( __file__ + "/../../.." ) + "/save_data/fault_injection_solns/"

################
#  PARSE ARGS  #
################
# parse arguments from the command line
def parseArgs( ) :
  argDict = {}   # empty dict

  argDict = parseCommandLineInput.parseCommandLineInput( )  # get dictionary of arguments.

  return argDict

############
#  DRIVER  #
############
def driver() :
  # get list of command line args, except prog name
  argList = sys.argv[1:]

  # print help if no args provided
  if len(argList) < 1 :
    thisFilename = os.path.basename(__file__)     # name of this file
    sys.exit( "No arguments provided. Please run 'python " + sys.argv[0] + " -h' for assistance." )

  # ----------------------------------------------- #

  # pass list to parse args, get dict of args
  argDict = parseArgs( )
  print argDict

  # check if EOT is an integer (this better pass!)
  try :
    val = int( argDict[ "EOT" ] )
  except :
    tools.bp( __name__, inspect.stack()[0][3], " Could not convert EOT into integer: EOT = " + str(eot) )

  # =================================================================== #
  # loop until find a bug (or not).

  ITER_COUNT       = 0
  runTranslator    = True
  tableListPath    = None
  datalogProgPath  = None
  irCursor         = None
  saveDB           = None
  triedSolnList    = []
  currentTriedSoln = None
  executionStatus  = None

  prevTriedSoln    = None
  while True :

    executionData   = LDFICore( argDict, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, triedSolnList, prevTriedSoln, ITER_COUNT )

    parsedResults    = executionData[0]
    runTranslator    = executionData[1] # a value indicating whether the db is appropriately populated
    tableListPath    = executionData[2]
    datalogProgPath  = executionData[3]
    irCursor         = executionData[4]
    saveDB           = executionData[5]
    triedSolnList    = executionData[6]
    currentTriedSoln = executionData[7]
    executionStatus  = executionData[8]

    #if currentTriedSoln :
    #  print "currentTriedSoln = " + str( currentTriedSoln )
    #  tools.bp( __name__, inspect.stack()[0][3], "evalTools.bugFreeExecution( parsedResults, argDict[ 'EOT' ], executionStatus ) = " + str(evalTools.bugFreeExecution( parsedResults, argDict[ 'EOT' ], executionStatus )) )

    ITER_COUNT += 1
    # ---------------------------------------------------------------------- #
    # control loop iterations
    if ONE_CORE_ITERATION_ONLY : # only run a single iteration of LDFI (good for debugging)
      break

    else :
      # sanity check pre and post must appear in the evaluation results.
      if not "pre" in parsedResults :
        dedt.cleanUp( irCursor, saveDB )
        tools.bp( __name__, inspect.stack()[0][3], "ERROR : no rule defining pre" )
      elif not "post" in parsedResults :
        dedt.cleanUp( irCursor, saveDB )
        tools.bp( __name__, inspect.stack()[0][3], "ERROR : no rule defining post" )

      # ****************************************************************** #
      #                          CHECK FOR BUG                             #
      # ****************************************************************** #
      #
      bugEval     = evalTools.bugFreeExecution( parsedResults, argDict[ 'EOT' ], executionStatus )
      isBugFree   = bugEval[0]
      explanation = bugEval[1]

      # case execution is bug free
      if isBugFree :
        pass # run another iteration in the infinite loop over LDFICore

      # case BUG EXISTS!!! *dalek accent* EXTERMINATE! EXTERMINATE!
      else :
        # place magic post processing and visualization code here. =]
        print "HIT BUGGER!!!"

        if DRIVER_DEBUG :
          print
          print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
          print "    RUNNING POST PROCESSING"
          print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
          print

        # save the solution which caused the bug and the reason why
        if DRIVER_DEBUG :
          print "isBugFree        = " + str( isBugFree )
          print "currentTriedSoln = " + str( currentTriedSoln )
          print "explanation      = " + str( explanation )

        if os.path.isdir( FINAL_FI_SOLN_SAVEPATH ) :
          save_fi_results_filename = FINAL_FI_SOLN_SAVEPATH + "fault_injection_soln_" + str(time.strftime("%d-%m-%Y")) + "_" + str( time.strftime( "%H"+"hrs-"+"%M"+"mins-"+"%S" +"secs" )) + "_" + str(ITER_COUNT) + ".txt"
          outfile = open( save_fi_results_filename, "w" )
          outfile.write( str( currentTriedSoln ) )
          outfile.write( "\n" )
          outfile.write( explanation )
          outfile.write( "\n" )
          outfile.close()
          print "pyLDFI saved fault injection solution information in : " + save_fi_results_filename
        else :
          tools.bp( __name__, inspect.stack()[0][3], "FATAL ERROR : directory for saving files containing fault injection solution information does not exist:\n" + FINAL_FI_SOLN_SAVEPATH )

        # generate prov graphs of buggy executions.
        vizTools.generateBuggyProvGraphs( parsedResults, argDict[ "EOT" ], irCursor, ITER_COUNT )

        break # break the infinite loop over LDFICore
      # ****************************************************************** #

    # ---------------------------------------------------------------------- #

    prevTriedSoln = currentTriedSoln

  # =================================================================== #

  # -------------------------------------------- #
  # cleanUp saved db stuff
  dedt.cleanUp( irCursor, saveDB )

  # -------------------------------------------- #
  # sanity check
  print "PROGRAM EXITED SUCCESSFULLY"

###############
#  LDFI CORE  #
###############
def LDFICore( argDict, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, triedSolnList, prevTriedSoln, iter_count ) :

  print
  print "*******************************************************"
  print "                 RUNNING LDFI CORE"
  print "*******************************************************"
  print

  os.system( "rm " + C4_DUMP_SAVEPATH )

  # ----------------------------------------------- #

  # translate all input dedalus files into a single datalog program
  outputs = None
  if runTranslator :
    outputs         = dedt.translateDedalus( argDict )
    tableListPath   = outputs[0] # string of table names
    datalogProgPath = outputs[1] # path to datalog program
    irCursor        = outputs[2] # ir db cursor
    saveDB          = outputs[3] # ir db save file
    runTranslator   = False

  if DRIVER_DEBUG :
    if outputs :
      print "outputs              = " + str( outputs )
    print "table   list    path = " + tableListPath
    print "datalog program path = " + datalogProgPath

  # ----------------------------------------------- #
  # evaluate

  resultsPath = None

  # c4
  savepath = C4_DUMP_SAVEPATH
  if RUN_C4_DIRECTLY :
    resultsPath = c4_evaluator.runC4_directly( datalogProgPath, tableListPath, savepath )
  else :
    c4_evaluator.runC4_wrapper( datalogProgPath, tableListPath )

  # ----------------------------------------------- #
  # get provenance trees
  if PROV_TREES_ON :

    if DRIVER_DEBUG :
      print "\n~~~~ BUILDING PROV TREE ~~~~"

    if resultsPath :
      print "Using c4 results from : " + resultsPath
      parsedResults = tools.getEvalResults_file_c4( resultsPath )

      # initialize provenance tree structure
      provTreeComplete = ProvTree.ProvTree( "FinalState", parsedResults, irCursor )

      # grab the set of post records at EOT.
      # assume the right-most attribute/variable/field of the post schema
      # represents the last send time (aka EOT).
      eot = argDict[ "EOT" ]
      postrecords_all = parsedResults[ "post" ]
      postrecords_eot = []

      if DRIVER_DEBUG :
        print "postrecords_all = " + str(postrecords_all)

      for rec in postrecords_all :
        print "rec     = " + str(rec)
        print "rec[-1] = " + str(rec[-1])
        print "eot     = " + str(eot)

        # sanity check
        # check if last element of post record is an integer
        try :
          val = int( rec[-1] )
        except :
          tools.bp( __name__, inspect.stack()[0][3], " Could not convert last element of record " + str(rec) + ", rec[-1] = " + str(rec[-1]) + " into an integer. Therefore, cannot compare with EOT." )

        # collect eot post records only
        if int( rec[-1] ) == int( eot ) :
          postrecords_eot.append( rec )

      print "postrecords_eot = " + str(postrecords_eot)

      # !!! RETURN EARLY IF POST CONTAINS NO EOT RECORDS !!!
      if len( postrecords_eot ) < 1 :
        return ( parsedResults, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, None, prevTriedSoln, "noMoreEOTPostRecords")

      # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #
      # populate prov tree
      for seedRecord in postrecords_eot :
        if DRIVER_DEBUG :
          print " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
          print "           NEW POST RECORD "
          print "seedRecord = " + str( seedRecord )
        newProvTree = provTreeComplete.generateProvTree( "post", seedRecord )
        provTreeComplete.subtrees.append( newProvTree )
      # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

      if OUTPUT_PROV_TREES_ON :
        print "provTreeComplete :"
        provTreeComplete.createGraph( None, iter_count )

    else :
      sys.exit( "ERROR: No path to c4 results file.\nAborting..." ) # sanity check

  # -------------------------------------------- #
  # graphs to CNF

  if TREE_CNF_ON and PROV_TREES_ON :

    if DRIVER_DEBUG :
      print "\n~~~~ CONVERTING PROV TREE TO CNF ~~~~"

    provTree_fmla = EncodedProvTree_CNF.EncodedProvTree_CNF( provTreeComplete ) # get fmla with provTree_fmla.CNFFormula

    if provTree_fmla.rawformula :
      print ">>> provTree_fmla.rawformula = " + str( provTree_fmla.rawformula )
      print
      print ">>> provTree_fmla.rawformula.display() = " + str( provTree_fmla.rawformula.display() )
      print
      print ">>> provTree_fmla.cnfformula = " + str( provTree_fmla.cnfformula )
      print

      if OUTPUT_TREE_CNF_ON :
        provTree_fmla.rawformula.graph()

    else :
      tools.bp( __name__, inspect.stack()[0][3], "ERROR: provTree_fmla.rawformula is empty. Aborting execution..." )

  # -------------------------------------------- #
  # solve CNF
  finalSolnList = []
  if SOLVE_TREE_CNF_ON :
    solns = solverTools.solveCNF( provTree_fmla.cnfformula )

    # sanity check
    if DRIVER_DEBUG :
      print "***************************"
      print "*    PRINTING ALL SOLNS    "
      print "***************************"

    # +++++++++++++++++++++++++++++++++++++++++++++ #
    # collect solns and process into legible format
    if solns :
      numid    = 1

      finalStr = []
      for s in solns.solutions() :
        numsolns = solns.numsolns

        # make pretty
        for var in s :
          finalStr.append( solverTools.toggle_format_str( var, "legible" ) )

        if DRIVER_DEBUG :
          print "SOLN : " + str(numid) + " of " + str( numsolns ) + "\n" + str( finalStr )
          numid += 1

        # add soln to soln list and clear temporary save list for the next iteration
        finalSolnList.append( finalStr )
        finalStr = []

      #tools.bp( __name__, inspect.stack()[0][3], "finalSolnList = " + str(finalSolnList) )

      # duplicates are annoying.
      tmp = []
      for s in finalSolnList :
        if s : # skip empties
          if not s in tmp :
            tmp.append( s )
      finalSolnList = tmp

      # remove all solutions containing non-clock facts.
      tmp = []
      for s in finalSolnList :
        clockOnly = True
        for i in s :
          if not i.startswith( "clock(" ) :
            clockOnly = False # hit a non-clock fact
        if clockOnly :
          tmp.append( s )

      # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #
      # set final final copy of the solution list
      finalSolnList = tmp
      # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #

    else :
      tools.bp( __name__, inspect.stack()[0][3], "Congratulations! No solutions exist, meaning the solver could not find a counterexample, which means your program is pyLDFI certified. =D\nAborting..." )
    # +++++++++++++++++++++++++++++++++++++++++++++ #

  # -------------------------------------------- #
  # new datalog prog
  if DRIVER_DEBUG :
    print "before: finalSolnList = " + str( finalSolnList )

  finalSolnList  = listDiff( finalSolnList, triedSolnList ) # remove triedSolns from final solution list

  if DRIVER_DEBUG :
    print "after: finalSolnList = " + str( finalSolnList )
    print "triedSolnList = " + str( triedSolnList )

  # case the finalSolnList still contains clock-only solns
  if len( finalSolnList ) > 0 :
    executionInfo    = newProgGenerationTools.buildNewProg( finalSolnList, irCursor, iter_count )
    newProgSavePath  = executionInfo[0]
    currentTriedSoln = executionInfo[1]
    triedSolnList.append( currentTriedSoln )  # add to list of tried solns

  # case no more clock-only solutions exist
  else :
    return ( parsedResults, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, triedSolnList, None, "exhaustedClockOnlySolns" )

  # -------------------------------------------- #
  return ( parsedResults, runTranslator, tableListPath, datalogProgPath, irCursor, saveDB, triedSolnList, currentTriedSoln, "GOOD" )

###############
#  LIST DIFF  #
###############
def listDiff( finalList, triedList ) :

  newFinal = []

  for item in finalList :
    if not item in triedList :
      newFinal.append( item )

  return newFinal

#########################
#  THREAD OF EXECUTION  #
#########################
driver()

#########
#  EOF  #
#########
<|endoftext|>


<commit_before>#!/usr/bin/env python
"""
/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
http://bohrium.bitbucket.org

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
"""
from _util import dtype_from_bhc, dtype_name
import bhc
import numpy

# This module consist of bohrium.ndarray methods

#Returns True if 'ary' is a Bohrium array
def check(ary):
    return hasattr(ary, "bhc_ary")

#Returns True if 'ary' is a NumPy view with a Bohrium base array
def check_biclass(ary):
    if not isinstance(ary, numpy.ndarray) or numpy.isscalar(ary):
        return False
    if check(ary):
        return False
    else:
        return check(get_base(ary))

#Returns a Bohrium version of 'ary' if 'ary' is a NumPy view with a
#Bohrium base array else 'ary' is returned unmodified
def fix_biclass(ary):
    if check_biclass(ary):
        return ary.view(type(get_base(ary)))
    else:
        return ary

#Creates a new bohrium.ndarray with 'bhc_ary' as the Bohrium-C part.
#Use a new Bohrium-C array when 'bhc_ary' is None.
def new(shape, dtype, bhc_ary=None):
    import _bh #We import locally in order to avoid cycles
    ret = _bh.ndarray(shape, dtype=dtype)
    if bhc_ary is None:
        new_bhc_base(ret)
    else:
        ret.bhc_ary = bhc_ary
    exec "bhc.bh_multi_array_%s_set_temp(ret.bhc_ary, 0)"%dtype_name(dtype)
    return ret

#Creates a new Bohrium-C base array.
def new_bhc_base(ary):
    if not check(ary):
        raise TypeError("must be a Bohrium array")

    if ary.base is not None:
        raise ValueError("Views do not have a Bohrium-C base array")

    if ary.bhc_ary is not None:
        raise ValueError("The array has a Bohrium-C base array already")

    if not ary.flags['BEHAVED']:
        raise ValueError("Bohrium arrays must be aligned, writeable, and in machine byte-order")

    if not ary.flags['OWNDATA']:
        raise ValueError("Bohrium base arrays must own its data")

    if not ary.flags['C_CONTIGUOUS']:
        raise ValueError("For now Bohrium only supports C-style arrays")

    dtype = dtype_name(ary)
    exec "ary.bhc_ary = bhc.bh_multi_array_%s_new_empty(ary.ndim, ary.shape)"%dtype

#Get the final base array of 'ary'
def get_base(ary):
    if ary.base is None:
        return ary
    else:
        base = ary.base
        while base.base is not None:
            base = base.base
        if check(ary) and not check(base):
            raise RuntimeError("A Bohrium view points to a NumPy base")
        return base

#Return True when 'ary' is a base array
def is_base(ary):
    b = get_base(ary)
    return b is ary

#Returns the Bohrium-C part of the array (supports both Bohrium or NumPy arrays)
#NB: the returned object is always a view and should be
#deleted after use through call to 'del_bhc_obj()'
def get_bhc(ary):
    base = get_base(ary)
    if not check(base):
        raise TypeError("the base must be a Bohrium array")
    if not ary.flags['BEHAVED']:
        raise ValueError("Bohrium arrays must be aligned, writeable, and in machine byte-order")
    if ary.dtype != base.dtype:
        raise ValueError("Bohrium base and view must have same data type")

    #Lets make sure that 'ary' has a Bohrium-C base array
    if base.bhc_ary is None:
        base._data_np2bhc()

    dtype = dtype_name(base)
    exec "bh_base = bhc.bh_multi_array_%s_get_base(base.bhc_ary)"%dtype
    offset = (ary.ctypes.data - base.ctypes.data) / base.itemsize
    if (ary.ctypes.data - base.ctypes.data) % base.itemsize != 0:
        raise TypeError("The view offset must be element aligned")
    if not (0 <= offset < base.size):
        raise TypeError("The view offset is greater than the total number of elements in the base!")
    strides = []
    for s in ary.strides:
        strides.append(s / base.itemsize)
        if s % base.itemsize != 0:
            raise TypeError("The strides must be element aligned")

    f = eval("bhc.bh_multi_array_%s_new_from_view"%dtype)
    return f(bh_base, ary.ndim, offset, ary.shape, strides)

#Delete the Bohrium-C object
def del_bhc_obj(bhc_obj):
    exec "bhc.bh_multi_array_%s_destroy(bhc_obj)"%dtype_from_bhc(bhc_obj)

#Delete the Bohrium-C part of the bohrium.ndarray and its base
def del_bhc(ary):
    if ary.bhc_ary is not None:
        del_bhc_obj(ary.bhc_ary)
        ary.bhc_ary = None
    base = get_base(ary)
    if base is not ary:
        del_bhc(base)

#Return the Bohrium-C data pointer (represented by a Python integer)
#When allocate is True, it allocates memory instead of returning None
#When nullify is True, the Bohrium-C data pointer is set to NULL
def get_bhc_data_pointer(ary, allocate=False, nullify=False):
    if not check(ary):
        raise TypeError("must be a Bohrium array")
    ary = get_base(ary)
    dtype = dtype_name(ary)
    bhc_ary = get_bhc(ary)
    exec "bhc.bh_multi_array_%s_sync(bhc_ary)"%dtype
    exec "base = bhc.bh_multi_array_%s_get_base(bhc_ary)"%dtype
    exec "data = bhc.bh_multi_array_%s_get_base_data(base)"%dtype
    if data is None:
        if not allocate:
            return 0
        exec "data = bhc.bh_multi_array_%s_get_base_data_and_force_alloc(base)"%dtype
        if data is None:
            raise MemoryError()
    if nullify:
        exec "bhc.bh_multi_array_%s_nullify_base_data(base)"%dtype
    return int(data)

<commit_msg>Checking for out of bounds views in get_bhc()<commit_after>#!/usr/bin/env python
"""
/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
http://bohrium.bitbucket.org

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
"""
from _util import dtype_from_bhc, dtype_name
import bhc
import numpy

# This module consist of bohrium.ndarray methods

#Returns True if 'ary' is a Bohrium array
def check(ary):
    return hasattr(ary, "bhc_ary")

#Returns True if 'ary' is a NumPy view with a Bohrium base array
def check_biclass(ary):
    if not isinstance(ary, numpy.ndarray) or numpy.isscalar(ary):
        return False
    if check(ary):
        return False
    else:
        return check(get_base(ary))

#Returns a Bohrium version of 'ary' if 'ary' is a NumPy view with a
#Bohrium base array else 'ary' is returned unmodified
def fix_biclass(ary):
    if check_biclass(ary):
        return ary.view(type(get_base(ary)))
    else:
        return ary

#Creates a new bohrium.ndarray with 'bhc_ary' as the Bohrium-C part.
#Use a new Bohrium-C array when 'bhc_ary' is None.
def new(shape, dtype, bhc_ary=None):
    import _bh #We import locally in order to avoid cycles
    ret = _bh.ndarray(shape, dtype=dtype)
    if bhc_ary is None:
        new_bhc_base(ret)
    else:
        ret.bhc_ary = bhc_ary
    exec "bhc.bh_multi_array_%s_set_temp(ret.bhc_ary, 0)"%dtype_name(dtype)
    return ret

#Creates a new Bohrium-C base array.
def new_bhc_base(ary):
    if not check(ary):
        raise TypeError("must be a Bohrium array")

    if ary.base is not None:
        raise ValueError("Views do not have a Bohrium-C base array")

    if ary.bhc_ary is not None:
        raise ValueError("The array has a Bohrium-C base array already")

    if not ary.flags['BEHAVED']:
        raise ValueError("Bohrium arrays must be aligned, writeable, and in machine byte-order")

    if not ary.flags['OWNDATA']:
        raise ValueError("Bohrium base arrays must own its data")

    if not ary.flags['C_CONTIGUOUS']:
        raise ValueError("For now Bohrium only supports C-style arrays")

    dtype = dtype_name(ary)
    exec "ary.bhc_ary = bhc.bh_multi_array_%s_new_empty(ary.ndim, ary.shape)"%dtype

#Get the final base array of 'ary'
def get_base(ary):
    if ary.base is None:
        return ary
    else:
        base = ary.base
        while base.base is not None:
            base = base.base
        if check(ary) and not check(base):
            raise RuntimeError("A Bohrium view points to a NumPy base")
        return base

#Return True when 'ary' is a base array
def is_base(ary):
    b = get_base(ary)
    return b is ary

#Returns the Bohrium-C part of the array (supports both Bohrium or NumPy arrays)
#NB: the returned object is always a view and should be
#deleted after use through call to 'del_bhc_obj()'
def get_bhc(ary):
    base = get_base(ary)
    if not check(base):
        raise TypeError("the base must be a Bohrium array")
    if not ary.flags['BEHAVED']:
        raise ValueError("Bohrium arrays must be aligned, writeable, and in machine byte-order")
    if ary.dtype != base.dtype:
        raise ValueError("Bohrium base and view must have same data type")
    if not (base.ctypes.data <= ary.ctypes.data < base.ctypes.data + base.nbytes):
        raise ValueError("The view must point to data within the base array")

    #Lets make sure that 'ary' has a Bohrium-C base array
    if base.bhc_ary is None:
        base._data_np2bhc()

    dtype = dtype_name(base)
    offset = (ary.ctypes.data - base.ctypes.data) / base.itemsize
    if (ary.ctypes.data - base.ctypes.data) % base.itemsize != 0:
        raise TypeError("The view offset must be element aligned")
    if not (0 <= offset < base.size):
        raise TypeError("The view offset is greater than the total number of elements in the base!")
    strides = []
    for s in ary.strides:
        strides.append(s / base.itemsize)
        if s % base.itemsize != 0:
            raise TypeError("The strides must be element aligned")

    exec "bh_base = bhc.bh_multi_array_%s_get_base(base.bhc_ary)"%dtype
    f = eval("bhc.bh_multi_array_%s_new_from_view"%dtype)
    return f(bh_base, ary.ndim, offset, ary.shape, strides)

#Delete the Bohrium-C object
def del_bhc_obj(bhc_obj):
    exec "bhc.bh_multi_array_%s_destroy(bhc_obj)"%dtype_from_bhc(bhc_obj)

#Delete the Bohrium-C part of the bohrium.ndarray and its base
def del_bhc(ary):
    if ary.bhc_ary is not None:
        del_bhc_obj(ary.bhc_ary)
        ary.bhc_ary = None
    base = get_base(ary)
    if base is not ary:
        del_bhc(base)

#Return the Bohrium-C data pointer (represented by a Python integer)
#When allocate is True, it allocates memory instead of returning None
#When nullify is True, the Bohrium-C data pointer is set to NULL
def get_bhc_data_pointer(ary, allocate=False, nullify=False):
    if not check(ary):
        raise TypeError("must be a Bohrium array")
    ary = get_base(ary)
    dtype = dtype_name(ary)
    bhc_ary = get_bhc(ary)
    exec "bhc.bh_multi_array_%s_sync(bhc_ary)"%dtype
    exec "base = bhc.bh_multi_array_%s_get_base(bhc_ary)"%dtype
    exec "data = bhc.bh_multi_array_%s_get_base_data(base)"%dtype
    if data is None:
        if not allocate:
            return 0
        exec "data = bhc.bh_multi_array_%s_get_base_data_and_force_alloc(base)"%dtype
        if data is None:
            raise MemoryError()
    if nullify:
        exec "bhc.bh_multi_array_%s_nullify_base_data(base)"%dtype
    return int(data)

<|endoftext|>


<commit_before># Copyright (c) 2012 Lars Hupfeldt Nielsen, Hupfeldt IT
# All rights reserved. This work is under a BSD license, see LICENSE.TXT.

# pylint: disable=E0611
from pytest import raises, xfail

from .utils.utils import config_error, next_line_num, assert_lines_in
from .utils.compare_json import compare_json

from multiconf import mc_config, ConfigItem, ConfigException, MC_REQUIRED
from multiconf.decorators import required, named_as

from multiconf.envs import EnvFactory

def ce(line_num, *lines):
    return config_error(__file__, line_num, *lines)

ef = EnvFactory()
dev1 = ef.Env('dev1')
dev2 = ef.Env('dev2')
dev3 = ef.Env('dev3')
dev4 = ef.Env('dev4')
dev5 = ef.Env('dev5')
g_dev12 = ef.EnvGroup('g_dev12', dev1, dev2)
g_dev34 = ef.EnvGroup('g_dev23', dev3, dev4)
g_dev12_3 = ef.EnvGroup('g_dev12_3', g_dev12, dev3)
g_dev2_34 = ef.EnvGroup('g_dev2_34', dev2, g_dev34)
pp = ef.Env('pp')
prod = ef.Env('prod')
g_ppr = ef.EnvGroup('g_ppr', pp, prod)

class item(ConfigItem):
    def __init__(self, anattr=MC_REQUIRED, mc_include=None, mc_exclude=None):
        super(item, self).__init__(mc_include=mc_include, mc_exclude=mc_exclude)
        self.anattr = anattr
        self.anotherattr = None
        self.b = None

@named_as('item')
@required('anitem')
class decorated_item(ConfigItem):
    xx = 3

    def __init__(self, mc_include=None, mc_exclude=None):
        super(decorated_item, self).__init__(mc_include=mc_include, mc_exclude=mc_exclude)
        self.anotherattr = MC_REQUIRED

_include_exclude_for_configitem_expected_json = """{
    "__class__": "_ConfigRoot",
    "__id__": 0000,
    "env": {
        "__class__": "Env",
        "name": "prod"
    },
    "item": false,
    "item #Excluded: <class 'test.include_exclude2_test.item'>": true
}"""

def test_exclude_include_overlapping_groups_excluded_resolved_with_mc_required():
    @mc_config(ef)
    def conf(_):
        """Covers exclude resolve branch"""
        with item(mc_include=[g_dev12, g_dev12_3, pp, dev2], mc_exclude=[g_dev34, g_dev2_34, dev3]) as it:
            it.setattr('anattr', pp=1, g_dev12_3=2)
            it.setattr('b', pp=1, dev2=0)
            it.setattr('anotherattr', default=111, dev5=7)

    cr = ef.config(prod)
    assert not cr.item
    assert compare_json(cr, _include_exclude_for_configitem_expected_json, test_excluded=True)

    cr = ef.config(dev1)
    assert cr.item

    cr = ef.config(dev2)
    assert cr.item
    assert cr.item.b == 0

    cr = ef.config(dev3)
    assert not cr.item

    cr = ef.config(dev4)
    assert not cr.item

    cr = ef.config(pp)
    assert cr.item
    assert cr.item.anattr == 1
    assert cr.item.b == 1
    assert cr.item.anotherattr == 111

_include_exclude_for_configitem_required_decorator_expected_json = """{
    "__class__": "_ConfigRoot",
    "__id__": 0000,
    "env": {
        "__class__": "Env",
        "name": "prod"
    },
    "item": false,
    "item #Excluded: <class 'test.include_exclude2_test.decorated_item'>": true
}"""

def test_exclude_include_overlapping_groups_excluded_resolved_with_required_decorator():
    class anitem(ConfigItem):
        xx = 222

    @mc_config(ef)
    def conf(_):
        """Covers exclude resolve branch"""
        with decorated_item(mc_include=[g_dev12, g_dev12_3, pp, dev2], mc_exclude=[g_dev34, g_dev2_34, dev3]) as it:
            anitem()
            it.setattr('anotherattr', default=111, dev5=7)

    cr = ef.config(prod)
    assert not cr.item
    assert compare_json(cr, _include_exclude_for_configitem_required_decorator_expected_json, test_excluded=True)

    cr = ef.config(dev1)
    assert cr.item

    cr = ef.config(dev2)
    assert cr.item

    cr = ef.config(dev3)
    assert not cr.item

    cr = ef.config(dev4)
    assert not cr.item

    cr = ef.config(pp)
    assert cr.item.xx == 3
    assert cr.item.anitem.xx == 222
    assert cr.item.anotherattr == 111

def test_exclude_include_overlapping_groups_included_resolved():
    @mc_config(ef)
    def conf(_):
        """Covers include resolve branch"""
        with item(mc_include=[dev3, g_dev12, g_dev12_3, pp, dev2], mc_exclude=[g_dev34, g_dev2_34]) as it:
            it.setattr('anattr', pp=1, g_dev12_3=2, dev5=117, g_ppr=4)

    cr = ef.config(prod)
    assert not cr.item
    assert compare_json(cr, _include_exclude_for_configitem_expected_json, test_excluded=True)

    cr = ef.config(dev1)
    assert cr.item

    cr = ef.config(dev2)
    assert cr.item

    cr = ef.config(dev3)
    assert cr.item

    cr = ef.config(dev4)
    assert not cr.item

    cr = ef.config(pp)
    assert cr.item
    assert cr.item.anattr == 1

_exclude_include_overlapping_groups_excluded_unresolved_expected_ex = """
Env('dev2') is specified in both include and exclude, with no single most specific group or direct env:
 - from exclude: EnvGroup('g_dev12_3') {
   EnvGroup('g_dev12') {
      Env('dev1'),
      Env('dev2')
   },
   Env('dev3')
}
 - from include: EnvGroup('g_dev2_34') {
   Env('dev2'),
   EnvGroup('g_dev23') {
      Env('dev3'),
      Env('dev4')
   }
}""".strip()

# TODO multiple envs errors
"""File "%(file)s", line %(line)d
ConfigError: Env 'dev2' is specified in both include and exclude, with no single most specific group or direct env:
    from: EnvGroup('g_dev12_3') {
     EnvGroup('g_dev12') {
       Env('dev1'),
       Env('dev2')
  },
     Env('dev3')
}
    from: EnvGroup('g_dev2_34') {
     Env('dev2'),
     EnvGroup('g_dev23') {
       Env('dev3'),
       Env('dev4')
  }
}
File "%(file)s", line %(line)d
ConfigError: Env 'dev3' is specified in both include and exclude, with no single most specific group or direct env:
    from: EnvGroup('g_dev23') {
     Env('dev3'),
     Env('dev4')
}
    from: EnvGroup('g_dev12_3') {
     EnvGroup('g_dev12') {
       Env('dev1'),
       Env('dev2')
  },
     Env('dev3')
}
    from: EnvGroup('g_dev2_34') {
     Env('dev2'),
     EnvGroup('g_dev23') {
       Env('dev3'),
       Env('dev4')
  }
}
""".strip()

def test_exclude_include_overlapping_groups_excluded_unresolved_init(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            errorline[0] = next_line_num()
            item(mc_include=[g_dev12_3, pp], mc_exclude=[g_dev34, g_dev2_34])

    print(str(exinfo.value))
    assert "There were 2 errors when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    print(serr)
    expected = _exclude_include_overlapping_groups_excluded_unresolved_expected_ex % dict(file=__file__, line=errorline[0])
    print('---------------------')
    print(expected)
    assert expected in serr

def test_exclude_include_overlapping_groups_excluded_unresolved_init_reversed(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            errorline[0] = next_line_num()
            item(anattr=1, mc_include=[g_dev34, g_dev2_34], mc_exclude=[g_dev12_3, pp])

    #assert "There was 1 error when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    assert _exclude_include_overlapping_groups_excluded_unresolved_expected_ex % dict(file=__file__, line=errorline[0]) in serr

def test_exclude_include_overlapping_groups_excluded_unresolved_mc_select_envs(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            with item() as it:
                errorline[0] = next_line_num()
                it.mc_select_envs(include=[g_dev12_3, pp], exclude=[g_dev34, g_dev2_34])

    assert "There were 2 errors when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    assert _exclude_include_overlapping_groups_excluded_unresolved_expected_ex % dict(file=__file__, line=errorline[0]) in serr

def test_exclude_include_overlapping_groups_excluded_unresolved_mc_select_envs_reversed(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            with item() as it:
                errorline[0] = next_line_num()
                it.mc_select_envs(include=[g_dev34, g_dev2_34], exclude=[g_dev12_3, pp])

    assert "There were 2 errors when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    assert _exclude_include_overlapping_groups_excluded_unresolved_expected_ex % dict(file=__file__, line=errorline[0]) in serr

def test_exclude_include_overlapping_groups_dev3_finally_resolved_dev2_unresolved(capsys):
    xfail("TODO implement test")
    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            item(mc_include=[g_dev12_3, pp], mc_exclude=[g_dev34, g_dev2_34, dev3])

    assert "There was 1 error when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    expected = "ConfigError: Env 'dev2' is specified in both include and exclude, with no single most specific group or direct env:"
    assert expected in serr

def test_exclude_include_overlapping_groups_dev3_dev2_finally_resolved():
    @mc_config(ef)
    def _(_):
        with item(mc_include=[g_dev12_3, pp], mc_exclude=[g_dev34, g_dev2_34, dev3, dev2]) as it:
            it.setattr('anattr', g_dev12_3=123, pp=1)

def test_exclude_include_error_before_exclude(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            with item() as it:
                errorline[0] = next_line_num()
                it.setattr('_a', 7)
                it.mc_select_envs(exclude=[prod])
                raise Exception()

    _sout, serr = capsys.readouterr()
    msg = "Trying to set attribute '_a' on a config item. Atributes starting with '_' can not be set using item.setattr. Use assignment instead."
    assert ce(errorline[0], msg) == serr
<commit_msg>add missing 'anattr' arg<commit_after># Copyright (c) 2012 Lars Hupfeldt Nielsen, Hupfeldt IT
# All rights reserved. This work is under a BSD license, see LICENSE.TXT.

# pylint: disable=E0611
from pytest import raises, xfail

from .utils.utils import config_error, next_line_num, assert_lines_in
from .utils.compare_json import compare_json

from multiconf import mc_config, ConfigItem, ConfigException, MC_REQUIRED
from multiconf.decorators import required, named_as

from multiconf.envs import EnvFactory

def ce(line_num, *lines):
    return config_error(__file__, line_num, *lines)

ef = EnvFactory()
dev1 = ef.Env('dev1')
dev2 = ef.Env('dev2')
dev3 = ef.Env('dev3')
dev4 = ef.Env('dev4')
dev5 = ef.Env('dev5')
g_dev12 = ef.EnvGroup('g_dev12', dev1, dev2)
g_dev34 = ef.EnvGroup('g_dev23', dev3, dev4)
g_dev12_3 = ef.EnvGroup('g_dev12_3', g_dev12, dev3)
g_dev2_34 = ef.EnvGroup('g_dev2_34', dev2, g_dev34)
pp = ef.Env('pp')
prod = ef.Env('prod')
g_ppr = ef.EnvGroup('g_ppr', pp, prod)

class item(ConfigItem):
    def __init__(self, anattr=MC_REQUIRED, mc_include=None, mc_exclude=None):
        super(item, self).__init__(mc_include=mc_include, mc_exclude=mc_exclude)
        self.anattr = anattr
        self.anotherattr = None
        self.b = None

@named_as('item')
@required('anitem')
class decorated_item(ConfigItem):
    xx = 3

    def __init__(self, mc_include=None, mc_exclude=None):
        super(decorated_item, self).__init__(mc_include=mc_include, mc_exclude=mc_exclude)
        self.anotherattr = MC_REQUIRED

_include_exclude_for_configitem_expected_json = """{
    "__class__": "_ConfigRoot",
    "__id__": 0000,
    "env": {
        "__class__": "Env",
        "name": "prod"
    },
    "item": false,
    "item #Excluded: <class 'test.include_exclude2_test.item'>": true
}"""

def test_exclude_include_overlapping_groups_excluded_resolved_with_mc_required():
    @mc_config(ef)
    def conf(_):
        """Covers exclude resolve branch"""
        with item(mc_include=[g_dev12, g_dev12_3, pp, dev2], mc_exclude=[g_dev34, g_dev2_34, dev3]) as it:
            it.setattr('anattr', pp=1, g_dev12_3=2)
            it.setattr('b', pp=1, dev2=0)
            it.setattr('anotherattr', default=111, dev5=7)

    cr = ef.config(prod)
    assert not cr.item
    assert compare_json(cr, _include_exclude_for_configitem_expected_json, test_excluded=True)

    cr = ef.config(dev1)
    assert cr.item

    cr = ef.config(dev2)
    assert cr.item
    assert cr.item.b == 0

    cr = ef.config(dev3)
    assert not cr.item

    cr = ef.config(dev4)
    assert not cr.item

    cr = ef.config(pp)
    assert cr.item
    assert cr.item.anattr == 1
    assert cr.item.b == 1
    assert cr.item.anotherattr == 111

_include_exclude_for_configitem_required_decorator_expected_json = """{
    "__class__": "_ConfigRoot",
    "__id__": 0000,
    "env": {
        "__class__": "Env",
        "name": "prod"
    },
    "item": false,
    "item #Excluded: <class 'test.include_exclude2_test.decorated_item'>": true
}"""

def test_exclude_include_overlapping_groups_excluded_resolved_with_required_decorator():
    class anitem(ConfigItem):
        xx = 222

    @mc_config(ef)
    def conf(_):
        """Covers exclude resolve branch"""
        with decorated_item(mc_include=[g_dev12, g_dev12_3, pp, dev2], mc_exclude=[g_dev34, g_dev2_34, dev3]) as it:
            anitem()
            it.setattr('anotherattr', default=111, dev5=7)

    cr = ef.config(prod)
    assert not cr.item
    assert compare_json(cr, _include_exclude_for_configitem_required_decorator_expected_json, test_excluded=True)

    cr = ef.config(dev1)
    assert cr.item

    cr = ef.config(dev2)
    assert cr.item

    cr = ef.config(dev3)
    assert not cr.item

    cr = ef.config(dev4)
    assert not cr.item

    cr = ef.config(pp)
    assert cr.item.xx == 3
    assert cr.item.anitem.xx == 222
    assert cr.item.anotherattr == 111

def test_exclude_include_overlapping_groups_included_resolved():
    @mc_config(ef)
    def conf(_):
        """Covers include resolve branch"""
        with item(mc_include=[dev3, g_dev12, g_dev12_3, pp, dev2], mc_exclude=[g_dev34, g_dev2_34]) as it:
            it.setattr('anattr', pp=1, g_dev12_3=2, dev5=117, g_ppr=4)

    cr = ef.config(prod)
    assert not cr.item
    assert compare_json(cr, _include_exclude_for_configitem_expected_json, test_excluded=True)

    cr = ef.config(dev1)
    assert cr.item

    cr = ef.config(dev2)
    assert cr.item

    cr = ef.config(dev3)
    assert cr.item

    cr = ef.config(dev4)
    assert not cr.item

    cr = ef.config(pp)
    assert cr.item
    assert cr.item.anattr == 1

_exclude_include_overlapping_groups_excluded_unresolved_expected_ex = """
Env('dev2') is specified in both include and exclude, with no single most specific group or direct env:
 - from exclude: EnvGroup('g_dev12_3') {
   EnvGroup('g_dev12') {
      Env('dev1'),
      Env('dev2')
   },
   Env('dev3')
}
 - from include: EnvGroup('g_dev2_34') {
   Env('dev2'),
   EnvGroup('g_dev23') {
      Env('dev3'),
      Env('dev4')
   }
}""".strip()

# TODO multiple envs errors
"""File "%(file)s", line %(line)d
ConfigError: Env 'dev2' is specified in both include and exclude, with no single most specific group or direct env:
    from: EnvGroup('g_dev12_3') {
     EnvGroup('g_dev12') {
       Env('dev1'),
       Env('dev2')
  },
     Env('dev3')
}
    from: EnvGroup('g_dev2_34') {
     Env('dev2'),
     EnvGroup('g_dev23') {
       Env('dev3'),
       Env('dev4')
  }
}
File "%(file)s", line %(line)d
ConfigError: Env 'dev3' is specified in both include and exclude, with no single most specific group or direct env:
    from: EnvGroup('g_dev23') {
     Env('dev3'),
     Env('dev4')
}
    from: EnvGroup('g_dev12_3') {
     EnvGroup('g_dev12') {
       Env('dev1'),
       Env('dev2')
  },
     Env('dev3')
}
    from: EnvGroup('g_dev2_34') {
     Env('dev2'),
     EnvGroup('g_dev23') {
       Env('dev3'),
       Env('dev4')
  }
}
""".strip()

def test_exclude_include_overlapping_groups_excluded_unresolved_init(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            errorline[0] = next_line_num()
            item(anattr=1, mc_include=[g_dev12_3, pp], mc_exclude=[g_dev34, g_dev2_34])

    print(str(exinfo.value))
    assert "There were 2 errors when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    print(serr)
    expected = _exclude_include_overlapping_groups_excluded_unresolved_expected_ex % dict(file=__file__, line=errorline[0])
    print('---------------------')
    print(expected)
    assert expected in serr

def test_exclude_include_overlapping_groups_excluded_unresolved_init_reversed(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            errorline[0] = next_line_num()
            item(anattr=1, mc_include=[g_dev34, g_dev2_34], mc_exclude=[g_dev12_3, pp])

    #assert "There was 1 error when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    assert _exclude_include_overlapping_groups_excluded_unresolved_expected_ex % dict(file=__file__, line=errorline[0]) in serr

def test_exclude_include_overlapping_groups_excluded_unresolved_mc_select_envs(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            with item(anattr=1) as it:
                errorline[0] = next_line_num()
                it.mc_select_envs(include=[g_dev12_3, pp], exclude=[g_dev34, g_dev2_34])

    assert "There were 2 errors when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    assert _exclude_include_overlapping_groups_excluded_unresolved_expected_ex % dict(file=__file__, line=errorline[0]) in serr

def test_exclude_include_overlapping_groups_excluded_unresolved_mc_select_envs_reversed(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            with item(anattr=1) as it:
                errorline[0] = next_line_num()
                it.mc_select_envs(include=[g_dev34, g_dev2_34], exclude=[g_dev12_3, pp])

    assert "There were 2 errors when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    assert _exclude_include_overlapping_groups_excluded_unresolved_expected_ex % dict(file=__file__, line=errorline[0]) in serr

def test_exclude_include_overlapping_groups_dev3_finally_resolved_dev2_unresolved(capsys):
    xfail("TODO implement test")
    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            item(anattr=1, mc_include=[g_dev12_3, pp], mc_exclude=[g_dev34, g_dev2_34, dev3])

    assert "There was 1 error when defining item" in str(exinfo.value)
    _sout, serr = capsys.readouterr()
    expected = "ConfigError: Env 'dev2' is specified in both include and exclude, with no single most specific group or direct env:"
    assert expected in serr

def test_exclude_include_overlapping_groups_dev3_dev2_finally_resolved():
    @mc_config(ef)
    def _(_):
        with item(mc_include=[g_dev12_3, pp], mc_exclude=[g_dev34, g_dev2_34, dev3, dev2]) as it:
            it.setattr('anattr', g_dev12_3=123, pp=1)

def test_exclude_include_error_before_exclude(capsys):
    xfail("TODO implement test")
    errorline = [None]

    with raises(ConfigException) as exinfo:
        @mc_config(ef)
        def _(_):
            with item() as it:
                errorline[0] = next_line_num()
                it.setattr('_a', 7)
                it.mc_select_envs(exclude=[prod])
                raise Exception()

    _sout, serr = capsys.readouterr()
    msg = "Trying to set attribute '_a' on a config item. Atributes starting with '_' can not be set using item.setattr. Use assignment instead."
    assert ce(errorline[0], msg) == serr
<|endoftext|>


<commit_before>
import discord
from discord.ext import commands

import collections
import copy
import random
import tempfile

from modules import maze
from modules import utilities
from utilities import checks
from utilities import errors

def setup(bot):
	bot.add_cog(Reactions(bot))

	async def process_reactions(reaction, user):
		if user == bot.user:
			return
		await bot.cogs["Reactions"].reaction_messages[reaction.message.id](reaction, user)
		await bot.db.execute(
			"""
			UPDATE meta.stats
			SET reaction_responses = reaction_responses + 1
			WHERE timestamp = $1
			""",
			bot.online_time
		)
		# Count fixed to stop counting own reactions on 2019-10-25

	@bot.event
	async def on_reaction_add(reaction, user):
		if "Reactions" in bot.cogs and reaction.message.id in bot.cogs["Reactions"].reaction_messages:
			await process_reactions(reaction, user)

	@bot.event
	async def on_reaction_remove(reaction, user):
		if "Reactions" in bot.cogs and reaction.message.id in bot.cogs["Reactions"].reaction_messages:
			await process_reactions(reaction, user)

class Reactions(commands.Cog):

	def __init__(self, bot):
		self.bot = bot
		self.reaction_messages = {}
		self.mazes = {}
		self.numbers = {'\N{KEYCAP TEN}': 10}
		for number in range(9):
			self.numbers[chr(ord('\u0031') + number) + '\N{COMBINING ENCLOSING KEYCAP}'] = number + 1 # '\u0031' - 1
		self.arrows = collections.OrderedDict([('\N{LEFTWARDS BLACK ARROW}', 'W'), ('\N{UPWARDS BLACK ARROW}', 'N'), ('\N{DOWNWARDS BLACK ARROW}', 'S'), ('\N{BLACK RIGHTWARDS ARROW}', 'E')]) # tuple?
		self.controls = collections.OrderedDict([('\N{BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR}', "pause_resume"), ('\N{BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', "skip"), ('\N{CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY}', "replay"), ('\N{TWISTED RIGHTWARDS ARROWS}', "shuffle"), ('\N{RADIO}', "radio"), ('\N{SPEAKER WITH ONE SOUND WAVE}', "volume_down"), ('\N{SPEAKER WITH THREE SOUND WAVES}', "volume_up")])
		self.reaction_commands = (
			(self.guess, "Games", "guess", [], [checks.not_forbidden()]),
			(self.news, "Resources", "news", [], [checks.not_forbidden()]),
			(self.maze, "Games", "maze", [], [checks.not_forbidden()]),
			(self.playing, "Audio", "playing", ["player"], [checks.not_forbidden(), commands.guild_only()])
		)
		for command, cog_name, parent_name, aliases, command_checks in self.reaction_commands:
			self.reactions.add_command(commands.Command(command, aliases = aliases, checks = command_checks))
			if (cog := self.bot.get_cog(cog_name)) and (parent := getattr(cog, parent_name)):
				parent.add_command(commands.Command(command, name = "reactions", aliases = ["reaction", 'r'], checks = command_checks))

	def cog_unload(self):
		for command, cog_name, parent_name, *_ in self.reaction_commands:
			if (cog := self.bot.get_cog(cog_name)) and (parent := getattr(cog, parent_name)):
				parent.remove_command("reactions")

	@commands.group(aliases = ["reaction"], invoke_without_command = True, case_insensitive = True)
	@checks.not_forbidden()
	async def reactions(self, ctx):
		'''Reactions versions of commands'''
		await ctx.send_help(ctx.command)

	async def guess(self, ctx):
		'''
		Guessing game
		With reactions
		'''
		guess_message = await ctx.embed_reply("Guess a number between 1 to 10")
		embed = guess_message.embeds[0]
		answer = random.randint(1, 10)
		for number_emote in sorted(self.numbers.keys()):
			await guess_message.add_reaction(number_emote)
		self.reaction_messages[guess_message.id] = lambda reaction, user: self.guess_reaction_processor(ctx.author, answer, embed, reaction, user)

	async def guess_reaction_processor(self, player, answer, embed, reaction, user):
		if user == player and reaction.emoji in self.numbers:
			if self.numbers[reaction.emoji] == answer:
				embed.description = "{}: It was {}!".format(player.display_name, self.numbers[reaction.emoji])
				await reaction.message.edit(embed = embed)
				del self.reaction_messages[reaction.message.id]
			else:
				embed.description = "{}: Guess a number between 1 to 10. No, it's not {}".format(player.display_name, self.numbers[reaction.emoji])
				await reaction.message.edit(embed = embed)

	async def news(self, ctx, source : str):
		'''
		News
		With Reactions
		Powered by NewsAPI.org
		'''
		async with ctx.bot.aiohttp_session.get("https://newsapi.org/v1/articles?source={}&apiKey={}".format(source, ctx.bot.NEWSAPI_ORG_API_KEY)) as resp:
			data = await resp.json()
		if data["status"] != "ok":
			await ctx.embed_reply(":no_entry: Error: {}".format(data["message"]))
			return
		response = await ctx.reply("React with a number from 1 to 10 to view each news article")
		numbers = {'\N{KEYCAP TEN}': 10}
		for number in range(9):
			numbers[chr(ord('\u0031') + number) + '\N{COMBINING ENCLOSING KEYCAP}'] = number + 1 # '\u0031' - 1
		for number_emote in sorted(numbers.keys()):
			await response.add_reaction(number_emote)
		while True:
			reaction, user = await self.bot.wait_for_reaction_add_or_remove(message = response, user = ctx.author, emoji = numbers.keys())
			number = numbers[reaction.emoji]
			article = data["articles"][number - 1]
			output = "Article {}:".format(number)
			output += "\n**{}**".format(article["title"])
			if article.get("publishedAt"):
				output += " ({})".format(article.get("publishedAt").replace('T', " ").replace('Z', ""))
			# output += "\n{}".format(article["description"])
			# output += "\n<{}>".format(article["url"])
			output += "\n{}".format(article["url"])
			output += "\nSelect a different number for another article"
			await response.edit(content = "{}: {}".format(ctx.author.display_name, output))

	# TODO: urband
	# TODO: rtg

	async def maze(self, ctx, width : int = 5, height : int = 5, random_start : bool = False, random_end : bool = False):
		'''
		Maze game
		With reactions
		width: 2 - 100
		height: 2 - 100
		React with an arrow key to move
		'''
		maze_instance = maze.Maze(width, height, random_start = random_start, random_end = random_end)
		maze_message = await ctx.embed_reply(ctx.bot.CODE_BLOCK.format(maze_instance.print_visible()), footer_text = "Your current position: {}, {}".format(maze_instance.column + 1, maze_instance.row + 1))
		self.mazes[maze_message.id] = maze_instance
		for emote in tuple(self.arrows.keys()) + ("\N{PRINTER}",):
			await maze_message.add_reaction(emote)
		self.reaction_messages[maze_message.id] = lambda reaction, user: self.maze_reactions_processor(ctx.author, reaction, user)

	async def maze_reactions_processor(self, player, reaction, user):
		if user == player:
			maze_instance = self.mazes[reaction.message.id]
			if reaction.emoji in self.arrows.keys():
				embed = reaction.message.embeds[0]
				moved = maze_instance.move(self.arrows[reaction.emoji].lower())
				embed.set_footer(text = f"Your current position: {maze_instance.column + 1}, {maze_instance.row + 1}")
				if moved:
					if maze_instance.reached_end():
						embed.description = (f"{self.bot.CODE_BLOCK.format(maze_instance.print_visible())}\n"
												f"Congratulations! You reached the end of the maze in {maze_instance.move_counter} moves")
						del self.reaction_messages[reaction.message.id]
					else:
						embed.description = self.bot.CODE_BLOCK.format(maze_instance.print_visible())
				else:
					embed.description = (f"{self.bot.CODE_BLOCK.format(maze_instance.print_visible())}\n"
											":no_entry: You can't go that way")
				await reaction.message.edit(embed = embed)
			elif reaction.emoji == "\N{PRINTER}":
				with tempfile.TemporaryFile(dir = self.bot.data_path + "/temp") as maze_file:
					maze_file.write(('\n'.join(maze_instance.visible)).encode())
					maze_file.flush()
					maze_file.seek(0)
					await reaction.message.channel.send(content = f"{player.display_name}:\n"
																	"Your maze is attached",
														file = discord.File(maze_file.file, filename = "maze.txt"))

	async def playing(self, ctx):
		'''Audio player'''
		try:
			embed = self.bot.cogs["Audio"].players[ctx.guild.id].current_embed()
		except errors.AudioNotPlaying:
			player_message = await ctx.embed_reply(":speaker: There is no song currently playing")
		else:
			embed.set_author(name = ctx.author.display_name, icon_url = ctx.author.avatar_url)
			player_message, embed = await self.bot.say(embed = embed)
		await self.bot.attempt_delete_message(ctx.message)
		for control_emote in self.controls.keys():
			await player_message.add_reaction(control_emote)
		self.reaction_messages[player_message.id] = lambda reaction, user: self.playing_reactions_processor(ctx, reaction, user)

	# TODO: Queue?, Empty?, Settext?, Other?
	# TODO: Resend player?

	async def playing_reactions_processor(self, ctx, reaction, user):
		if reaction.emoji in self.controls:
			if self.controls[reaction.emoji] == "pause_resume":
				permitted = await ctx.get_permission("pause", id = user.id)
				if permitted or user == ctx.guild.owner or user.id == self.bot.owner_id:
					embed = discord.Embed(color = ctx.bot.bot_color).set_author(name = user.display_name, icon_url = user.avatar_url)
					try:
						self.bot.cogs["Audio"].players[ctx.guild.id].pause()
					except errors.AudioNotPlaying:
						embed.description = ":no_entry: There is no song to pause"
					except errors.AudioAlreadyDone:
						self.bot.cogs["Audio"].players[ctx.guild.id].resume()
						embed.description = ":play_pause: Resumed song"
					else:
						embed.description = ":pause_button: Paused song"
					await self.bot.send_message(ctx.channel, embed = embed)
					await self.bot.attempt_delete_message(ctx.message)
			elif self.controls[reaction.emoji] in ("skip", "replay", "shuffle", "radio"):
				permitted = await ctx.get_permission(self.controls[reaction.emoji], id = user.id)
				if permitted or user.id in (ctx.guild.owner.id, self.bot.owner_id):
					message = copy.copy(ctx.message)
					message.content = "{}{}".format(ctx.prefix, self.controls[reaction.emoji])
					await self.bot.process_commands(message)
					# Timestamp for radio
			elif self.controls[reaction.emoji] in ("volume_down", "volume_up"):
				permitted = await ctx.get_permission("volume", id = user.id)
				if permitted or user.id in (ctx.guild.owner, self.bot.owner_id):
					try:
						current_volume = self.bot.cogs["Audio"].players[ctx.guild.id].get_volume()
					except errors.AudioNotPlaying:
						await ctx.embed_reply(":no_entry: Couldn't change volume\nThere's nothing playing right now")
					if self.controls[reaction.emoji] == "volume_down": set_volume = current_volume - 10
					elif self.controls[reaction.emoji] == "volume_up": set_volume = current_volume + 10
					message = copy.copy(ctx.message)
					message.content = "{}volume {}".format(ctx.prefix, set_volume)
					await self.bot.process_commands(message)

<commit_msg>[Discord] Fix checks for aliased reaction subcommands<commit_after>
import discord
from discord.ext import commands

import collections
import copy
import random
import tempfile

from modules import maze
from modules import utilities
from utilities import checks
from utilities import errors

def setup(bot):
	bot.add_cog(Reactions(bot))

	async def process_reactions(reaction, user):
		if user == bot.user:
			return
		await bot.cogs["Reactions"].reaction_messages[reaction.message.id](reaction, user)
		await bot.db.execute(
			"""
			UPDATE meta.stats
			SET reaction_responses = reaction_responses + 1
			WHERE timestamp = $1
			""",
			bot.online_time
		)
		# Count fixed to stop counting own reactions on 2019-10-25

	@bot.event
	async def on_reaction_add(reaction, user):
		if "Reactions" in bot.cogs and reaction.message.id in bot.cogs["Reactions"].reaction_messages:
			await process_reactions(reaction, user)

	@bot.event
	async def on_reaction_remove(reaction, user):
		if "Reactions" in bot.cogs and reaction.message.id in bot.cogs["Reactions"].reaction_messages:
			await process_reactions(reaction, user)

class Reactions(commands.Cog):

	def __init__(self, bot):
		self.bot = bot
		self.reaction_messages = {}
		self.mazes = {}
		self.numbers = {'\N{KEYCAP TEN}': 10}
		for number in range(9):
			self.numbers[chr(ord('\u0031') + number) + '\N{COMBINING ENCLOSING KEYCAP}'] = number + 1 # '\u0031' - 1
		self.arrows = collections.OrderedDict([('\N{LEFTWARDS BLACK ARROW}', 'W'), ('\N{UPWARDS BLACK ARROW}', 'N'), ('\N{DOWNWARDS BLACK ARROW}', 'S'), ('\N{BLACK RIGHTWARDS ARROW}', 'E')]) # tuple?
		self.controls = collections.OrderedDict([('\N{BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR}', "pause_resume"), ('\N{BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR}', "skip"), ('\N{CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY}', "replay"), ('\N{TWISTED RIGHTWARDS ARROWS}', "shuffle"), ('\N{RADIO}', "radio"), ('\N{SPEAKER WITH ONE SOUND WAVE}', "volume_down"), ('\N{SPEAKER WITH THREE SOUND WAVES}', "volume_up")])
		self.reaction_commands = (
			(self.guess, "Games", "guess", [], [checks.not_forbidden().predicate]),
			(self.news, "Resources", "news", [], [checks.not_forbidden().predicate]),
			(self.maze, "Games", "maze", [], [checks.not_forbidden().predicate]),
			(self.playing, "Audio", "playing", ["player"], [checks.not_forbidden().predicate, commands.guild_only().predicate])
		)
		for command, cog_name, parent_name, aliases, command_checks in self.reaction_commands:
			self.reactions.add_command(commands.Command(command, aliases = aliases, checks = command_checks))
			if (cog := self.bot.get_cog(cog_name)) and (parent := getattr(cog, parent_name)):
				parent.add_command(commands.Command(command, name = "reactions", aliases = ["reaction", 'r'], checks = command_checks))

	def cog_unload(self):
		for command, cog_name, parent_name, *_ in self.reaction_commands:
			if (cog := self.bot.get_cog(cog_name)) and (parent := getattr(cog, parent_name)):
				parent.remove_command("reactions")

	@commands.group(aliases = ["reaction"], invoke_without_command = True, case_insensitive = True)
	@checks.not_forbidden()
	async def reactions(self, ctx):
		'''Reactions versions of commands'''
		await ctx.send_help(ctx.command)

	async def guess(self, ctx):
		'''
		Guessing game
		With reactions
		'''
		guess_message = await ctx.embed_reply("Guess a number between 1 to 10")
		embed = guess_message.embeds[0]
		answer = random.randint(1, 10)
		for number_emote in sorted(self.numbers.keys()):
			await guess_message.add_reaction(number_emote)
		self.reaction_messages[guess_message.id] = lambda reaction, user: self.guess_reaction_processor(ctx.author, answer, embed, reaction, user)

	async def guess_reaction_processor(self, player, answer, embed, reaction, user):
		if user == player and reaction.emoji in self.numbers:
			if self.numbers[reaction.emoji] == answer:
				embed.description = "{}: It was {}!".format(player.display_name, self.numbers[reaction.emoji])
				await reaction.message.edit(embed = embed)
				del self.reaction_messages[reaction.message.id]
			else:
				embed.description = "{}: Guess a number between 1 to 10. No, it's not {}".format(player.display_name, self.numbers[reaction.emoji])
				await reaction.message.edit(embed = embed)

	async def news(self, ctx, source : str):
		'''
		News
		With Reactions
		Powered by NewsAPI.org
		'''
		async with ctx.bot.aiohttp_session.get("https://newsapi.org/v1/articles?source={}&apiKey={}".format(source, ctx.bot.NEWSAPI_ORG_API_KEY)) as resp:
			data = await resp.json()
		if data["status"] != "ok":
			await ctx.embed_reply(":no_entry: Error: {}".format(data["message"]))
			return
		response = await ctx.reply("React with a number from 1 to 10 to view each news article")
		numbers = {'\N{KEYCAP TEN}': 10}
		for number in range(9):
			numbers[chr(ord('\u0031') + number) + '\N{COMBINING ENCLOSING KEYCAP}'] = number + 1 # '\u0031' - 1
		for number_emote in sorted(numbers.keys()):
			await response.add_reaction(number_emote)
		while True:
			reaction, user = await self.bot.wait_for_reaction_add_or_remove(message = response, user = ctx.author, emoji = numbers.keys())
			number = numbers[reaction.emoji]
			article = data["articles"][number - 1]
			output = "Article {}:".format(number)
			output += "\n**{}**".format(article["title"])
			if article.get("publishedAt"):
				output += " ({})".format(article.get("publishedAt").replace('T', " ").replace('Z', ""))
			# output += "\n{}".format(article["description"])
			# output += "\n<{}>".format(article["url"])
			output += "\n{}".format(article["url"])
			output += "\nSelect a different number for another article"
			await response.edit(content = "{}: {}".format(ctx.author.display_name, output))

	# TODO: urband
	# TODO: rtg

	async def maze(self, ctx, width : int = 5, height : int = 5, random_start : bool = False, random_end : bool = False):
		'''
		Maze game
		With reactions
		width: 2 - 100
		height: 2 - 100
		React with an arrow key to move
		'''
		maze_instance = maze.Maze(width, height, random_start = random_start, random_end = random_end)
		maze_message = await ctx.embed_reply(ctx.bot.CODE_BLOCK.format(maze_instance.print_visible()), footer_text = "Your current position: {}, {}".format(maze_instance.column + 1, maze_instance.row + 1))
		self.mazes[maze_message.id] = maze_instance
		for emote in tuple(self.arrows.keys()) + ("\N{PRINTER}",):
			await maze_message.add_reaction(emote)
		self.reaction_messages[maze_message.id] = lambda reaction, user: self.maze_reactions_processor(ctx.author, reaction, user)

	async def maze_reactions_processor(self, player, reaction, user):
		if user == player:
			maze_instance = self.mazes[reaction.message.id]
			if reaction.emoji in self.arrows.keys():
				embed = reaction.message.embeds[0]
				moved = maze_instance.move(self.arrows[reaction.emoji].lower())
				embed.set_footer(text = f"Your current position: {maze_instance.column + 1}, {maze_instance.row + 1}")
				if moved:
					if maze_instance.reached_end():
						embed.description = (f"{self.bot.CODE_BLOCK.format(maze_instance.print_visible())}\n"
												f"Congratulations! You reached the end of the maze in {maze_instance.move_counter} moves")
						del self.reaction_messages[reaction.message.id]
					else:
						embed.description = self.bot.CODE_BLOCK.format(maze_instance.print_visible())
				else:
					embed.description = (f"{self.bot.CODE_BLOCK.format(maze_instance.print_visible())}\n"
											":no_entry: You can't go that way")
				await reaction.message.edit(embed = embed)
			elif reaction.emoji == "\N{PRINTER}":
				with tempfile.TemporaryFile(dir = self.bot.data_path + "/temp") as maze_file:
					maze_file.write(('\n'.join(maze_instance.visible)).encode())
					maze_file.flush()
					maze_file.seek(0)
					await reaction.message.channel.send(content = f"{player.display_name}:\n"
																	"Your maze is attached",
														file = discord.File(maze_file.file, filename = "maze.txt"))

	async def playing(self, ctx):
		'''Audio player'''
		try:
			embed = self.bot.cogs["Audio"].players[ctx.guild.id].current_embed()
		except errors.AudioNotPlaying:
			player_message = await ctx.embed_reply(":speaker: There is no song currently playing")
		else:
			embed.set_author(name = ctx.author.display_name, icon_url = ctx.author.avatar_url)
			player_message, embed = await self.bot.say(embed = embed)
		await self.bot.attempt_delete_message(ctx.message)
		for control_emote in self.controls.keys():
			await player_message.add_reaction(control_emote)
		self.reaction_messages[player_message.id] = lambda reaction, user: self.playing_reactions_processor(ctx, reaction, user)

	# TODO: Queue?, Empty?, Settext?, Other?
	# TODO: Resend player?

	async def playing_reactions_processor(self, ctx, reaction, user):
		if reaction.emoji in self.controls:
			if self.controls[reaction.emoji] == "pause_resume":
				permitted = await ctx.get_permission("pause", id = user.id)
				if permitted or user == ctx.guild.owner or user.id == self.bot.owner_id:
					embed = discord.Embed(color = ctx.bot.bot_color).set_author(name = user.display_name, icon_url = user.avatar_url)
					try:
						self.bot.cogs["Audio"].players[ctx.guild.id].pause()
					except errors.AudioNotPlaying:
						embed.description = ":no_entry: There is no song to pause"
					except errors.AudioAlreadyDone:
						self.bot.cogs["Audio"].players[ctx.guild.id].resume()
						embed.description = ":play_pause: Resumed song"
					else:
						embed.description = ":pause_button: Paused song"
					await self.bot.send_message(ctx.channel, embed = embed)
					await self.bot.attempt_delete_message(ctx.message)
			elif self.controls[reaction.emoji] in ("skip", "replay", "shuffle", "radio"):
				permitted = await ctx.get_permission(self.controls[reaction.emoji], id = user.id)
				if permitted or user.id in (ctx.guild.owner.id, self.bot.owner_id):
					message = copy.copy(ctx.message)
					message.content = "{}{}".format(ctx.prefix, self.controls[reaction.emoji])
					await self.bot.process_commands(message)
					# Timestamp for radio
			elif self.controls[reaction.emoji] in ("volume_down", "volume_up"):
				permitted = await ctx.get_permission("volume", id = user.id)
				if permitted or user.id in (ctx.guild.owner, self.bot.owner_id):
					try:
						current_volume = self.bot.cogs["Audio"].players[ctx.guild.id].get_volume()
					except errors.AudioNotPlaying:
						await ctx.embed_reply(":no_entry: Couldn't change volume\nThere's nothing playing right now")
					if self.controls[reaction.emoji] == "volume_down": set_volume = current_volume - 10
					elif self.controls[reaction.emoji] == "volume_up": set_volume = current_volume + 10
					message = copy.copy(ctx.message)
					message.content = "{}volume {}".format(ctx.prefix, set_volume)
					await self.bot.process_commands(message)

<|endoftext|>