Compare commits

...

2 Commits

Author SHA1 Message Date
Jarred Sumner
2dcf948934 [bun:test] Implement --isolate flag (first pass at this) 2023-05-24 02:09:21 -07:00
Jarred Sumner
c968fc447e Only add, don't remove 2023-05-24 02:08:44 -07:00
8 changed files with 61 additions and 5 deletions

View File

@@ -41,7 +41,7 @@ us_socket_context_t* ScriptExecutionContext::webSocketContextSSL()
us_bun_socket_context_options_t opts;
memset(&opts, 0, sizeof(us_bun_socket_context_options_t));
// adds root ca
opts.request_cert = true;
opts.request_cert = true;
// but do not reject unauthorized
opts.reject_unauthorized = false;
this->m_ssl_client_websockets_ctx = us_create_bun_socket_context(1, loop, sizeof(size_t), opts);
@@ -109,7 +109,7 @@ void ScriptExecutionContext::regenerateIdentifier()
Locker locker { allScriptExecutionContextsMapLock };
ASSERT(allScriptExecutionContextsMap().contains(m_identifier));
allScriptExecutionContextsMap().remove(m_identifier);
// allScriptExecutionContextsMap().remove(m_identifier);
m_identifier = ++lastUniqueIdentifier;
@@ -121,14 +121,14 @@ void ScriptExecutionContext::addToContextsMap()
{
Locker locker { allScriptExecutionContextsMapLock };
ASSERT(!allScriptExecutionContextsMap().contains(m_identifier));
allScriptExecutionContextsMap().add(m_identifier, this);
// allScriptExecutionContextsMap().add(m_identifier, this);
}
void ScriptExecutionContext::removeFromContextsMap()
{
Locker locker { allScriptExecutionContextsMapLock };
ASSERT(allScriptExecutionContextsMap().contains(m_identifier));
allScriptExecutionContextsMap().remove(m_identifier);
// allScriptExecutionContextsMap().remove(m_identifier);
}
}

View File

