public async Task CanCreateMonthlyAliases(DateTime utcNow) {
            SystemClock.SetFixedTime(utcNow);
            var index = new MonthlyEmployeeIndex(_configuration, 1);
            await index.DeleteAsync();
            
            using (new DisposableAction(() => index.DeleteAsync().GetAwaiter().GetResult())) {
                await index.ConfigureAsync();
                var repository = new EmployeeRepository(index.Employee);

                for (int i = 0; i < 4; i++) {
                    var employee = await repository.AddAsync(EmployeeGenerator.Generate(createdUtc: utcNow.SubtractMonths(i)));
                    Assert.NotNull(employee?.Id);

                    Assert.Equal(1, await index.GetCurrentVersionAsync());
                    var existsResponse = await _client.IndexExistsAsync(index.GetIndex(employee.CreatedUtc));
                    _logger.Trace(() => existsResponse.GetRequest());
                    Assert.True(existsResponse.IsValid);
                    Assert.True(existsResponse.Exists);

                    var aliasesResponse = await _client.GetAliasesAsync(a => a.Index(index.GetIndex(employee.CreatedUtc)));
                    _logger.Trace(() => aliasesResponse.GetRequest());
                    Assert.True(aliasesResponse.IsValid);
                    Assert.Equal(1, aliasesResponse.Indices.Count);

                    var aliases = aliasesResponse.Indices.Values.Single().Select(s => s.Name).ToList();
                    aliases.Sort();

                    Assert.Equal(GetExpectedEmployeeMonthlyAliases(index, utcNow, employee.CreatedUtc), String.Join(", ", aliases));
                }
            }
        }
        public async Task MaintainOnlyOldIndexesWithNoExistingAliases() {
            SystemClock.SetFixedTime(SystemClock.UtcNow.EndOfYear());

            var index = new MonthlyEmployeeIndex(_configuration, 1);
            index.MaxIndexAge = SystemClock.UtcNow.EndOfMonth() - SystemClock.UtcNow.SubtractMonths(12).StartOfMonth();

            await index.EnsureIndexAsync(SystemClock.UtcNow.SubtractMonths(12));
            var existsResponse = await _client.IndexExistsAsync(index.GetIndex(SystemClock.UtcNow.SubtractMonths(12)));
            _logger.Trace(() => existsResponse.GetRequest());
            Assert.True(existsResponse.IsValid);
            Assert.True(existsResponse.Exists);

            index.MaxIndexAge = SystemClock.UtcNow.EndOfMonth() - SystemClock.UtcNow.StartOfMonth();
            await DeleteAliases(index.GetVersionedIndex(SystemClock.UtcNow.SubtractMonths(12)));

            await index.MaintainAsync();
            existsResponse = await _client.IndexExistsAsync(index.GetIndex(SystemClock.UtcNow.SubtractMonths(12)));
            _logger.Trace(() => existsResponse.GetRequest());
            Assert.True(existsResponse.IsValid);
            Assert.False(existsResponse.Exists);
        }
        public async Task MonthlyIndexMaxAge(DateTime utcNow) {
            SystemClock.SetFixedTime(utcNow);

            var index = new MonthlyEmployeeIndex(_configuration, 1);
            index.MaxIndexAge = SystemClock.UtcNow.EndOfMonth() - SystemClock.UtcNow.StartOfMonth();
            await index.DeleteAsync();

            using (new DisposableAction(() => index.DeleteAsync().GetAwaiter().GetResult())) {
                await index.ConfigureAsync();
                
                await index.EnsureIndexAsync(utcNow);
                var existsResponse = await _client.IndexExistsAsync(index.GetIndex(utcNow));
                _logger.Trace(() => existsResponse.GetRequest());
                Assert.True(existsResponse.IsValid);
                Assert.True(existsResponse.Exists);

                await index.EnsureIndexAsync(utcNow.Subtract(index.MaxIndexAge.GetValueOrDefault()));
                existsResponse = await _client.IndexExistsAsync(index.GetIndex(utcNow.Subtract(index.MaxIndexAge.GetValueOrDefault())));
                _logger.Trace(() => existsResponse.GetRequest());
                Assert.True(existsResponse.IsValid);
                Assert.True(existsResponse.Exists);

                var endOfTwoMonthsAgo = utcNow.SubtractMonths(2).EndOfMonth();
                await Assert.ThrowsAsync<ArgumentException>(async () => await index.EnsureIndexAsync(endOfTwoMonthsAgo));
                existsResponse = await _client.IndexExistsAsync(index.GetIndex(endOfTwoMonthsAgo));
                _logger.Trace(() => existsResponse.GetRequest());
                Assert.True(existsResponse.IsValid);
                Assert.False(existsResponse.Exists);
            }
        }