What is Coyote?
Coyote is a set of .NET libraries and tools designed to help ensure that your code is free of bugs. Too often developers are drowning in the complexity of their own code and many hours are wasted trying to track down impossible-to-find bugs, especially when dealing with concurrent code or various other sources of non-determinism (like message ordering, failures, timeouts and so on).
Coyote provides programming models to express concurrent systems. These programming models offer convenient ways to program at a high-level of abstraction. As mentioned below, Coyote currently supports two programming models: a familiar tasks-based programming model (currently in-preview) as well as a more advanced actor-based programming model. These programming models are built using asynchronous APIs, supported by a lightweight runtime, making it easy to program efficient non-blocking code.
Coyote helps write powerful, expressive tests for your code. You can declare sources of non-determinism (such as timers, failures, etc.) as part of your tests. The Coyote testing tool can systematically explore a large number of interleavings of concurrent operations as well as non-deterministic choices so that it covers a large set of behaviors in a very short time. This is different from stress testing. Coyote takes control of the concurrency so that it can manipulate every possible scheduling. With appropriate mocking, Coyote can also do this in “developer” mode on a single laptop with little or no dependence on the bigger production environment.
Coyote is not a verification system. It does not use theorem proving to make correctness guarantees, instead it uses intelligent search strategies to drive systematic testing, based on deep understanding of concurrency primitives that you have used in your code. This approach has proven to work well for large production teams, including many teams in Microsoft Azure because it has a small barrier to entry with almost immediate benefits for those who adopt it.
Coyote does not require that a team starts from scratch and rebuild their system. Often it is too expensive to start over. Instead Coyote can be adopted gradually, adding more and more structure around your Coyote-aware code. The more of this structure you add the more benefit you get from Coyote, but it is certainly not an all or nothing proposition.
So Coyote brings together elements of design, development and testing into an integrated package that works really well in the real world. See our case studies for some great customer testimonials.
Supported programming models
Coyote supports two main programming models:
Asynchronous tasks, which follows the popular task-based asynchronous pattern. This programming model offers a
Tasktype that serves as a drop-in-replacement type for the native .NET
System.Threading.Tasks.Task. As with the native
Task, a Coyote
Taskrepresents an asynchronous operation that the programmer can coordinate using the
awaitkeywords of C#. In production, a Coyote
Taskexecutes with the same semantics of a native
Task. In fact, it is simply a thin wrapper around a native
Taskobject. During testing, however, is where the magic happens. Coyote controls the execution of each Coyote
Taskso that it can explore various different interleavings to find bugs. Alternatively, you can use the binary rewriting feature of Coyote to automatically instrument your application, taking control of
System.Threading.Tasks.Taskobjects and related concurrency types from the Task Parallel Library, without having to use Coyote’s drop-in-replacement library.
Asynchronous actors is an actor-based programming model that allows you to express your design and concurrency at a higher-level of abstraction. This programming model starts with the
Actortype that represents a long-lived, interactive asynchronous object. An actor can create new actors, send events to other actors, and handle received events. This more advanced programming model is ideal for cases when asynchronous tasks get too unwieldy. This programming model also provides a
StateMachinetype for easy development of event-driven state-machines. A
StateMachineis simply an
Statesand event-driven state transitions.
Note that you can only systematically test the above two programming models together using Coyote’s
binary rewriting to take control of
System.Threading.Tasks.Task objects. Mixing the Coyote
Actor type with the custom Coyote
type is not supported.