feat: add bytes.indexOf, server.acceptBatch, server.pendingCount, stdin data callback, and coverage/valgrind make targets
Implement `bytesIndexOf` foreign function supporting optional start offset for searching byte sequences. Add `serverAcceptBatch` and `serverPendingCount` to net module for batch accepting connections and querying pending queue size. Refactor `stdinFileTimerCallback` to pass read bytes to Wren callback instead of null, with separate handling for EOF. Introduce `coverage_64bit` build config with gcov flags, plus `coverage`, `valgrind`, `clean-coverage`, and `publish` phony targets in Makefile. Fix memory leak in regex by nullifying freed pointers on allocation failure.
This commit is contained in:
+22
-6
@@ -27,6 +27,8 @@ parser.add_argument('--suffix', default='')
|
||||
parser.add_argument('suite', nargs='?')
|
||||
parser.add_argument('--skip-tests', action='store_true')
|
||||
parser.add_argument('--skip-examples', action='store_true')
|
||||
parser.add_argument('--valgrind', action='store_true',
|
||||
help='Run tests under valgrind')
|
||||
|
||||
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
@@ -150,10 +152,15 @@ class Test:
|
||||
return True
|
||||
|
||||
|
||||
def run(self, app, type):
|
||||
# Invoke wren and run the test.
|
||||
def run(self, app, type, valgrind=False):
|
||||
test_arg = self.path
|
||||
proc = Popen([app, test_arg], stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||
if valgrind:
|
||||
cmd = ['valgrind', '--leak-check=full', '--error-exitcode=99',
|
||||
'--suppressions=' + join(dirname(realpath(__file__)), 'valgrind.supp'),
|
||||
app, test_arg]
|
||||
else:
|
||||
cmd = [app, test_arg]
|
||||
proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||
|
||||
# If a test takes longer than five seconds, kill it.
|
||||
#
|
||||
@@ -173,12 +180,14 @@ class Test:
|
||||
if timed_out[0]:
|
||||
self.fail("Timed out.")
|
||||
else:
|
||||
self.validate(type == "example", proc.returncode, out, err)
|
||||
if valgrind and proc.returncode == 99:
|
||||
self.fail("Valgrind detected memory errors")
|
||||
self.validate(type == "example", proc.returncode, out, err, valgrind)
|
||||
finally:
|
||||
timer.cancel()
|
||||
|
||||
|
||||
def validate(self, is_example, exit_code, out, err):
|
||||
def validate(self, is_example, exit_code, out, err, valgrind=False):
|
||||
if self.compile_errors and self.runtime_error_message:
|
||||
self.fail("Test error: Cannot expect both compile and runtime errors.")
|
||||
return
|
||||
@@ -189,6 +198,13 @@ class Test:
|
||||
except:
|
||||
self.fail('Error decoding output.')
|
||||
|
||||
if valgrind:
|
||||
err_lines = []
|
||||
for line in err.split('\n'):
|
||||
if not line.startswith('==') and not line.startswith('--'):
|
||||
err_lines.append(line)
|
||||
err = '\n'.join(err_lines)
|
||||
|
||||
error_lines = err.split('\n')
|
||||
|
||||
# Validate that an expected runtime error occurred.
|
||||
@@ -376,7 +392,7 @@ def run_script(app, path, type):
|
||||
# It's a skipped or non-test file.
|
||||
return
|
||||
|
||||
test.run(app, type)
|
||||
test.run(app, type, args.valgrind)
|
||||
|
||||
# Display the results.
|
||||
if len(test.failures) == 0:
|
||||
|
||||
Reference in New Issue
Block a user