Revert "[wasm] Add a new wasm-js testsuite to run js-api tests"
This reverts commit a12203c64b
.
Reason for revert: Breaks isolate_tests
https://ci.chromium.org/p/v8/builders/luci.v8.ci/V8%20Linux%20-%20builder/36777
Original change's description:
> [wasm] Add a new wasm-js testsuite to run js-api tests
>
> These changes were necessary to run with the new style of jsapi tests
> introduced in https://github.com/WebAssembly/spec/pull/883.
>
> Change-Id: I4629dd48d595ed97ed0607dec9e7d9808c706a7e
> Reviewed-on: https://chromium-review.googlesource.com/c/1277724
> Commit-Queue: Ben Smith <binji@chromium.org>
> Reviewed-by: Andreas Haas <ahaas@chromium.org>
> Reviewed-by: Michael Achenbach <machenbach@chromium.org>
> Reviewed-by: Mathias Bynens <mathias@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#56745}
TBR=binji@chromium.org,machenbach@chromium.org,yangguo@chromium.org,ahaas@chromium.org,clemensh@chromium.org,mathias@chromium.org
Change-Id: I2edd0ca94cb5990322571879c81671fa835f3ecd
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/1286526
Reviewed-by: Bill Budge <bbudge@chromium.org>
Commit-Queue: Bill Budge <bbudge@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56746}
This commit is contained in:
parent
a12203c64b
commit
5c5dd02128
2
.gitignore
vendored
2
.gitignore
vendored
@ -52,7 +52,7 @@
|
||||
/test/mozilla/data
|
||||
/test/test262/data
|
||||
/test/test262/harness
|
||||
/test/wasm-js/data
|
||||
/test/wasm-js
|
||||
/test/wasm-spec-tests/tests
|
||||
/test/wasm-spec-tests/tests.tar.gz
|
||||
/third_party/*
|
||||
|
4
DEPS
4
DEPS
@ -84,8 +84,8 @@ deps = {
|
||||
Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + 'a245b955fe9cd620081ed267fae303c88d033fef',
|
||||
'v8/tools/luci-go':
|
||||
Var('chromium_url') + '/chromium/src/tools/luci-go.git' + '@' + '445d7c4b6a4f10e188edb395b132e3996b127691',
|
||||
'v8/test/wasm-js/data':
|
||||
Var('chromium_url') + '/external/github.com/WebAssembly/spec.git' + '@' + 'cf67a477d2d802329640ef4e6461e4c180d8f910',
|
||||
'v8/test/wasm-js':
|
||||
Var('chromium_url') + '/external/github.com/WebAssembly/spec.git' + '@' + 'db9cd40808a90ecc5f4a23e88fb375c8f60b8d52',
|
||||
}
|
||||
|
||||
recursedeps = [
|
||||
|
@ -16,7 +16,6 @@ group("gn_all") {
|
||||
"mozilla:v8_mozilla",
|
||||
"preparser:v8_preparser",
|
||||
"test262:v8_test262",
|
||||
"wasm-js:v8_wasm_js",
|
||||
"wasm-spec-tests:v8_wasm_spec_tests",
|
||||
"webkit:v8_webkit",
|
||||
]
|
||||
@ -81,7 +80,6 @@ group("v8_bot_default") {
|
||||
"mkgrokdump:mkgrokdump",
|
||||
"preparser:v8_preparser",
|
||||
"unittests:unittests",
|
||||
"wasm-js:v8_wasm_js",
|
||||
"wasm-spec-tests:v8_wasm_spec_tests",
|
||||
"webkit:v8_webkit",
|
||||
]
|
||||
@ -101,7 +99,6 @@ group("v8_default") {
|
||||
"mkgrokdump:mkgrokdump",
|
||||
"preparser:v8_preparser",
|
||||
"unittests:unittests",
|
||||
"wasm-js:v8_wasm_js",
|
||||
"wasm-spec-tests:v8_wasm_spec_tests",
|
||||
]
|
||||
}
|
||||
|
139
test/mjsunit/wasm/jsapi-harness.js
Normal file
139
test/mjsunit/wasm/jsapi-harness.js
Normal file
@ -0,0 +1,139 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// TODO(eholk): Once we have stable test IDs, use those as the key instead.
|
||||
// See https://github.com/WebAssembly/spec/issues/415
|
||||
//
|
||||
// Flags: --expose-wasm --allow-natives-syntax
|
||||
|
||||
const known_failures = {
|
||||
// Enter failing tests like follows:
|
||||
// "'WebAssembly.Instance.prototype.exports' accessor property":
|
||||
// 'https://bugs.chromium.org/p/v8/issues/detail?id=5507',
|
||||
};
|
||||
|
||||
let failures = [];
|
||||
let unexpected_successes = [];
|
||||
|
||||
let last_promise = new Promise((resolve, reject) => { resolve(); });
|
||||
|
||||
function test(func, description) {
|
||||
let maybeErr;
|
||||
try { func(); }
|
||||
catch(e) { maybeErr = e; }
|
||||
if (typeof maybeErr !== 'undefined') {
|
||||
var known = "";
|
||||
if (known_failures[description]) {
|
||||
known = " (known)";
|
||||
}
|
||||
print(`${description}: FAIL${known}. ${maybeErr}`);
|
||||
failures.push(description);
|
||||
} else {
|
||||
if (known_failures[description]) {
|
||||
unexpected_successes.push(description);
|
||||
}
|
||||
print(`${description}: PASS.`);
|
||||
}
|
||||
}
|
||||
|
||||
function promise_test(func, description) {
|
||||
last_promise = last_promise.then(func)
|
||||
.then(_ => {
|
||||
if (known_failures[description]) {
|
||||
unexpected_successes.push(description);
|
||||
}
|
||||
print(`${description}: PASS.`);
|
||||
})
|
||||
.catch(err => {
|
||||
var known = "";
|
||||
if (known_failures[description]) {
|
||||
known = " (known)";
|
||||
}
|
||||
print(`${description}: FAIL${known}. ${err}`);
|
||||
failures.push(description);
|
||||
});
|
||||
}
|
||||
|
||||
let assert_true = assertEquals.bind(null, true);
|
||||
let assert_false = assertEquals.bind(null, false);
|
||||
|
||||
function same_value(x, y) {
|
||||
if (y !== y) {
|
||||
// NaN case
|
||||
return x!==x;
|
||||
}
|
||||
if (x === 0 && y === 0) {
|
||||
// Distinguish +0 and -0
|
||||
return 1/x === 1/y;
|
||||
}
|
||||
return x === y;
|
||||
}
|
||||
|
||||
let assert_equals = function(expected, found, description) {
|
||||
if (typeof found != typeof expected) {
|
||||
assert_true(false, "assert_equals", description,
|
||||
"expected (" + typeof expected + ") ${expected} but got (" +
|
||||
typeof found + ") ${found}", {expected:expected, found:found});
|
||||
}
|
||||
assert_true(same_value(found, expected), "assert_equals", description,
|
||||
"expected ${expected} but got ${found}",
|
||||
{expected:expected, found:found});
|
||||
}
|
||||
|
||||
let assert_not_equals = function(expected, found, description) {
|
||||
assert_true(!same_value(found, expected), "assert_not_equals", description,
|
||||
"got disallowed value ${found}", {found:found});
|
||||
}
|
||||
|
||||
function assert_unreached(description) {
|
||||
throw new Error(`unreachable:\n${description}`);
|
||||
}
|
||||
|
||||
function assertErrorMessage(f, ctor, test) {
|
||||
try { f(); }
|
||||
catch (e) {
|
||||
assert_true(e instanceof ctor, "expected exception " + ctor.name + ", got " + e);
|
||||
return;
|
||||
}
|
||||
assert_true(false, "expected exception " + ctor.name + ", no exception thrown");
|
||||
};
|
||||
|
||||
load("test/wasm-js/test/harness/wasm-constants.js");
|
||||
load("test/wasm-js/test/harness/wasm-module-builder.js");
|
||||
load("test/wasm-js/test/js-api/jsapi.js");
|
||||
|
||||
assertPromiseResult(last_promise, _ => {
|
||||
if (failures.length > 0) {
|
||||
let unexpected = false;
|
||||
print("Some tests FAILED:");
|
||||
for (let i in failures) {
|
||||
if (known_failures[failures[i]]) {
|
||||
print(` ${failures[i]} [KNOWN: ${known_failures[failures[i]]}]`);
|
||||
} else {
|
||||
print(` ${failures[i]}`);
|
||||
unexpected = true;
|
||||
}
|
||||
}
|
||||
if (unexpected_successes.length > 0) {
|
||||
unexpected = true;
|
||||
print("");
|
||||
print("Unexpected successes:");
|
||||
for(let i in unexpected_successes) {
|
||||
print(` ${unexpected_successes[i]}`);
|
||||
}
|
||||
print("Some tests SUCCEEDED but were known failures. If you've fixed " +
|
||||
"the bug, please remove the test from the known failures list.")
|
||||
}
|
||||
if (unexpected) {
|
||||
print("\n");
|
||||
print(" #############################################################");
|
||||
print(" # #");
|
||||
print(" # Unexpected outcome. Did you forget to run 'gclient sync'? #");
|
||||
print(" # #");
|
||||
print(" #############################################################");
|
||||
print("\n");
|
||||
assertUnreachable("Unexpected outcome");
|
||||
}
|
||||
}
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
# Copyright 2018 the V8 project authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
group("v8_wasm_js") {
|
||||
testonly = true
|
||||
|
||||
data_deps = [
|
||||
"../..:d8",
|
||||
"../../tools:v8_testrunner",
|
||||
]
|
||||
|
||||
data = [
|
||||
"./",
|
||||
"../mjsunit/mjsunit.js",
|
||||
]
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
W3C 3-clause BSD License
|
||||
|
||||
http://www.w3.org/Consortium/Legal/2008/03-bsd-license.html
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of works must retain the original copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the original copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the W3C nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this work without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,74 +0,0 @@
|
||||
# Copyright 2018 the V8 project authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from testrunner.local import testsuite
|
||||
from testrunner.objects import testcase
|
||||
|
||||
ANY_JS = ".any.js"
|
||||
WPT_ROOT = "/wasm/jsapi/"
|
||||
META_SCRIPT_REGEXP = re.compile(r"META:\s*script=(.*)")
|
||||
|
||||
class TestSuite(testsuite.TestSuite):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestSuite, self).__init__(*args, **kwargs)
|
||||
self.testroot = os.path.join(self.root, "data", "test", "js-api")
|
||||
self.mjsunit_js = os.path.join(os.path.dirname(self.root), "mjsunit",
|
||||
"mjsunit.js")
|
||||
|
||||
def ListTests(self):
|
||||
tests = []
|
||||
for dirname, dirs, files in os.walk(self.testroot):
|
||||
for dotted in [x for x in dirs if x.startswith(".")]:
|
||||
dirs.remove(dotted)
|
||||
dirs.sort()
|
||||
files.sort()
|
||||
for filename in files:
|
||||
if (filename.endswith(ANY_JS)):
|
||||
fullpath = os.path.join(dirname, filename)
|
||||
relpath = fullpath[len(self.testroot) + 1 : -len(ANY_JS)]
|
||||
testname = relpath.replace(os.path.sep, "/")
|
||||
test = self._create_test(testname)
|
||||
tests.append(test)
|
||||
return tests
|
||||
|
||||
def _test_class(self):
|
||||
return TestCase
|
||||
|
||||
|
||||
class TestCase(testcase.D8TestCase):
|
||||
def _get_files_params(self):
|
||||
files = [os.path.join(self.suite.mjsunit_js),
|
||||
os.path.join(self.suite.root, "testharness.js")]
|
||||
|
||||
source = self.get_source()
|
||||
for script in META_SCRIPT_REGEXP.findall(source):
|
||||
if script.startswith(WPT_ROOT):
|
||||
# Matched an absolute path, strip the root and replace it with our
|
||||
# local root.
|
||||
script = os.path.join(self.suite.testroot, script[len(WPT_ROOT):])
|
||||
elif not script.startswith("/"):
|
||||
# Matched a relative path, prepend this test's directory.
|
||||
thisdir = os.path.dirname(self._get_source_path())
|
||||
script = os.path.join(thisdir, script)
|
||||
else:
|
||||
raise Exception("Unexpected absolute path for script: \"%s\"" % script);
|
||||
|
||||
files.append(script)
|
||||
|
||||
files.extend([
|
||||
self._get_source_path(),
|
||||
os.path.join(self.suite.root, "testharness-after.js")
|
||||
])
|
||||
return files
|
||||
|
||||
def _get_source_path(self):
|
||||
# All tests are named `path/name.any.js`
|
||||
return os.path.join(self.suite.testroot, self.path + ANY_JS)
|
||||
|
||||
|
||||
def GetSuite(*args, **kwargs):
|
||||
return TestSuite(*args, **kwargs)
|
@ -1,16 +0,0 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Uses lastPromise defined in testharness.js
|
||||
|
||||
assertPromiseResult(lastPromise, _ => {
|
||||
if (failures.length > 0) {
|
||||
let message = 'Some tests FAILED:\n';
|
||||
for (const failure of failures) {
|
||||
message += ` ${failure}\n`;
|
||||
}
|
||||
|
||||
failWithMessage(message);
|
||||
}
|
||||
});
|
@ -1,142 +0,0 @@
|
||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Implementations of some functions from testharness.js
|
||||
// See https://github.com/web-platform-tests/wpt/blob/master/resources/testharness.js
|
||||
// Licensed as follows:
|
||||
//
|
||||
// Distributed under both the W3C Test Suite License [1] and the W3C
|
||||
// 3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
|
||||
// policies and contribution forms [3].
|
||||
// [1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
|
||||
// [2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
|
||||
// [3] http://www.w3.org/2004/10/27-testcases
|
||||
|
||||
const failures = [];
|
||||
|
||||
let lastPromise = Promise.resolve();
|
||||
|
||||
function test(func, description) {
|
||||
let maybeErr;
|
||||
try { func({unreached_func: assert_unreached}); }
|
||||
catch(e) { maybeErr = e; }
|
||||
if (typeof maybeErr !== 'undefined') {
|
||||
console.log(`${description}: FAIL. ${maybeErr}`);
|
||||
failures.push(description);
|
||||
} else {
|
||||
console.log(`${description}: PASS.`);
|
||||
}
|
||||
}
|
||||
|
||||
function promise_test(func, description) {
|
||||
lastPromise = lastPromise.then(func)
|
||||
.then(_ => {
|
||||
console.log(`${description}: PASS.`);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`${description}: FAIL. ${err}`);
|
||||
failures.push(description);
|
||||
});
|
||||
}
|
||||
|
||||
const assert_true = assertEquals.bind(null, true);
|
||||
const assert_false = assertEquals.bind(null, false);
|
||||
|
||||
function same_value(x, y) {
|
||||
if (y !== y) {
|
||||
// NaN case
|
||||
return x!==x;
|
||||
}
|
||||
if (x === 0 && y === 0) {
|
||||
// Distinguish +0 and -0
|
||||
return 1/x === 1/y;
|
||||
}
|
||||
return x === y;
|
||||
}
|
||||
|
||||
function assert_equals(expected, found, description) {
|
||||
if (typeof found != typeof expected) {
|
||||
assert_true(false, "assert_equals", description,
|
||||
"expected (" + typeof expected + ") ${expected} but got (" +
|
||||
typeof found + ") ${found}", {expected:expected, found:found});
|
||||
}
|
||||
assert_true(same_value(found, expected), "assert_equals", description,
|
||||
"expected ${expected} but got ${found}",
|
||||
{expected:expected, found:found});
|
||||
}
|
||||
|
||||
function assert_not_equals(expected, found, description) {
|
||||
assert_true(!same_value(found, expected), "assert_not_equals", description,
|
||||
"got disallowed value ${found}", {found:found});
|
||||
}
|
||||
|
||||
function assert_array_equals(actual, expected, description) {
|
||||
assert_true(
|
||||
typeof actual === 'object' && actual !== null && 'length' in actual,
|
||||
'assert_array_equals', description, 'value is ${actual}, expected array',
|
||||
{actual: actual});
|
||||
assert_true(
|
||||
actual.length === expected.length, 'assert_array_equals', description,
|
||||
'lengths differ, expected ${expected} got ${actual}',
|
||||
{expected: expected.length, actual: actual.length});
|
||||
|
||||
for (let i = 0; i < actual.length; i++) {
|
||||
assert_true(
|
||||
actual.hasOwnProperty(i) === expected.hasOwnProperty(i),
|
||||
'assert_array_equals', description,
|
||||
'property ${i}, property expected to be ${expected} but was ${actual}',
|
||||
{
|
||||
i: i,
|
||||
expected: expected.hasOwnProperty(i) ? 'present' : 'missing',
|
||||
actual: actual.hasOwnProperty(i) ? 'present' : 'missing'
|
||||
});
|
||||
assert_true(
|
||||
same_value(expected[i], actual[i]), 'assert_array_equals', description,
|
||||
'property ${i}, expected ${expected} but got ${actual}',
|
||||
{i: i, expected: expected[i], actual: actual[i]});
|
||||
}
|
||||
}
|
||||
|
||||
function assert_unreached(description) {
|
||||
throw new Error(`unreachable:\n${description}`);
|
||||
}
|
||||
|
||||
function format_value(s) {
|
||||
// TODO
|
||||
try {
|
||||
return String(s);
|
||||
} catch(e) {
|
||||
return `<String(e) for type ${typeof(e)} threw>`;
|
||||
}
|
||||
}
|
||||
|
||||
function promise_rejects(test, expected, promise, description) {
|
||||
return promise
|
||||
.then(() => assert_unreached('Should have rejected: ' + description))
|
||||
.catch(function(e) {
|
||||
assert_throws(expected, function() {
|
||||
throw e;
|
||||
}, description);
|
||||
});
|
||||
}
|
||||
|
||||
function assert_class_string(object, class_string, description) {
|
||||
assert_equals(
|
||||
{}.toString.call(object), '[object ' + class_string + ']', description);
|
||||
}
|
||||
|
||||
function assert_throws(code, func, description) {
|
||||
try {
|
||||
func();
|
||||
} catch (e) {
|
||||
assert_true(e.name === code.name, "expected exception " + code.name + ", got " + e.name);
|
||||
return;
|
||||
}
|
||||
assert_true(false, "expected exception " + code.name + ", no exception thrown");
|
||||
}
|
||||
|
||||
function setup(func) {
|
||||
// TODO need to do anything fancier here?
|
||||
func();
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
# Copyright 2018 the V8 project authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
[
|
||||
[ALWAYS, {
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=8319
|
||||
'interface': [FAIL],
|
||||
'memory/grow': [FAIL],
|
||||
'memory/constructor': [FAIL],
|
||||
'table/grow': [FAIL],
|
||||
'table/constructor': [FAIL],
|
||||
'table/get-set': [FAIL],
|
||||
'module/customSections': [FAIL],
|
||||
'global/constructor': [FAIL],
|
||||
'global/value-get-set': [FAIL],
|
||||
}] # ALWAYS
|
||||
]
|
@ -51,7 +51,6 @@ TEST_MAP = {
|
||||
"inspector",
|
||||
"webkit",
|
||||
"mkgrokdump",
|
||||
"wasm-js",
|
||||
"fuzzer",
|
||||
"message",
|
||||
"preparser",
|
||||
@ -66,7 +65,6 @@ TEST_MAP = {
|
||||
"wasm-spec-tests",
|
||||
"inspector",
|
||||
"mkgrokdump",
|
||||
"wasm-js",
|
||||
"fuzzer",
|
||||
"message",
|
||||
"preparser",
|
||||
|
@ -27,16 +27,16 @@ mkdir ${SPEC_TEST_DIR}/tmp
|
||||
|
||||
./tools/dev/gm.py x64.release d8
|
||||
|
||||
cd ${V8_DIR}/test/wasm-js/data/interpreter
|
||||
cd ${V8_DIR}/test/wasm-js/interpreter
|
||||
|
||||
# The next step requires that ocaml is installed. See the README.md in
|
||||
# ${V8_DIR}/test/wasm-js/data/interpreter/.
|
||||
# ${V8_DIR}/test/wasm-js/interpreter/.
|
||||
make clean all
|
||||
|
||||
cd ${V8_DIR}/test/wasm-js/data/test/core
|
||||
cd ${V8_DIR}/test/wasm-js/test/core
|
||||
|
||||
|
||||
./run.py --wasm ${V8_DIR}/test/wasm-js/data/interpreter/wasm --js ${V8_DIR}/out/x64.release/d8 --out ${SPEC_TEST_DIR}/tmp
|
||||
./run.py --wasm ${V8_DIR}/test/wasm-js/interpreter/wasm --js ${V8_DIR}/out/x64.release/d8 --out ${SPEC_TEST_DIR}/tmp
|
||||
cp ${SPEC_TEST_DIR}/tmp/*.js ${SPEC_TEST_DIR}/tests/
|
||||
rm -rf ${SPEC_TEST_DIR}/tmp
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user