1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/mobile/robocop/FennecMochitestAssert.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,252 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko; 1.9 + 1.10 +import java.util.LinkedList; 1.11 + 1.12 +import android.os.SystemClock; 1.13 + 1.14 +public class FennecMochitestAssert implements Assert { 1.15 + private LinkedList<testInfo> mTestList = new LinkedList<testInfo>(); 1.16 + 1.17 + // Internal state variables to make logging match up with existing mochitests 1.18 + private int mLineNumber = 0; 1.19 + private int mPassed = 0; 1.20 + private int mFailed = 0; 1.21 + private int mTodo = 0; 1.22 + 1.23 + // Used to write the first line of the test file 1.24 + private boolean mLogStarted = false; 1.25 + 1.26 + // Used to write the test-start/test-end log lines 1.27 + private String mLogTestName = ""; 1.28 + 1.29 + // Measure the time it takes to run test case 1.30 + private long mStartTime = 0; 1.31 + 1.32 + public FennecMochitestAssert() { 1.33 + } 1.34 + 1.35 + /** Write information to a logfile and logcat */ 1.36 + public void dumpLog(String message) { 1.37 + FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message); 1.38 + } 1.39 + 1.40 + /** Write information to a logfile and logcat */ 1.41 + public void dumpLog(String message, Throwable t) { 1.42 + FennecNativeDriver.log(FennecNativeDriver.LogLevel.INFO, message, t); 1.43 + } 1.44 + 1.45 + /** Set the filename used for dumpLog. */ 1.46 + public void setLogFile(String filename) { 1.47 + FennecNativeDriver.setLogFile(filename); 1.48 + 1.49 + String message; 1.50 + if (!mLogStarted) { 1.51 + dumpLog(Integer.toString(mLineNumber++) + " INFO SimpleTest START"); 1.52 + mLogStarted = true; 1.53 + } 1.54 + 1.55 + if (mLogTestName != "") { 1.56 + long diff = SystemClock.uptimeMillis() - mStartTime; 1.57 + message = Integer.toString(mLineNumber++) + " INFO TEST-END | " + mLogTestName; 1.58 + message += " | finished in " + diff + "ms"; 1.59 + dumpLog(message); 1.60 + mLogTestName = ""; 1.61 + } 1.62 + } 1.63 + 1.64 + public void setTestName(String testName) { 1.65 + String[] nameParts = testName.split("\\."); 1.66 + mLogTestName = nameParts[nameParts.length - 1]; 1.67 + mStartTime = SystemClock.uptimeMillis(); 1.68 + 1.69 + dumpLog(Integer.toString(mLineNumber++) + " INFO TEST-START | " + mLogTestName); 1.70 + } 1.71 + 1.72 + class testInfo { 1.73 + public boolean mResult; 1.74 + public String mName; 1.75 + public String mDiag; 1.76 + public boolean mTodo; 1.77 + public boolean mInfo; 1.78 + public testInfo(boolean r, String n, String d, boolean t, boolean i) { 1.79 + mResult = r; 1.80 + mName = n; 1.81 + mDiag = d; 1.82 + mTodo = t; 1.83 + mInfo = i; 1.84 + } 1.85 + 1.86 + } 1.87 + 1.88 + private void _logMochitestResult(testInfo test, String passString, String failString) { 1.89 + boolean isError = true; 1.90 + String resultString = failString; 1.91 + if (test.mResult || test.mTodo) { 1.92 + isError = false; 1.93 + } 1.94 + if (test.mResult) 1.95 + { 1.96 + resultString = passString; 1.97 + } 1.98 + String diag = test.mName; 1.99 + if (test.mDiag != null) diag += " - " + test.mDiag; 1.100 + 1.101 + String message = Integer.toString(mLineNumber++) + " INFO " + resultString + " | " + mLogTestName + " | " + diag; 1.102 + dumpLog(message); 1.103 + 1.104 + if (test.mInfo) { 1.105 + // do not count TEST-INFO messages 1.106 + } else if (test.mTodo) { 1.107 + mTodo++; 1.108 + } else if (isError) { 1.109 + mFailed++; 1.110 + } else { 1.111 + mPassed++; 1.112 + } 1.113 + if (isError) { 1.114 + junit.framework.Assert.fail(message); 1.115 + } 1.116 + } 1.117 + 1.118 + public void endTest() { 1.119 + String message; 1.120 + 1.121 + if (mLogTestName != "") { 1.122 + long diff = SystemClock.uptimeMillis() - mStartTime; 1.123 + message = Integer.toString(mLineNumber++) + " INFO TEST-END | " + mLogTestName; 1.124 + message += " | finished in " + diff + "ms"; 1.125 + dumpLog(message); 1.126 + mLogTestName = ""; 1.127 + } 1.128 + 1.129 + message = Integer.toString(mLineNumber++) + " INFO TEST-START | Shutdown"; 1.130 + dumpLog(message); 1.131 + message = Integer.toString(mLineNumber++) + " INFO Passed: " + Integer.toString(mPassed); 1.132 + dumpLog(message); 1.133 + message = Integer.toString(mLineNumber++) + " INFO Failed: " + Integer.toString(mFailed); 1.134 + dumpLog(message); 1.135 + message = Integer.toString(mLineNumber++) + " INFO Todo: " + Integer.toString(mTodo); 1.136 + dumpLog(message); 1.137 + message = Integer.toString(mLineNumber++) + " INFO SimpleTest FINISHED"; 1.138 + dumpLog(message); 1.139 + } 1.140 + 1.141 + public void ok(boolean condition, String name, String diag) { 1.142 + testInfo test = new testInfo(condition, name, diag, false, false); 1.143 + _logMochitestResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL"); 1.144 + mTestList.add(test); 1.145 + } 1.146 + 1.147 + public void is(Object actual, Object expected, String name) { 1.148 + boolean pass = checkObjectsEqual(actual, expected); 1.149 + ok(pass, name, getEqualString(actual, expected, pass)); 1.150 + } 1.151 + 1.152 + public void isnot(Object actual, Object notExpected, String name) { 1.153 + boolean pass = checkObjectsNotEqual(actual, notExpected); 1.154 + ok(pass, name, getNotEqualString(actual, notExpected, pass)); 1.155 + } 1.156 + 1.157 + public void ispixel(int actual, int r, int g, int b, String name) { 1.158 + int aAlpha = ((actual >> 24) & 0xFF); 1.159 + int aR = ((actual >> 16) & 0xFF); 1.160 + int aG = ((actual >> 8) & 0xFF); 1.161 + int aB = (actual & 0xFF); 1.162 + boolean pass = checkPixel(actual, r, g, b); 1.163 + ok(pass, name, "Color rgba(" + aR + "," + aG + "," + aB + "," + aAlpha + ")" + (pass ? " " : " not") + " close enough to expected rgb(" + r + "," + g + "," + b + ")"); 1.164 + } 1.165 + 1.166 + public void isnotpixel(int actual, int r, int g, int b, String name) { 1.167 + int aAlpha = ((actual >> 24) & 0xFF); 1.168 + int aR = ((actual >> 16) & 0xFF); 1.169 + int aG = ((actual >> 8) & 0xFF); 1.170 + int aB = (actual & 0xFF); 1.171 + boolean pass = checkPixel(actual, r, g, b); 1.172 + ok(!pass, name, "Color rgba(" + aR + "," + aG + "," + aB + "," + aAlpha + ")" + (!pass ? " is" : " is not") + " different enough from rgb(" + r + "," + g + "," + b + ")"); 1.173 + } 1.174 + 1.175 + private boolean checkPixel(int actual, int r, int g, int b) { 1.176 + // When we read GL pixels the GPU has already processed them and they 1.177 + // are usually off by a little bit. For example a CSS-color pixel of color #64FFF5 1.178 + // was turned into #63FFF7 when it came out of glReadPixels. So in order to compare 1.179 + // against the expected value, we use a little fuzz factor. For the alpha we just 1.180 + // make sure it is always 0xFF. There is also bug 691354 which crops up every so 1.181 + // often just to make our lives difficult. However the individual color components 1.182 + // should never be off by more than 8. 1.183 + int aAlpha = ((actual >> 24) & 0xFF); 1.184 + int aR = ((actual >> 16) & 0xFF); 1.185 + int aG = ((actual >> 8) & 0xFF); 1.186 + int aB = (actual & 0xFF); 1.187 + boolean pass = (aAlpha == 0xFF) /* alpha */ 1.188 + && (Math.abs(aR - r) <= 8) /* red */ 1.189 + && (Math.abs(aG - g) <= 8) /* green */ 1.190 + && (Math.abs(aB - b) <= 8); /* blue */ 1.191 + if (pass) { 1.192 + return true; 1.193 + } else { 1.194 + return false; 1.195 + } 1.196 + } 1.197 + 1.198 + public void todo(boolean condition, String name, String diag) { 1.199 + testInfo test = new testInfo(condition, name, diag, true, false); 1.200 + _logMochitestResult(test, "TEST-UNEXPECTED-PASS", "TEST-KNOWN-FAIL"); 1.201 + mTestList.add(test); 1.202 + } 1.203 + 1.204 + public void todo_is(Object actual, Object expected, String name) { 1.205 + boolean pass = checkObjectsEqual(actual, expected); 1.206 + todo(pass, name, getEqualString(actual, expected, pass)); 1.207 + } 1.208 + 1.209 + public void todo_isnot(Object actual, Object notExpected, String name) { 1.210 + boolean pass = checkObjectsNotEqual(actual, notExpected); 1.211 + todo(pass, name, getNotEqualString(actual, notExpected, pass)); 1.212 + } 1.213 + 1.214 + private boolean checkObjectsEqual(Object a, Object b) { 1.215 + if (a == null || b == null) { 1.216 + if (a == null && b == null) { 1.217 + return true; 1.218 + } 1.219 + return false; 1.220 + } else { 1.221 + return a.equals(b); 1.222 + } 1.223 + } 1.224 + 1.225 + private String getEqualString(Object a, Object b, boolean pass) { 1.226 + if (pass) { 1.227 + return a + " should equal " + b; 1.228 + } 1.229 + return "got " + a + ", expected " + b; 1.230 + } 1.231 + 1.232 + private boolean checkObjectsNotEqual(Object a, Object b) { 1.233 + if (a == null || b == null) { 1.234 + if ((a == null && b != null) || (a != null && b == null)) { 1.235 + return true; 1.236 + } else { 1.237 + return false; 1.238 + } 1.239 + } else { 1.240 + return !a.equals(b); 1.241 + } 1.242 + } 1.243 + 1.244 + private String getNotEqualString(Object a, Object b, boolean pass) { 1.245 + if(pass) { 1.246 + return a + " should not equal " + b; 1.247 + } 1.248 + return "didn't expect " + a + ", but got it"; 1.249 + } 1.250 + 1.251 + public void info(String name, String message) { 1.252 + testInfo test = new testInfo(true, name, message, false, true); 1.253 + _logMochitestResult(test, "TEST-INFO", "INFO FAILED?"); 1.254 + } 1.255 +}