-
-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: Isolated testing and SentryOptions
tests
#80
base: main
Are you sure you want to change the base?
Changes from 29 commits
c182831
5a8bc3a
301fa62
f8da579
42fd616
123ffa0
c3f284f
5833894
506d197
04a318f
abbccba
8bbd306
aa4becd
310738f
71ec692
4c57ef9
1e88cd5
8e69de8
17ddc4f
31f9f2a
cd2aec6
0930fe4
6348c2c
9cee1f0
e1288ec
ac3f7c3
72dfe31
45d021f
b96a863
5f00372
720e2b0
c60d7e3
6aefa3c
a108dfa
4209bc2
b4c3f79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
project/addons | ||
project/export_presets.cfg | ||
project/.vscode | ||
project/reports | ||
|
||
src/sdk_version.gen.h | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,9 @@ func _configure(options: SentryOptions) -> void: | |
options.before_send = _before_send | ||
options.on_crash = _on_crash | ||
|
||
# Unit testing hooks (if you're exploring the demo project, pretend the following line doesn't exist). | ||
TestingConfiguration.configure_options(options) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Allowing unit tests to hook into our configuration script. I call such tests isolated, as they need to be executed separately from other similar tests. There is a new script that automates running them in a batch. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: This would break if the demo project were shipped without unit test files, which is how we currently do it. |
||
|
||
|
||
## before_send callback example | ||
func _before_send(ev: SentryEvent) -> SentryEvent: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
class_name TestingConfiguration | ||
extends RefCounted | ||
|
||
|
||
## Detects whether an isolated test suite is running and calls its static `configure_options()` method. | ||
## - Since SentryOptions can be configured only once, such test suites must be executed separately. | ||
## - This method is called from "example_configuration.gd". | ||
static func configure_options(options: SentryOptions): | ||
var args: PackedStringArray = OS.get_cmdline_args() | ||
var idx := args.find("-a") | ||
if idx == -1 or args.size() == idx + 1: | ||
return | ||
var path := "res://" + args[idx + 1] | ||
if not path.ends_with(".gd"): | ||
return | ||
if not FileAccess.file_exists(path): | ||
return | ||
var scr: GDScript = load(path) | ||
if scr.has_method(&"configure_options"): | ||
scr.call(&"configure_options", options) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
extends GdUnitTestSuite | ||
## Test "events_per_frame" error logger limit. | ||
|
||
|
||
signal callback_processed | ||
|
||
var _num_events: int = 0 | ||
|
||
|
||
static func configure_options(options: SentryOptions) -> void: | ||
# Only one error is allowed to be logged as event per processed frame. | ||
options.error_logger_limits.events_per_frame = 1 | ||
# Make sure other limits are not interfering. | ||
options.error_logger_limits.repeated_error_window_ms = 0 | ||
options.error_logger_limits.throttle_events = 88 | ||
|
||
|
||
func before_test() -> void: | ||
SentrySDK._set_before_send(_before_send) | ||
|
||
|
||
func _before_send(_ev: SentryEvent) -> SentryEvent: | ||
_num_events += 1 | ||
callback_processed.emit() | ||
return null | ||
|
||
|
||
## Only one error should be logged within 1 processed frame. | ||
func test_events_per_frame_limit() -> void: | ||
push_error("dummy-error") | ||
push_error("dummy-error") | ||
push_error("dummy-error") | ||
assert_signal(self).is_emitted("callback_processed") | ||
limbonaut marked this conversation as resolved.
Show resolved
Hide resolved
|
||
await get_tree().create_timer(0.1).timeout | ||
assert_int(_num_events).is_equal(1) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
extends GdUnitTestSuite | ||
## Test "repeated_error_window_ms" error logger limit. | ||
|
||
|
||
signal callback_processed | ||
|
||
var _num_events: int = 0 | ||
|
||
|
||
static func configure_options(options: SentryOptions) -> void: | ||
# Ignore duplicate errors within 1 second window. | ||
options.error_logger_limits.repeated_error_window_ms = 1000 | ||
# Make sure other limits are not interfering. | ||
options.error_logger_limits.events_per_frame = 88 | ||
options.error_logger_limits.throttle_events = 88 | ||
|
||
|
||
func before_test() -> void: | ||
SentrySDK._set_before_send(_before_send) | ||
|
||
|
||
func _before_send(_ev: SentryEvent) -> SentryEvent: | ||
_num_events += 1 | ||
callback_processed.emit() | ||
return null | ||
|
||
|
||
## Only one error should be logged within 1 second time window, and another one after 1 second passes. | ||
func test_repeating_error_window_limit() -> void: | ||
push_error("dummy-error") | ||
push_error("dummy-error") | ||
await assert_signal(self).is_emitted("callback_processed") | ||
assert_int(_num_events).is_equal(1) | ||
|
||
# Wait for 1 second window to expire. | ||
await get_tree().create_timer(1.0).timeout | ||
|
||
push_error("dummy-error") | ||
push_error("dummy-error") | ||
await assert_signal(self).is_emitted("callback_processed") | ||
assert_int(_num_events).is_equal(2) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
extends GdUnitTestSuite | ||
## Test error logger throttling limits. | ||
|
||
|
||
signal callback_processed | ||
|
||
var _num_events: int = 0 | ||
|
||
|
||
static func configure_options(options: SentryOptions) -> void: | ||
# Allow only two errors to be logged as events within 1 second time window. | ||
options.error_logger_limits.throttle_events = 2 | ||
options.error_logger_limits.throttle_window_ms = 1000 | ||
# Make sure other limits are not interfering. | ||
options.error_logger_limits.events_per_frame = 88 | ||
options.error_logger_limits.repeated_error_window_ms = 0 | ||
|
||
|
||
func before_test() -> void: | ||
SentrySDK._set_before_send(_before_send) | ||
|
||
|
||
func _before_send(_ev: SentryEvent) -> SentryEvent: | ||
_num_events += 1 | ||
callback_processed.emit() | ||
return null | ||
|
||
|
||
## Only two errors should be logged within the assigned time window. | ||
func test_throttling_limits() -> void: | ||
push_error("dummy-error") | ||
push_error("dummy-error") | ||
push_error("dummy-error") | ||
await assert_signal(self).is_emitted("callback_processed") | ||
await assert_signal(self).is_emitted("callback_processed") | ||
await get_tree().create_timer(0.1).timeout | ||
assert_int(_num_events).is_equal(2) | ||
|
||
# Wait for throttling window to expire. | ||
await get_tree().create_timer(1.0).timeout | ||
|
||
push_error("dummy-error") | ||
push_error("dummy-error") | ||
push_error("dummy-error") | ||
await assert_signal(self).is_emitted("callback_processed") | ||
await assert_signal(self).is_emitted("callback_processed") | ||
await get_tree().create_timer(0.1).timeout | ||
assert_int(_num_events).is_equal(4) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
extends GdUnitTestSuite | ||
## Events should not be logged for errors when the logger is disabled. | ||
|
||
|
||
signal callback_processed | ||
|
||
var _num_events: int = 0 | ||
|
||
|
||
static func configure_options(options: SentryOptions) -> void: | ||
options.error_logger_enabled = false | ||
|
||
# Make sure other limits are not interfering. | ||
options.error_logger_limits.events_per_frame = 88 | ||
options.error_logger_limits.throttle_events = 88 | ||
options.error_logger_limits.repeated_error_window_ms = 0 | ||
options.error_logger_limits.throttle_window_ms = 0 | ||
|
||
|
||
func before_test() -> void: | ||
SentrySDK._set_before_send(_before_send) | ||
|
||
|
||
func _before_send(_ev: SentryEvent) -> SentryEvent: | ||
_num_events += 1 | ||
callback_processed.emit() | ||
return null | ||
|
||
|
||
func test_event_and_breadcrumb_masks() -> void: | ||
push_error("dummy-error") | ||
push_warning("dummy-warning") | ||
|
||
await assert_signal(self).is_not_emitted("callback_processed") | ||
|
||
assert_int(_num_events).is_equal(0) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
extends GdUnitTestSuite | ||
## Events and breadcrumbs should be logged when "error_logger_event_mask" and | ||
## "error_logger_breadcrumb_mask" are configured to include all categories. | ||
|
||
|
||
signal callback_processed | ||
|
||
var _num_events: int = 0 | ||
|
||
|
||
static func configure_options(options: SentryOptions) -> void: | ||
var mask = SentryOptions.MASK_ERROR | SentryOptions.MASK_SCRIPT | SentryOptions.MASK_SHADER | SentryOptions.MASK_WARNING | ||
options.error_logger_event_mask = mask | ||
options.error_logger_breadcrumb_mask = mask | ||
|
||
# Make sure other limits are not interfering. | ||
options.error_logger_limits.events_per_frame = 88 | ||
options.error_logger_limits.throttle_events = 88 | ||
options.error_logger_limits.repeated_error_window_ms = 0 | ||
options.error_logger_limits.throttle_window_ms = 0 | ||
|
||
|
||
func before_test() -> void: | ||
SentrySDK._set_before_send(_before_send) | ||
|
||
|
||
func _before_send(_ev: SentryEvent) -> SentryEvent: | ||
_num_events += 1 | ||
callback_processed.emit() | ||
return null | ||
|
||
|
||
## Both events or breadcrumbs should be logged for error and warning. | ||
## TODO: can't verify breadcrumbs yet, maybe later. | ||
func test_event_and_breadcrumb_masks() -> void: | ||
push_error("dummy-error") | ||
push_warning("dummy-warning") | ||
await assert_signal(self).is_emitted("callback_processed") | ||
|
||
await get_tree().create_timer(0.1).timeout | ||
assert_int(_num_events).is_equal(2) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
extends GdUnitTestSuite | ||
## Events and breadcrumbs should not be logged when both "error_logger_event_mask" | ||
## and "error_logger_breadcrumb_mask" are set to zero. | ||
|
||
|
||
signal callback_processed | ||
|
||
var _num_events: int = 0 | ||
|
||
|
||
static func configure_options(options: SentryOptions) -> void: | ||
options.error_logger_event_mask = 0 | ||
options.error_logger_breadcrumb_mask = 0 | ||
|
||
|
||
func before_test() -> void: | ||
SentrySDK._set_before_send(_before_send) | ||
|
||
|
||
func _before_send(_ev: SentryEvent) -> SentryEvent: | ||
_num_events += 1 | ||
callback_processed.emit() | ||
return null | ||
|
||
|
||
## No events or breadcrumbs should be logged for errors. | ||
## TODO: can't verify breadcrumbs yet, maybe later. | ||
func test_event_and_breadcrumb_masks() -> void: | ||
push_error("dummy-error") | ||
push_warning("dummy-warning") | ||
await assert_signal(self).is_not_emitted("callback_processed") | ||
|
||
await get_tree().create_timer(0.1).timeout | ||
assert_int(_num_events).is_equal(0) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
extends GdUnitTestSuite | ||
## Verify that the options set in a configuration callback are correctly reflected in event objects. | ||
|
||
|
||
signal callback_processed | ||
|
||
|
||
static func configure_options(options: SentryOptions) -> void: | ||
options.release = "1.2.3" | ||
options.environment = "testing" | ||
|
||
|
||
func before_test() -> void: | ||
SentrySDK._set_before_send(_before_send) | ||
|
||
|
||
func _before_send(ev: SentryEvent) -> SentryEvent: | ||
assert_str(ev.release).is_equal("1.2.3") | ||
assert_str(ev.environment).is_equal("testing") | ||
callback_processed.emit() | ||
return null | ||
|
||
|
||
## Verify that the options are correctly propagated to event objects. | ||
func test_options_integrity() -> void: | ||
var ev := SentrySDK.create_event() | ||
SentrySDK.capture_event(ev) | ||
assert_signal(self).is_emitted("callback_processed") | ||
limbonaut marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For information, reports are created when unit tests are executed in the editor or from CLI.