1006 lines
26 KiB
Haxe
1006 lines
26 KiB
Haxe
|
import haxe.zip.Compress;
|
||
|
import haxe.zip.Uncompress;
|
||
|
import haxe.zip.FlushMode;
|
||
|
import sys.FileSystem;
|
||
|
import sys.db.Connection;
|
||
|
import sys.db.Sqlite;
|
||
|
import sys.db.Mysql;
|
||
|
import sys.FileSystem;
|
||
|
import haxe.io.Bytes;
|
||
|
import haxe.io.BytesData;
|
||
|
|
||
|
import cpp.Random;
|
||
|
import cpp.net.Poll;
|
||
|
import sys.io.File;
|
||
|
import sys.io.FileSeek;
|
||
|
import sys.net.Host;
|
||
|
import sys.net.Socket;
|
||
|
import sys.net.UdpSocket;
|
||
|
import sys.net.UdpSocket;
|
||
|
import sys.io.Process;
|
||
|
|
||
|
#if haxe4
|
||
|
import sys.thread.Deque;
|
||
|
import sys.thread.Thread;
|
||
|
#else
|
||
|
import cpp.vm.Deque;
|
||
|
import cpp.vm.Thread;
|
||
|
#end
|
||
|
|
||
|
using cpp.NativeArray;
|
||
|
using cpp.AtomicInt;
|
||
|
|
||
|
// These should be ignored in haxe 3.3...
|
||
|
import cpp.link.StaticStd;
|
||
|
import cpp.link.StaticRegexp;
|
||
|
import cpp.link.StaticZlib;
|
||
|
import cpp.link.StaticMysql;
|
||
|
import cpp.link.StaticSqlite;
|
||
|
|
||
|
|
||
|
@:buildXml('<include name="${HXCPP}/src/hx/libs/ssl/Build.xml"/>')
|
||
|
extern class SslTest
|
||
|
{
|
||
|
@:extern @:native("_hx_ssl_init")
|
||
|
extern public static function socket_init():Void;
|
||
|
}
|
||
|
|
||
|
class Test
|
||
|
{
|
||
|
static var errors = new Array<String>();
|
||
|
static var lastErrorCount = 0;
|
||
|
|
||
|
var x:Int;
|
||
|
|
||
|
public function new()
|
||
|
{
|
||
|
x = 1;
|
||
|
}
|
||
|
|
||
|
public static function log(t:String)
|
||
|
{
|
||
|
Sys.println(t);
|
||
|
}
|
||
|
|
||
|
public static function v(t:String)
|
||
|
{
|
||
|
Sys.println(" " + t);
|
||
|
}
|
||
|
|
||
|
public static function ok()
|
||
|
{
|
||
|
if (lastErrorCount==errors.length)
|
||
|
{
|
||
|
v("ok");
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
lastErrorCount=errors.length;
|
||
|
v("bad");
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function error(e:String)
|
||
|
{
|
||
|
Sys.println("Test Failed:" + e);
|
||
|
errors.push(e);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
public static function thisFile()
|
||
|
{
|
||
|
#if nme_install_tool
|
||
|
var bytes:haxe.io.Bytes = ApplicationMain.getAsset("Test.hx");
|
||
|
#else
|
||
|
var bytes = sys.io.File.getBytes("Test.hx");
|
||
|
#end
|
||
|
return bytes;
|
||
|
}
|
||
|
|
||
|
public static function testDb(cnx:Connection) : Int
|
||
|
{
|
||
|
v("connected :" + cnx);
|
||
|
if (cnx.dbName() == "SQLite") {
|
||
|
cnx.request("
|
||
|
CREATE TABLE IF NOT EXISTS UserPwd (
|
||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
|
name TEXT,
|
||
|
age INTEGER,
|
||
|
money DOUBLE,
|
||
|
password BLOB
|
||
|
)");
|
||
|
cnx.request("SELECT '豪鬼' test");
|
||
|
} else {
|
||
|
cnx.request("
|
||
|
CREATE TABLE IF NOT EXISTS UserPwd (
|
||
|
id INTEGER NOT NULL AUTO_INCREMENT,
|
||
|
name TEXT,
|
||
|
age INTEGER,
|
||
|
money DOUBLE,
|
||
|
password BLOB,
|
||
|
PRIMARY KEY(id)
|
||
|
)");
|
||
|
}
|
||
|
var dels = cnx.request("DELETE FROM UserPwd");
|
||
|
if (dels.nfields != 0)
|
||
|
return error("Bad DELETE'd result");
|
||
|
v("deleted " + dels.length + " existing rows");
|
||
|
|
||
|
cnx.request("INSERT INTO UserPwd (name,age,money,password) VALUES ('John',32,100.45,X'c0ffee')");
|
||
|
cnx.request("INSERT INTO UserPwd (name,age,money,password) VALUES ('Bob',14,4.50,X'deadbeef01020304')");
|
||
|
|
||
|
var rset = cnx.request("SELECT * FROM UserPwd");
|
||
|
|
||
|
var length = rset.length;
|
||
|
v("found "+length+" users");
|
||
|
if (length!=2)
|
||
|
return error("Bad user count");
|
||
|
for( row in rset )
|
||
|
{
|
||
|
var pass:Dynamic = row.password;
|
||
|
var password = Std.is(pass, haxe.io.BytesData) ? haxe.io.Bytes.ofData(pass) : pass;
|
||
|
var md5 = haxe.crypto.Md5.make(password).toHex().substr(0,8);
|
||
|
v(" user "+row.name+" is "+row.age+" years old, password:" + md5);
|
||
|
if (md5!="5f80e231" && md5!="8ed0b363")
|
||
|
return error("Bad binary blob store");
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static function testDate()
|
||
|
{
|
||
|
log("Test date");
|
||
|
var now = Date.now();
|
||
|
v(Std.string(now));
|
||
|
var then = Date.fromString("1977-06-11");
|
||
|
v(Std.string(then));
|
||
|
if (now.getTime()<=then.getTime())
|
||
|
return error("Date fromString - time travel");
|
||
|
|
||
|
var later = DateTools.makeUtc(1996,5,4,17,55,11);
|
||
|
v(Std.string(later));
|
||
|
|
||
|
var diff:Float = untyped __global__.__hxcpp_timezone_offset(now.mSeconds);
|
||
|
v("timezone offet:" + diff);
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public static function testCompress()
|
||
|
{
|
||
|
log("Test compress");
|
||
|
var bytes = thisFile();
|
||
|
|
||
|
var compress = new Compress(9);
|
||
|
compress.setFlushMode(FlushMode.FINISH);
|
||
|
var buffer = haxe.io.Bytes.alloc(bytes.length * 2 + 100);
|
||
|
var r = compress.execute(bytes,0,buffer,0);
|
||
|
compress.close();
|
||
|
var compressed = buffer.sub(0,r.write);
|
||
|
v("compressed size " + compressed.length );
|
||
|
|
||
|
v("try closing too many times...");
|
||
|
var caughtError = false;
|
||
|
try
|
||
|
{
|
||
|
compress.close();
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
v("correctly caught " + e );
|
||
|
caughtError = true;
|
||
|
}
|
||
|
if (!caughtError)
|
||
|
error("Zlib closed without throwing error");
|
||
|
|
||
|
var decompressed = Uncompress.run(compressed);
|
||
|
v("decompressed size:" + decompressed.length + "/" + bytes.length);
|
||
|
if (decompressed.compare(bytes)!=0)
|
||
|
return error("Compress/Uncompress mismatch");
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
|
||
|
public static function testRegexp()
|
||
|
{
|
||
|
log("Test Regexp/BytesInput");
|
||
|
|
||
|
// This utf8 comment is parsed by the code ...
|
||
|
// su©©ess
|
||
|
var success = false;
|
||
|
var utf8Match = ~/su©+ess/u;
|
||
|
|
||
|
// This comment is parsed by the code ...
|
||
|
//XML<xml value="Hello World!"/>
|
||
|
var match = ~/^..XML/;
|
||
|
var input = new haxe.io.BytesInput(thisFile());
|
||
|
try {
|
||
|
while(true)
|
||
|
{
|
||
|
var line = input.readLine();
|
||
|
if (match.match(line))
|
||
|
{
|
||
|
var xml = Xml.parse(line.substr(5));
|
||
|
v("found xml:" + xml.firstElement().get("value"));
|
||
|
if (xml.firstElement().get("value")!="Hello World!")
|
||
|
return error("Bad universal greeting");
|
||
|
}
|
||
|
if (utf8Match.match(line))
|
||
|
{
|
||
|
v("found utf8:" + utf8Match.matched(0));
|
||
|
success = true;
|
||
|
}
|
||
|
}
|
||
|
} catch (e:Dynamic) { }
|
||
|
if (!success)
|
||
|
return error("Could not find success in utf8 code");
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public static function testRegexpMixedUnicode() {
|
||
|
var success = true;
|
||
|
|
||
|
// when matching a utf8 subject string against a utf16 pattern and vice versa
|
||
|
for (pattern => subject in ["[A-Za-zÀ-ÖØ-öø-ÿ0-9]+" => "a", "[A-Z]+" => "ÀÖA"]) {
|
||
|
if (new EReg(pattern, "").match(subject)) {
|
||
|
v('"$subject" matches against ~/$pattern/');
|
||
|
} else {
|
||
|
return error('"$subject" does not match against ~/$pattern/');
|
||
|
}
|
||
|
}
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public static function testSqlite()
|
||
|
{
|
||
|
log("Test sqlite");
|
||
|
var dbFile = "hxcpp.db";
|
||
|
var cnx = Sqlite.open(dbFile);
|
||
|
if (testDb(cnx)!=0)
|
||
|
return error("db error");
|
||
|
cnx.close();
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
|
||
|
public static function testMysql()
|
||
|
{
|
||
|
log("Test mysql");
|
||
|
var cnx:sys.db.Connection = null;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
cnx = Mysql.connect({
|
||
|
host : "localhost",
|
||
|
port : 3306,
|
||
|
user : "hxcpp",
|
||
|
pass : "hxcpp",
|
||
|
socket : null,
|
||
|
database : "hxcpp"
|
||
|
});
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
v("mysql got error - ok because no server" );
|
||
|
}
|
||
|
|
||
|
if (cnx!=null)
|
||
|
{
|
||
|
if (testDb(cnx)!=0)
|
||
|
error("TestDB failed");
|
||
|
cnx.close();
|
||
|
}
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public static function testRandom()
|
||
|
{
|
||
|
log("Test Random");
|
||
|
var rand = new Random();
|
||
|
var f0 = rand.float();
|
||
|
var f1 = rand.float();
|
||
|
v('samples $f0,$f1');
|
||
|
if (f0==f1)
|
||
|
return error("Not random enough");
|
||
|
rand.setSeed(1);
|
||
|
var i0 = rand.int(256);
|
||
|
rand.setSeed(2);
|
||
|
var i1 = rand.int(256);
|
||
|
v('int samples $i0,$i1');
|
||
|
if (i0!=91 || i1!=217)
|
||
|
return error("Non-repeatable random seed, should be 91,217");
|
||
|
var tries = 0;
|
||
|
while(rand.int(1000)!=999)
|
||
|
tries++;
|
||
|
v('tries to 1000 = $tries');
|
||
|
if (tries!=749)
|
||
|
return error("Non-repeatable random iterations");
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public static function tryFunc( func ) : Bool
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
func();
|
||
|
return true;
|
||
|
}
|
||
|
catch(e:Dynamic) { }
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static function testFile()
|
||
|
{
|
||
|
log("Test File");
|
||
|
try
|
||
|
{
|
||
|
var filename = "testfile.txt";
|
||
|
tryFunc( function() FileSystem.deleteFile(filename) );
|
||
|
tryFunc( function() FileSystem.deleteFile(filename+"-copy") );
|
||
|
tryFunc( function() FileSystem.deleteFile(filename+".bin") );
|
||
|
tryFunc( function() FileSystem.deleteFile(filename+".out") );
|
||
|
|
||
|
var contents = "line1\nline2\n";
|
||
|
|
||
|
v("compare...");
|
||
|
File.saveContent(filename,contents);
|
||
|
if ( File.getContent(filename)!=contents )
|
||
|
return error("getContent mismatch");
|
||
|
|
||
|
v("copy...");
|
||
|
File.copy(filename,filename+"-copy");
|
||
|
var bytes = File.getBytes(filename+"-copy");
|
||
|
if ( bytes.compare( Bytes.ofString(contents) ) !=0 )
|
||
|
return error("copy getBytes mismatch");
|
||
|
|
||
|
File.saveBytes(filename+".bin",bytes);
|
||
|
|
||
|
v("file in...");
|
||
|
var fileIn = File.read(filename+".bin");
|
||
|
if (fileIn.readByte()!=contents.charCodeAt(0))
|
||
|
return error("File readByte mismatch");
|
||
|
var buffer = Bytes.alloc(5);
|
||
|
buffer.set(0,'-'.code);
|
||
|
buffer.set(4,'+'.code);
|
||
|
if (fileIn.readBytes(buffer,1,3)!=3)
|
||
|
return error("Could not read 3 bytes");
|
||
|
v( "read 3: " + buffer.toString() );
|
||
|
if ( buffer.toString() != "-ine+" )
|
||
|
return error("Bad sub-buffer readBytes");
|
||
|
v("seek...");
|
||
|
if (fileIn.tell()!=4)
|
||
|
return error("tell!=4");
|
||
|
fileIn.seek(4, SeekCur );
|
||
|
if (fileIn.tell()!=8)
|
||
|
return error("SeekCur tell!=8");
|
||
|
fileIn.seek(7, SeekBegin );
|
||
|
if (fileIn.tell()!=7)
|
||
|
return error("SeekSet tell!=7");
|
||
|
var rest = Bytes.alloc( contents.length - fileIn.tell() );
|
||
|
fileIn.readBytes(rest,0,rest.length);
|
||
|
if (fileIn.eof())
|
||
|
return error("File at end, but not eof");
|
||
|
fileIn.seek( -contents.length, SeekEnd );
|
||
|
if (fileIn.tell()!=0)
|
||
|
return error("File seek from end to beginning failed");
|
||
|
fileIn.close();
|
||
|
|
||
|
v("write...");
|
||
|
var fileOut = File.write(filename+".out");
|
||
|
fileOut.writeByte('W'.code);
|
||
|
if (fileOut.writeBytes(buffer,1,3)!=3)
|
||
|
return error("Could not write 3 bytes");
|
||
|
if (fileOut.tell()!=4)
|
||
|
return error("Bad tell on file write");
|
||
|
fileOut.flush();
|
||
|
if (File.getContent(filename+".out")!="Wine")
|
||
|
return error("Bad reading after flush");
|
||
|
fileOut.seek(1,SeekBegin);
|
||
|
fileOut.writeByte('a'.code);
|
||
|
fileOut.close();
|
||
|
var contents = File.getContent(filename+".out");
|
||
|
v("have :" + contents);
|
||
|
if (contents!="Wane")
|
||
|
return error("Bad readback after seek");
|
||
|
|
||
|
v("cleanup...");
|
||
|
FileSystem.deleteFile(filename);
|
||
|
FileSystem.deleteFile(filename + "-copy");
|
||
|
FileSystem.deleteFile(filename + ".bin");
|
||
|
FileSystem.deleteFile(filename + ".out");
|
||
|
return ok();
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
return error("Unexpected error in testFile: " + e);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
public static function testHost()
|
||
|
{
|
||
|
log("Test Host");
|
||
|
try
|
||
|
{
|
||
|
var localhost = Host.localhost();
|
||
|
v('localhost :$localhost');
|
||
|
var host = new Host(localhost);
|
||
|
v('host :$host');
|
||
|
// var reverse = host.reverse();
|
||
|
// v('reverse :$reverse');
|
||
|
return ok();
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
return error("Unexpected error in testHost: " + e);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
public static function testFileSystem()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
|
||
|
log("Test FileSystem");
|
||
|
tryFunc( function() FileSystem.deleteFile("dir/file.txt") );
|
||
|
tryFunc( function() FileSystem.deleteFile("dir/txt.file") );
|
||
|
tryFunc( function() FileSystem.deleteFile("dir/child") );
|
||
|
tryFunc( function() FileSystem.deleteDirectory("dir") );
|
||
|
|
||
|
v("create dir");
|
||
|
if (!tryFunc( function() FileSystem.createDirectory("dir") ) )
|
||
|
return error("Could not create 'dir'");
|
||
|
if (!tryFunc( function() FileSystem.createDirectory("dir/child") ) )
|
||
|
return error("Could not create 'dir/child'");
|
||
|
File.saveContent("dir/file.txt","hello");
|
||
|
var stat = FileSystem.stat("dir/file.txt");
|
||
|
v(Std.string(stat));
|
||
|
if (stat.size!=5)
|
||
|
return error("File does not contain 5 bytes");
|
||
|
if ( Std.string(stat.ctime).length != 19)
|
||
|
return error("File ctime does not appear to be a date");
|
||
|
|
||
|
v("exists");
|
||
|
if (!FileSystem.exists("dir"))
|
||
|
return error("'dir' should exist");
|
||
|
if (!FileSystem.exists("dir/file.txt"))
|
||
|
return error("'/file.txt' should exist");
|
||
|
var files = FileSystem.readDirectory("dir");
|
||
|
v("dir contents:" + files);
|
||
|
if (files.length!=2 || files.indexOf("file.txt")<0 || files.indexOf("child")<0)
|
||
|
return error("Unexpected dir contents " + (files.indexOf("file.txt") + "," + files.indexOf("child")) );
|
||
|
if (tryFunc( function() FileSystem.deleteDirectory("dir/junk") ) )
|
||
|
return error("No error deleting junk directory");
|
||
|
if (tryFunc( function() FileSystem.deleteFile("dir/junk") ) )
|
||
|
return error("No error deleting junk file");
|
||
|
if (tryFunc( function() FileSystem.deleteFile("dir/child") ) )
|
||
|
return error("No error deleting directory as file");
|
||
|
if (tryFunc( function() FileSystem.deleteDirectory("dir/file.txt") ) )
|
||
|
return error("No error deleting file as directory");
|
||
|
var fullPath = FileSystem.fullPath("dir/child");
|
||
|
v('fullPath: $fullPath');
|
||
|
var fullPath = FileSystem.fullPath("dir/file.txt");
|
||
|
v('fullPath: $fullPath');
|
||
|
v("isDirectory...");
|
||
|
if (FileSystem.isDirectory("dir/file.txt"))
|
||
|
return error("file appears to be a directory");
|
||
|
if (!FileSystem.isDirectory("dir/child"))
|
||
|
return error("directory appears to not be a directory");
|
||
|
if (FileSystem.isDirectory("dir/junk"))
|
||
|
return error("junk appears to be a directory");
|
||
|
if (FileSystem.isDirectory("dir/file.txt"))
|
||
|
return error("file appears to be a directory");
|
||
|
|
||
|
v("rename...");
|
||
|
if (tryFunc( function() FileSystem.rename("dir/a", "dir/b")) )
|
||
|
return error("No error renaming missing file");
|
||
|
FileSystem.rename("dir/file.txt","dir/txt.file");
|
||
|
if (!FileSystem.exists("dir/txt.file") || FileSystem.exists("dir/file.txt"))
|
||
|
return error("Rename seemed to go wrong " + FileSystem.readDirectory("dir"));
|
||
|
v("cleanup..");
|
||
|
FileSystem.deleteFile("dir/txt.file");
|
||
|
FileSystem.deleteDirectory("dir/child");
|
||
|
FileSystem.deleteDirectory("dir");
|
||
|
if (FileSystem.readDirectory(".").indexOf("dir")>=0)
|
||
|
return error("Directory removed, but sill there?:" + FileSystem.readDirectory("."));
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
return error("Unexpected error in testFileSystem: " + e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
public static function testSys()
|
||
|
{
|
||
|
log("Test Sys");
|
||
|
try
|
||
|
{
|
||
|
Sys.putEnv("mykey","123");
|
||
|
var env = Sys.getEnv("mykey");
|
||
|
v("got env:" + env);
|
||
|
if (env!="123")
|
||
|
return error("Bad environment get");
|
||
|
v("little sleep...");
|
||
|
var t0 = Sys.time();
|
||
|
Sys.sleep(0.1);
|
||
|
var t1 = Sys.time();
|
||
|
v("Slept for: " + (t1-t0));
|
||
|
if (t1<=t0 || (t1-t0)>10)
|
||
|
return error("Too sleepy");
|
||
|
v("CpuTime: " + Sys.cpuTime());
|
||
|
v("Cwd: " + Sys.getCwd());
|
||
|
v("Program Path: " + Sys.programPath());
|
||
|
var env = Sys.environment();
|
||
|
v("Environment mykey: " + env.get("mykey") );
|
||
|
if (env.get("mykey")!="123")
|
||
|
return error("Could not find mykey in environment");
|
||
|
v("Ignore getChar auto test");
|
||
|
v("Args: " + Sys.args());
|
||
|
v("SystemName: " + Sys.systemName());
|
||
|
v("Skipping Sys.setTimeLocale" + Sys.setTimeLocale);
|
||
|
// Sys.command
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
return error("Unexpected error in testSys: " + e);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
public static function testCommand()
|
||
|
{
|
||
|
log("Test Command");
|
||
|
try
|
||
|
{
|
||
|
var code = Sys.command( Sys.programPath(), ["exit", "13"]);
|
||
|
if (code!=13)
|
||
|
return error('Process exited with code $code, not 13');
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
return error("Unexpected error in testCommand: " + e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function runAsProcess()
|
||
|
{
|
||
|
var args = Sys.args();
|
||
|
var job = args.shift();
|
||
|
if (job=="exit")
|
||
|
{
|
||
|
Sys.exit( Std.parseInt(args[0]) );
|
||
|
}
|
||
|
else if (job=="socket")
|
||
|
{
|
||
|
socketClient();
|
||
|
Sys.exit(0);
|
||
|
}
|
||
|
else
|
||
|
Sys.println('Unknown job : "$job"');
|
||
|
Sys.exit(-99);
|
||
|
}
|
||
|
|
||
|
public static function testPoll()
|
||
|
{
|
||
|
log("Test poll");
|
||
|
try
|
||
|
{
|
||
|
|
||
|
var poll = new Poll(4);
|
||
|
poll.prepare([],[]);
|
||
|
var t0 = Sys.time();
|
||
|
v("poll...");
|
||
|
poll.poll([],0.1);
|
||
|
var t = Sys.time()-t0;
|
||
|
v('took ${t}s');
|
||
|
/*
|
||
|
if (t<0.1)
|
||
|
return error("Timeout too soon");
|
||
|
if (t>10)
|
||
|
return error("Timeout too slow");
|
||
|
*/
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
return error("Unexpected error in testPoll: " + e);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
public static function testUdpSocket()
|
||
|
{
|
||
|
log("Test UdpSocket");
|
||
|
try
|
||
|
{
|
||
|
|
||
|
var udp = new UdpSocket();
|
||
|
udp.close();
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
return error("Unexpected error in testUdpSocket: " + e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static var socketClientRunning = true;
|
||
|
public static function readOutput(proc:Process)
|
||
|
{
|
||
|
Thread.create( function() {
|
||
|
while(true)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
var line = proc.stdout.readLine();
|
||
|
v("---> " + line);
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
var code = proc.exitCode();
|
||
|
v("process exit code :" + code);
|
||
|
socketClientRunning = false;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
public static function testSocket()
|
||
|
{
|
||
|
log("Test Socket");
|
||
|
try
|
||
|
{
|
||
|
v("Spawn client..");
|
||
|
var proc = new Process( Sys.programPath(), ["socket"] );
|
||
|
readOutput(proc);
|
||
|
v("connect localhost..");
|
||
|
var host = new Host("localhost");
|
||
|
var socket = new Socket();
|
||
|
socket.bind(host,0xcccc);
|
||
|
v("listen...");
|
||
|
socket.listen(1);
|
||
|
v("accept...");
|
||
|
var connected = socket.accept();
|
||
|
v("connected!");
|
||
|
|
||
|
var input = connected.input;
|
||
|
var output = connected.output;
|
||
|
|
||
|
v("send...");
|
||
|
connected.setFastSend(true);
|
||
|
connected.write("ping");
|
||
|
var buffer = Bytes.alloc(8);
|
||
|
if (input.readBytes(buffer,0,8)!=8)
|
||
|
return error("Could not read from socket");
|
||
|
var got = buffer.toString();
|
||
|
v('got $got');
|
||
|
if (got!="pingpong")
|
||
|
return error("Bad socket read");
|
||
|
|
||
|
v("close connection..");
|
||
|
connected.close();
|
||
|
v("close original..");
|
||
|
socket.close();
|
||
|
|
||
|
for(wait in 0...10)
|
||
|
{
|
||
|
if (!socketClientRunning)
|
||
|
break;
|
||
|
v("wait for client...");
|
||
|
Sys.sleep(0.1);
|
||
|
}
|
||
|
if (socketClientRunning)
|
||
|
return error("Socket client did not finish");
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
return error("Unexpected error in Socket: " + e);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
public static function socketClient()
|
||
|
{
|
||
|
log("Client proc...");
|
||
|
var host = new Host("localhost");
|
||
|
var socket:Socket = null;
|
||
|
for(attempt in 0...10)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
log("Client connect...");
|
||
|
socket = new Socket();
|
||
|
socket.connect(host,0xcccc);
|
||
|
break;
|
||
|
}
|
||
|
catch(e:Dynamic)
|
||
|
{
|
||
|
socket.close();
|
||
|
socket = null;
|
||
|
log("Client failed :" + e);
|
||
|
}
|
||
|
log("sleep...");
|
||
|
Sys.sleep(0.25);
|
||
|
}
|
||
|
|
||
|
if (socket==null)
|
||
|
Sys.exit(-1);
|
||
|
v("connected client");
|
||
|
|
||
|
var input = socket.input;
|
||
|
var output = socket.output;
|
||
|
|
||
|
var buffer = Bytes.alloc(4);
|
||
|
input.readBytes(buffer,0,4);
|
||
|
v("client got " + buffer);
|
||
|
output.writeBytes( Bytes.ofString( buffer.toString() + "pong" ), 0, 8);
|
||
|
output.flush();
|
||
|
|
||
|
v("bye");
|
||
|
socket.shutdown(true,true);
|
||
|
}
|
||
|
|
||
|
public static function testSsl() : Int
|
||
|
{
|
||
|
log("Test ssl");
|
||
|
SslTest.socket_init();
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public static function testSerialization() : Int
|
||
|
{
|
||
|
log("Test serialization");
|
||
|
var orig:haxe.Int64 = haxe.Int64.make(0xdeadbeef,0xbeefdead);
|
||
|
var recon:haxe.Int64 = haxe.Unserializer.run(haxe.Serializer.run(orig));
|
||
|
if (orig!=recon)
|
||
|
error('Bad Int64 serialization $orig != $recon');
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
|
||
|
// Hide from optimizer
|
||
|
static function getOne() return 1;
|
||
|
|
||
|
public static function testThread()
|
||
|
{
|
||
|
log("Test thread");
|
||
|
v("atomics..");
|
||
|
|
||
|
var a:AtomicInt = getOne();
|
||
|
var aPtr = cpp.Pointer.addressOf(a);
|
||
|
if (aPtr.exchangeIf(2,3))
|
||
|
error("Bad exchageIf " + a);
|
||
|
if (!aPtr.exchangeIf(1,3))
|
||
|
error("No exchageIf " + a);
|
||
|
if (a!=3)
|
||
|
error("Bad exchageIf value ");
|
||
|
if (aPtr.atomicInc()!=3)
|
||
|
error("Bad atomicInc return");
|
||
|
if (a!=4)
|
||
|
error("Bad atomicInc value " + a);
|
||
|
if (aPtr.atomicDec()!=4)
|
||
|
error("Bad atomicDec return");
|
||
|
if (a!=3)
|
||
|
error("Bad atomicDec value " + a);
|
||
|
|
||
|
|
||
|
a = getOne();
|
||
|
v('deque a=$a');
|
||
|
|
||
|
var q = new Deque<Int>();
|
||
|
q.add(1);
|
||
|
q.add(2);
|
||
|
q.add(3);
|
||
|
var mainThread = Thread.current();
|
||
|
// +100000
|
||
|
Thread.create(function() {
|
||
|
q.pop(true);
|
||
|
for(i in 0...100000)
|
||
|
aPtr.atomicInc();
|
||
|
mainThread.sendMessage(null);
|
||
|
});
|
||
|
// +100000
|
||
|
Thread.create(function() {
|
||
|
q.pop(true);
|
||
|
for(i in 0...100000)
|
||
|
aPtr.atomicInc();
|
||
|
mainThread.sendMessage(null);
|
||
|
} );
|
||
|
// -200000
|
||
|
Thread.create(function() {
|
||
|
q.pop(true);
|
||
|
for(i in 0...200000)
|
||
|
aPtr.atomicDec();
|
||
|
mainThread.sendMessage(null);
|
||
|
} );
|
||
|
|
||
|
v("wait for reply..");
|
||
|
for(i in 0...3)
|
||
|
{
|
||
|
Thread.readMessage(true);
|
||
|
v('got $i');
|
||
|
}
|
||
|
|
||
|
if (a!=1)
|
||
|
error('Bad deque count : $a');
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public static function testFloatReads()
|
||
|
{
|
||
|
log("Test float bytes");
|
||
|
|
||
|
var bytes =haxe.io.Bytes.alloc(1+4+8);
|
||
|
bytes.fill(0,1,46);
|
||
|
|
||
|
// Test unaligned read/write
|
||
|
bytes.setFloat(1,1.25);
|
||
|
bytes.setDouble(5,1.25);
|
||
|
|
||
|
if (bytes.get(0)!=46)
|
||
|
error("Bad byte 0");
|
||
|
|
||
|
if (bytes.getDouble(5)!=bytes.getFloat(1))
|
||
|
error("Bad byte read/write");
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public dynamic function getX() return x;
|
||
|
|
||
|
public static function testDynamicMember()
|
||
|
{
|
||
|
log("Test dynamic member");
|
||
|
var t = new Test();
|
||
|
if (t.getX()!=1)
|
||
|
error("Bad dynamic member function");
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
|
||
|
@:noDebug
|
||
|
public static function testNoDebug()
|
||
|
{
|
||
|
log("Test noDebug");
|
||
|
// Just testing to see it it compiles...
|
||
|
if ( null == new haxe.io.BytesBuffer() )
|
||
|
error("Bad alloc");
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
@:noDebug
|
||
|
public static function testNoDebugNoAlloc()
|
||
|
{
|
||
|
log("Test noDebug, no alloc");
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public static function testIntParsing()
|
||
|
{
|
||
|
log("Test int parsing");
|
||
|
var val = Std.parseInt('0x1');
|
||
|
if (val != 1)
|
||
|
{
|
||
|
error('parsed hex value was not 1, $val');
|
||
|
}
|
||
|
var val = Std.parseInt(' 0x1');
|
||
|
if (val != 1)
|
||
|
{
|
||
|
error('parsed hex value was not 1, $val');
|
||
|
}
|
||
|
var val = Std.parseInt('\t0x1');
|
||
|
if (val != 1)
|
||
|
{
|
||
|
error('parsed hex value was not 1, $val');
|
||
|
}
|
||
|
var val = Std.parseInt(' 0x');
|
||
|
if (val != 0)
|
||
|
{
|
||
|
error('parsed hex value was not 0, $val');
|
||
|
}
|
||
|
var val = Std.parseInt(' 0xyz');
|
||
|
if (val != 0)
|
||
|
{
|
||
|
error('parsed hex value was not 0, $val');
|
||
|
}
|
||
|
var val = Std.parseInt('-0x1');
|
||
|
if (val != -1)
|
||
|
{
|
||
|
error('parsed hex value was not 1, $val');
|
||
|
}
|
||
|
var val = Std.parseInt(' -0x1');
|
||
|
if (val != -1)
|
||
|
{
|
||
|
error('parsed hex value was not 1, $val');
|
||
|
}
|
||
|
var val = Std.parseInt('\t-0x1');
|
||
|
if (val != -1)
|
||
|
{
|
||
|
error('parsed hex value was not 1, $val');
|
||
|
}
|
||
|
var val = Std.parseInt(' -0x');
|
||
|
if (val != 0)
|
||
|
{
|
||
|
error('parsed hex value was not 0, $val');
|
||
|
}
|
||
|
var val = Std.parseInt(' -0xyz');
|
||
|
if (val != 0)
|
||
|
{
|
||
|
error('parsed hex value was not 0, $val');
|
||
|
}
|
||
|
var val = Std.parseInt(' 5');
|
||
|
if (val != 5)
|
||
|
{
|
||
|
error('parsed int value was not 5, $val');
|
||
|
}
|
||
|
var val = Std.parseInt(' \t\n5');
|
||
|
if (val != 5)
|
||
|
{
|
||
|
error('parsed int value was not 5, $val');
|
||
|
}
|
||
|
|
||
|
return ok();
|
||
|
}
|
||
|
|
||
|
public static function main()
|
||
|
{
|
||
|
var exitCode = 0;
|
||
|
if (Sys.args().length>0)
|
||
|
{
|
||
|
runAsProcess();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
exitCode |= testDate();
|
||
|
exitCode |= testCompress();
|
||
|
exitCode |= testRegexp();
|
||
|
exitCode |= testRegexpMixedUnicode();
|
||
|
exitCode |= testSqlite();
|
||
|
exitCode |= testMysql();
|
||
|
exitCode |= testRandom();
|
||
|
exitCode |= testFile();
|
||
|
exitCode |= testFileSystem();
|
||
|
exitCode |= testHost();
|
||
|
exitCode |= testSys();
|
||
|
exitCode |= testCommand();
|
||
|
exitCode |= testPoll();
|
||
|
exitCode |= testUdpSocket();
|
||
|
exitCode |= testSocket();
|
||
|
exitCode |= testThread();
|
||
|
exitCode |= testSsl();
|
||
|
exitCode |= testSerialization();
|
||
|
exitCode |= testFloatReads();
|
||
|
exitCode |= testDynamicMember();
|
||
|
exitCode |= testNoDebug();
|
||
|
exitCode |= testNoDebugNoAlloc();
|
||
|
exitCode |= testIntParsing();
|
||
|
|
||
|
if (exitCode!=0)
|
||
|
Sys.println("############# Errors running tests:\n " + errors.join("\n ") );
|
||
|
else
|
||
|
Sys.println("All tests passed.");
|
||
|
Sys.exit(exitCode);
|
||
|
}
|
||
|
}
|
||
|
}
|