| using Lucene.Net.Codecs; |
| using Lucene.Net.Codecs.Asserting; |
| using Lucene.Net.Codecs.CheapBastard; |
| using Lucene.Net.Codecs.Compressing; |
| using Lucene.Net.Codecs.Lucene3x; |
| using Lucene.Net.Codecs.Lucene40; |
| using Lucene.Net.Codecs.Lucene41; |
| using Lucene.Net.Codecs.Lucene42; |
| using Lucene.Net.Codecs.Lucene45; |
| using Lucene.Net.Codecs.Lucene46; |
| using Lucene.Net.Codecs.MockRandom; |
| using Lucene.Net.Codecs.SimpleText; |
| using Lucene.Net.Diagnostics; |
| using Lucene.Net.Index; |
| using Lucene.Net.Search; |
| using Lucene.Net.Search.Similarities; |
| using System; |
| using System.Collections.Generic; |
| using System.Globalization; |
| using System.IO; |
| using System.Reflection; |
| using System.Threading; |
| using JCG = J2N.Collections.Generic; |
| using Console = Lucene.Net.Util.SystemConsole; |
| |
| // LUCENENET NOTE: These are primarily here because they are referred to |
| // in the XML documentation. Be sure to add a new option if a new test framework |
| // is being supported. |
| #if TESTFRAMEWORK_MSTEST |
| using AssumptionViolatedException = Microsoft.VisualStudio.TestTools.UnitTesting.AssertInconclusiveException; |
| #elif TESTFRAMEWORK_NUNIT |
| using AssumptionViolatedException = NUnit.Framework.InconclusiveException; |
| #elif TESTFRAMEWORK_XUNIT |
| using AssumptionViolatedException = Lucene.Net.TestFramework.SkipTestException; |
| #endif |
| |
| namespace Lucene.Net.Util |
| { |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /// <summary> |
| /// Setup and restore suite-level environment (fine grained junk that |
| /// doesn't fit anywhere else). |
| /// </summary> |
| // LUCENENET specific: This class was refactored to be called directly from LuceneTestCase, since |
| // we didn't port over the entire test suite from Java. |
| internal sealed class TestRuleSetupAndRestoreClassEnv : AbstractBeforeAfterRule |
| { |
| /// <summary> |
| /// Restore these system property values. |
| /// </summary> |
| private Dictionary<string, string> restoreProperties = new Dictionary<string, string>(); |
| |
| private Codec savedCodec; |
| private CultureInfo savedLocale; |
| private InfoStream savedInfoStream; |
| private TimeZoneInfo savedTimeZone; |
| |
| internal CultureInfo locale; |
| internal TimeZoneInfo timeZone; |
| internal Similarity similarity; |
| internal Codec codec; |
| |
| /// <seealso cref="LuceneTestCase.SuppressCodecsAttribute"/> |
| internal ISet<string> avoidCodecs; |
| |
| internal class ThreadNameFixingPrintStreamInfoStream : TextWriterInfoStream |
| { |
| public ThreadNameFixingPrintStreamInfoStream(TextWriter @out) |
| : base(@out) |
| { |
| } |
| |
| public override void Message(string component, string message) |
| { |
| if ("TP".Equals(component, StringComparison.Ordinal)) |
| { |
| return; // ignore test points! |
| } |
| string name; |
| if (Thread.CurrentThread.Name != null && Thread.CurrentThread.Name.StartsWith("TEST-", StringComparison.Ordinal)) |
| { |
| // The name of the main thread is way too |
| // long when looking at IW verbose output... |
| name = "main"; |
| } |
| else |
| { |
| name = Thread.CurrentThread.Name; |
| } |
| m_stream.WriteLine(component + " " + m_messageID + " [" + DateTime.Now + "; " + name + "]: " + message); |
| } |
| } |
| |
| public override void Before(LuceneTestCase testInstance) |
| { |
| // LUCENENET specific - SOLR setup code removed |
| |
| // if verbose: print some debugging stuff about which codecs are loaded. |
| if (LuceneTestCase.Verbose) |
| { |
| // LUCENENET: Only list the services if the underlying ICodecFactory |
| // implements IServiceListable |
| if (Codec.GetCodecFactory() is IServiceListable) |
| { |
| ICollection<string> codecs = Codec.AvailableCodecs; |
| foreach (string codec in codecs) |
| { |
| Console.WriteLine("Loaded codec: '" + codec + "': " + Codec.ForName(codec).GetType().Name); |
| } |
| } |
| |
| // LUCENENET: Only list the services if the underlying IPostingsFormatFactory |
| // implements IServiceListable |
| if (PostingsFormat.GetPostingsFormatFactory() is IServiceListable) |
| { |
| ICollection<string> postingsFormats = PostingsFormat.AvailablePostingsFormats; |
| foreach (string postingsFormat in postingsFormats) |
| { |
| Console.WriteLine("Loaded postingsFormat: '" + postingsFormat + "': " + PostingsFormat.ForName(postingsFormat).GetType().Name); |
| } |
| } |
| } |
| |
| savedInfoStream = InfoStream.Default; |
| Random random = LuceneTestCase.Random; |
| bool v = random.NextBoolean(); |
| if (LuceneTestCase.UseInfoStream) |
| { |
| InfoStream.Default = new ThreadNameFixingPrintStreamInfoStream(Console.Out); |
| } |
| else if (v) |
| { |
| InfoStream.Default = new NullInfoStream(); |
| } |
| |
| Type targetClass = testInstance?.GetType() ?? LuceneTestCase.GetTestClass(); |
| avoidCodecs = new JCG.HashSet<string>(); |
| var suppressCodecsAttribute = targetClass.GetCustomAttribute<LuceneTestCase.SuppressCodecsAttribute>(); |
| if (suppressCodecsAttribute != null) |
| { |
| avoidCodecs.UnionWith(suppressCodecsAttribute.Value); |
| } |
| |
| // set back to default |
| LuceneTestCase.OldFormatImpersonationIsActive = false; |
| |
| savedCodec = Codec.Default; |
| int randomVal = random.Next(10); |
| if ("Lucene3x".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) || ("random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) && |
| "random".Equals(LuceneTestCase.TestPostingsFormat, StringComparison.Ordinal) && |
| "random".Equals(LuceneTestCase.TestDocValuesFormat, StringComparison.Ordinal) && |
| randomVal == 3 && |
| !ShouldAvoidCodec("Lucene3x"))) // preflex-only setup |
| { |
| codec = Codec.ForName("Lucene3x"); |
| if (Debugging.AssertsEnabled) Debugging.Assert((codec is PreFlexRWCodec), "fix your ICodecFactory to scan Lucene.Net.Tests before Lucene.Net.TestFramework"); |
| LuceneTestCase.OldFormatImpersonationIsActive = true; |
| } |
| else if ("Lucene40".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) || ("random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) && |
| "random".Equals(LuceneTestCase.TestPostingsFormat, StringComparison.Ordinal) && |
| randomVal == 0 && |
| !ShouldAvoidCodec("Lucene40"))) // 4.0 setup |
| { |
| codec = Codec.ForName("Lucene40"); |
| LuceneTestCase.OldFormatImpersonationIsActive = true; |
| if (Debugging.AssertsEnabled) Debugging.Assert((codec is Lucene40RWCodec), "fix your ICodecFactory to scan Lucene.Net.Tests before Lucene.Net.TestFramework"); |
| if (Debugging.AssertsEnabled) Debugging.Assert((PostingsFormat.ForName("Lucene40") is Lucene40RWPostingsFormat), "fix your IPostingsFormatFactory to scan Lucene.Net.Tests before Lucene.Net.TestFramework"); |
| } |
| else if ("Lucene41".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) || ("random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) && |
| "random".Equals(LuceneTestCase.TestPostingsFormat, StringComparison.Ordinal) && |
| "random".Equals(LuceneTestCase.TestDocValuesFormat, StringComparison.Ordinal) && |
| randomVal == 1 && |
| !ShouldAvoidCodec("Lucene41"))) |
| { |
| codec = Codec.ForName("Lucene41"); |
| LuceneTestCase.OldFormatImpersonationIsActive = true; |
| if (Debugging.AssertsEnabled) Debugging.Assert((codec is Lucene41RWCodec), "fix your ICodecFactory to scan Lucene.Net.Tests before Lucene.Net.TestFramework"); |
| } |
| else if ("Lucene42".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) || ("random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) && |
| "random".Equals(LuceneTestCase.TestPostingsFormat, StringComparison.Ordinal) && |
| "random".Equals(LuceneTestCase.TestDocValuesFormat, StringComparison.Ordinal) && |
| randomVal == 2 && |
| !ShouldAvoidCodec("Lucene42"))) |
| { |
| codec = Codec.ForName("Lucene42"); |
| LuceneTestCase.OldFormatImpersonationIsActive = true; |
| if (Debugging.AssertsEnabled) Debugging.Assert((codec is Lucene42RWCodec), "fix your ICodecFactory to scan Lucene.Net.Tests before Lucene.Net.TestFramework"); |
| } |
| else if ("Lucene45".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) || ("random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) && |
| "random".Equals(LuceneTestCase.TestPostingsFormat, StringComparison.Ordinal) && |
| "random".Equals(LuceneTestCase.TestDocValuesFormat, StringComparison.Ordinal) && |
| randomVal == 5 && |
| !ShouldAvoidCodec("Lucene45"))) |
| { |
| codec = Codec.ForName("Lucene45"); |
| LuceneTestCase.OldFormatImpersonationIsActive = true; |
| if (Debugging.AssertsEnabled) Debugging.Assert((codec is Lucene45RWCodec), "fix your ICodecFactory to scan Lucene.Net.Tests before Lucene.Net.TestFramework"); |
| } |
| else if (("random".Equals(LuceneTestCase.TestPostingsFormat, StringComparison.Ordinal) == false) |
| || ("random".Equals(LuceneTestCase.TestDocValuesFormat, StringComparison.Ordinal) == false)) |
| { |
| // the user wired postings or DV: this is messy |
| // refactor into RandomCodec.... |
| |
| PostingsFormat format; |
| if ("random".Equals(LuceneTestCase.TestPostingsFormat, StringComparison.Ordinal)) |
| { |
| format = PostingsFormat.ForName("Lucene41"); |
| } |
| else if ("MockRandom".Equals(LuceneTestCase.TestPostingsFormat, StringComparison.Ordinal)) |
| { |
| format = new MockRandomPostingsFormat(new Random(random.Next())); |
| } |
| else |
| { |
| format = PostingsFormat.ForName(LuceneTestCase.TestPostingsFormat); |
| } |
| |
| DocValuesFormat dvFormat; |
| if ("random".Equals(LuceneTestCase.TestDocValuesFormat, StringComparison.Ordinal)) |
| { |
| dvFormat = DocValuesFormat.ForName("Lucene45"); |
| } |
| else |
| { |
| dvFormat = DocValuesFormat.ForName(LuceneTestCase.TestDocValuesFormat); |
| } |
| |
| codec = new Lucene46CodecAnonymousInnerClassHelper(this, format, dvFormat); |
| } |
| else if ("SimpleText".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) |
| || ("random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) && randomVal == 9 && LuceneTestCase.Rarely(random) && !ShouldAvoidCodec("SimpleText"))) |
| { |
| codec = new SimpleTextCodec(); |
| } |
| else if ("CheapBastard".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) |
| || ("random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) && randomVal == 8 && !ShouldAvoidCodec("CheapBastard") && !ShouldAvoidCodec("Lucene41"))) |
| { |
| // we also avoid this codec if Lucene41 is avoided, since thats the postings format it uses. |
| codec = new CheapBastardCodec(); |
| } |
| else if ("Asserting".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) |
| || ("random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) && randomVal == 6 && !ShouldAvoidCodec("Asserting"))) |
| { |
| codec = new AssertingCodec(); |
| } |
| else if ("Compressing".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) |
| || ("random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal) && randomVal == 5 && !ShouldAvoidCodec("Compressing"))) |
| { |
| codec = CompressingCodec.RandomInstance(random); |
| } |
| else if (!"random".Equals(LuceneTestCase.TestCodec, StringComparison.Ordinal)) |
| { |
| codec = Codec.ForName(LuceneTestCase.TestCodec); |
| } |
| else if ("random".Equals(LuceneTestCase.TestPostingsFormat, StringComparison.Ordinal)) |
| { |
| codec = new RandomCodec(random, avoidCodecs); |
| } |
| else |
| { |
| if (Debugging.AssertsEnabled) Debugging.Assert(false); |
| } |
| Codec.Default = codec; |
| |
| // Initialize locale/ timezone. |
| string testLocale = SystemProperties.GetProperty("tests:locale", "random"); // LUCENENET specific - reformatted with : |
| string testTimeZone = SystemProperties.GetProperty("tests:timezone", "random"); // LUCENENET specific - reformatted with : |
| |
| // Always pick a random one for consistency (whether tests.locale was specified or not). |
| savedLocale = CultureInfo.CurrentCulture; |
| CultureInfo randomLocale = LuceneTestCase.RandomCulture(random); |
| locale = testLocale.Equals("random", StringComparison.Ordinal) ? randomLocale : LuceneTestCase.CultureForName(testLocale); |
| #if FEATURE_CULTUREINFO_CURRENTCULTURE_SETTER |
| CultureInfo.CurrentCulture = locale; |
| #else |
| Thread.CurrentThread.CurrentCulture = locale; |
| #endif |
| |
| // TimeZone.getDefault will set user.timezone to the default timezone of the user's locale. |
| // So store the original property value and restore it at end. |
| // LUCENENET specific - commented |
| //restoreProperties["user:timezone"] = SystemProperties.GetProperty("user:timezone"); |
| savedTimeZone = TimeZoneInfo.Local; |
| TimeZoneInfo randomTimeZone = LuceneTestCase.RandomTimeZone(random); |
| timeZone = testTimeZone.Equals("random", StringComparison.Ordinal) ? randomTimeZone : TimeZoneInfo.FindSystemTimeZoneById(testTimeZone); |
| //TimeZone.Default = TimeZone; // LUCENENET NOTE: There doesn't seem to be an equivalent to this, but I don't think we need it. |
| similarity = random.NextBoolean() ? (Similarity)new DefaultSimilarity() : new RandomSimilarityProvider(random); |
| |
| // Check codec restrictions once at class level. |
| try |
| { |
| CheckCodecRestrictions(codec); |
| } |
| catch (Exception e) |
| { |
| Console.Error.WriteLine("NOTE: " + e.Message + " Suppressed codecs: " + avoidCodecs); |
| throw; // LUCENENET: CA2200: Rethrow to preserve stack details (https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2200-rethrow-to-preserve-stack-details) |
| } |
| } |
| |
| private class Lucene46CodecAnonymousInnerClassHelper : Lucene46Codec |
| { |
| private readonly TestRuleSetupAndRestoreClassEnv outerInstance; |
| |
| private PostingsFormat format; |
| private DocValuesFormat dvFormat; |
| |
| public Lucene46CodecAnonymousInnerClassHelper(TestRuleSetupAndRestoreClassEnv outerInstance, PostingsFormat format, DocValuesFormat dvFormat) |
| { |
| this.outerInstance = outerInstance; |
| this.format = format; |
| this.dvFormat = dvFormat; |
| } |
| |
| public override PostingsFormat GetPostingsFormatForField(string field) |
| { |
| return format; |
| } |
| |
| public override DocValuesFormat GetDocValuesFormatForField(string field) |
| { |
| return dvFormat; |
| } |
| |
| public override string ToString() |
| { |
| return base.ToString() + ": " + format.ToString() + ", " + dvFormat.ToString(); |
| } |
| } |
| |
| /// <summary> |
| /// Check codec restrictions. |
| /// </summary> |
| /// <exception cref="AssumptionViolatedException"> if the class does not work with a given codec. </exception> |
| private void CheckCodecRestrictions(Codec codec) |
| { |
| LuceneTestCase.AssumeFalse("Class not allowed to use codec: " + codec.Name + ".", ShouldAvoidCodec(codec.Name)); |
| |
| if (codec is RandomCodec && avoidCodecs.Count > 0) |
| { |
| foreach (string name in ((RandomCodec)codec).FormatNames) |
| { |
| LuceneTestCase.AssumeFalse("Class not allowed to use postings format: " + name + ".", ShouldAvoidCodec(name)); |
| } |
| } |
| |
| PostingsFormat pf = codec.PostingsFormat; |
| LuceneTestCase.AssumeFalse("Class not allowed to use postings format: " + pf.Name + ".", ShouldAvoidCodec(pf.Name)); |
| |
| LuceneTestCase.AssumeFalse("Class not allowed to use postings format: " + LuceneTestCase.TestPostingsFormat + ".", ShouldAvoidCodec(LuceneTestCase.TestPostingsFormat)); |
| } |
| |
| /// <summary> |
| /// After suite cleanup (always invoked). |
| /// </summary> |
| public override void After(LuceneTestCase testInstance) |
| { |
| // LUCENENT specific - Not used in .NET |
| //foreach (KeyValuePair<string, string> e in restoreProperties) |
| //{ |
| // SystemProperties.SetProperty(e.Key, e.Value); |
| //} |
| //restoreProperties.Clear(); |
| |
| Codec.Default = savedCodec; |
| InfoStream.Default = savedInfoStream; |
| if (savedLocale != null) |
| { |
| locale = savedLocale; |
| #if FEATURE_CULTUREINFO_CURRENTCULTURE_SETTER |
| CultureInfo.CurrentCulture = savedLocale; |
| #else |
| Thread.CurrentThread.CurrentCulture = savedLocale; |
| #endif |
| } |
| if (savedTimeZone != null) |
| { |
| timeZone = savedTimeZone; |
| } |
| } |
| |
| /// <summary> |
| /// Should a given codec be avoided for the currently executing suite? |
| /// </summary> |
| private bool ShouldAvoidCodec(string codec) |
| { |
| return avoidCodecs.Count > 0 && avoidCodecs.Contains(codec); |
| } |
| } |
| } |