| using Lucene.Net.Codecs; |
| using Lucene.Net.Configuration; |
| using NUnit.Framework; |
| using System; |
| using System.Threading; |
| |
| 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> |
| /// <see cref="LuceneTestFrameworkInitializer"/> may be subclassed by end users in order to |
| /// use standard dependency injection techniques for classes under test. A subclass of <see cref="LuceneTestFrameworkInitializer"/> |
| /// will be executed automatically by NUnit. To work properly with the Lucene.NET test framework, the subclass |
| /// must be placed outside of all namespaces, which ensures it is only executed 1 time per test assembly. |
| /// <para/> |
| /// The following abstract factories can be overridden for testing purposes: |
| /// <list type="table"> |
| /// <listheader> |
| /// <term>Abstraction</term> |
| /// <term>Factory Method Name</term> |
| /// <term>Default</term> |
| /// </listheader> |
| /// <item> |
| /// <term><see cref="ICodecFactory"/></term> |
| /// <term><see cref="CodecFactory"/></term> |
| /// <term><see cref="TestCodecFactory"/></term> |
| /// </item> |
| /// <item> |
| /// <term><see cref="IDocValuesFormatFactory"/></term> |
| /// <term><see cref="DocValuesFormatFactory"/></term> |
| /// <term><see cref="TestDocValuesFormatFactory"/></term> |
| /// </item> |
| /// <item> |
| /// <term><see cref="IPostingsFormatFactory"/></term> |
| /// <term><see cref="PostingsFormatFactory"/></term> |
| /// <term><see cref="TestPostingsFormatFactory"/></term> |
| /// </item> |
| /// <item> |
| /// <term><see cref="IConfigurationFactory"/></term> |
| /// <term><see cref="ConfigurationFactory"/></term> |
| /// <term><see cref="TestConfigurationFactory"/></term> |
| /// </item> |
| /// </list> |
| /// <para/> |
| /// <b>Example:</b> |
| /// <code> |
| /// // IMPORTANT: Do not put the initializer in a namespace |
| /// public class MyTestFrameworkInitializer : LuceneTestFrameworkInitializer |
| /// { |
| /// protected override IConfigurationFactory LoadConfigurationFactory() |
| /// { |
| /// // Inject a custom configuration factory |
| /// return new MyConfigurationFactory(); |
| /// } |
| /// |
| /// protected override void TestFrameworkSetUp() |
| /// { |
| /// // Inject a custom configuration factory |
| /// ConfigurationFactory = new MyConfigurationFactory(); |
| /// |
| /// // Do any additional dependency injection setup here |
| /// } |
| /// } |
| /// </code> |
| /// </summary> |
| [SetUpFixture] |
| public abstract class LuceneTestFrameworkInitializer |
| { |
| // Initialization target must be static to ensure the initializer only fires one |
| // time per application run (even when the static EnsureInitialized() method is called). |
| private static object initializationTarget; |
| |
| |
| // LUCENENET specific factory methods to scan the test framework for codecs/docvaluesformats/postingsformats only once |
| |
| /// <summary> |
| /// The <see cref="ICodecFactory"/> implementation to use to load codecs during testing. |
| /// </summary> |
| protected static ICodecFactory CodecFactory { get; set; } = new TestCodecFactory(); |
| |
| /// <summary> |
| /// The <see cref="IDocValuesFormatFactory"/> implementation to use to load doc values during testing. |
| /// </summary> |
| protected static IDocValuesFormatFactory DocValuesFormatFactory { get; set; } = new TestDocValuesFormatFactory(); |
| |
| /// <summary> |
| /// The <see cref="IPostingsFormatFactory"/> implementation to use to load postings formats during testing. |
| /// </summary> |
| protected static IPostingsFormatFactory PostingsFormatFactory { get; set; } = new TestPostingsFormatFactory(); |
| |
| /// <summary> |
| /// The <see cref="IConfigurationFactory"/> implementation to use to load configuration settings during testing. |
| /// See: <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/"> |
| /// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/</a>. |
| /// </summary> |
| [CLSCompliant(false)] |
| protected static IConfigurationFactory ConfigurationFactory { get; set; } = new TestConfigurationFactory(); |
| |
| /// <summary> |
| /// Overridden in a derived class, can be used to initialize factory instances that are |
| /// injected into Lucene.NET during test operations, or perform other one-time initialization |
| /// of the test framework setup. |
| /// <para/> |
| /// NOTE: To initialize 1 time for your entire test library, only create a single derived class |
| /// and place it outside of any namespace. |
| /// </summary> |
| protected virtual void TestFrameworkSetUp() |
| { |
| // Runs only once per test framework run before all tests |
| } |
| |
| |
| /// <summary> |
| /// Overridden in a derived class, can be used to tear down classes one-time |
| /// for the test framework. |
| /// </summary> |
| protected virtual void TestFrameworkTearDown() |
| { |
| // Runs only once per test framework run after all tests |
| } |
| |
| /// <summary> |
| /// When this class is derived in a test assembly, this method is automatically called |
| /// by NUnit one time before all tests run. |
| /// </summary> |
| [OneTimeSetUp] |
| protected void OneTimeSetUpBeforeTests() |
| { |
| try |
| { |
| TestFrameworkSetUp(); |
| |
| // Initialize of the test factories here, so that doesn't happen |
| // when EnsureInitialized() is called. |
| Initialize(); |
| } |
| catch (Exception ex) |
| { |
| // Write the stack trace so we have something to go on if an error occurs here. |
| throw new Exception($"An exception occurred during OneTimeSetUpBeforeTests:\n{ex.ToString()}", ex); |
| } |
| } |
| |
| /// <summary> |
| /// When this class is derived in a test assembly, this method is automatically called |
| /// by NUnit one time after all tests run. |
| /// </summary> |
| [OneTimeTearDown] |
| protected void OneTimeTearDownAfterTests() |
| { |
| try |
| { |
| TestFrameworkTearDown(); |
| } |
| catch (Exception ex) |
| { |
| // Write the stack trace so we have something to go on if an error occurs here. |
| throw new Exception($"An exception occurred during OneTimeTearDownAfterTests:\n{ex.ToString()}", ex); |
| } |
| } |
| |
| /// <summary> |
| /// The default implementation of the initializer that is simply used to initialize with the |
| /// default test factory implementations. |
| /// </summary> |
| private class DefaultLuceneTestFrameworkInitializer : LuceneTestFrameworkInitializer { } |
| |
| /// <summary> |
| /// Can be called by an external source to ensure that the test framework has been initialized. |
| /// <see cref="Initialize()"/> only occurs if it hasn't already been called by NUnit in a subclass |
| /// of this class. |
| /// </summary> |
| internal static void EnsureInitialized() |
| { |
| new DefaultLuceneTestFrameworkInitializer().Initialize(); |
| } |
| |
| private void Initialize() |
| { |
| LazyInitializer.EnsureInitialized(ref initializationTarget, () => |
| { |
| // Setup the factories |
| ConfigurationSettings.SetConfigurationFactory(ConfigurationFactory); |
| Codec.SetCodecFactory(CodecFactory); |
| DocValuesFormat.SetDocValuesFormatFactory(DocValuesFormatFactory); |
| PostingsFormat.SetPostingsFormatFactory(PostingsFormatFactory); |
| |
| IncrementInitalizationCount(); // For testing |
| |
| return new object(); // Placeholder to indicate our initializer has been run already |
| }); |
| } |
| |
| internal virtual void IncrementInitalizationCount() |
| { |
| } |
| } |
| } |