@@ -217,6 +217,7 @@ extern "C" void JSCInitialize(const char* envp[], size_t envc, void (*onCrash)(c
JSC::Options::useResizableArrayBuffer() = true;
JSC::Options::showPrivateScriptsInStackTraces() = true;
JSC::Options::useSetMethods() = true;
JSC::Options::useCodeCache() = true;
if (LIKELY(envc > 0)) {
while (envc--) {
@@ -423,6 +424,26 @@ const JSC::ClassInfo GlobalObject::s_info = { "GlobalObject"_s, &Base::s_info, n
extern "C" JSClassRef* Zig__getAPIGlobals(size_t* count);
extern "C" const JSC__JSValue* Zig__getAPIConstructors(size_t* count, JSC__JSGlobalObject*);
extern "C" Zig::GlobalObject* GlobalObject__createNewDefault(Zig::GlobalObject* currentDefault, Zig::GlobalObject* initialDefault)
{
auto& vm = currentDefault->vm();
auto* prototype = JSC::JSGlobalObject::create(vm, initialDefault->globalObjectStructure());
Zig::GlobalObject* newDefault = Zig::GlobalObject::create(vm, Zig::GlobalObject::createStructure(vm, prototype, jsNull()));
newDefault->setConsole(newDefault);
size_t count = 0;
JSClassRef* globalObjectClass = Zig__getAPIGlobals(&count);
if (count > 0) {
newDefault->installAPIGlobals(globalObjectClass, count, vm);
}
if (initialDefault != currentDefault) {
gcUnprotect(currentDefault);
}
return newDefault;
}
static JSGlobalObject* deriveShadowRealmGlobalObject(JSGlobalObject* globalObject)
{
auto& vm = globalObject->vm();
@@ -503,7 +524,6 @@ GlobalObject::~GlobalObject()
finalizer(toNapi(this), napiInstanceData, napiInstanceDataFinalizerHint);
}
delete crypto;
scriptExecutionContext()->removeFromContextsMap();
}

View File

@@ -362,6 +362,7 @@ pub const VirtualMachine = struct {
preload: []const string = &[_][]const u8{},
unhandled_pending_rejection_to_capture: ?*JSC.JSValue = null,
standalone_module_graph: ?*bun.StandaloneModuleGraph = null,
initial_global_object: *JSC.JSGlobalObject,
hot_reload: bun.CLI.Command.HotReload = .none,
@@ -683,6 +684,7 @@ pub const VirtualMachine = struct {
const is_first = !VirtualMachine.get().has_loaded_constructors;
if (is_first) {
VirtualMachine.get().global = globalObject;
VirtualMachine.get().initial_global_object = globalObject;
VirtualMachine.get().has_loaded_constructors = true;
}
@@ -746,6 +748,7 @@ pub const VirtualMachine = struct {
vm.* = VirtualMachine{
.global = undefined,
.initial_global_object = undefined,
.allocator = allocator,
.entry_point = ServerEntryPoint{},
.event_listeners = EventListenerMixin.Map.init(allocator),
@@ -813,6 +816,12 @@ pub const VirtualMachine = struct {
return vm;
}
extern fn GlobalObject__createNewDefault(*JSGlobalObject, *JSGlobalObject) *JSGlobalObject;
pub fn resetDefaultGlobalObject(this: *VirtualMachine) void {
this.global = GlobalObject__createNewDefault(this.global, this.initial_global_object);
this.event_loop.global = this.global;
}
pub fn init(
allocator: std.mem.Allocator,
_args: Api.TransformOptions,
@@ -843,6 +852,7 @@ pub const VirtualMachine = struct {
vm.* = VirtualMachine{
.global = undefined,
.initial_global_object = undefined,
.allocator = allocator,
.entry_point = ServerEntryPoint{},
.event_listeners = EventListenerMixin.Map.init(allocator),

View File

@@ -376,6 +376,7 @@ pub const TestRunner = struct {
test_timeout_timer: ?*bun.uws.Timer = null,
last_test_timeout_timer_duration: u32 = 0,
active_test_for_timeout: ?TestRunner.Test.ID = null,
isolate: bool = false,
global_callbacks: struct {
beforeAll: std.ArrayListUnmanaged(JSC.JSValue) = .{},

View File

@@ -211,6 +211,7 @@ pub const Arguments = struct {
// TODO: update test completions
const test_only_params = [_]ParamType{
clap.parseParam("--isolate Create a new global for each test file") catch unreachable,
clap.parseParam("--timeout <NUMBER> Set the per-test timeout in milliseconds, default is 5000.") catch unreachable,
clap.parseParam("--update-snapshots Update snapshot files") catch unreachable,
clap.parseParam("--rerun-each <NUMBER> Re-run each test file <NUMBER> times, helps catch certain bugs") catch unreachable,
@@ -380,6 +381,8 @@ pub const Arguments = struct {
};
}
}
ctx.test_options.isolate = args.flag("--isolate");
ctx.test_options.update_snapshots = args.flag("--update-snapshots");
if (args.option("--rerun-each")) |repeat_count| {
if (repeat_count.len > 0) {
@@ -916,6 +919,7 @@ pub const Command = struct {
default_timeout_ms: u32 = 5 * std.time.ms_per_s,
update_snapshots: bool = false,
repeat_count: u32 = 0,
isolate: bool = false,
};
pub const Context = struct {

View File

@@ -436,6 +436,7 @@ pub const TestCommand = struct {
reporter.repeat_count = @max(ctx.test_options.repeat_count, 1);
reporter.jest.callback = &reporter.callback;
jest.Jest.runner = &reporter.jest;
reporter.jest.isolate = ctx.test_options.isolate;
js_ast.Expr.Data.Store.create(default_allocator);
js_ast.Stmt.Data.Store.create(default_allocator);
@@ -721,8 +722,15 @@ pub const TestCommand = struct {
vm.main_hash = @truncate(u32, bun.hash(resolution.path_pair.primary.text));
var repeat_count = reporter.repeat_count;
var repeat_index: u32 = 0;
const original_preload_len = vm.preload.len;
while (repeat_index < repeat_count) : (repeat_index += 1) {
var promise = try vm.loadEntryPoint(resolution.path_pair.primary.text);
defer {
if (reporter.jest.isolate) {
vm.preload.len = original_preload_len;
vm.resetDefaultGlobalObject();
}
}
switch (promise.status(vm.global.vm())) {
.Rejected => {
@@ -772,6 +780,7 @@ pub const TestCommand = struct {
prev_unhandled_count = vm.unhandled_error_counter;
}
}
switch (vm.aggressive_garbage_collection) {
.none => {},
.mild => {

View File

@@ -0,0 +1,6 @@
import { test, expect } from "bun:test";
test("Object.foo", () => {
expect(Object.foo).toBeUndefined();
Object.bar = false;
});

View File

@@ -0,0 +1,6 @@
import { test, expect } from "bun:test";
test("Object.foo", () => {
Object.foo = true;
expect(Object.bar).toBeUndefined();
});