@ -1,48 +1,76 @@
#!/usr/bin/python
#!/usr/bin/env python
# Copyright (c) 2017 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Test result update & verify script for the local refstack database .
"""
import os
import argparse
import datetime
import requests
import os
from collections import namedtuple
import json
def getData ( entry ) :
guidelines = [ " 2015.03 " , " 2015.04 " , " 2015.05 " , " 2015.07 " , " 2016.01 " ,
" 2016.08 " , " 2017.01 " ]
components = [ " Platform " , " Compute " , " Storage " ]
""" Extract and reformat data from a product data csv """
guidelines = [ ' 2015.03 ' , ' 2015.04 ' , ' 2015.05 ' , ' 2015.07 ' , ' 2016.01 ' ,
' 2016.08 ' , ' 2017.01 ' , ' 2017.09 ' ]
components = [ ' platform ' , ' compute ' , ' storage ' , ' object ' ]
if len ( entry ) < 10 :
return None , None , None
if entry [ 9 ] != " " and entry [ 9 ] != " " :
refstackLink = entry [ 9 ]
testId = refstackLink . split ( " / " ) [ - 1 ]
refstackLink = entry [ 9 ] . strip ( )
guideline = entry [ 4 ] . strip ( )
target = entry [ 5 ] . lower ( ) . strip ( )
if refstackLink :
testId = refstackLink . split ( ' / ' ) [ - 1 ]
else :
refstackLink = None
testId = None
if entry [ 4 ] != " " and entry [ 4 ] != " " and entry [ 4 ] in guidelines :
guideline = entry [ 4 ]
else :
if guideline not in guidelines :
guideline = None
if entry [ 5 ] != " " and entry [ 5 ] != " " and entry [ 5 ] in components :
target = entry [ 5 ] . lower ( )
if target == " storage " :
target = " object "
else :
if target not in components :
target = None
elif target == " storage " :
target = " object "
return testId , guideline , target
def linkChk ( link , token ) :
print ( " checking result with a test ID of: " + link . split ( " / " ) [ - 1 ] )
""" Check existence of and access to api result link """
print ( " now checking result: " + link )
if not link :
return False
try :
if " " in link :
return False
response = requests . get (
link , headers = { ' Authorization ' : ' Bearer ' + token } )
headers = { ' Authorization ' : ' Bearer ' + token }
response = requests . get ( link , headers )
if response . status_code == 200 :
return json . loads ( response . text )
elif response . status_code == 401 or response . status_code == 403 :
print ( " Authentication Failed. link check response code: " +
str ( response . status_code ) )
return False
elif response . status_code == 400 :
print ( " Malformed Request. link response code: " +
str ( response . status_code ) )
return False
else :
print ( " Link check response_status_code= " +
str ( response . status_code ) )
@ -52,50 +80,98 @@ def linkChk(link, token):
return False
def updateResult ( apiLink , target , guideline , token , results_log ) :
success = True
with open ( results_log , ' a ' ) as logfile :
logfile . write ( str ( datetime . datetime . now ( ) ) + " , " )
response = requests . post ( apiLink + ' /meta/shared ' , headers = {
' Authorization ' : ' Bearer ' + token } , data = ' true ' )
if response . status_code != 201 :
print ( " Update shared status response_status_code= " +
str ( response . status_code ) )
logfile . write ( apiLink + " ,0, " )
success = False
else :
logfile . write ( apiLink + " ,1, " )
if " .json " not in guideline :
guideline = str ( guideline ) + " .json "
response = requests . post ( apiLink + ' /meta/guideline ' , headers = {
' Authorization ' : ' Bearer ' + token } , data = guideline )
if response . status_code != 201 :
print ( " Update guideline response_status_code= " +
str ( response . status_code ) )
logfile . write ( guideline + " ,0, " )
success = False
def updateField ( header , apiLink , raw_data ) :
""" Update a given metadata field """
valid_keytype = [ ' shared ' , ' guideline ' , ' target ' ]
keytype = raw_data . type
keyval = raw_data . value
if keytype not in valid_keytype or not keyval :
updresult = " %s keypair does not exist " % ( keytype )
return updresult , False
link = apiLink . strip ( ) + ' /meta/ ' + keytype
response = requests . post ( link , data = keyval , headers = header )
if response . status_code != 201 :
print ( ' update response status code= %d ' %
response . status_code )
print ( ' update response text= ' + response . text )
updresult = ( " %s field update failed. reason: %s " %
( keytype , response . text . replace ( ' , ' , ' ' ) ) )
return updresult , False
else :
updresult = " %s field update successful, " % ( keytype )
return updresult , True
def updateResult ( apiLink , target , guideline , token , record ) :
""" Update metadata for result and verify if all updates are a success """
MetadataField = namedtuple ( ' MetadataField ' , [ ' type ' , ' value ' ] )
success = [ ]
header = { ' Authorization ' : ' Bearer ' + token }
with open ( record , ' a ' ) as r :
r . write ( str ( datetime . datetime . now ( ) ) + " , " + apiLink + " , " )
# update the shared field
data = MetadataField ( ' shared ' , ' true ' )
shared_result , shared_status = updateField ( header , apiLink , data )
r . write ( shared_result )
success . append ( shared_status )
# update the target field
data = MetadataField ( ' target ' , target )
target_result , target_status = updateField ( header , apiLink , data )
r . write ( target_result )
success . append ( target_status )
# update the guideline field
data = MetadataField ( ' guideline ' , guideline + ' .json ' )
gl_result , gl_status = updateField ( header , apiLink , data )
r . write ( gl_result )
success . append ( gl_status )
if not all ( success ) :
r . write ( ' unable to verify. \n ' )
return False
# if there were no update failures, we can verify the result
# this is the operation most likely to fail, so extra checks are
# in order
print ( ' Test Result updated successfully. Attempting verification. ' )
try :
response = requests . put ( apiLink ,
json = { ' verification_status ' : 1 } ,
headers = header )
except Exception as ex :
print ( ' Exception raised while verifying test result: %s ' %
( str ( ex ) ) )
r . write ( ' verification failed: %s \n ' % ( str ( ex ) ) )
return False
updated = verification_chk ( apiLink , header )
if response . status_code not in ( 200 , 201 ) :
print ( ' verification failure status code= %d ' %
response . status_code )
print ( ' verification failure detail= %s ' %
response . text )
r . write ( ' verification unsuccessful: detail: %s \n ' %
( response . text ) )
return False
elif not updated :
print ( " verification_status field failed to update " )
r . write ( ' verification status update failed. detail: %s \n ' %
( response . text ) )
return False
else :
logfile . write ( guideline + " ,1, " )
response = requests . post ( apiLink + ' /meta/target ' , headers = {
' Authorization ' : ' Bearer ' + token } , data = target )
if response . status_code != 201 :
print ( " Update target response_status_code= " +
str ( response . status_code ) )
logfile . write ( target + " ,0, " )
success = False
print ( ' Test result verified! \n ' )
r . write ( ' Test result successfully verified \n ' )
return True
def verification_chk ( link , header ) :
try :
response = requests . get ( link , header )
status = int ( response . json ( ) [ ' verification_status ' ] )
if status == 1 :
return True
else :
logfile . write ( target + " ,1, " )
if success :
print ( " test result updated. Verifying. " )
response = requests . put ( apiLink , headers = {
' Authorization ' : ' Bearer ' + token } ,
json = { ' verification_status ' : 1 } )
if response . status_code != 201 :
success = False
else :
print ( " Test result verified. " )
logfile . write ( str ( int ( success ) ) + ' \n ' )
return success
return False
except Exception as ex :
print ( ' Exception raised while ensuring update of ' +
' verification status: ' + str ( ex ) )
return False
def main ( ) :
@ -111,12 +187,13 @@ def main():
help = " the base URL of the endpoint. ex: http://examplerefstack.com/v1 " )
parser . add_argument ( " --token " , " -t " , metavar = " t " , type = str ,
action = " store " , required = True , help = " API auth token " )
parser . add_argument ( " --logfile " , " -l " , metavar = " l " , type = str ,
parser . add_argument ( " --record " , " -r " , metavar = " r " , type = str ,
action = " store " , default = " verification_results.csv " ,
help = " name of logfile to output data into " )
help = " name of file to output update & verification " +
" run record data into " )
result = parser . parse_args ( )
infile = result . file
logfile = result . logfile
record = result . record
endpoint = result . endpoint
token = result . token
with open ( infile ) as f :
@ -124,30 +201,28 @@ def main():
linect = linect + 1
entry = line . split ( " , " )
testId , guideline , target = getData ( entry )
if testId is None or guideline is None or target is None :
if None in ( testId , guideline , target ) :
print (
" entry found at line " + str ( linect ) +
" cannot be updated and verified: entry incomplete. ")
" cannot be updated and verified: entry incomplete. \n ")
else :
apiLink = os . path . join ( endpoint , ' results ' , testId )
testResult = linkChk ( apiLink , token )
if testResult :
if testResult . get ( ' verification_status ' ) :
print (
" Result has already been verified; nothing to do. " )
print ( " Result has been verified. \n " )
else :
print (
" Result link is valid. Updating result with ID " +
testId )
" Result link is valid. Updating... " )
success = updateResult ( apiLink , target , guideline ,
token , logfile )
token , record )
if not success :
print ( " update of the results with the ID " +
testId + " failed. please recheck your " +
" spreadsheet and try again ")
" spreadsheet and try again \n ")
else :
print ( " the test result " + testId +
" cannot be verified due to a broken result link. " )
print ( " the test result " + testId + " cannot be " +
" verified due to a link verification failure \n " )
main ( )