barn_lock

C# clipboard locking and a crash

While testing a feature that accessed the clipboard recently, I came up against an interesting clipboard scenario.

What test strategies and models can we use to approach this feature in order to highlight the most important risks?

A straight-forward approach is to treat the clipboard as an external resource.

After all, it’s an external resource!

Generally, we normally don’t consider it an external resource — it’s part of Windows, it’s just a simple API call and it’s almost always available.

However, the clipboard is a resource shared by other applications. Because of this characteristic, all the issues that come with sharing a resource (waiting for access, locking, deadlocking, etc.) become higher risk areas.

The advantage of this approach is you start thinking about things that may happen if the shared resource is unavailable.

But the clipboard is always available, right?

Like any shared resource, it can be held up. So what  does your application do when it’s held up?

That’s exactly what this piece of code does.

It holds onto the clipboard a bit longer than it should. It’s not the nicest thing to  do, but it can happen.

Another application may have a bug, or perhaps a large amount of data is being copied to the clipboard causing a slight delay. The application you’re testing should be able to recover from such errors, because there’s no guarantee that every other application is a good citizen.

The key risk being assessed is… 

Does a busy clipboard cause issues for your application? It caused a crash in my case.

This C# snippet does the magic of hanging onto the clipboard for 30 seconds. Should be more than enough time for you to get into your application under test to do your investigation.

class Program
{
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern IntPtr GetOpenClipboardWindow();

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern bool OpenClipboard(IntPtr hWndNewOwner);

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern bool CloseClipboard();

    static void Main(string[] args)
    {
        int secondsToLockClipboard = 30;

        IntPtr handleWnd = GetOpenClipboardWindow();
        OpenClipboard(handleWnd);

        for (int i = 1; i         {
            System.Threading.Thread.Sleep(1000);
            Console.WriteLine(i);
        }

        CloseClipboard();
    }
}

The difficulty is coming up with this particular scenario. In this case, by modeling the components in the software and thinking about how to make components unavailable, the test ideas started flowing.

Happy testing!


About the Author
Avatar

Ray Li

Ray is a software engineer and data enthusiast who has been blogging for over a decade. He loves to learn, teach and grow. You’ll usually find him wrangling data, programming and lifehacking.

Leave a Reply

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

four − one =

This site uses Akismet to reduce spam. Learn how your comment data is processed.