Package com.asakusafw.testdriver

Source Code of com.asakusafw.testdriver.OperatorTestEnvironment

/**
* Copyright 2011-2014 Asakusa Framework Team.
*
* Licensed 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.
*/
package com.asakusafw.testdriver;

import java.net.URL;
import java.text.MessageFormat;
import java.util.Map;

import org.apache.hadoop.conf.Configuration;
import org.junit.rules.ExternalResource;

import com.asakusafw.runtime.core.BatchContext;
import com.asakusafw.runtime.flow.RuntimeResourceManager;
import com.asakusafw.runtime.stage.StageConstants;
import com.asakusafw.runtime.util.VariableTable;
import com.asakusafw.runtime.util.VariableTable.RedefineStrategy;
import com.asakusafw.testdriver.core.TestingEnvironmentConfigurator;
import com.asakusafw.testdriver.hadoop.ConfigurationFactory;
import com.asakusafw.utils.collections.Maps;

/**
* 演算子のテスト時に各種プラグインを利用可能にするためのリソース。
* <p>
* テストクラス内で以下のように利用する:
* </p>
<pre><code>
&#64;Rule
public OperatorTestEnvironment resource = new OperatorTestEnvironment();
</code></pre>
* <p>
* 上記のように記述することで、クラスパス上の{@code asakusa-resources.xml}というファイルがあれば読みだし、
* 各種プラグインが提供するクラスを利用できるようになる。
* </p>
* <p>
* 別の設定ファイルを利用する場合は、下記のようにクラスパス上のファイル名を指定する。
* </p>
<pre><code>
&#64;Rule
public OperatorTestEnvironment resource = new OperatorTestEnvironment("com/example/testing.xml");
</code></pre>
* <p>
* さらに設定をアドホックに変更する場合、次のように行う。
* </p>
<pre><code>
&#64;Rule
public OperatorTestEnvironment resource = new OperatorTestEnvironment(...);

&#64;Test
public void sometest() {
    resource.configure("key", "value");
    ...
    resource.reload();

    &lt;test code&gt;
}
</code></pre>
* @since 0.1.0
* @version 0.7.0
*/
public class OperatorTestEnvironment extends ExternalResource {

    static {
        TestingEnvironmentConfigurator.initialize();
    }

    /**
     * The embedded default configuration file.
     * @since 0.7.0
     */
    static final String DEFAULT_CONFIGURATION_PATH = "default-asakusa-resources.xml";

    private RuntimeResourceManager manager;

    private final String configurationPath;

    private final boolean explicitConfigurationPath;

    private final Map<String, String> batchArguments;

    private final Map<String, String> extraConfigurations;

    private boolean dirty;

    /**
     * インスタンスを生成する。
     */
    public OperatorTestEnvironment() {
        this(RuntimeResourceManager.CONFIGURATION_FILE_NAME, false);
    }

    /**
     * 設定ファイルのパスを指定して、インスタンスを生成する。
     * @param configurationPath クラスパス上の設定ファイルのパス
     * @throws IllegalArgumentException 引数に{@code null}が指定された場合
     */
    public OperatorTestEnvironment(String configurationPath) {
        this(configurationPath, true);
    }

    private OperatorTestEnvironment(String configurationPath, boolean explicit) {
        if (configurationPath == null) {
            throw new IllegalArgumentException("configurationPath must not be null"); //$NON-NLS-1$
        }
        this.configurationPath = configurationPath;
        this.explicitConfigurationPath = explicit;
        this.extraConfigurations = Maps.create();
        this.batchArguments = Maps.create();
        this.dirty = false;
    }

    @Override
    protected void before() {
        Configuration conf = createConfig();
        for (Map.Entry<String, String> entry : extraConfigurations.entrySet()) {
            conf.set(entry.getKey(), entry.getValue());
        }
        if (batchArguments.isEmpty() == false) {
            VariableTable variables = new VariableTable(RedefineStrategy.OVERWRITE);
            for (Map.Entry<String, String> entry : batchArguments.entrySet()) {
                variables.defineVariable(entry.getKey(), entry.getValue());
            }
            conf.set(StageConstants.PROP_ASAKUSA_BATCH_ARGS, variables.toSerialString());
        }

        manager = new RuntimeResourceManager(conf);
        try {
            manager.setup();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 設定項目を追加する。
     * <p>
     * このメソッドは、プラグインの設定を変更するために主に利用する。
     * </p>
     * <p>
     * このメソッドを実行した場合、テスト実行前に
     * {@link #reload()}メソッドを起動して設定を再読み込みする必要がある。
     * </p>
     * @param key 追加する項目のキー名
     * @param value 追加する項目の値、{@code null}の場合には項目を削除する
     * @throws IllegalArgumentException 引数に{@code null}が指定された場合
     * @see #reload()
     */
    public void configure(String key, String value) {
        if (key == null) {
            throw new IllegalArgumentException("key must not be null"); //$NON-NLS-1$
        }
        if (value != null) {
            extraConfigurations.put(key, value);
        } else {
            extraConfigurations.remove(key);
        }
        dirty = true;
    }

    /**
     * バッチ実行時引数(変数表)を設定する。
     * <p>
     * このメソッドは、変数表(${...}で指定する変数)を変更するために主に利用する。
     * ここで設定した値は、{@link BatchContext#get(String)}やインポーターの設定の中などで利用できる。
     * </p>
     * <p>
     * このメソッドを実行した場合、テスト実行前に
     * {@link #reload()}メソッドを起動して設定を再読み込みする必要がある。
     * </p>
     * @param key 追加する項目のキー名
     * @param value 追加する項目の値、{@code null}の場合には項目を削除する
     * @throws IllegalArgumentException 引数に{@code null}が指定された場合
     */
    public void setBatchArg(String key, String value) {
        if (key == null) {
            throw new IllegalArgumentException("key must not be null"); //$NON-NLS-1$
        }
        if (value != null) {
            batchArguments.put(key, value);
        } else {
            batchArguments.remove(key);
        }
        dirty = true;
    }

    /**
     * 設定内容を再読み込みする。
     */
    public void reload() {
        dirty = false;
        after();
        before();
    }

    /**
     * {@link RuntimeResourceManager}が利用する設定情報を返す。
     * @return {@link RuntimeResourceManager}が利用する設定情報
     */
    protected Configuration createConfig() {
        Configuration conf = ConfigurationFactory.getDefault().newInstance();
        URL resource = conf.getClassLoader().getResource(configurationPath);
        if (resource == null && explicitConfigurationPath == false) {
            // if implicit configuration file is not found, we use the embedded default configuration file
            resource = OperatorTestEnvironment.class.getResource(DEFAULT_CONFIGURATION_PATH);
        }
        if (resource == null) {
            throw new IllegalStateException(MessageFormat.format(
                    "演算子テスト用の設定ファイルが見つかりません: {0}",
                    configurationPath));
        }
        conf.addResource(resource);
        return conf;
    }

    @Override
    protected void after() {
        if (manager != null) {
            try {
                manager.cleanup();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (dirty) {
            throw new AssertionError("configure()によって設定が書き換えられていますが、reload()されていないようです");
        }
    }
}
TOP

Related Classes of com.asakusafw.testdriver.OperatorTestEnvironment

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.