def test_two_conditions_query_as_dict(): rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) qualifiers = {'State' : 'Submitted', 'Ready' : 'False' } response = rally.get('Defect', fetch=True, query=qualifiers, limit=10) assert response.resultCount > 0
def test_default_isolated_workspace(): """ Using a known valid Rally server and known valid access credentials, obtain a Rally instance and confirm that the default workspace and project are set to DEFAULT_WORKSPACE and DEFAULT_PROJECT and that the current workspace and project are indeed the DEFAULT_WORKSPACE and DEFAULT_PROJECT values. Furthermore the construction of a GET related URL will contain the correct workspace and project specifications in the QUERY_STRING. And any attempt to change the workspace via rally.setWorkspace(some_name) will result in a Exception being raised """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD, server_ping=False, isolated_workspace=True) context1 = rally.contextHelper.currentContext() workspace = rally.getWorkspace() project = rally.getProject() context2 = rally.contextHelper.currentContext() assert context1 == context2 assert context1.workspace == DEFAULT_WORKSPACE assert workspace.Name == DEFAULT_WORKSPACE assert context1.project == DEFAULT_PROJECT assert project.Name == DEFAULT_PROJECT url = makeResourceUrl(rally, 'Defect') #print(url) expected_workspace_clause = 'workspace=workspace/%s' % str(workspace.oid) assert expected_workspace_clause in url problem_text = 'No reset of of the Workspace is permitted when the isolated_workspace option is specified' with py.test.raises(Exception) as excinfo: rally.setWorkspace(ALTERNATE_WORKSPACE) actualErrVerbiage = excinfo.value.args[0] assert excinfo.value.__class__.__name__ == 'RallyRESTAPIError' assert actualErrVerbiage == problem_text
def test_get_distant_duplicated_project(): """ Using a known valid Rally server and known valid access credentials, obtain a Rally instance and use it to obtain a Project instance for a Project whose name contains multiple path elements with the elements separated by the ' // ' token string. Expect the result to return one and only one Project that is the correct Project. The result should have the correct Parent Project. When the Rally instance is called to setProject with the value of that multi element path for the Project it should do so and should return the correct value when asked for the current Project. """ rally = Rally(server=TRIAL, user=YETI_USER, password=YETI_PSWD, workspace=BOONDOCKS_WORKSPACE, project=BOONDOCKS_PROJECT) dupey_project = rally.getProject(DEEP_DUPE) assert dupey_project is not None assert dupey_project.__class__.__name__ == 'Project' assert dupey_project.Name == DEEP_DUPE criteria = 'Name = "%s"' % 'Corral' expected_parent = rally.get('Project', fetch="Name,ObjectID,Parent,Children", query=criteria, projectScopeDown=False, instance=True) assert expected_parent is not None assert expected_parent.__class__.__name__ == 'Project' assert expected_parent.Name == 'Corral' assert dupey_project.Parent.ref == expected_parent.ref result = rally.setProject(DEEP_DUPE) assert result is None cur_project = rally.getProject() assert cur_project.Name == DEEP_DUPE
def test_set_mep_project_used_as_default_in_request_operation(): """ Using a known valid Rally server and known valid access credentials, obtain a Rally instance associated with a unique Project name within a valid Workspace. Subsequently, set the instance's Project to a Project whose name is a duplicate. The duplicate Project is specified as a path chain of: baseProject // nextLevelProject // leafProject At least one of the other non-target duplicates should exist in a shorter path. Issue a request using the target duplicate Project m-e-p. The result should be an Artifact whose projet matches the target duplicate Project leaf name and ref exactly. """ rally = Rally(server=TRIAL, user=YETI_USER, password=YETI_PSWD, workspace=BOONDOCKS_WORKSPACE, project=BOONDOCKS_PROJECT) rally.setProject(DEEP_DUPE) target_story = 'US3' result = rally.get('Story', fetch="FormattedID,Name,Description,State,Project", query='FormattedID = %s' % target_story, projectScopeUp=False) assert result is not None assert result.resultCount > 0 stories = [story for story in result] assert len(stories) > 0 hits = [story for story in stories if story.FormattedID == target_story] assert len(hits) == 1 hit = hits[0] assert hit.FormattedID == target_story
def main(args): options = [opt for opt in args if opt.startswith('--')] args = [arg for arg in args if arg not in options] server, user, password, workspace, project = rallySettings(options) #print " ".join(["|%s|" % item for item in [server, user, '********', workspace, project]]) if not args: errout("ERROR: You must supply an entity name!\n") sys.exit(1) entity = args[0] if entity in ['UserStory', 'User Story', 'Story']: entity = "HierarchicalRequirement" #if '/' in entity: # parent, entity = entity.split('/', 1) try: rally = Rally(server, user=user, password=password) except Exception as ex: errout(str(ex.args[0])) sys.exit(1) schema_item = rally.typedef(entity) print schema_item
def test_defects_revision_history(): """ Using a known valid Rally server and known valid access credentials, issue a simple query (no qualifying criteria) against a Rally entity (Defect) known to have an attribute (RevisionHistory) that has an attribute (Revisions) that is a Rally collections reference. This test demonstrates the lazy-evaluation of non first-level attributes. Ultimately, the attributes deeper than the first level must be obtained and have their attributes filled out completely (_hydrated == True). """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) response = rally.get('Defect', fetch=True, limit=10) defect1 = response.next() defect2 = response.next() assert defect1.oid != defect2.oid d1_revs = defect1.RevisionHistory.Revisions d2_revs = defect2.RevisionHistory.Revisions assert type(d1_revs) == types.ListType assert type(d2_revs) == types.ListType d1_rev1 = d1_revs.pop() # now the revs are in stack order, newest first, original the last d2_rev1 = d2_revs.pop() # ditto assert d1_rev1.RevisionNumber == 0 assert d2_rev1.RevisionNumber == 0 assert d1_rev1.Description != "" and len(d1_rev1.Description) > 0 assert d2_rev1.Description != "" and len(d2_rev1.Description) > 0 assert d1_rev1._hydrated == True assert d2_rev1._hydrated == True
def main(args): options = [opt for opt in args if opt.startswith('--')] args = [arg for arg in args if arg not in options] if not args: print USAGE sys.exit(9) server, username, password, apikey, workspace, project = rallyWorkset(options) if apikey: rally = Rally(server, apikey=apikey, workspace=workspace, project=project) else: rally = Rally(server, user=username, password=password, workspace=workspace, project=project) rally.enableLogging('rally.hist.chgsets') # name of file you want the logging to go to repo_name = args.pop(0) since = None if args: since = args.pop(0) try: days = int(since) now = time.time() since_ts = now - (days * 86400) since = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime(since_ts)) except: since = None showRepoItems(rally, repo_name, workspace=workspace, limit=ITEM_LIMIT, since_date=since)
def test_getAllowedValues_for_UserStory_Milestone(): """ Using a known valid Rally server and known valid access credentials, request allowed value information for the Milestones field of the UserStory entity. The Milestones field is a standard field of schema type COLLECTION whose value is entirely context dependent on the specific artifact so getting allowed values doesn't really make sense in the same way as an attribute like State or Severity that has a finite set of possible values that are the same for every Story or Defect in the workspace. Because of that characteristic, we return a list with a single True value ( [True] ) to designate that yes, technically the Milestones field has allowed values but that asking for them on a specific AC artifact short-circuits. The proper way to get all of the AllowedValues for Milestones is to query the Milestone entity itself. There are numerous other standard attributes with the same sort of semantic that are excluded from chasing the COLLECTION url and returning some list of values. (like, Changesets, Discussions, Tags, etc.) """ rally = Rally(server=AGICEN, apikey=API_KEY) avs = rally.getAllowedValues('Story', 'Milestones') assert avs == [True] response = rally.get('Milestone', fetch=True, workspace=LARGE_WORKSPACE, project=LARGE_PROJECT_TREE_BASE, projectScopeDown=True) milestones = [item for item in response] assert len(milestones) > 150 # Given the singular name of the target field (which is invalid...) return a None value avs = rally.getAllowedValues('Story', 'Milestone') assert avs is None
def main(args): options = [opt for opt in args if opt.startswith('--')] args = [arg for arg in args if arg not in options] server, user, password, workspace, project = rallySettings(options) print " ".join(["|%s|" % item for item in [server, user, password, workspace, project]]) # add in the debug=True keyword arg if you want more verbiage ... rally = Rally(server, user, password, workspace=workspace, project=project, debug=True) workspace = rally.getWorkspace() print "Workspace: %s " % workspace.Name #print "Workspace: %12.12s %-18.18s (%s)" % (workspace.oid, workspace.Name, workspace.ref) project = rally.getProject() print "Project : %s " % project.Name #print "Project : %12.12s %-18.18s (%s)" % (project.oid, project.Name, project.ref) # uncomment this to see all of your accessible workspaces and projects # workspaces = rally.getWorkspaces() # for workspace in workspaces: # print " ", workspace.Name # projects = rally.getProjects(workspace=workspace.Name) # if projects: # print "" # print " Projects:" # for project in projects: # print " ", project.Name # else: # print " No projects" # print "" sys.exit(0)
def test_bad_server_spec(): """ Use a known to be invalid server name using prohibited characters in the server name. Do the same test using default access credentials and known correct valid credentials to an existing Rally server. The status_code in the response must indicate a non-success condition. """ bad_server = "ww!w.\fo,o\r\n.c%om" expectedErrMsg = "Unknown host" with py.test.raises(RallyRESTAPIError) as excinfo: rally = Rally(server=bad_server, timeout=3) response = rally.get('Project', fetch=False, limit=10) actualErrVerbiage = excinfo.value.args[0] # becuz Python2.6 deprecates message :-( assert excinfo.value.__class__.__name__ == 'RallyRESTAPIError' assert 'cannot resolve' in actualErrVerbiage and 'Unknown host' in actualErrVerbiage time.sleep(1) with py.test.raises(RallyRESTAPIError) as excinfo: rally = Rally(server=bad_server, user=TRIAL_USER, password=TRIAL_PSWD, timeout=3) response = rally.get('Project', fetch=False, limit=5) actualErrVerbiage = excinfo.value.args[0] # becuz Python2.6 deprecates message :-( assert excinfo.value.__class__.__name__ == 'RallyRESTAPIError' assert 'cannot resolve' in actualErrVerbiage and 'Unknown host' in actualErrVerbiage time.sleep(1)
def main(args): options = [opt for opt in args if opt.startswith('--')] args = [arg for arg in args if arg not in options] if not args: errout("ERROR: You must supply an entity name!\n") sys.exit(1) server, username, password, apikey, workspace, project = rallyWorkset(options) try: if apikey: rally = Rally(server, apikey=apikey, workspace=workspace, project=project) else: rally = Rally(server, user=username, password=password, workspace=workspace, project=project) except Exception as ex: errout(str(ex.args[0])) sys.exit(1) entity = args[0] if entity in ['UserStory', 'User Story', 'Story']: entity = "HierarchicalRequirement" #if '/' in entity: # parent, entity = entity.split('/', 1) schema_item = rally.typedef(entity) print(schema_item)
def test_bad_server_spec(): """ Use a known to be invalid server name using prohibited characters in the server name. Do the same test using default access credentials and known correct valid credentials to an existing Rally server. The status_code in the response must indicate a non-success condition. """ bad_server = "ww!w.\fo,o\r\n.c%om" expectedErrMsg = "404 Target host: '%s' doesn't support the Rally WSAPI" % bad_server altErrText = "non-existent or unreachable" with py.test.raises(RallyRESTAPIError) as excinfo: rally = Rally(server=bad_server, timeout=3) response = rally.get('Project', fetch=False, limit=10) actualErrVerbiage = excinfo.value.args[0] # becuz Python2.6 deprecates message :-( assert excinfo.value.__class__.__name__ == 'RallyRESTAPIError' assert actualErrVerbiage == expectedErrMsg or altErrText in actualErrVerbiage with py.test.raises(RallyRESTAPIError) as excinfo: rally = Rally(server=bad_server, user=TRIAL_USER, password=TRIAL_PSWD, timeout=3) response = rally.get('Project', fetch=False, limit=5) actualErrVerbiage = excinfo.value.args[0] # becuz Python2.6 deprecates message :-( assert excinfo.value.__class__.__name__ == 'RallyRESTAPIError' assert actualErrVerbiage == expectedErrMsg or altErrText in actualErrVerbiage
def main(args): options = [opt for opt in args if opt.startswith('--')] args = [arg for arg in args if arg not in options] if not args: print USAGE sys.exit(9) # specify the Rally server and credentials server, username, password, workspace, project = rallySettings(options) #print " ".join(["|%s|" % opt for opt in [server, username, '********', workspace]]) rally = Rally(server, user=username, password=password, workspace=workspace, warn=False) rally.enableLogging('rally.hist.chgsets') # name of file you want the logging to go to repo_name = args.pop(0) since = None if args: since = args.pop(0) try: days = int(since) now = time.time() since_ts = now - (days * 86400) since = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime(since_ts)) except: since = None showRepoItems(rally, repo_name, workspace=workspace, limit=ITEM_LIMIT, since_date=since)
def test_default_context(): """ Using a known valid Rally server and known valid access credentials, obtain a Rally instance and confirm that the default workspace and project are set to DEFAULT_WORKSPACE and DEFAULT_PROJECT and that the current workspace and project are indeed the DEFAULT_WORKSPACE and DEFAULT_PROJECT values. Furthermore the construction of a GET related URL will contain the correct workspace and project specifications in the QUERY_STRING. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD, server_ping=False) context1 = rally.contextHelper.currentContext() workspace = rally.getWorkspace() project = rally.getProject() context2 = rally.contextHelper.currentContext() assert context1 == context2 assert context1.workspace == DEFAULT_WORKSPACE assert workspace.Name == DEFAULT_WORKSPACE assert context1.project == DEFAULT_PROJECT assert project.Name == DEFAULT_PROJECT url = makeResourceUrl(rally, 'Defect') #print(url) expected_workspace_clause = 'workspace=workspace/%s' % str(workspace.oid) assert expected_workspace_clause in url expected_project_clause = 'project=project/%s' % str(project.oid) assert expected_project_clause in url
def main(args): options = [opt for opt in args if opt.startswith('--')] args = [arg for arg in args if arg not in options] server, user, password, workspace, project = rallySettings(options) #print " ".join(["|%s|" % item for item in [server, user, password, workspace, project]]) if not args: print "You must supply an entity name!" sys.exit(1) query = "" target = args[0] if target in ['UserStory', 'User Story', 'Story']: target = "HierarchicalRequirement" if '/' in target: parent, entity = target.split('/', 1) target = entity query = 'ElementName = "%s"' % target try: rally = Rally(server, user=user, password=password) except Exception as ex: errout(str(ex.args[0])) sys.exit(1) typedef = rally.typedef(target) showAttributes(typedef.Attributes) print "" print "-" * 64 print "" for ix, ancestor in enumerate(typedef.inheritanceChain()): print "%s %s" % (" " * (ix*4), ancestor)
class Avant_Rally(object): iterations = [] rally = None def __init__(self, project): self.project = project def connect(self, username, password): self.rally = Rally(server, user, password, project=self.project) self.rally.enableLogging('rally.simple-use.log') def fetch_Iterations(self): self.iterations = [] response = self.rally.get('Iteration', fetch=True) for rls in response: iter = Iteration() rlsStart = rls.StartDate.split('T')[0] # just need the date part rlsDate = rls.EndDate.split('T')[0] # ditto self.iterations.append(iter.set_Iteration(rlsStart, rlsDate, rls.Name, rls.PlannedVelocity, self.rally)) def display_Iterations(self): for i in self.iterations: print "\n\n%s %s --> %s\t" % \ (i.name, i.start_date, i.end_date) i.display_User_Stories(i.name)
def main(args): options = [opt for opt in args if opt.startswith('--')] args = [arg for arg in args if arg not in options] server, user, password, apikey, workspace, project = rallyWorkset(options) rally = Rally(server, user, password, apikey=apikey, workspace=workspace, project=project) entity_name = 'Milestone' fields = 'FormattedID,Name,TargetProject,TargetDate,TotalArtifactCount' response = rally.get(entity_name, fetch=fields, order="TargetDate,FormattedID", project=project, projectScopeDown=True) if response.errors: errout("Request could not be successfully serviced, error code: %d\n" % response.status_code) errout("\n".join(response.errors)) sys.exit(1) if response.resultCount == 0: errout('No items found for %s\n' % entity_name) sys.exit(2) milestones = [item for item in response] sans_project = [mi for mi in milestones if not mi.TargetProject] with_project = [mi for mi in milestones if mi.TargetProject] with_project.sort(key=lambda mi: mi.TargetProject.Name) for item in (with_project + sans_project): proj_name = item.TargetProject.Name if item.TargetProject else "" print(" %15.15s %-6.6s %-36.36s %3d %-10.10s %s " % \ (item.oid, item.FormattedID, item.Name, item.TotalArtifactCount, item.TargetDate, proj_name))
def get_rally_connection(USER, PASSWORD, PROJECT, VERSION='1.43', SERVER='rally1.rallydev.com'): ''' return a rally connection object ''' # get the rally connection object rally = Rally(SERVER, USER, PASSWORD, version=VERSION, project=PROJECT) rally.enableLogging('/tmp/rally.log') return rally
def get_story(formatted_id): r = Rally(server, apikey=apikey, project=project) r.enableLogging('rally.log') aa = r.get('UserStory', fetch=True, query='FormattedID = "' + formatted_id + '"', instance=True) return dict_from_story(aa)
def basic_connection(): """ Using a known valid Rally server and access credentials, issue a simple query request against a known valid Rally entity. """ rally = Rally(server=PROD, user=PROD_USER, password=PROD_PSWD) response = rally.get('Project', fetch=False, limit=10) print response
def test_limit_query(): """ Use a pagesize of 200 and a limit of 80 in the params in the URL """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) qualifier = "State = Submitted" response = rally.get('Defect', fetch=True, query=qualifier, pagesize=200, limit=80) items = [item for item in response] assert len(items) == 80
def test_start_and_limit_query(): """ Use a pagesize of 50 and a start index value of 20 and a limit of 60 in the params in the URL """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) qualifier = "State = Submitted" response = rally.get('Defect', fetch=True, query=qualifier, pagesize=50, start=20,limit=60) items = [item for item in response] assert len(items) == 60
def test_getAllowedValues_for_UserStory(): """ Using a known valid Rally server and known valid access credentials, request allowed value information for the Milestones field of the UserStory entity. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) avs = rally.getAllowedValues('Story', 'Milestones') assert len(avs) == 1 assert avs == [True]
def rallyLogin(self): server = 'rally1.rallydev.com' user = '******' password = '******' project = 'MBH - HNL' workspace = 'default' rally = Rally(server, user, password, workspace=workspace, project=project) rally.enableLogging('mypyral.log') return rally
def test_post_pull_request(): expectedErrMsg = '422 Requested type name "pullrequest" is unknown.' #rally = Rally(server=TESTN, user=TESTN_USER, password=TESTN_PSWD) #rally = Rally(server=AGICEN, user=AGICEN_USER, password=AGICEN_PSWD) rally = Rally(server=AGICEN, apikey=AGICEN_SUB_100_API_KEY) #with py.test.raises(RallyRESTAPIError) as excinfo: pr = rally.create('PullRequest', dummy_data, project=None) assert pr is not None assert pr.oid
def test_all_users_query(): """ Using a known valid Rally server and known valid access credentials, request information about every user associated with the current subscription. """ rally = Rally(server=PREVIEW, user=PREVIEW_USER, password=PREVIEW_PSWD) everybody = rally.getAllUsers() assert len(everybody) > 0 assert len([user for user in everybody if user.DisplayName == 'Sara']) == 1
def test_basic_connection_with_apikey(): """ Using a known valid Rally server and valid API Key value, issue a simple query request against a known valid Rally target. """ rally = Rally(server=PROD, apikey=API_KEY) response = rally.get('Project', fetch=False, limit=10) assert response != None assert response.status_code == 200 time.sleep(1)
def test_basic_connection(): """ Using a known valid Rally server and access credentials, issue a simple query request against a known valid Rally entity. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) response = rally.get('Project', fetch=False, limit=10) assert response != None assert response.status_code == 200 time.sleep(1)
def test_five_condition_query_in_list(): rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) qualifiers = ["State = Submitted", "FormattedID < DE6000", "FormattedID != DE5986", 'Priority = "High Attention"', "Severity != Cosmetic" ] response = rally.get('Defect', fetch=True, query=qualifiers, limit=10) assert response.resultCount > 0
def test_start_value_query(): """ Use a pagesize of 200 and a start index value of 300 in the params in the URL """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) qualifier = "State = Submitted" response = rally.get('Defect', fetch=True, query=qualifier, pagesize=200, start=300) items = [item for item in response] assert len(items) > 200 assert len(items) < 600
def test_explictly_set_workspace_as_default_context(): rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD, workspace=DEFAULT_WORKSPACE) workspace = rally.getWorkspace() assert workspace.Name == DEFAULT_WORKSPACE project = rally.getProject() assert project.Name == DEFAULT_PROJECT url = makeResourceUrl(rally, 'Defect') #print(url) expected_workspace_clause = 'workspace=workspace/%s' % str(workspace.oid) assert expected_workspace_clause in url expected_project_clause = 'project=project/%s' % str(project.oid) assert expected_project_clause in url
def test_multiple_page_response_query(): """ Using a known valid Rally server and known valid access credentials, issue a simple query (no qualifying criteria) against a Rally entity (Defect) known to have more than 5 items. Set the pagesize to 5 to force pyral to retrieve multiple pages to satisfy the query. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) response = rally.get('Defect', fetch=False, pagesize=5, limit=15) count = 0 for ix, bugger in enumerate(response): count += 1 assert response.resultCount > 5 assert count <= response.resultCount assert count == 15
def test_basic_query(): """ Using a known valid Rally server and known valid access credentials, issue a simple filtering query targeting RecycleBinEntry items whose Name value does not contain a specific value. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) response = rally.get('RecycleBinEntry', fetch="ObjectID,ID,Name", query='Name = "Gone but not forgotten with the wind"', limit=100) assert response.status_code == 200 assert response.errors == [] assert response.warnings == [] assert response.resultCount > 0
def test_non_default_wksprj_specify_workspace_and_project_equal_None_context(): rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD, workspace=ALTERNATE_WORKSPACE, project=ALTERNATE_PROJECT) workspace = rally.getWorkspace() assert workspace.Name == ALTERNATE_WORKSPACE project = rally.getProject() assert project.Name == ALTERNATE_PROJECT url = makeResourceUrl(rally, 'Defect', workspace=None, project=None) #print(url) assert '&workspace=' not in url assert '&project=' not in url
def test_single_condition_query_plain_expression(): """ Using a known valid Rally server and known valid access credentials, issue a query with a single qualifying criterion against a Rally entity (Defect) known to exist for which the qualifying criterion should return one or more Defects. The qualifying criterion is a string that is _not_ surrounded with paren chars. """ rally = Rally(server=AGICEN, user=AGICEN_USER, password=AGICEN_PSWD) workspace = rally.getWorkspace() project = rally.getProject() qualifier = 'State = "Submitted"' response = rally.get('Defect', fetch=True, query=qualifier, limit=10) assert response.resultCount > 0
def test_multiple_entities_query(): """ Using a known valid Rally server and known valid access credentials, issue a simple query (no qualifying criteria) for a comma separated list of known valid Rally entity names. As of Rally WSAPI 1.x, this is an invalid request; only a single Rally entity can be specified. """ rally = Rally(server=AGICEN, user=AGICEN_USER, password=AGICEN_PSWD) multiple_entities = "Project,Workspace" with py.test.raises(InvalidRallyTypeNameError) as excinfo: response = rally.get(multiple_entities, fetch=False, limit=10) actualErrVerbiage = excinfo.value.args[0] assert excinfo.value.__class__.__name__ == 'InvalidRallyTypeNameError' assert actualErrVerbiage == multiple_entities
def test_obtain_instance_using_mep_project(): """ Using a known valid Rally server and known valid access credentials, obtain a Rally instance associated with specifying a valid but multi-element-path Project within a valid Workspace. A subsequent call on the instance to obtain the current Project should return a pyral entity for Project that has a ref for the correct m-e-p Project. """ rally = Rally(server=AGICEN, user=YETI_USER, password=YETI_PSWD, workspace=BOONDOCKS_WORKSPACE, project=DEEP_DUPE) cur_project = rally.getProject() assert cur_project.Name == DEEP_DUPE
def test_start_and_limit_query(): """ Use a pagesize of 50 and a start index value of 10 and a limit of 40 in the params in the URL """ rally = Rally(server=AGICEN, user=AGICEN_USER, password=AGICEN_PSWD) qualifier = "State = Submitted" response = rally.get('Defect', fetch=True, query=qualifier, pagesize=50, start=10, limit=40) items = [item for item in response] assert len(items) > 10 assert len(items) <= 40
def test_query_pull_requests(): #rally = Rally(server=AGICEN, user=AGICEN_USER, password=AGICEN_PSWD) #rally = Rally(server=TESTN, user=TESTN_USER, password=TESTN_PSWD) rally = Rally(server=AGICEN, apikey=AGICEN_SUB_100_API_KEY) attrs = "ExternalId,ExternalFormattedId,Artifact,Name,Url,Description" response = rally.get('PullRequest', fetch=attrs, project=None) assert response.status_code == 200 assert len(response.errors) == 0 assert len(response.warnings) == 0 prs = [pr for pr in response] assert len(prs) > 0 assert prs[0].Artifact assert prs[0].Artifact.__class__.__name__ == 'HierarchicalRequirement' print (prs[0].Artifact.oid) print(prs[0].details())
def main(args): options = [opt for opt in args if opt.startswith('--')] args = [arg for arg in args if arg not in options] #server, user, password, apikey, workspace, project = rallyWorkset(options) #if apikey: rally = Rally(server, user, password, apikey=apikey, workspace=workspace, project=project) #else: # rally = Rally(server, user, password, workspace=workspace, project=project) rally.enableLogging("rally.history.showstories") Hierarchfields = "FormattedID,Name,Iteration,TaskRemainingTotal,TaskStatus" #,Feature" Artifactfields = "owner,tags" #criterion = '((Iteration.Name contains "Iteration 3")OR(Iteration.Name contains "Iteration 7")) AND (Feature != null)' #query = "%s " criterion = '(Iteration.Name contains "PI%s - Iteration %s")' % ( pivalue, iterationvalue) response = rally.get('HierarchicalRequirement', fetch=Hierarchfields, query=criterion, order="FormattedID", pagesize=200, limit=400) # artifactresponse = rally.get('Artifacts', fetch=True, query=criterion, order="owner", limit=400) print criterion postmessage = "*Current Stories Iteration Stories*" + "\n" + "```" for story in response: #print (story.FormattedID,story.Iteration) postmessage = postmessage + "%-8s %-70s %-4.1f %-25s" % ( story.FormattedID, story.Name, story.TaskRemainingTotal, story.TaskStatus) + "\n" postmessage = postmessage + "```" + "\n" print response.resultCount, "qualifying stories" slack.chat.post_message(channel=channel, text=postmessage, username="******", as_user=False)
def main(args): global rally global server_name global debug debug = 1 #Parse Command line options parser = argparse.ArgumentParser("create_data") parser.add_argument("server", help="Server options = sales, integrations or partner", type=str) args = parser.parse_args() server_name = args.server.lower() create_pid() config = SafeConfigParser() config.read('config.ini') user_name = config.get(server_name, 'username') password = config.get(server_name, 'password') workspace = config.get(server_name, 'workspace') project = config.get(server_name, 'project') rally_server = config.get(server_name, 'server') print "server name is %s" % args.server print "username is now " + user_name #server, user, password, apikey, workspace, project = rallyWorkset(options) try: rally = Rally(rally_server, user_name, "Kanban!!", workspace=workspace, project=project) except Exception, details: print("Error logging in") close_pid() sys.exit(1)
def test_getSchemaInfo(): """ Using a known valid Rally server and known valid access credentials, obtain a Rally instance and call the getSchemaInfo method for the default workspace. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) schema_info = rally.getSchemaInfo(rally.getWorkspace()) assert type(schema_info) == list assert len(schema_info) > 50 subs_schema = [item for item in schema_info if item['Name'] == 'Subscription'] assert subs_schema != None assert len(subs_schema) == 1 assert type(subs_schema) == list assert u'Attributes' in subs_schema[0] assert len(subs_schema[0][u'Attributes']) > 15
def test_four_ored_conditions_in_parrened_string(): """ Take a user query with OR conditions in which the parenneg groups are already supplied in AgileCentral conformant "binary" condition style """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD, workspace=BOONDOCKS_WORKSPACE, project=BOONDOCKS_PROJECT) qualifiers = '((((Name = "Brazen%20Milliwogs") OR (Name = "Jenkins")) OR (Name = "Refusnik")) OR (Name = "Salamandra"))' response = rally.get('Project', fetch=True, query=qualifiers, limit=10) assert response.resultCount > 0 projects = [project for project in response] #print([project.Name for project in projects]) assert response.resultCount == 2 # Only Jenkins and Salamandra exist or or accessible to the accessing account
def test_get_project(): """ Using a known valid Rally server and known valid access credentials, issue a simple query (no qualifying criteria) for a known valid Rally entity. """ rally = Rally(server=PREVIEW, user=PREVIEW_USER, password=PREVIEW_PSWD) response = rally.get('Project', fetch=False, limit=10) assert response.status_code == 200 assert response.errors == [] assert response.warnings == [] assert response.resultCount > 0 proj_rec = response.next() print proj_rec._ref print proj_rec.ref print proj_rec.oid
def test_set_non_default_workspace_and_project_context(): rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD, workspace=ALTERNATE_WORKSPACE, project=ALTERNATE_PROJECT) workspace = rally.getWorkspace() assert workspace.Name == ALTERNATE_WORKSPACE project = rally.getProject() assert project.Name == ALTERNATE_PROJECT url = makeResourceUrl(rally, 'Defect') #print url expected_workspace_clause = 'workspace=workspace/%s' % str(workspace.oid) assert expected_workspace_clause in url expected_project_clause = 'project=project/%s' % str(project.oid) assert expected_project_clause in url
def test_non_default_workspace_project_specify_project_equal_None_context(): rally = Rally(server=AGICEN, user=AGICEN_USER, password=AGICEN_PSWD, workspace=ALTERNATE_WORKSPACE, project=ALTERNATE_PROJECT) workspace = rally.getWorkspace() assert workspace.Name == ALTERNATE_WORKSPACE project = rally.getProject() assert project.Name == ALTERNATE_PROJECT url = makeResourceUrl(rally, 'Defect', project=None) #print(url) expected_workspace_clause = 'workspace=workspace/%s' % str(workspace.oid) assert expected_workspace_clause in url assert '&project=' not in url
def main(args): options = [opt for opt in args if opt.startswith('-')] args = [arg for arg in args if arg not in options] if len(args) < 1: errout('ERROR: Wrong number of arguments\n') printHelp() sys.exit(3) server = 'rally1.rallydev.com' apikey = '_LhzUHJ1GQJQWkEYepqIJV9NO96FkErDpQvmHG4WQ' workspace = 'Sabre Production Workspace' project = 'Sabre' rally = Rally(server, apikey=apikey, workspace=workspace, project=project) bPrintStatus = True fileName = 'out.csv' with open(fileName, 'w', newline='', encoding="utf-8") as csvfile: #write header outfile = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) outrow = ["Type", "PGM", "PRJ", "FEA.ID", "TF.ID", "US.ID"] + \ [field for field in gFields] outfile.writerow(outrow) for token in args: processQueryTokens(rally, bPrintStatus, outfile, token)
def initRally(cmdLineOptions): requiredOptions = {'rallyServer','rallyUser','rallyPassword'} print 'Setting up Rally (pyral v{version})...'.format(version = pyral.__version__) if not requiredOptions.issubset(cmdLineOptions): print "ERROR: One of more of the required Rally options ({}) missing.".format(requiredOptions) sys.exit() return Rally(cmdLineOptions['rallyServer'], cmdLineOptions['rallyUser'], cmdLineOptions['rallyPassword'])
def test_bogus_query(): """ Using a known valid Rally server and known valid access credentials, issue a simple query specifying a entity for which there is no valid Rally entity. The status_code in the response must not indicate a valid request/response and the errors attribute must have some descriptive info about the error. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) bogus_entity = "Payjammas" expectedErrMsg = "not a valid Rally entity: %s" % bogus_entity with py.test.raises(InvalidRallyTypeNameError) as excinfo: response = rally.get('Payjammas', fetch=False, limit=10) actualErrVerbiage = excinfo.value.args[ 0] # becuz Python2.6 deprecates message :-( assert excinfo.value.__class__.__name__ == 'InvalidRallyTypeNameError' assert actualErrVerbiage == bogus_entity
def test_all_fields_query(): """ Using a known valid Rally server and known valid access credentials, issue a simple query (no qualifying criteria) for a known valid Rally entity. The fetch value is True so each entity returned in the response (data) will have its _hydrated attribute value set to True. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) response = rally.get('Project', fetch=True, limit=10) assert response.status_code == 200 assert len(response.errors) == 0 assert response.resultCount > 1 for project in response: assert project.oid > 0 assert len(project.Name) > 0 assert project._hydrated == True
def test_three_conditions_query_as_dict(): """ """ # TODO: note that an attribute value containing a '/' char will fail # have yet to determine how to get this to work with Rally WSAPI ... rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) qualifiers = { "State": "Submitted", "Priority": "High Attention", "Ready": "False" #'Severity : "Major Problem"', #'Severity : "Crash/DataLoss"', } response = rally.get('Defect', fetch=True, query=qualifiers, limit=10) assert response.resultCount > 0
def test_two_condition_query_in_unparenned_string(): """ Using a known valid Rally server and known valid access credentials, issue a query with two qualifying conditions against a Rally entity (Defect) known to exist for which the qualifying criterion should return one or more Defects. The qualifying criterion is a list that contains two condition strings, each condition string does _not_ have any surrounding paren chars. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) double_qualifier = "State = Submitted AND FormattedID != US100" response = rally.get('Defect', fetch=True, query=double_qualifier, limit=10) assert response.resultCount > 0
def test_get_image_binary_attachment(): # Use prior testing outcome for the story and attachment target target_workspace = 'Yeti Rally Workspace' target_project = 'Anti-Cyclone' target_story = 'US6099' attachment_name = 'alpine-snow-glen-plake-quote.png' attachment_type = 'image/png' rally = Rally(server=RALLY, user=YETI_USER, password=YETI_PSWD, workspace=target_workspace, project=target_project) criteria = f'FormattedID = "{target_story}"' response = rally.get("UserStory", fetch='ObjectID,Name,Description,Attachments', query=criteria) assert response.resultCount == 1 story = response.next() assert len(story.Attachments) == 1 attachment_from_collection = story.Attachments[0] attachment_specific = rally.getAttachment(story, attachment_name) assert attachment_from_collection.Name == attachment_specific.Name assert attachment_from_collection.Content == attachment_specific.Content assert len(attachment_specific.Content) > 950000 clone_file = 'test/plakism.png' with open(clone_file, 'wb') as imf: imf.write(attachment_specific.Content) assert os.path.exists(clone_file) FILE_PROG = "file" import platform plat_ident = platform.system() if plat_ident.startswith('CYGWIN'): plat_ident = 'Cygwin' if plat_ident == "Windows": FILE_PROG = "C:/cygwin/bin/file" #print("platform identification: {0}".format(plat_ident)) import subprocess process = subprocess.run([FILE_PROG, clone_file], stdout=subprocess.PIPE, universal_newlines=True) assert 'plakism.png: PNG image data, 1074 x 538, 8-bit/color RGBA, non-interlaced' in process.stdout os.remove(clone_file)
def test_story_fields(): """ Using a known valid Rally server and known valid access credentials, issue a simple query (no qualifying criteria) for a known valid Rally entity, and observe that you can access both standard and custom fields by the field Display Name. """ rally = Rally(server=AGICEN, user=AGICEN_USER, password=AGICEN_PSWD) response = rally.get( 'Story', fetch=True, query=['NumberofCases = 9', 'AffectedCustomers = "abc, xyz"']) assert response.status_code == 200 story = response.next() assert story.NumberofCases == 9 assert story.AffectedCustomers == 'abc, xyz'
def test_default_workspace_non_default_valid_project(): """ Using valid Rally access credentials, connect without specifying the workspace, specify the name of project (not the default) which is valid for the default workspace. Return status should be OK, the Rally instance's RallyContextHelper _inflated value should be 'minimal' """ project = 'My Project' rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD, project=project) response = rally.get('Project', fetch=False) assert response != None assert response.status_code == 200 assert rally._wpCacheStatus() == 'minimal'
def test_named_default_workspace_named_default_project(): """ Using valid Rally access credentials, connect specifying the workspace name (which is the default value), specifying the name of project (which is the default value). Return status should be OK, the Rally instance's RallyContextHelper _inflated value should be 'minimal' """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD, workspace=DEFAULT_WORKSPACE, project=DEFAULT_PROJECT) response = rally.get('Project') assert response != None assert response.status_code == 200 assert rally._wpCacheStatus() == 'minimal'
def test_three_condition_query_in_list(): """ Using a known valid Rally server and known valid access credentials, issue a query with three qualifying conditions against a Rally entity (Defect) known to exist for which the qualifying criterion should return one or more Defects. The qualifying criterion is a list that contains three condition strings, each condition string does _not_ have any surrounding paren chars. """ rally = Rally(server=TRIAL, user=TRIAL_USER, password=TRIAL_PSWD) #qualifiers = ["State = Submitted", "FormattedID != DE100", "Owner.UserName != horsefeathers"] qualifiers = [ "State = Submitted", "FormattedID != DE100", "Severity != UltraMegaHurt" ] response = rally.get('Defect', fetch=True, query=qualifiers, limit=10) assert response.resultCount > 0
def connect(): server = get_env("RALLY_SERVER") user = get_env("RALLY_USER") password = get_env("RALLY_PASSWORD") apikey = get_env("RALLY_APIKEY") project = get_env("RALLY_PROJECT") or 'default' rally = Rally(server, user, password, apikey, project=project) return rally
def test_default_workspace_with_named_default_project(): """ Using valid Rally access credentials, connect without specifying the workspace, specify the name of project which is the default project name. Return status should be OK, the Rally instance's RallyContextHelper _inflated value should be 'minimal' """ project = 'Sample Project' rally = Rally(server=AGICEN, user=AGICEN_USER, password=AGICEN_PSWD, project=project) response = rally.get('Project', fetch=False) assert response != None assert response.status_code == 200 assert rally._wpCacheStatus() == 'minimal'
def test_user_info_query(): """ Using a known valid Rally server and known valid access credentials, request the information associated with a single username. """ rally = Rally(server=PREVIEW, user=PREVIEW_USER, password=PREVIEW_PSWD) qualifiers = rally.getUserInfo(username='******') assert len(qualifiers) == 1 user = qualifiers.pop() assert user.Name == 'Paul' assert user.UserName == '*****@*****.**' assert user.UserProfile.DefaultWorkspace.Name == 'User Story Pattern' assert user.Role == 'ORGANIZER' ups = [up for up in user.UserPermissions] assert len(ups) > 0 up = ups.pop(0) assert up.Role == 'Admin'