Thursday, May 26, 2016

Troubleshooting the dreaded "The build directory of the test run either does not exist or access permission is required." error message in Microsoft Test Manager

Our company is starting to use the Microsoft Test Manager a lot more to manage our testing, both manual and automated. Additionally, we've recently started on creating some new Test Controllers and Test Agents with an exotic network configuration. On one of these new Test Controllers, I've started creating Lab test runs, and been getting the error message "The build directory of the test run either does not exist or access permission is required." When you Google this error message, you get what's described in this post on MSDN. In my case, this was the former problem: the account under which the test controller was running couldn't see the build folder.

After reading that last statement, you might say "well, why didn't you check to make sure that the drop folder was in the place it should have been ?". And, I did. Sort of. Due to our network configuration and aliases, my user could see it on the expected place at the alias in my portion of the network, but the user under which the Test Controller was running (not the tests themselves as configured in the Microsoft Test Manager, but instead the Test Controller software, they're not the same user) couldn't because we have some synchronization going on. Once I logged on to the machine on which the Test Controller service was running ** AS THE USER UNDER WHICH THE TEST CONTROLLER WAS RUNNING ** and went to the network alias myself, I could finally see that the synchronization between the locations on the network that had the same alias wasn't running and the build that I expected to be there was in fact not running.

Problem solved.

Monday, May 02, 2016

Migrating code in TFS from one Team Project to another Team Project within the same Team Project Collection

My company has frequently had the issue of moving code around within the same Team Project Collection as shifting desires and motivations for the organization of our code have swayed our company. Previously, we've used tools such as the TFS Integration Platform available on code plex. That project has its share of issues, namely that:
a) It was half baked to begin with
b) It's no longer maintained and doesn't work for versions later than TFS 2012.

Fortunately for me, thanks to a fortuitous Stack Overflow post, I've found the following script to recursively move the content of one folder to another folder, and it even works across Team Projects within the same collection (but not across Team Project Collections):

Param(
    [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string] $SourceFolder,
    [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string] $TargetFolder
)

Get-TfsChildItem $SourceFolder |
    select -Skip 1 |  # skip the root dir
    foreach {
        & "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\TF.exe" rename $_.serveritem $_.serveritem.replace($SourceFolder, $TargetFolder)
    }

In order to run the script above, you'll need both Visual Studio and TFS Power Tools installed. When you install the Power Tools, you'll need to ensure that the PowerShell module is selected in the installation options. Also, because the path to the Power Tools PowerShell module isn't put in the PSModulesPath by default, you'll have to manually import the module into your PowerShell settings like so (before you run the script):

Import-Module "C:\Program Files (x86)\Microsoft Team Foundation Server 2013 Power Tools\Microsoft.TeamFoundation.PowerTools.PowerShell.dll"

Saturday, April 16, 2016

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost:xxxxx' is therefore not allowed access

While developing an adal.js app with OData in IISExpress, I'm getting the following error:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost:44315' is therefore not allowed access

Turns out the problem is that I needed to include the CORS package from Microsoft:

Install-Package Microsoft.AspNet.WebApi.Cors

Once that's in there, I also need to enable CORS using the 'EnableCors' extension method on my HttpConfiguration.

Tuesday, April 12, 2016

Using ADAL.js correctly with AngularJS when setting up your endpoints

When searching around and using the tutorials on how to correctly use adal.js to authenticate your calls to Web API (or anything else) in Azure, you'll often see a block similar to this that you have to put in your App.js to configure your main module:

adalAuthenticationServiceProvider.init(
{
tenant: 'mytenant.onmicrosoft.com',
clientId: 'abc4db9b-9c54-4fdf-abcd-1234ec148319',
endpoints: {
'https://localhost:44301/api': 'https://some-app-id-uri/'
}
},
$httpProvider
);

You'll notice that this appears to be pointing to the Web API root of a service running on localhost, and you'd be right. For this to work correctly, you'll need to enable OAUTH 2 path matching in the application manifest of the **client** that's connecting to the service!

Wednesday, March 30, 2016

