diff --git a/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs b/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs index 988b63faf4..210aa689a0 100644 --- a/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs +++ b/src/Lucene.Net.TestFramework/Util/LuceneTestCase.cs @@ -105,9 +105,9 @@ namespace Lucene.Net.Util /// It is recommended to configure the culture also, since they are randomly picked from a list /// of cultures installed on a given machine, so the culture will vary from one machine to the next. /// - /// + /// ///

.runsettings File Configuration Example

- /// + /// /// /// <RunSettings> /// <TestRunParameters> @@ -120,9 +120,9 @@ namespace Lucene.Net.Util /// See the .runsettings documentation at: /// https://docs.microsoft.com/en-us/visualstudio/test/configure-unit-tests-by-using-a-dot-runsettings-file. /// - /// + /// ///

Attribute Configuration Example

- /// + /// /// /// [assembly: Lucene.Net.Util.RandomSeed("0x1ffa1d067056b0e6")] /// [assembly: NUnit.Framework.SetCulture("sw-TZ")] @@ -134,7 +134,7 @@ namespace Lucene.Net.Util /// Add a file named lucene.testSettings.config to the executable directory or /// any directory between the executable and the root of the drive with the following contents. /// - /// + /// /// /// { /// "tests": { @@ -160,7 +160,7 @@ namespace Lucene.Net.Util /// sw-TZ /// /// - /// + /// /// [TestFixture] public abstract partial class LuceneTestCase //: Assert // Wait long for leaked threads to complete before failure. zk needs this. - See LUCENE-3995 for rationale. @@ -510,7 +510,7 @@ public SystemPropertyData() /// /// TODO: javadoc? - public bool UseInfoStream { get; } + public bool UseInfoStream { get; } /// /// A random multiplier which you should use when writing random tests: @@ -1271,6 +1271,24 @@ public static void DumpArray(string label, object[] objs, TextWriter stream) DumpEnumerator(label, iter, stream); } + /// + /// Creates a new with a . + /// + /// The Lucene compatibility Version + /// The analyzer to use + /// Returns a new . + /// + /// This was backported as a result of fixing lucene#12626 from Lucene 9.9.0 in Lucene.NET. + /// The later versions of this code do not have the version parameter, but keeping it here + /// for consistency with below. + /// + public static IndexWriterConfig NewSnapshotIndexWriterConfig(LuceneVersion v, Analyzer analyzer) + { + IndexWriterConfig c = NewIndexWriterConfig(v, analyzer); + c.SetIndexDeletionPolicy(new SnapshotDeletionPolicy(NoDeletionPolicy.INSTANCE)); + return c; + } + /// /// Create a new with random defaults. /// @@ -1731,7 +1749,7 @@ public static Field NewField(Random random, string name, string value, FieldType } /// - /// Return a random from the available cultures on the system. + /// Return a random from the available cultures on the system. /// /// See https://issues.apache.org/jira/browse/LUCENE-4020. /// @@ -1741,7 +1759,7 @@ public static CultureInfo RandomCulture(Random random) // LUCENENET specific ren } /// - /// Return a random from the available timezones on the system + /// Return a random from the available timezones on the system /// /// See https://issues.apache.org/jira/browse/LUCENE-4020. /// @@ -2037,7 +2055,7 @@ public static IndexSearcher NewSearcher(IndexReader r, bool maybeWrap, bool wrap /// /// Gets a resource from the classpath as . This method should only /// be used, if a real file is needed. To get a stream, code should prefer - /// using + /// using /// this.GetType().Assembly and this.GetType(). /// protected virtual Stream GetDataFile(string name) @@ -2879,7 +2897,7 @@ public virtual void AssertFieldInfosEquals(string info, IndexReader leftReader, /// /// Returns true if the file exists (can be opened), false - /// if it cannot be opened, and (unlike .NET's + /// if it cannot be opened, and (unlike .NET's /// ) if there's some /// unexpected error, returns false. /// @@ -2921,7 +2939,7 @@ public static DirectoryInfo CreateTempDir() /// /// Creates an empty, temporary folder with the given name under the /// system's or if supplied, the tempDir system property. - /// + /// /// The folder will be automatically removed after the /// test class completes successfully. The test should close any file handles that would prevent /// the folder from being removed. @@ -2940,7 +2958,7 @@ public static DirectoryInfo CreateTempDir(string prefix) { throw RuntimeException.Create("Failed to get a temporary name too many times, check your temp directory and consider manually cleaning it: " + System.IO.Path.GetTempPath()); } - // LUCENENET specific - need to use a random file name instead of a sequential one or two threads may attempt to do + // LUCENENET specific - need to use a random file name instead of a sequential one or two threads may attempt to do // two operations on a file at the same time. //f = new DirectoryInfo(Path.Combine(System.IO.Path.GetTempPath(), "LuceneTemp", prefix + "-" + attempt)); f = new DirectoryInfo(Path.Combine(@base, "LuceneTemp", prefix + "-" + Path.GetFileNameWithoutExtension(Path.GetRandomFileName()))); @@ -3157,7 +3175,7 @@ internal static void LogNativeFSFactoryDebugInfo() /// value, chosen from (approximately) the usual /// normal distribution with mean 0.0 and standard deviation /// 1.0, is pseudorandomly generated and returned. - /// + /// /// This uses the polar method of G. E. P. Box, M. E. Muller, and /// G. Marsaglia, as described by Donald E. Knuth in The Art of /// Computer Programming, Volume 3: Seminumerical Algorithms, @@ -3193,4 +3211,4 @@ public void OnDispose(IndexReader reader) } } } -} \ No newline at end of file +} diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs index 8cf738904c..a482874c78 100644 --- a/src/Lucene.Net.Tests/Index/TestIndexWriter.cs +++ b/src/Lucene.Net.Tests/Index/TestIndexWriter.cs @@ -2556,12 +2556,26 @@ public virtual void TestCommitWithUserDataOnly() dir.Dispose(); } + // LUCENENET-specific: backport fix and test from Lucene 9.9.0 (lucene#12626, lucene#12637) + private Dictionary GetLiveCommitData(IndexWriter writer) + { + Dictionary data = new Dictionary(); + // LUCENENET UPGRADE TODO: in a post-4.8 port, this should use LiveCommitData + foreach (var ent in writer.CommitData) + { + data.Put(ent.Key, ent.Value); + } + + return data; + } + [Test] public virtual void TestGetCommitData() { Directory dir = NewDirectory(); IndexWriter writer = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, null)); - writer.SetCommitData(new Dictionary() { + writer.SetCommitData(new Dictionary() + { {"key", "value"} }); Assert.AreEqual("value", writer.CommitData["key"]); @@ -2575,6 +2589,49 @@ public virtual void TestGetCommitData() dir.Dispose(); } + // LUCENENET-specific: backport fix and test from Lucene 9.9.0 (lucene#12626, lucene#12637) + [Test] + public void TestGetCommitDataFromOldSnapshot() + { + Directory dir = NewDirectory(); + IndexWriter writer = new IndexWriter(dir, NewSnapshotIndexWriterConfig(TEST_VERSION_CURRENT, null)); + // LUCENENET UPGRADE TODO: in a post-4.8 port, this should use SetLiveCommitData + writer.SetCommitData(new Dictionary + { + { "key", "value" }, + }); + assertEquals("value", GetLiveCommitData(writer)["key"]); + writer.Commit(); + // Snapshot this commit to open later + IndexCommit indexCommit = + ((SnapshotDeletionPolicy)writer.Config.IndexDeletionPolicy).Snapshot(); + writer.Dispose(); + + // Modify the commit data and commit on close so the most recent commit data is different + writer = new IndexWriter(dir, NewSnapshotIndexWriterConfig(TEST_VERSION_CURRENT, null)); + // LUCENENET UPGRADE TODO: in a post-4.8 port, this should use SetLiveCommitData + writer.SetCommitData(new Dictionary() + { + { "key", "value2" }, + }); + + assertEquals("value2", GetLiveCommitData(writer)["key"]); + writer.Dispose(); + + // validate that when opening writer from older snapshotted index commit, the old commit data is + // visible + writer = + new IndexWriter( + dir, + NewSnapshotIndexWriterConfig(TEST_VERSION_CURRENT, null) + .SetOpenMode(OpenMode.APPEND) + .SetIndexCommit(indexCommit)); + assertEquals("value", GetLiveCommitData(writer)["key"]); + writer.Dispose(); + + dir.Dispose(); + } + [Test] public virtual void TestIterableThrowsException() { diff --git a/src/Lucene.Net/Index/SegmentInfos.cs b/src/Lucene.Net/Index/SegmentInfos.cs index 1295df946a..a6167f3672 100644 --- a/src/Lucene.Net/Index/SegmentInfos.cs +++ b/src/Lucene.Net/Index/SegmentInfos.cs @@ -305,8 +305,8 @@ internal static string SegmentNumberToString(long segment, bool allowLegacyNames private JCG.List segments = new JCG.List(); /// - /// If non-null, information about loading segments_N files - /// will be printed here. + /// If non-null, information about loading segments_N files + /// will be printed here. /// private static TextWriter infoStream = null; @@ -891,7 +891,7 @@ public object Clone() /// If non-null, information about retries when loading /// the segments file will be printed to this. /// - public static TextWriter InfoStream + public static TextWriter InfoStream { set => // LUCENENET specific - use a SafeTextWriterWrapper to ensure that if the TextWriter @@ -1452,6 +1452,8 @@ internal void Replace(SegmentInfos other) { RollbackSegmentInfos(other.AsList()); lastGeneration = other.lastGeneration; + // LUCENENET-specific: backport fix from Lucene 9.9.0 (lucene#12626, lucene#12637) + userData = other.userData; } /// @@ -1611,7 +1613,7 @@ internal void Remove(int index) } /// - /// Return true if the provided + /// Return true if the provided /// is contained. /// /// WARNING: O(N) cost @@ -1632,4 +1634,4 @@ internal int IndexOf(SegmentCommitInfo si) return segments.IndexOf(si); } } -} \ No newline at end of file +}