Package com.asakusafw.testtools

Source Code of com.asakusafw.testtools.TestUtils

/**
* 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.testtools;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.SequenceFile;

import com.asakusafw.runtime.io.ModelInput;
import com.asakusafw.runtime.io.ModelOutput;
import com.asakusafw.runtime.stage.temporary.TemporaryStorage;
import com.asakusafw.testtools.db.DbUtils;
import com.asakusafw.testtools.excel.ExcelUtils;
import com.asakusafw.testtools.inspect.Cause;
import com.asakusafw.testtools.inspect.DefaultInspector;
import com.asakusafw.testtools.inspect.Inspector;

/**
* テストツールのエントリ。
*/
public class TestUtils {

    /**
     * テーブル名をキーに、テストデータを保持するマップ。
     */
    private final Map<String, TestDataHolder> dataHolderMap = new HashMap<String, TestDataHolder>();


    /**
     * テーブル名をキーに、検査に使用するクラスを保持するマップ。
     */
    private final Map<String, Inspector> inspectorMap = new HashMap<String, Inspector>();

    /**
     * テストがNGだったとき原因。
     */
    private final List<Cause> causes = new ArrayList<Cause>();

    /**
     * オブジェクトの生成時刻。
     */
    long startTime;

    /**
     * コンストラクタ、 Excelファイルを含むディレクトリを指定する。
     * @param dir 対象のディレクトリ
     * @throws IOException ファイルの読み出しに失敗した場合
     */
    public TestUtils(File dir) throws IOException {
        if (!dir.isDirectory()) {
            throw new IOException(MessageFormat.format(
                    "{0} is not a directory",
                    dir.getAbsolutePath()));
        }
        List<File> excelFileList = collectExcelFileList(dir);
        init(excelFileList);
    }

    private List<File> collectExcelFileList(File dir) {
        File[] files = dir.listFiles();
        List<File> excelFileList = new ArrayList<File>();
        for (File file : files) {
            String filename = file.getAbsolutePath();
            String lowcaseFilename = filename.toLowerCase();
            if (lowcaseFilename.endsWith(".xls")) {
                excelFileList.add(file);
            }
        }
        Collections.sort(excelFileList);
        return excelFileList;
    }

    /**
     * コンストラクタ、Excelファイルのリストを指定する。
     * @param excelFileList Excelファイルの一覧
     * @throws IOException Excelファイルの読み出しに失敗した場合
     */
    public TestUtils(List<File> excelFileList) throws IOException {
        init(excelFileList);
    }


    /**
     * 指定のExcelファイルを読み込み、初期化する。
     * @param excelFileList Excelファイルの一覧
     * @throws IOException Excelファイルの読み出しに失敗した場合
     */
    private void init(List<File> excelFileList) throws IOException {
        for (File file : excelFileList) {
            String filename = file.getAbsolutePath();
            String lowcaseFilename = filename.toLowerCase();
            if (!lowcaseFilename.endsWith(".xls")) {
                throw new IOException(MessageFormat.format(
                        "Excelファイルではありません({0})",
                        file.getAbsolutePath()));
            }
            ExcelUtils excelUtils = new ExcelUtils(filename);
            TestDataHolder dataHolder = excelUtils.getTestDataHolder();
            dataHolderMap.put(dataHolder.getTablename(), dataHolder);
        }
        startTime = System.currentTimeMillis();
    }

