TDD Test Sample

In this post I would like to demonstrate few of my TDD (Test Driven Development) skills!

TDD

I  started TDD during 2010 with a Product Development Company.  Thereafter I am a Big Fan & Advocate of TDD.

Following are the Properties & Advantages of TDD:

  1. In TDD we first write the Unit Test. Then we start with the actual Code Method.  As the Test Method evolves the Original Method evolves too.
  2. TDD ensures the code is released with enough testing.
  3. TDD is an Investment for Future
  4. TDD is essential for Products
  5. TDD gives the Flexibility for Refactoring, More Confident Deployments
  6. TDD is used mostly in the Backend side

Coding Test

We want to expose a service that calculates the total spend given a supplier ID.

public class SpendService

{

public SpendSummary GetTotalSpend(int supplierId) { … }

}

The business logic is quite straightforward: the total spend is the sum of all the invoices, grouped by year. However, some of the suppliers are working with a separate branch of the company, which has its own invoicing platform.

Therefore, the flow should work as follows:

1) A SupplierService returns supplier data, which can be used to understand whether a supplier is external or not

2) If the supplier is not external, invoice data can be retrieved through the InvoiceRepository class

3) If the supplier is external, invoice data can be retrieved through the ExternalInvoiceService class

4) ExternalInvoiceService invokes a separate system, which might fail. However, data from this system is regularly backed up in a failover storage. A FailoverInvoiceService class gives access to that storage. It is ok to return failover data when ExternalInvoiceService fails.

5) Failover data might be not fresh. A timestamp property indicates when it has been originally stored. If this date is older than a month, it means that it has not been refreshed. In this case, the GetTotalSpend method should fail.

6) When ExternalInvoiceService is offline, usually calls tend to timeout, which means that the method takes long to complete. Therefore, after 3 consecutive errors, we want to bypass ExternalInvoiceService and go to FailoverInvoiceService directly, with the same logic as before. After 1 minute, we can try to re-enable ExternalInvoiceService again.

Solution

