org.zeroxlab.benchmark.Case.java Source code

Java tutorial

Introduction

Here is the source code for org.zeroxlab.benchmark.Case.java

Source

/*
 * Copyright (C) 2010 0xlab - http://0xlab.org/
 *
 * 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 org.zeroxlab.benchmark;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Intent;
import android.util.Log;

public abstract class Case {
    protected String TAG = "Case";

    protected String PACKAGE = Benchmark.PACKAGE;
    protected String TESTER;

    /* If mRepeatMax = 3, mRepeatNow will count from 0 to 2*/
    private int mRepeatMax = 1;
    private int mRepeatNow;
    protected boolean mInvolved;
    protected long[] mResult;

    private final static String SOURCE = "SOURCE";
    private final static String INDEX = "INDEX";
    private final static String RESULT = "RESULT";
    private final static String ROUND = "ROUND";
    private final static String SWWINDOW = "SWWINDOW";
    private final static String SWLAYER = "SWLAYER";

    protected int mCaseRound = 30;
    protected boolean mUseSV = true;
    protected boolean mSwWin = false;
    protected boolean mSwLayer = false;

    public String mType = "";
    public String[] mTags = {};

    /**
     * Constructor to generate instance.
     *
     * It defines the Case as "Please run Tester for N round, repeat N times"
     * @param tag The tag name of the subclass Case. It is generally the Subclass Name
     * @param tester The taget tester be used by subclass Case. It should be full class name.
     * @param repeat The tester will run *repeat* times.
     * @param round To tell tester to run itself as *round* round.
     */
    protected Case(String tag, String tester, int repeat, int round) {
        this(tag, tester, repeat, round, false, false);
    }

    protected Case(String tag, String tester, int repeat, int round, boolean swWin, boolean swLayer) {
        TAG = tag;
        TESTER = tester;
        mRepeatMax = repeat;
        mCaseRound = round;
        mSwWin = swWin;
        mSwLayer = swLayer;
        reset();
    }

    abstract public String getDescription();

    abstract public String getTitle();

    abstract public ArrayList<Scenario> getScenarios();

    public final static void putRound(Intent intent, int round) {
        intent.putExtra(ROUND, round);
    }

    public final static void putSwWindow(Intent intent, boolean swWin) {
        intent.putExtra(SWWINDOW, swWin);
    }

    public final static void putSwLayer(Intent intent, boolean swLayer) {
        intent.putExtra(SWLAYER, swLayer);
    }

    public final static void putIndex(Intent intent, int index) {
        intent.putExtra(INDEX, index);
    }

    public final static void putSource(Intent intent, String source) {
        intent.putExtra(SOURCE, source);
    }

    public final static void putResult(Intent intent, long result) {
        intent.putExtra(RESULT, result);
    }

    public final static int getRound(Intent intent) {
        return intent.getIntExtra(ROUND, 100);
    }

    public final static boolean isSoftwareWindow(Intent intent) {
        return intent.getBooleanExtra(SWWINDOW, false);
    }

    public final static boolean isSoftwareLayer(Intent intent) {
        return intent.getBooleanExtra(SWLAYER, false);
    }

    public final static int getIndex(Intent intent) {
        return intent.getIntExtra(INDEX, -1);
    }

    public final static String getSource(Intent intent) {
        String source = intent.getStringExtra(SOURCE);
        if (source == null) {
            return "unknown";
        }

        if (source.equals("")) {
            return "unknown";
        }

        return source;
    }

    public final static long getResult(Intent intent) {
        long defaultResult = -1;
        return intent.getLongExtra(RESULT, defaultResult);
    }

    public final static String decorate(String prefix, boolean useSurfaceView, boolean swWindow, boolean swLayer) {

        if (useSurfaceView)
            return prefix;

        if (swWindow) {
            if (swLayer)
                return prefix + "(SW-WL)";
            else
                return prefix + "(SW-W)";
        } else {
            if (swLayer)
                return prefix + "(SW-L)";
            else
                return prefix + "(HW)";
        }
    }

    public String getTag() {
        return TAG;
    }

    protected Intent generateIntent() {
        /* if run out of the repeat times, go back directly */
        if (mRepeatNow >= mRepeatMax) {
            return null;
        }

        Intent intent = new Intent();
        intent.setClassName(PACKAGE, TESTER);
        Case.putRound(intent, mCaseRound);
        Case.putSwWindow(intent, mSwWin);
        Case.putSwLayer(intent, mSwLayer);
        Case.putSource(intent, TAG);
        Case.putIndex(intent, mRepeatNow);

        mRepeatNow = mRepeatNow + 1;

        return intent;
    }

    public void clear() {
        mResult = new long[mRepeatMax];
        mRepeatNow = mRepeatMax; // no more repeating times
        mInvolved = false;
    }

    /* Reset the repeat time to default value. clear result */
    public void reset() {
        mResult = new long[mRepeatMax];
        mRepeatNow = 0;
        mInvolved = true;
    }

    public boolean isFinish() {
        /* If mRepeatMax = 3, mRepeatNow will count from 0 to 2*/
        return (mRepeatNow >= mRepeatMax);
    }

    /** To read the SOURCE of this intent to see if this intent belong to this case
     *
     * @return return True if this intent belong to this case, otherwise return false
     */
    public boolean realize(Intent intent) {
        if (intent == null) {
            Log.i(TAG, "Intent is null");
            return false;
        }

        String source = Case.getSource(intent);
        if (source == null || source.equals("")) {
            return false;
        }

        if (source.equals(TAG)) {
            return true;
        } else {
            return false;
        }
    }

    public boolean parseIntent(Intent intent) {
        if (intent == null) {
            Log.i(TAG, "Intent is null");
            return false;
        }

        String tag = Case.getSource(intent);

        if (tag == null || !tag.equals(TAG)) {
            Log.i(TAG, "Unknown intent, cannot parse it");
            return false;
        }

        int index = Case.getIndex(intent);
        if (index >= mRepeatMax) {
            Log.i(TAG, "Ooooops index >= mRepeatMax(" + mRepeatMax + "), how come?");
            return false;
        }

        return saveResult(intent, index);
    }

    /**
     * To Save the result from Tester into this Case
     * If subclass has its own way to analysis result, override this method
     *
     * @param intent The intent will be analysis
     * @param index The repeating time of this intent. (Tester might repeat N times)
     * @return return True if analysis sucessfully
     */
    protected boolean saveResult(Intent intent, int index) {
        long result = Case.getResult(intent);

        if (result == -1) {
            Log.i(TAG, "Oooops! result is " + result);
            return false;
        }

        mResult[index] = result;
        return true;
    }

    public boolean couldFetchReport() {
        if (!isFinish()) {
            return false;
        }

        if (mInvolved == false) {
            return false;
        }

        return true;
    }

    public String getResultOutput() {
        if (!couldFetchReport()) {
            return "No benchmark report";
        }

        String result = "";
        long total = 0;
        int length = mResult.length;
        for (int i = 0; i < length; i++) {
            total += mResult[i];
            result += "round " + i + ":" + mResult[i] + "\n";
        }

        result += "Average:" + (total / length) + "\n";
        return result;
    }

    /*
     *  Get Average Benchmark
     */
    public double getBenchmark(Scenario s) {
        double total = 0;
        int length = mResult.length;
        for (int i = 0; i < length; i++) {
            total += mResult[i];
        }
        return (double) total / length;
    }

    public String getXMLBenchmark() {
        if (!couldFetchReport()) {
            Log.e(TAG, "cannot fetch report: " + getTitle() + " : " + isFinish() + " : " + mInvolved);
            return "";
        }

        String result = "";

        ArrayList<Scenario> scenarios = getScenarios();
        Log.e(TAG, "length of scenarios: " + scenarios.size());

        for (Scenario s : scenarios) {
            if (s == null) {
                Log.e(TAG, "Scenario is null");
                continue;
            }
            String _result = "";
            _result += "<scenario";
            _result += " benchmark=\"" + s.mName.replace(" ", "") + "\"";
            _result += " unit=\"" + s.mType + "\"";
            _result += " tags=\"";
            for (String tag : s.mTags)
                _result += tag + ",";
            _result += "\"";
            _result += ">";
            if (!s.useStringResults) {
                Double total = 0.0;
                for (Double value : s.mResults) {
                    _result += value + " ";
                    total += value;
                }
                _result += "</scenario>";
                if (total == 0) {
                    Log.e(TAG, "_result total is 0: ");
                    Log.e(TAG, _result);
                    continue;
                }
            } else {
                if (s.mStringResults == null || s.mStringResults.length() == 0) {
                    Log.e(TAG, "string results is empty: " + s.mStringResults);
                    continue;
                }
                _result += s.mStringResults;
                _result += "</scenario>";
            }
            result += _result;
        }
        return result;
    }

    public JSONArray getJSONBenchmark() {
        JSONArray scenarioResult = new JSONArray();
        if (!couldFetchReport()) {
            Log.e(TAG, "cannot fetch report: " + getTitle() + " : " + isFinish() + " : " + mInvolved);
            return scenarioResult;
        }
        ArrayList<Scenario> scenarios = getScenarios();

        try {
            for (Scenario s : scenarios) {
                JSONObject jsonObj = new JSONObject();
                jsonObj.put("test_case_id", s.mName.replace(" ", ""));
                jsonObj.put("measurement", getBenchmark(s));
                jsonObj.put("units", s.mType);
                jsonObj.put("result", "pass");
                scenarioResult.put(jsonObj);
            }
        } catch (JSONException jsonE) {
            jsonE.printStackTrace();
        }
        return scenarioResult;
    }
}