Thursday, September 12, 2013

OAuth testing discussion continued
we had discussed a few test cases with OAuth earlier. The server has to validate a response. 

Wednesday, September 11, 2013

QueryFolders and QueryDefinitions are how the TFS arranges the QueryHierarchy in its object model. We were looking for ways to find items in this hierarchy. What we could do is we could cast the QueryHierarchy as another QueryFolder. Then access the QueryItem as by GUID or name with the accessor Item["Guid"] or Item["String"].  It is not clear from the documentation whether these are recursive but the paramter seems to indicate so.
In any case, you can use the FindNodeInSubTree method mentioned earlier with the Project object. Since the QueryHierarchy is part of the project, this search can return the desired result as well.
Another approach to do this search for a specific query definition would be to organize the query definition in a specific tree structure of the folders that is described by say a SubTreeHierarchy. When you cast any node in the the project level sub-tree into this SubTreeHierarchy object and it doesn't turn out to be a null, then you have an object that can tell you the path to the sought after query definition in constant time.
Another approach is to do breadth first search or a depth first search of the entire subtree. Since the structure of a tree at least for queries could be finite and the algorithms to search for the breadth first or depth first are known and since the starting point could be anywhere in the QueryHierarchy tree, this works well too.
In addition, lookup by name or Id could be faster, if we used the hash that the Item accessor provides. If possible, then the string could be used instead of the GUID.
Another approach to do this search could be to work with the structure alone instead of lookup by attributes such as name or id. For example, the third node of the folders under the second node of the folders under the root has the query definition we are interested in after we have looked it up in the Team Foundation Server using the Visual Studio Work Items selection in the team explorer.
Regardless of the method we use, we are relying on the object model to lookup the query, execute it and give us the desired results.
The object model differs from the API model in that we don't hide complexity behind the objects and their methods. In the API model for example, we take well known methods and arrange the resources. True the API could appear as methods of a singleton object or a composition but that's not what it is designed for. The APIs allow for any number of variations and mix in the API calls to solve different tasks that the APIs have been written for. By keeping the methods the same and promoting it over http, it only adds ease of use, diagnosability and testing by visual means. The API trace not only identifies sender, receiver, request, response, their payload and parameters but also the timestamp, the order and the duration for each. This is a sufficient plan to know what was invoked when and allows for usage outside the program.
This is where OData comes into picture. What we could achieve by client model to gain access to the data is now available via the web since they are exposed directly as resources for individual or collective listing.

OAuth testing continued

One more test I needed to add to my list earlier is that the tokens expiry time could be validated by waiting for the expiration time and trying it again. In addition, we could test that the refresh tokens are issued for non-expired tokens. Token issued to one client should not be usable by another client.
The spoofing client could even use the same API key as the spoofed client. If the same user authorizes two clients both of whom have now requested access tokens, then these tokens should be similar, work the same and generally not be transferable or exchanged. A client requesting user authorization cannot use the same token for non-user privileged API for another user.
In the previous post, there was a mention for the different services hosted by the team foundation server. We will explore them in detail now. These services are :
1. ITeamFoundationRegistry - Gets or reads user entries or values
2. IIdentityManagementService - Manage application groups and memberships.
3. ITeamFoundationJobService
4. IPropertyService
5. IEventService
6. ISecurityService
7. ILocationService
8. TswaClientHyperlinkService
9. ITemaProjectCollectionService
10. IAdministrationService
11. ICatalogService
12. VersionControlServer
13. WorkItemStore
14. IBuildServer
15. ITestManagementService
16. ILinking
17. ICommonStructureService3
18. IServerStatusService
19. IProcessTemplates

Tuesday, September 10, 2013

In today's post we want to cover the TFS client model library in detail. We will describe the hierarchy. The TeamProjectCollection is the root objectand we can instantiate a WorkItemStore with this root object. A WorkItemStore has a collection of projects. WE can look up the project we want by the name. When we find the project by name using the Projects propery of WorkItemStore, the corresponding Project object is returned. This Project item has a set of properties we are interested in. The project has AreaRootNodes that gets the collection of area root nodes. Recall that Area nodes can have path qualifiers so these are tree nodes. The next property is the Categories property and this gets us all the collection of work item type categories that belong to this project.
Take for example, the QueryHierarchy property. This is a replacement to the obsolete StoredQueries type and lets you get all the query items whether they are query folders or query definitions. Note that the query definition files are viewable only. This is there is a property called QueryText that gives you the text of the WIQL stored in these files but no way of executing that wIQL. You can then use this text to instantiate a Query object and invoke the RunLinkQuery. You need both the WorkItemStore and the WIQL to instantiate the Query object.  Thus given a URI to the TFS server, we have programmatically traversed the object model to find the query and execute it. Whenever you make or change the QueryItems in this tree, you can simply save the QueryHierarchy. This will save any changes anywhere in the tree. If you were to look for an item in this tree, you may have to implement a recursive search method that enumerates the contents of the current QueryFolder. However if you have a GUID you can use the find method to retrieve that specific item.There is a FindNodeInSubTree method that can do this recursion and it accepts a lookup based on a specified ID or a path. In most cases, this works well because with TFS workitems when we create, update or delete them in visual Studio, we can get their GUIDs by using copy full path or retrieving the GUID by a previous client object model call. There is a mention for a hash of all names of the items that can be looked via a Item property on the treenode but it doesn't seem to be available with VS2010.
TFS also provides a set of services that can be individually called for access to the resources they represent. You can get a reference to any service using the GetService method and it can take the type of the service you want to use as a parameter. 
TFS client object model provides a nice hierarchy of objects to use to our advantage. For example, you can navigate from the server scope to the project scope and then to the work items scope. And at any level you can enumerate the resources. This provides a convenient mechanism for the length and breadth of the organization.
The client object model is not the only thing. There's the server object model to be used at the server side. and the build process object model at the build machine.
The OData on the other hand gives the same flexibility outside the programming context. It is accessible over the web.
The way to navigate the OData from TFS is to use the OData model to find the workItem we are interested in. Here's how it would look like :
var proxy = CreateTFSServiceProxy(out baseURL, out teamProject, out workitemtype);
var workItems = proxy.Execute<WorkItem>(new Uri(string.Format(cultureInfo.InvariantCulture,
                                                             {0}/Projects('{1}')/WorkItems?$filter=Type eq '{2}' and Title eq '{3}' & $orderby=Id desc",
                                                             baseURL,
                                                             teamProject,
                                                             WorkItemType,
                                                             WorkItemTitle)))
                  .First();
 This lets us specify the filter in the Uri to get the results to we want. Then it can be processed or reported in any way.
or another way to execute the queries could be as follows:
var queryProxy = new TFSQueryProxy(Uri, ICredentials)
var queries = queryProxy.GetQueriesByProjectKey

TFS client object model provides a nice hierarchy of objects to use to our advantage. For example, you can navigate from the server scope to the project scope and then to the work items scope. And at any level you can enumerate the resources. This provides a convenient mechanism for the length and breadth of the organization.