mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-09-13 06:07:30 -04:00
Both grids restored the last good filter by recursing into the filter handler, which never terminated once the search index rather than the query was the problem: the restore fails the same way, and the retry uses the same filter. The user got an endless run of dialogs, each of them blaming a filter string that was fine. Only an empty last-good filter broke the loop, because that short-circuits before reaching the search engine. The fallback is now a bounded sequence -- last good filter, then no filter -- and the message distinguishes an index Libation cannot reach from a query it cannot parse. Only the first failure is reported, so restoring is quiet. A malformed query never surfaces as an IO-family exception, which QueryFailureShapeTests pins against the real engine, so a typo is never mistaken for index trouble or made to trigger a rebuild. Co-authored-by: rmcrackan <rmcrackan@gmail.com>
50 lines
2.1 KiB
C#
50 lines
2.1 KiB
C#
using LibationUiBase;
|
|
using Lucene.Net.Index;
|
|
using Lucene.Net.QueryParsers;
|
|
using Lucene.Net.Store;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using System;
|
|
using System.IO;
|
|
|
|
namespace LibationUiBase.Tests;
|
|
|
|
[TestClass]
|
|
public class SearchIndexRecoveryTests
|
|
{
|
|
[TestMethod]
|
|
public void instructions_name_the_folder_and_how_to_find_it()
|
|
{
|
|
StringAssert.Contains(SearchIndexRecovery.ManualRecoveryInstructions, "SearchEngine");
|
|
StringAssert.Contains(SearchIndexRecovery.ManualRecoveryInstructions, "Open log folder");
|
|
// the whole point of the guard is that the library survived
|
|
StringAssert.Contains(SearchIndexRecovery.ManualRecoveryInstructions, "library itself is fine");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Every way of failing to reach the index. Reporting one of these as a bad filter string sends the user
|
|
/// looking for a typo in a query that was fine.
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void failures_to_reach_the_index_are_told_apart_from_a_bad_query()
|
|
{
|
|
Assert.IsTrue(SearchIndexRecovery.IsIndexUnavailable(new IOException("read past EOF")));
|
|
Assert.IsTrue(SearchIndexRecovery.IsIndexUnavailable(new CorruptIndexException("checksum mismatch in segments file")));
|
|
Assert.IsTrue(SearchIndexRecovery.IsIndexUnavailable(new LockObtainFailedException("Lock obtain timed out")));
|
|
Assert.IsTrue(SearchIndexRecovery.IsIndexUnavailable(new UnauthorizedAccessException()));
|
|
// cloud-sync debris, which Lucene reports while parsing segments file names
|
|
Assert.IsTrue(SearchIndexRecovery.IsIndexUnavailable(new ArgumentException("Invalid or unsupported character in number: )")));
|
|
|
|
Assert.IsFalse(SearchIndexRecovery.IsIndexUnavailable(new ParseException("Cannot parse '[unclosed'")));
|
|
Assert.IsFalse(SearchIndexRecovery.IsIndexUnavailable(new ArgumentException("some other argument problem")));
|
|
}
|
|
|
|
/// <summary>A damaged index fails on every library change, and these steps only need following once.</summary>
|
|
[TestMethod]
|
|
public void the_user_is_told_once_per_session()
|
|
{
|
|
Assert.IsTrue(SearchIndexRecovery.ShouldNotify());
|
|
Assert.IsFalse(SearchIndexRecovery.ShouldNotify());
|
|
Assert.IsFalse(SearchIndexRecovery.ShouldNotify());
|
|
}
|
|
}
|