Add the ability to run tests with several sets of VM flags

The test-option VMOptions that can be placed in .dart test files can now be specified several times like this:

// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write

For each time VMOptions is specified a seperate test will be bun with the specified flags.

Used this to run the tests that uses sockets with short read and writes. Fixed a number of bugs in both stream implementation and in tests revealed by this.

R=iposva@google.com, ngeoffray@google.com

Review URL: http://codereview.chromium.org//8226016

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@388 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
sgjesse@google.com 2011-10-13 10:14:31 +00:00
parent 4e62db0de3
commit 1cd5459f7b
10 changed files with 130 additions and 83 deletions

View file

@ -97,16 +97,19 @@ class SocketInputStream implements InputStream {
void readUntil(List<int> pattern, void callback(List<int> resultBuffer)) {
void doRead() {
List<int> newBuffer;
if (_buffer != null) {
newBuffer = _buffer;
} else {
int size = _socket.available();
List<int> buffer = new List<int>(size);
int result = _socket.readList(buffer, 0, size);
int available = _socket.available();
if (available > 0) {
List<int> buffer = new List<int>(available);
int result = _socket.readList(buffer, 0, buffer.length);
if (result > 0) {
// TODO(hpayer): Avoid copying of data before pattern matching.
newBuffer = _getBufferedData(buffer, result);
}
} else if (_buffer != null) {
newBuffer = _buffer;
} else {
_socket.setDataHandler(doRead);
return;
}
int index = _matchPattern(newBuffer, pattern, 0);

View file

@ -3,6 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
//
// Echo server test program to test socket stream read until functionality.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
main() {
EchoServerStreamReadUntilTest.testMain();
@ -146,12 +151,16 @@ class EchoServer extends Isolate {
for (int i = 0; i < MSGSIZE - 1; i++) {
Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]);
}
outputStream.write(buffer, 0, buffer.length, null);
inputStream.readUntil(PATTERN2, dataReceived);
void next() {
inputStream.readUntil(PATTERN2, dataReceived);
}
bool done = outputStream.write(buffer, 0, buffer.length, next);
if (done) {
next();
}
} else {
Expect.equals(1, buffer.length);
outputStream.write(buffer, 0, buffer.length, null);
inputStream.readUntil(PATTERN2, dataReceived);
}
}

View file

@ -3,6 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
//
// Echo server test program to test socket streams.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
class EchoServerStreamTest {

View file

@ -3,6 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
//
// Echo server test program for testing sockets.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
class EchoServerTest {
@ -34,6 +39,7 @@ class EchoServerGame {
}
void sendData() {
Socket _socket;
void messageHandler() {
@ -41,24 +47,16 @@ class EchoServerGame {
int bytesRead = 0;
void handleRead() {
if (_socket.available() > 0) {
bytesRead += _socket.readList(
bufferReceived, bytesRead, MSGSIZE - bytesRead);
}
bytesRead += _socket.readList(
bufferReceived, bytesRead, MSGSIZE - bytesRead);
if (bytesRead < MSGSIZE) {
/*
* We check every time the whole buffer to verify data integrity.
*/
// We check every time the whole buffer to verify data integrity.
for (int i = 0; i < bytesRead; i++) {
Expect.equals(FIRSTCHAR + i, bufferReceived[i]);
}
_socket.setDataHandler(handleRead);
}
else {
/*
* We check every time the whole buffer to verify data integrity.
*/
} else {
// We check every time the whole buffer to verify data integrity.
for (int i = 0; i < MSGSIZE; i++) {
Expect.equals(FIRSTCHAR + i, bufferReceived[i]);
}
@ -130,7 +128,6 @@ class EchoServerGame {
int _port;
ReceivePort _receivePort;
SendPort _sendPort;
Socket _socket;
List<int> _buffer;
int _messages;
}
@ -152,40 +149,37 @@ class EchoServer extends Isolate {
int bytesRead = 0;
void handleRead() {
if (_client.available() > 0) {
bytesRead += _client.readList(buffer, bytesRead, msgSize - bytesRead);
}
if (bytesRead < msgSize) {
/*
* We check every time the whole buffer to verify data integrity.
*/
for (int i = 0; i < bytesRead; i++) {
Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]);
}
_client.setDataHandler(handleRead);
}
else {
/*
* We check every time the whole buffer to verify data integrity.
*/
for (int i = 0; i < msgSize; i++) {
Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]);
}
void writeMessage() {
int bytesWritten = 0;
void handleWrite() {
bytesWritten += _client.writeList(
buffer, bytesWritten, msgSize - bytesWritten);
if (bytesWritten < msgSize) {
_client.setWriteHandler(handleWrite);
}
int read = _client.readList(buffer, bytesRead, msgSize - bytesRead);
if (read > 0) {
bytesRead += read;
if (bytesRead < msgSize) {
// We check every time the whole buffer to verify data integrity.
for (int i = 0; i < bytesRead; i++) {
Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]);
}
handleWrite();
_client.setDataHandler(handleRead);
} else {
// We check every time the whole buffer to verify data integrity.
for (int i = 0; i < msgSize; i++) {
Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]);
}
void writeMessage() {
int bytesWritten = 0;
void handleWrite() {
int written = _client.writeList(
buffer, bytesWritten, msgSize - bytesWritten);
bytesWritten += written;
if (bytesWritten < msgSize) {
_client.setWriteHandler(handleWrite);
}
}
handleWrite();
}
writeMessage();
}
writeMessage();
}
}

View file

@ -3,6 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
//
// Process test program to test process communication.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
class ProcessStderrTest {
@ -32,7 +37,7 @@ class ProcessStderrTest {
process.close();
}
bool read = input.read(readBuffer, 0, BUFFERSIZE, readData);
bool read = input.read(readBuffer, 0, BUFFERSIZE, readData);
if (read) {
readData();
}

View file

@ -3,6 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
//
// Process test program to test process communication.
//
// VMOptions=
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
class ProcessStdoutTest {
@ -25,9 +30,7 @@ class ProcessStdoutTest {
List<int> readBuffer = new List<int>(BUFFERSIZE);
void dataWritten() {
print("data written");
void readData() {
print("data read");
for (int i = 0; i < BUFFERSIZE; i++) {
Expect.equals(buffer[i], readBuffer[i]);
}

View file

@ -106,8 +106,7 @@ main() {
# Patterns for matching test options in .dart files.
VM_OPTIONS_PATTERN = re.compile(r'// VMOptions=(.*)')
DART_OPTIONS_PATTERN = re.compile(r'// DartOptions=(.*)')
DART_OPTIONS_PATTERN = re.compile(r"// DartOptions=(.*)")
# Pattern for checking if the test is a web test.
DOM_IMPORT_PATTERN = re.compile(r'#import.*(dart:dom|html.dart).*\);',
@ -154,11 +153,7 @@ class Architecture(object):
self.test = test
self.build_root = utils.GetBuildRoot(OS_GUESS, self.mode, self.arch)
source = file(test).read()
self.vm_options = utils.ParseTestOptions(VM_OPTIONS_PATTERN,
source,
root_path)
if not self.vm_options: self.vm_options = []
self.vm_options = []
self.dart_options = utils.ParseTestOptions(DART_OPTIONS_PATTERN,
source,
root_path)

View file

@ -24,7 +24,7 @@ class Error(Exception):
class StandardTestCase(test.TestCase):
def __init__(self, context, path, filename, mode, arch):
def __init__(self, context, path, filename, mode, arch, vm_options = []):
super(StandardTestCase, self).__init__(context, path)
self.filename = filename
self.mode = mode
@ -34,6 +34,9 @@ class StandardTestCase(test.TestCase):
for flag in context.flags:
self.run_arch.vm_options.append(flag)
for flag in vm_options:
self.run_arch.vm_options.append(flag)
def IsNegative(self):
return self.GetName().endswith("NegativeTest")

View file

@ -20,6 +20,9 @@ from os.path import join, exists, basename
import utils
# Patterns for matching test options in .dart files.
VM_OPTIONS_PATTERN = re.compile(r"// VMOptions=(.*)")
class Error(Exception):
pass
@ -70,8 +73,20 @@ class StandardTestConfiguration(test.TestConfiguration):
tests.append(test_case.MultiTestCase(self.context,
test_path + [tag], test_source, kind, mode, arch))
else:
tests.append(test_case.StandardTestCase(self.context,
test_path, filename, mode, arch))
# Look for VM specified as comments in the source file. If
# several sets of VM options are specified create a separate
# test for each set.
source = file(filename).read()
vm_options_list = utils.ParseTestOptionsMultiple(VM_OPTIONS_PATTERN,
source,
test_path)
if vm_options_list:
for options in vm_options_list:
tests.append(test_case.StandardTestCase(self.context,
test_path, filename, mode, arch, options))
else:
tests.append(test_case.StandardTestCase(self.context,
test_path, filename, mode, arch))
return tests
def ListTests(self, current_path, path, mode, arch):
@ -169,7 +184,7 @@ class BrowserTestCase(test_case.StandardTestCase):
def IsBatchable(self):
return True
def Run(self):
command = self.run_arch.GetCompileCommand(self.fatal_static_type_errors)
if command != None:
@ -249,7 +264,7 @@ class CompilationTestConfiguration(test.TestConfiguration):
filename.append(f) # Remove .lib or .app suffix.
test_path = current_path + filename
test_dart_file = os.path.join(root, f)
if ((not self.Contains(path, test_path))
if ((not self.Contains(path, test_path))
or (not self.IsTest(test_dart_file))):
continue
tests.append(test_case.CompilationTestCase(test_path,

View file

@ -144,22 +144,36 @@ def GetBuildRoot(target_os, mode=None, arch=None):
return BUILD_ROOT[target_os]
def RewritePathSeparator(path, workspace):
# Paths in test files are always specified using '/'
# as the path separator. Replace with the actual
# path separator before use.
if ('/' in path):
split_path = path.split('/')
path = os.sep.join(split_path)
path = os.path.join(workspace, path)
if not os.path.exists(path):
raise Exception(path)
return path
def ParseTestOptions(pattern, source, workspace):
match = pattern.search(source)
# Options should be a single line in the test case no splits.
if match:
def rewrite(path, workspace):
# Paths in test files are always specified using '/'
# as the path separator. Replace with the actual
# path separator before use.
if ('/' in path):
split_path = path.split('/')
path = os.sep.join(split_path)
path = os.path.join(workspace, path)
if not os.path.exists(path):
raise Exception(path)
return path
return [rewrite(o, workspace) for o in match.group(1).split(' ')]
return [RewritePathSeparator(o, workspace) for o in match.group(1).split(' ')]
else:
return None
def ParseTestOptionsMultiple(pattern, source, workspace):
matches = pattern.findall(source)
if matches:
result = []
for match in matches:
if len(match) > 0:
result.append(
[RewritePathSeparator(o, workspace) for o in match.split(' ')]);
return result
else:
return None