Running and debugging Azure WebJobs locally on your development machine

Check out this article: https://github.com/Azure/azure-webjobs-sdk/wiki/Running-Locally

It shows you how to locally run and debug Azure WebJobs, which as it turns out is extremely handy because you can interact with all the Queues, Tables, Blobs etc as you normally would and get a full debugging environment.

Updating your Azure AD Application Manifest

We've recently found that as we develop more applications in Azure, we need to put safeguards on the deployment of the applications to ensure that they're configured correctly. Part of this means editing the application manifests to ensure that certain settings are always enforced on certain applications. Here's what Microsoft has to say about updating Application manifests.

Bottom line, if you want to automate anything to do with manifests, you'll have to write your own application to use the Azure Graph API libraries to retrieve the manifest / application settings and edit them.

Sunday, February 28, 2016

Properly invoking scheduled WebJobs

Recently we've found the need to start using Scheduled Azure WebJobs. However, the examples out there are all gargbage, even in the case where you can find an actual example using a scheduled WebJob rather than a continuous WebJob. So, for the benefit of anyone interested, including future me, here's the proper way to invoke a Scheduled WebJob in the entry point of the WebJobs assembly:

    /// <summary>
    /// The main entry point to the scheduled webjobs.
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Main entry point for the scheduled webjobs
        /// </summary>
        public static void Main()
        {
            IKernel kernel = new StandardKernel();

            kernel.Load(new ServicesScheduledWebJobsNinjectModule());

            var jobHostConfiguration = new JobHostConfiguration
            {
                JobActivator = new ServicesScheduledWebJobsActivator(kernel),
                DashboardConnectionString = ConfigurationManager.ConnectionStrings["AzureWebJobsDashboard"].ConnectionString,
                StorageConnectionString = ConfigurationManager.ConnectionStrings["AzureWebJobsStorage"].ConnectionString,
            };

            var host = new JobHost(jobHostConfiguration);

            // Must ensure that we call host.Start() to actually start the job host. Must do so in
            // order to ensure that all jobs we manually invoke can actually run.
            host.Start();

            // The following code will invoke all functions that have a 'NoAutomaticTriggerAttribute'
            // to indicate that they are scheduled methods.
            foreach (MethodInfo jobMethod in typeof(Functions).GetMethods().Where(m => m.GetCustomAttributes<NoAutomaticTriggerAttribute>().Any()))
            {
                try
                {
                    host.CallAsync(jobMethod).Wait();
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine("Failed to execute job method '{0}' with error: {1}", jobMethod.Name, ex);
                }
            }
        }
    }

What the above does is the following:

  • Configures the JobHost to use a dependency injection container via a custom IJobActivator implementation that, in our case, uses the Ninject dependency injection container.
  • Configures the JobHost with a custom configuration so that we can control various items, including the connection strings for the dashboard and jobs storage.
  • Starts the JobHost. This bit is important, because all the other examples out there neglect that this needs to be done.
  • Dynamically resolves all schedulable methods that should be invoked, using the NoAutomaticTriggerAttribute built in to the WebJobs SDK. This attribute is used internally by the SDK to determine which methods need to be invoked manually (i.e. on demand) rather than by a continuous invocation used by Continous WebJobs.

Continuous Delivery of Azure Web Services

See this:

https://azure.microsoft.com/en-us/documentation/articles/cloud-services-dotnet-continuous-delivery/

Sunday, February 21, 2016

Debugging Azure web apps on localhost

To get this working, you need to have an app registered with your localhost app root registered for the redirect URI and login URI. Here's the really important part of you're using AAD authentication:

You need to disable all forms of Authorization in IIS and enable Anonymous authentication for the application in the IIS manager on the web app itself so that Azure AD can take over the authentication!

Using adal.js and getting error AADSTS65001: The user or administrator has not consented to use the application with ID '....'

It turns out that you have to actually go in and give your javascript web client permissions to access the web api application in the Azure Active Directory management portal. Go figure.

Using adal.js and getting error AADSTS70005: response_type="token" not supported

