2

次のように pyral を使用して testcaseresult に添付ファイルを追加しようとしています:

   testCaseResult = rally.create('TestCaseResult', {'TestCase': tc.ref , 'Build': revision,
                          'Verdict': verdict[test.result], 'Date': resultdate, 'Notes': note,
                          'Tester': tester, 'Duration': runtime })


   res = rally.addAttachment(testCaseResult.oid, file);

TestaseResult は正常に作成されましたが、res は False です。

私は何を間違っていますか?私はoidを使用すべきではありませんか?testCaseResult、testCaseResult.oid、および「TestCaseResult /」+ testCaseResult.oidを渡そうとしましたが、どれも機能していないようです...

更新しました:

以下のマークの回答に基づいて (pyral は testcaseresult への添付ファイルの追加を直接サポートしていません)、次のサブルーチンを作成しました。

def addTestCaseResultAttachment(testCaseResult, filename, contentType='text/plain'):
    if not os.path.exists(filename):
        raise Exception('Named attachment filename: %s not found' % filename)
    if not os.path.isfile(filename):
        raise Exception('Named attachment filename: %s is not a regular file' % filename)

    attachment_file_name = os.path.basename(filename)
    attachment_file_size = os.path.getsize(filename)

    if attachment_file_size == 0:
        raise Exception('Cannot attach zero length file')

    if attachment_file_size > 5000000:
        raise Exception('Attachment file size too large, unable to attach to Rally Artifact')

    contents = ''
    with open(filename, 'r') as af:
        contents = base64.encodestring(af.read())

    # create an AttachmentContent item
    ac = rally.create('AttachmentContent', {"Content" : contents}, project=None)
    if not ac:
        raise RallyRESTAPIError('Unable to create AttachmentContent for %s' % attachment_file_name)

    attachment_info = { "Name"              :  attachment_file_name,
                        "Content"           :  ac.ref,       # ref to AttachmentContent
                        "ContentType"       :  contentType,
                        "Size"              :  attachment_file_size, # must be size before encoding!!
                        "User"              :  'user/%s' % me.oid,
                        "TestCaseResult"    :  testCaseResult.ref
                      }

    # and finally, create the Attachment
    attachment = rally.create('Attachment', attachment_info, project=None)
    if not attachment:
        raise RallyRESTAPIError('Unable to create Attachment for %s' % attachment_file_name)
4

2 に答える 2

3

問題は、以下に示すように、 pyral の restapi のaddAttachment メソッドが、Attachment オブジェクトの "Artifact" 属性に参照を設定することです ( restapiの 1241 行目から 1251 行目)。

    attachment_info = { "Name"        :  attachment_file_name,
                        "Content"     :  ac.ref,       # ref to AttachmentContent
                        "ContentType" :  mime_type,    
                        "Size"        :  attachment_file_size, # must be size before encoding!!
                        "User"        :  'user/%s' % self.contextHelper.user_oid,
                       #"Artifact"    :  artifact.ref  # (Artifact is an 'optional' field)
                      }

    # While it's actually possible to have an Attachment not linked to an Artifact,
    # in most cases, it'll be far more useful to have the linkage to an Artifact than not.
    if artifact:  
        attachment_info["Artifact"] = artifact.ref

したがって、addAttachment メソッドは実際には Artifact から継承するオブジェクト、つまり Stories、Defects、Tasks、TestCases などに対してのみ機能します。TestCaseResult は実際には WorkspaceDomainObject であり Artifact ではないため、この構文が選択されました。

新しい TestCaseResult を作成し、Attachment を追加する例を次に示します。

#!/usr/bin/env python

#################################################################################################
#
# create_tcr_and_attachment.py -- Create a New TestCaseResult and attach a file to it
#
USAGE = """
Usage: py create_tcr_and_attachment.py <TestCaseFormatedID> <filename>
"""
#################################################################################################

import sys, os
import re
import string
import base64