    /**
     * テストデータをデータベースに書き込みます。
     * @param createTable trueのときテーブルをdrop/createし、falseのときtruncateする
     */
    public void storeToDatabase(boolean createTable) {
        Connection conn = null;
        try {
            conn = DbUtils.getConnection();
            clearCache(conn);
            for (TestDataHolder dataHolder : dataHolderMap.values()) {
                dataHolder.storeToDatabase(conn, createTable);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DbUtils.closeQuietly(conn);
        }
    }

    private void clearCache(Connection connection) {
        assert connection != null;
        try {
            Statement statement = connection.createStatement();
            try {
                statement.execute("TRUNCATE TABLE __TG_CACHE_INFO");
                statement.execute("TRUNCATE TABLE __TG_CACHE_LOCK");
            } finally {
                statement.close();
            }
        } catch (SQLException e) {
            System.err.println("キャッシュの削除に失敗しました");
            e.printStackTrace();
        }
    }

    /**
     * 実行結果をデータベースから取り込みます。
     */
    public void loadFromDatabase() {
        Connection conn = null;
        try {
            conn = DbUtils.getConnection();
            for (TestDataHolder dataHolder : dataHolderMap.values()) {
                dataHolder.loadFromDatabase(conn);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DbUtils.closeQuietly(conn);
        }
    }

    /**
     * テストデータをシーケンスファイルに書き込みます。
     * @param tablename 対象テストデータのテーブル名
     * @param writer 書き込み先
     * @deprecated Use {@link #storeToTemporary(String, Configuration, Path)} instead
     */
    @Deprecated
    public void storeToSequenceFile(String tablename, SequenceFile.Writer writer) {
        TestDataHolder dataHolder = dataHolderMap.get(tablename);
        try {
            dataHolder.store(writer);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 実行結果をシーケンスファイルから取り込みます。
     * @param tablename 対象実行データのテーブル名
     * @param reader 取り込み元
     * @deprecated Use {@link #loadFromTemporary(String, Configuration, Path)} instead
     */
    @Deprecated
    public void loadFromSequenceFile(String tablename, SequenceFile.Reader reader) {
        TestDataHolder dataHolder = dataHolderMap.get(tablename);
        try {
            dataHolder.load(reader);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Loads dataset from the temporary area.
     * @param tableName corresponded table name
     * @param conf current configuration
     * @param path source path
     * @throws IOException if failed to load dataset
     * @throws IllegalArgumentException if some parameters were {@code null}
     * @since 0.2.5
     */
    public void loadFromTemporary(String tableName, Configuration conf, Path path) throws IOException {
        if (tableName == null) {
            throw new IllegalArgumentException("tableName must not be null"); //$NON-NLS-1$
        }
        if (conf == null) {
            throw new IllegalArgumentException("conf must not be null"); //$NON-NLS-1$
        }
        if (path == null) {
            throw new IllegalArgumentException("path must not be null"); //$NON-NLS-1$
        }
        TestDataHolder dataHolder = dataHolderMap.get(tableName);
        ModelInput<?> input = TemporaryStorage.openInput(conf, dataHolder.getModelClass(), path);
        try {
            dataHolder.load(input);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            input.close();
        }
    }

    /**
     * Stores dataset into the temporary area.
     * @param tableName corresponded table name
     * @param conf current configuration
     * @param path source path
     * @throws IOException if failed to store dataset
     * @throws IllegalArgumentException if some parameters were {@code null}
     * @since 0.2.5
     */
    public void storeToTemporary(String tableName, Configuration conf, Path path) throws IOException {
        if (tableName == null) {
            throw new IllegalArgumentException("tableName must not be null"); //$NON-NLS-1$
        }
        if (conf == null) {
            throw new IllegalArgumentException("conf must not be null"); //$NON-NLS-1$
        }
        if (path == null) {
            throw new IllegalArgumentException("path must not be null"); //$NON-NLS-1$
        }
        TestDataHolder dataHolder = dataHolderMap.get(tableName);
        ModelOutput<?> output = TemporaryStorage.openOutput(conf, dataHolder.getModelClass(), path);
        try {
            dataHolder.store(output);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            output.close();
        }
    }

    /**
     * テストがNGだったときの理由を表す文字列を取得します。
     * @return テストがNGだったときの理由を表す文字列
     */
    public String getCauseMessage() {
        StringBuilder sb = new StringBuilder(String.format("%n"));
        for (Cause cause : causes) {
            sb.append(String.format("%s%n", cause.getMessage()));
        }
        return sb.toString();
    }

    /**
     * テスト対象のテーブル名のセットを返す。
     * @return テーブル名の一覧
     */
    public Set<String> getTablenames() {
        return dataHolderMap.keySet();
    }

    /**
     * テーブル名に対応するモデルクラスを返す。
     * @param tablename 対象のテーブル名
     * @return 対応するモデルクラス
     */
    public Class<?> getClassByTablename(String tablename) {
        TestDataHolder dataHolder = dataHolderMap.get(tablename);
        if (dataHolder == null) {
            throw new RuntimeException("No such tablename: " + tablename);
        }
        return dataHolder.getModelClass();
    }

    /**
     * モデルクラスに対応するテーブル名を返す。
     * @param modelClass 対象のモデルクラス
     * @return 対応するテーブル名
     */
    public String getTablenameByClass(Class<?> modelClass) {
        for (Map.Entry<String, TestDataHolder> entry : dataHolderMap.entrySet()) {
            if (entry.getValue().getModelClass() == modelClass) {
                return entry.getKey();
            }
        }
        throw new RuntimeException(MessageFormat.format(
                "Unknown model class: {0}",
                modelClass.getName()));
    }

    /**
     * 検査に使用するInspectorを指定する。
     * 指定しなかった場合、{@link DefaultInspector}が使用される。
     * @param tablename テーブル名
     * @param inspector 使用するInspector
     */
    public void setInspector(String tablename, Inspector inspector) {
        inspectorMap.put(tablename, inspector);
    }

    /**
     * テストがNGだったとき原因を取得します。
     * @return テストがNGだったとき原因
     */
    public List<Cause> getCauses() {
        return causes;
    }

    /**
     * 実行結果が期待したものかを確認します。
     * @return OKの場合true
     */
    public boolean inspect() {
        boolean success = true;
        for (String tablename : dataHolderMap.keySet()) {
            TestDataHolder dataHolder = dataHolderMap.get(tablename);
            Inspector inspector = inspectorMap.get(tablename);
            if (inspector == null) {
                inspector = new DefaultInspector();
            }
            inspector.setColumnInfos(dataHolder.getColumnInfos());
            inspector.setStartTime(startTime);
            inspector.setFinishTime(System.currentTimeMillis());
            inspector.inspect(dataHolder);
            if (!inspector.isSuccess()) {
                success = false;
                causes.addAll(inspector.getCauses());
            }
        }
        return success;
    }
}
TOP

Related Classes of com.asakusafw.testtools.TestUtils

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.