I've recently started using adal.js with OData in an AngularJS 1.5 application and been getting this error with attempting to connect my client-side XHR requests to my Web API application.

Following the advice here, changing the AAD manifest of the AngularJS web client from this:

"oauth2AllowImplicitFlow": false

... to this:

"oauth2AllowImplicitFlow": true

... seems to have solved the problem.

Tuesday, February 16, 2016

Getting CORS requests working in Web API 2

I've just recently started playing with using adal.js to connect to Azure Active Directory for authentication so that I can set up an AngularJS => Web API scenario with OData connections.

I followed the page on asp.net here.

However, I'm still running into the following problem: // TODO

Monday, February 08, 2016

How to move a shelveset from one branch to another in TFS

You're going to have to start by installing the TFS PowerTools for TFS 2013 (or whatever version is appropriate for you). Once you have the powertools installed and the tools added to your PATH (if they're not already added by the installer), run a command similar to the following in the command line:

tfpt unshelve /migrate /source:"$/ProjectName/Branch" /target:"$/ProjectName/Targetbranch" "My Shelveset Name"

This will unshelve your shelveset into your new branch for you.

WARNING: Before you do this, make sure you're unshelving into a clean branch with no Pending Changes, otherwise you could inadvertently overwrite or otherwise lose important changes.

Friday, January 22, 2016

Retrieving the list of Service Principals in your Azure subscription(s)

Recently I found that I needed to grant certain users permissions in my applications, specifically I needed to put Service Principals into groups in order to grant them permissions in my application so that they can access protected data.

I found out that in Azure PowerShell, there's the module 'MSOnline', which contains the following pertinent commands:

Connect-MsolService:

Connects your current session to your MSOnline account

Get-MsolServicePrincipal:

Retrieves a listing of all of the Service Principals in your subscription(s)

Monday, January 18, 2016

Enabling manipulation of Azure Active Directory groups through Web Applications via the Azure Graph SDK

In your application(s) (plural if you're using a web / native application delegating to a Web Services API which is doing the actual work), you'll need to go into their pages in the Azure Active Directory management page. Once there, edit the permissions of the applications to include the following:

Under the delegated-to application:

  • Under "Application Permissions", select:
    • Read and write domains
    • Read and write directory data
    • Read directory data
  • Under "Delegated Permissions", select:
    • Read and write directory data
    • Read and write all groups
    • Read all groups
    • Access the directory as the signed-in user
    • Read directory data
Under the top-level application:

  • Under "Delegated permissions", select:
    • Read and write directory data 
    • Read and write all groups 
    • Read all groups 
    • Access the directory as the signed-in user 
    • Read directory data

Tuesday, December 08, 2015

Getting the SQL Server PowerShell tools

They're apparently not that easy to find. The SQL Server PowerShell Tools come as part of the SQL Server Feature Pack for their respective versions. You can find the SQL Server 2014 Feature Pack (along with the PowerShell Tools) here.

Thursday, October 22, 2015

Querying PowerShell for module and cmdlet information

I've recently realized that it's of incredible benefit to start designing our systems such that they're open and easily queryable by any system, particularly .NET and PowerShell. As a result, I've started designing modules for PowerShell to let my team administrate our systems. This has led me to realize that they need some of the basics of PowerShell to query what's available to them, because none of them have really used PowerShell before. The following commands should be of help to beginners:

Show the currently loaded PowerShell modules: Get-Module

Show the available PowerShell modules: Get-Module -ListAvailable

Show the cmdlets available in a particular module: Get-Command -Module [module name]

* in the case of our custom compiled C# module assembly, this is the name of the assembly (not the name of the assembly file, e.g. MyCompany.MyAssembly, not MyCompany.MyAssembly.dll)


Sunday, October 18, 2015

Accessing TFS via PowerShell

I'm ashamed to admit that only today did I find out that there are PowerShell cmdlets for TFS.

You can load them into a PowerShell session by executing this:

add-pssnapin Microsoft.TeamFoundation.PowerShell

Once that's done, you can get started with the following commands:

Get-Help Get-TfsServer

See this post on Hey Scripting Guy.