Infrastructure Configuration Tests: Ignore a Test Based Upon the Non-Existance of a X.509 Certificate

Businesses are increasingly relying on X.509 certificates to lock down access to sensitive websites and web services, this has become increasingly prevalent on the Windows platform since Microsoft’s Windows Azure API uses X.509 certificates to lock down access to an individual subscriptions services in this exact way. This poses a bit of a headache for teams writing infrastructure configuration tests as these tests will fail against environments if the developer does not have the certificate installed.

As I have mentioned in previous posts it is good practice to provide a mechanism for infrastructure configuration tests to execute conditionally, I have shown how we do this for dates and Version Numbers. The same mechanism can be used to conditionally execute a test based upon the existence of a Certificate in a specified store.

The core of this technique is the CertificateExistsAttributeBase class which provides the base access to the certificate store and abstracts the Certificate Logic away from the concrete implementation:


1. public abstract class CertificateExistsAtributeBase : Attribute, ITestAction {
2. public void BeforeTest(TestDetails testDetails) {
3. var certificates = GetCertificates();
4.
5. if (certificates.Count == 0) {
6. Assert.Ignore("Certificate identified by {0} not found in {1} in
7. {2}", GetFindCriteria(), StoreName, StoreLocation);
8. }
9. }
10.
11. private X509Certificate2Collection GetCertificates() {
12. X509Store store = null;
13.
14. try {
15. store = new X509Store(StoreName, StoreLocation);
16. store.Open(OpenFlags.ReadOnly);
17. return store.Certificates.Find(GetX509FindType(), GetFindCriteria(), ValidOnly);
18. }
19. catch (CryptographicException cex) {
20. Assert.Ignore("Unable to retreive certificate: " +
21. cex.Message);
22. }
23. catch (SecurityException secex) {
24. Assert.Ignore("Unable to retreive certificate: " +
25. secex.Message);
26. }
27. finally {
28. if (store != null) {
29. store.Close();
30. }
31. }
32.
33. return null;
34. }
35.
36. protected bool ValidOnly = true;
37.
38. protected StoreName StoreName = StoreName.My;
39.
40. protected StoreLocation StoreLocation = StoreLocation.CurrentUser;
41.
42. protected abstract object GetFindCriteria();
43.
44. protected abstract X509FindType GetX509FindType();
45.
46. public void AfterTest(TestDetails testDetails) { }
47. public ActionTargets Targets { get; pri


Classes can then derive from this base attribute to provide specific, certificate matching functionality in the form of an ITestAction attribute:


1. [Test, IgnoreIfCertificateDoesNotExistByThumbprint("66E0BC68570E30FBA6207B1050AC72DC5B48CF47", validOnly: false)]
2. public void Should_Execute_Because_Certificate_Found() {
3. Assert.Pass();
4. }

5. [Test, IgnoreIfCertificateDoesNotExistByThumbprint("AED4CAEEAE1981AEAAE2012ADAE1981CEAAD1989", validOnly: false)]
6. public void Should_Not_Execute_Because_Certificate_Missing() {
7. Assert.Fail();
8. }


This pattern can be taken a step further by creating domain specific attributes for the different type of client certificate used by your project:


1. public class IgnoreIfDevManagementCertificateDoesNotExist : IgnoreIfCertificateDoesNotExistByThumbprint {
2. public IgnoreIfDevManagementCertificateDoesNotExist()
3. : base("66E0BC68570E30FBA6207B1050AC72DC5B48CF47", StoreName.My, StoreLocation.CurrentUser, validOnly: false) { }
4. }

5. public class IgnoreIfProductionManagementCertificateDoesNotExist : IgnoreIfCertificateDoesNotExistByThumbprint {
6. public IgnoreIfProductionManagementCertificateDoesNotExist()
7. : base("AED4CAEEAE1981AEAAE2012ADAE1981CEAAD1989", StoreName.My, StoreLocation.CurrentUser, validOnly: false) { }
8. }


Once everything has been put together, and assuming you are using ReSharper and Visual Studio 2013 to execute your tests it should look something like this:

Leave a Reply

Your email address will not be published. Required fields are marked *