from pyral import Rally, rallySettings

#################################################################################################

errout = sys.stderr.write

ATTACHMENT_ATTRIBUTES = ['oid', 'ObjectID', '_type', '_ref', '_CreatedAt', 'Name',
                         'CreationDate', 'Description', 
                         'Content', 'ContentType', 'Size', 
                         'Subscription', 
                         'Workspace',
                         'Artifact', 
                         'User'
                        ] 

ATTACHMENT_IMPORTANT_ATTRS = """
    Subscription   ref     (supplied at creation)
    Workspace      ref     (supplied at creation)

    Name           STRING      Required    (name of the file, like foo.txt or ThePlan.doc)
    User           ref to User Required   Settable  (User who added the object)

    Content        ref to AttachmentContent
    Size           INTEGER     Required
    ContentType    STRING      Required


    Artifact       ref to Artifact            (optional field)

    Description    TEXT        Optional

"""

#################################################################################################

def main(args):
    options = [opt for opt in args if opt.startswith('--')]
    args    = [arg for arg in args if arg not in options]
    server = "rally1.rallydev.com"
    user = "user@company.com"
    password = "topsecret"
    workspace = "My Workspace"
    project = "My Project"
    print " ".join(["|%s|" % item for item in [server, user, '********', workspace, project]])
    rally = Rally(server, user, password, workspace=workspace, version="1.43")  # specify the Rally server and credentials
    rally.enableLogging('rally.hist.create_tcr_and_attachment') # name of file you want logging to go to

    if len(args) != 2:
        errout('ERROR: You must supply a Test Case FormattedID and an attachment file name')
        errout(USAGE)
        sys.exit(1)

    targetTCID, filename = args

    me = rally.getUserInfo(username=user).pop(0)
    print "%s user oid: %s" % (user, me.oid)

    target_project = rally.getProject()
    target_tc  = rally.get('TestCase', query='FormattedID = %s' % targetTCID, instance=True)    

    datestring = "2014-05-01"

    tcr_info = {
         "TestCase"     : target_tc.ref,
         "Build"        : "master-91321",
         "Date"         : datestring,
         "Verdict"      : "Pass",
         "Notes"        : "Honeycomb harvest project."
       }

    print "Creating Test Case Result ..."
    tcr = rally.put('TestCaseResult', tcr_info)
    print "Created  TCR: %s" % (tcr.oid)

    print "Creating AttachmentContent"

    if not os.path.exists(filename):
        raise Exception('Named attachment filename: %s not found' % filename)
    if not os.path.isfile(filename):
        raise Exception('Named attachment filename: %s is not a regular file' % filename)

    attachment_file_name = os.path.basename(filename)
    attachment_file_size = os.path.getsize(filename)
    if attachment_file_size > 5000000:
        raise Exception('Attachment file size too large, unable to attach to Rally Artifact')

    contents = ''
    with open(filename, 'r') as af:
        contents = base64.encodestring(af.read())

    # create an AttachmentContent item
    ac = rally.create('AttachmentContent', {"Content" : contents}, project=None)
    if not ac:
        raise RallyRESTAPIError('Unable to create AttachmentContent for %s' % attachment_file_name)

    attachment_info = { "Name"              :  attachment_file_name,
                        "Content"           :  ac.ref,       # ref to AttachmentContent
                        "ContentType"       :  "image/jpeg",    
                        "Size"              :  attachment_file_size, # must be size before encoding!!
                        "User"              :  'user/%s' % me.oid,
                        "TestCaseResult"    :  tcr.ref
                      }

    # and finally, create the Attachment
    attachment = rally.create('Attachment', attachment_info, project=None)
    if not attachment:
        raise RallyRESTAPIError('Unable to create Attachment for %s' % attachment_file_name)    


#################################################################################################
#################################################################################################

if __name__ == '__main__':
    main(sys.argv[1:])
于 2014-05-01T20:54:10.690 に答える