[TestClass]
    public class SpendServiceTest
    {
        private UnityContainer container;

        [TestInitialize]
        public void TestInit()
        {
            container = new UnityContainer();
            container.RegisterType<ISupplierDataService, SupplierDataServiceStub>();
            container.RegisterType<ISupplierService, SupplierService>();
            container.RegisterType<IInvoiceRepository, InvoiceRepositoryStub>();
            container.RegisterType<IExternalSpendService, ExternalInvoiceServiceStub>();
            container.RegisterType<ICircuitBreaker, ExternalSpendServiceInvoker>();
            container.RegisterType<IFailoverInvoiceService, FailoverInvoiceServiceStub>();
        }

        [TestMethod]
        public void SpendService_InternalCustomer_Name_Test()
        {
            // Arrange
            int supplierId = 1;
            SpendService spendService = container.Resolve<InternalSpendService>();

            // Act
            SpendSummary result = spendService.GetTotalSpend(supplierId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(“Supplier Internal”, result.Name);
        }

        [TestMethod]
        public void SpendService_InternalCustomer_Spend_Test()
        {
            // Arrange
            int supplierId = 1;
            SpendService spendService = container.Resolve<InternalSpendService>();

            // Act
            SpendSummary result = spendService.GetTotalSpend(supplierId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(2, result.Years.Count);
            Assert.AreEqual(2000, result.Years[0].TotalSpend);
            Assert.AreEqual(1000, result.Years[1].TotalSpend);
        }

        [TestMethod]
        public void SpendService_ExternalCustomer_Name_Test()
        {
            // Arrange
            int supplierId = 2;
            SpendService spendService = container.Resolve<ExternalSpendService>();

            // Act
            SpendSummary result = spendService.GetTotalSpend(supplierId);

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(“Supplier External”, result.Name);
        }

}

Following is Circuit Breaker.

public interface ICircuitBreaker
{
    int MaxTries { get; }

    int ClosedTimeSeconds { get; }

    int ObsoleteDaysLimit { get; }

    bool IsOpenState { get; set; }

    DateTime FailedTimestamp { get; set; }

    void Reset();

    List<SpendDetail> GetSpendDetail(int supplierId);
}

One Stub Sample.

public class FailoverInvoiceServiceStub : IFailoverInvoiceService
    {
        public FailoverInvoiceCollection GetInvoices(int supplierId)
        {
            FailoverInvoiceCollection result = new FailoverInvoiceCollection();

            if (supplierId == 2)
            {
                IList<ExternalInvoice> list = new List<ExternalInvoice>();
                list.Add(new ExternalInvoice() { Year = 2018, TotalAmount = 900 }); // Only 1 Year
                result.Timestamp = DateTime.Now;
                result.Invoices = list.ToArray();
            }
            else if (supplierId == 3)
            {
                IList<ExternalInvoice> list = new List<ExternalInvoice>();
                list.Add(new ExternalInvoice() { Year = 2018, TotalAmount = 900 }); // Only 1 Year
                result.Timestamp = DateTime.Now;
                result.Invoices = list.ToArray();
            }
            else if (supplierId == 4)
            {
                IList<ExternalInvoice> list = new List<ExternalInvoice>();
                list.Add(new ExternalInvoice() { Year = 2017, TotalAmount = 800 });
                result.Timestamp = DateTime.Now.AddDays(-32); // Obsolete Date
                result.Invoices = list.ToArray();
            }

            return result;
        }
    }

Strategies

I have been using following Frameworks & Strategies:

  1. Unit Test created using C#
  2. Moq Framework for Mocking
  3. Stubbing using C# Classes
  4. Wrapper Methods for Static Methods unit testing

References

You can find the Code in GitHub.

https://github.com/jeanpaulva/jp-tdd

Summary

This is a TDD Code Demonstration to showcase my skills. 

Thank you All!

Azure Database – Service Tiers–Performance

In this Post we can explore the Advantage of SQL Database Tiers Scalability.

Scalability

Azure provides Flexibility of Scaling Up/Down based on the Demand. 

Create a Database

Create an Azure Database with Default Options.  You will get it created in Standard service tier.

image

Performance Test

You can create a Table with 10 columns & Insert 10 Lakh Records.

It took around 2 hour for me.

Scale Up

Now we need to Scale Up and Test.

Choose the database Configuration as shown below.

image

In the appearing window choose Premium.

Choose the 500 DTU option.  Now click Apply button.  Wait for Few minutes for the Upgrade to complete.

image

DTU

DTU represents Data Throughput Unit. More the DTU More the Performance.

Run the Results

Now run the same Query again.  The performance got improved by 50% by completing in 1 hour.

Summary

Increasing the Service Tier / DTU will give quick jump up in performance during Peak hours.

Note

Do not forget to scale down after the purpose. Else the bills will also perform huge.

Mobile App Advantages

In this post we can consider the Advantages of Mobile App Feature of App Service.

Offline Storage

The Offline Storage provides data storage during No-Internet times.

Improved Responsiveness

For critical applications which require read/write response within 1 seconds can be achieved through Offline Storage of data helping read/write seamless.

Push Notifications

Azure Notification Hub support for Sending messages to multiple devices/platforms of Android, iOS, Windows etc.

Identity Management

AD Enabled for easier Security Integration

Social Media Integration

Facebook, Twitter Integration for Federated Authentication, Post Integration etc.

Scalability

Multiple devices can be supported through Auto Scale feature.

Staged Deployments

We can do Staged deployments where Production switching is possible through changing IPs

Continuous Integration

Continuous Integration with Visual Studio & Github possible.

Create Mobile App Service

We can create Mobile App Service from below link.

image

Azure Hosting Plans

Azure provides various Hosting Plans with various Hardware & Price mix.  We can select a Plan well suited for our purpose.

FREE Plan – F1

This plan is meant for Development Or Testing purposes.

It has restriction of 60 minutes/day compute.

This is Free!

But the hardware will be on shared basis.

image

image

image

Custom Domains are available with D1 and B1 plans.

Production Plans

Production level hosting plans are starting with S1.

image

S1 supports Auto Scalability up to 10 instances, Traffic Manager etc.

image

image

image

P1v1 supports Auto Scalability up to 20 instances.

image

image

Isolated Plans

These plans runs in their own network in  Single Tenancy mode.

image

image

image

Note

These plan includes the IaaS + PaaS components of hardware, operating system etc.

References

https://azure.microsoft.com/en-in/pricing/details/app-service/windows/

High Availability for Azure Deployments

Following are High Availability strategies while developing Azure Applications.

Multiple Instances

Ensure the application components, services have multiple instances.

Retry Pattern

In case of Transient failures that should not last long, the application should implement a Retry pattern to repeat the invoke and get through the service.

Circuit Breaker Pattern

For prolonged failures, the application should implement Circuit Breaker pattern so that subsequent failures will not hang the application.  Once the failure is resolved, the Circuit Breaker should open the gates back.

Message Broker

Implement a Message Broker for high critical tasks to ensure the tasks in the Queue is definitely processed.

Automate Deployments

Consider using Automated Deployments including for Updates too.

Deployment Slots

Usage of Deployment Slots enable switching between Production & Staging deployments.

Geo-replicate Database

Geo-Replicate the database for higher availability.

Monitoring Systems

Implement proper monitoring systems to track failures, notify on errors, long duration tasks etc.

Disaster Recovery

Create a multi-site recovery plan for mission critical applications.

Deployment Slots in Azure

Deployment Slots enable robust deployment through Production and Staging slots.

The default slot will be Production Slot.

The advantages of Deployment Slot are:

  • Staged Deployment
  • Swapping
  • Incremental Deployment
  • Rolling back Deployment

Staged Deployment

Here were can deploy the application to a non-production slot.  This allows to conduct UAT, QA verifications on the app to ensure it validates for a Production build.

Swapping

Once we verify the app, we can Swap the slots making it as Production.  This operation is so quick that it takes only few seconds.

Incremental Deployment

Step by Step changes are possible after deployment.

Rolling back Deployment

Swapping feature enables to rollback the deployment from production to staging, in case any errors occurs.

Azure Cosmos DB

Azure Cosmos DB provides a NoSQL database in Azure premises.  It is globally distributed, highly available, massively scalable database.  It is an extension of the previous DocumentDB which was used for storing databases.

image

Advantages

Following are the Advantages of Cosmos DB.

Scalability It is horizontally scalable

Globally Distributed It is available from multiple edge server end points reducing latency

Multi-Model It supports document, key-value & graph models

Multi-API It supports sql, mongodb, cassandra, azure table, gremlin apis.

Security It is fully & transparently encrypted

Create Cosmos DB

Open Azure Portal  > Search for Cosmos DB > Use Create Option as below.

image

Enter the details in appearing window.

image

You can access the same from Azure Cosmos DB tab from the left.

image

Development

Clicking on the Quick Start pane will give you the Development Code & Samples.

image