Testing a Basic Concurrent Cache: Implementation
Take a look at an example of a cache to understand the concepts of stateful properties.
Understanding the requirements
To use stateful tests, we’ll first need a stateful system to validate. The system we’ll use is a cache implemented as an Open Telecom Platform (OTP) gen_server
. A common optimization pattern is to use an Erlang Term Storage (ETS) table for reads and ensure the writes are safe by making them sequential through calls to the gen_server
. This creates a bit of contention on the write operations, so instead, we’ll try to write a cache that only uses ETS for all operations, with the gen_server
only working to keep the ETS table alive. The simple conceptual model (a cache handling data like a key-value store) and an implementation dangerously accessing ETS tables concurrently makes this a great candidate to demonstrate stateful property tests. We’ll see the cache implementation and how to approach modeling it to find potential bugs it may hide.
Our cache will have a simple set of requirements:
- Values can be read by searching for their key.
- The cache can be emptied on demand.
- The cache can be configured with a maximum number of items to hold in memory.
- Once the maximal size is reached, the