Update some things (#28)

This commit is contained in:
Rafał Mikrut 2021-02-23 19:12:20 +01:00 committed by GitHub
parent b52b5368a2
commit 7685576fe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 547 additions and 201 deletions

View File

@ -4,15 +4,15 @@
[sub_resource type="SpriteFrames" id=1] [sub_resource type="SpriteFrames" id=1]
animations = [ { animations = [ {
"frames": [ ExtResource( 5 ), ExtResource( 5 ), ExtResource( 5 ) ],
"loop": true,
"name": "New Anim",
"speed": 5.0
}, {
"frames": [ ExtResource( 5 ) ], "frames": [ ExtResource( 5 ) ],
"loop": true, "loop": true,
"name": "0", "name": "0",
"speed": 5.0 "speed": 5.0
}, {
"frames": [ ExtResource( 5 ), ExtResource( 5 ), ExtResource( 5 ) ],
"loop": true,
"name": "New Anim",
"speed": 5.0
} ] } ]
[sub_resource type="CapsuleShape2D" id=2] [sub_resource type="CapsuleShape2D" id=2]

View File

@ -8,16 +8,13 @@ var last_time : int
const PRINT_TIME_EVERY_MILISECONDS : int = 5000 const PRINT_TIME_EVERY_MILISECONDS : int = 5000
var time_to_print_next_time : int = PRINT_TIME_EVERY_MILISECONDS var time_to_print_next_time : int = PRINT_TIME_EVERY_MILISECONDS
var time_to_show: int = 15 * 1000 # How long test works in miliseconds var time_to_show: int = 25 * 1000 # How long test works in miliseconds
var time_for_each_step : int = -1 var time_for_each_step : int = -1
# Each scene runs alone # Each scene runs alone
const alone_steps : Array = [ const alone_steps : Array = [
"res://MainScenes/Control.tscn", "res://MainScenes/MainScenes.tscn",
"res://MainScenes/Node2D.tscn",
"res://MainScenes/Other.tscn",
"res://MainScenes/Spatial.tscn",
"res://Physics/2D/Physics2D.tscn", "res://Physics/2D/Physics2D.tscn",
"res://Physics/3D/Physics3D.tscn", "res://Physics/3D/Physics3D.tscn",
"res://Rendering/Lights2D/Lights2D.tscn", "res://Rendering/Lights2D/Lights2D.tscn",
@ -30,8 +27,8 @@ const alone_steps : Array = [
# This should be put regression scripts which needs to run only once # This should be put regression scripts which needs to run only once
const all_in_one : Array = [ const all_in_one : Array = [
"res://AIO/Operators/Operators.tscn", "res://AIO/Operators/Operators.tscn",
"res://AutomaticBugs/RealFunctionExecutor.tscn", "res://AutomaticBugs/FunctionExecutor.tscn",
#"res://AIO/AllNodes/ALL.tscn", #"res://AIO/AllNodes/ALL.tscn", # Take too much time - opens ~ 20 seconds in CI inside xvfb-run
] ]
func _init(): func _init():

View File

@ -1,6 +1,6 @@
extends Node extends Node
var function_exceptions = [ var function_exceptions : Array = [
# They exists without assigment like Class.method, because they may be a parent of other objects and children also should have disabled child.method, its children also etc. which is too much to do # They exists without assigment like Class.method, because they may be a parent of other objects and children also should have disabled child.method, its children also etc. which is too much to do
"align",# GH 45976 "align",# GH 45976
"_screen_pick_pressed",# GH 45977 "_screen_pick_pressed",# GH 45977
@ -37,47 +37,117 @@ var function_exceptions = [
"_edit_set_position", #GH 46018 "_edit_set_position", #GH 46018
"_edit_set_rect", #GH 46018 "_edit_set_rect", #GH 46018
"get", #GH 46019 "get", #GH 46019
"instance_has", #GH "instance_has", #GH 46020
"", #GH "_update_shader", #GH 46062
"", #GH "generate_tangents", #GH 46059
"", #GH "get_var", #GH 46096
"", #GH "force_drag", #GH 46114
"", #GH "set_script", #GH 46120
"getvar", #GH 46019
"get_available_chars", #GH 46118
"set_primary_interface", #GH 46180
"add_feed", #GH 46181
"open_midi_inputs", #GH 46183
"get_unix_time_from_datetime", #GH 46188
"set_icon", #GH 46189
"set_window_size", #GH 46187
"get_screen_size", #GH 46186
"get_screen_position", #GH 46185
"set_current_screen", #GH 46184
"build_capsule_planes", #GH
"build_cylinder_planes", #GH
"get_latin_keyboard_variant", #GH TODO Memory Leak
"add_feed", #GH
"poll", #GH - HTTP CLIENT
"make_atlas", #GH
"set_editor_hint", #GH
"", #GH "", #GH
"collide", #GH 46137
"collide_and_get_contacts", #GH 46137
"collide_with_motion", #GH 46137
"collide_with_motion_and_get_contacts", #GH 46137
# TODO is workaround for removing memory leak in Thread::start, should be fixed by GH 45618 # TODO Check this later
"start", "propagate_notification",
"notification",
# TODO Adds big spam when i>100 # TODO Adds big spam when i>100 - look for possiblity to
"add_sphere", "add_sphere",
# Spam when i~1000 - change to specific
"update_bitmask_region",
# Slow Function
"_update_sky",
# Undo/Redo function which doesn't provide enough information about types of objects, probably due vararg(variable size argument)
"add_do_method",
"add_undo_method",
# Do not save files and create files and folders # Do not save files and create files and folders
"pck_start",
"save", "save",
"save_png", "save_png",
"save_to_wav", "save_to_wav",
"save_to_file", "save_to_file",
"make_dir", "make_dir",
"make_dir_recursive", "make_dir_recursive",
"save_encrypted",
"save_encrypted_pass",
"dump_resources_to_file",
"dump_memory_to_file",
# This also allow to save files
"open",
"open_encrypted",
"open_encrypted_with_pass",
"open_compressed",
# Do not warp mouse # Do not warp mouse
"warp_mouse", "warp_mouse",
"warp_mouse_position", "warp_mouse_position",
# Looks like a bug in FuncRef, probably but not needed # OS
"call_func", "kill",
"shell_open",
"execute",
"delay_usec",
"delay_msec",
"alert", # Stupid alert window opens
# Godot Freeze # Godot Freeze
"wait_to_finish",
"accept_stream",
"connect_to_stream",
"discover", "discover",
"wait", "wait",
"register_text_enter",
"_create", # TODO Check
"set_gizmo", # Stupid function, needs as parameter an object which can't be instanced # TODO, create issue to hide it
# Spams Output
"print_tree",
"print_stray_nodes",
"print_tree_pretty",
"print_all_textures_by_size",
"print_all_resources",
"print_resources_in_use",
# Do not call other functions # Do not call other functions
"_call_function", "_call_function",
"call", "call",
"call_deferred", "call_deferred",
"callv",
# Looks like a bug in FuncRef, probably but not needed, because it call other functions
"call_func",
# Too dangerous, because add, mix and remove randomly nodes and objects # Too dangerous, because add, mix and remove randomly nodes and objects
"replace_by",
"create_instance",
"set_owner",
"set_root_node",
"instance",
"init_ref", "init_ref",
"reference", "reference",
"unreference", "unreference",
@ -85,39 +155,96 @@ var function_exceptions = [
"duplicate", "duplicate",
"queue_free", "queue_free",
"free", "free",
"print_tree",
"print_stray_nodes",
"print_tree_pretty",
"remove_and_skip", "remove_and_skip",
"remove_child", "remove_child",
"move_child", "move_child",
"raise", "raise",
"add_child", "add_child",
"add_child_below_node", "add_child_below_node",
]
# List of slow functions, which may frooze project
var slow_functions : Array = [
"interpolate_baked",
"get_baked_length",
"get_baked_points",
"get_closest_offset",
"get_closest_point", # Only Curve, but looks that a lot of other classes uses this
"get_baked_up_vectors",
"interpolate_baked_up_vector",
"tessellate",
"get_baked_tilts",
"set_enabled_inputs",
"grow_mask",
"force_update_transform",
# In 3d view some options are really slow, needs to be limited
"set_rings",
"set_amount", # Particles
# Just a little slow functions
"is_enabler_enabled",
"set_enabler",
"get_aabb",
"set_aabb",
"is_on_screen"
]
# Specific classes which are initialized in specific way e.g. var undo_redo = get_undo_redo() instead var undo_redo = UndoRedo.new()
var only_instance : Array = [
"UndoRedo",
"Object",
"JSONRPC",
"MainLoop",
"SceneTree",
"ARVRPositionalTracker",
]
var invalid_signals : Array = [
"multi_selected",
"item_collapsed",
"button_pressed",
"",
"",
"",
# Probably Vararg
"tween_step",
"tween_completed",
"tween_started",
"data_channel_received",
"",
]
var disabled_classes : Array = [
"ProjectSettings", # Don't mess with project settings, because they can broke entire your workflow
"EditorSettings", # Also don't mess with editor settings
"SceneTree", # Broke camera visibility
] ]
# Return all available classes to instance and test # Return all available classes to instance and test
func get_list_of_available_classes() -> Array: func get_list_of_available_classes() -> Array:
var debug_print : bool = false
var full_class_list : Array = Array(ClassDB.get_class_list()) var full_class_list : Array = Array(ClassDB.get_class_list())
var classes : Array = [] var classes : Array = []
full_class_list.sort() full_class_list.sort()
var c = 0 var c = 0
var rr = 0
for name_of_class in full_class_list: for name_of_class in full_class_list:
if name_of_class == "AudioServer": # Crash GH #45972 rr += 1
continue if name_of_class in disabled_classes:
if name_of_class == "NetworkedMultiplayerENet": # TODO - create leaked reference instance, look at it later
continue continue
if ClassDB.is_parent_class(name_of_class,"Node") or ClassDB.is_parent_class(name_of_class,"Reference"): # Only instance childrens of this if name_of_class.find("Server") != -1:
if debug_print: continue
print(name_of_class)
if ClassDB.can_instance(name_of_class): if !ClassDB.is_parent_class(name_of_class, "Node") && !ClassDB.is_parent_class(name_of_class, "Reference"):
classes.push_back(name_of_class) continue
c+= 1
else: if ClassDB.can_instance(name_of_class):
if debug_print: classes.push_back(name_of_class)
push_error("Failed to instance " + str(name_of_class) ) c+= 1
print(str(c) + " choosen classes from all " + str(full_class_list.size()) + " classes.") print(str(c) + " choosen classes from all " + str(full_class_list.size()) + " classes.")
return classes return classes

View File

@ -1,37 +1,31 @@
extends Node extends Node
var debug_print: bool = true
var add_to_tree: bool = true # Adds nodes to tree
var use_parent_methods: bool = false # Allows Node2D use Node methods etc. - it is a little slow option which rarely shows
var use_always_new_object: bool = true # Don't allow to "remeber" other function effects
func _ready() -> void: func _ready() -> void:
# NoiseTexture::_thread_done
# var aa = BoxShape.new()
# SurfaceTool.new().create_from(aa,0)
# Tree.new().get_column_width(0)
tests_all_functions() tests_all_functions()
# Test all functions
# TODO - Think about adding 'add_child', to test nodes in scene tree
# Test all functions which takes 0 arguments
func tests_all_functions() -> void: func tests_all_functions() -> void:
var debug_print : bool = false
var use_parent_methods : bool = false # Allows Node2D use Node methods etc. - it is a little slow option
var number_of_loops : int = 1 # Can be executed in multiple loops
var use_always_new_object : bool = true # Don't allow to "remeber" other function effects
# var sss = 0
for name_of_class in BasicData.get_list_of_available_classes(): for name_of_class in BasicData.get_list_of_available_classes():
if name_of_class.begins_with("_"): # TODO builtin classes like _Dictionary doesn't work properly in GDScript if name_of_class == "_OS": # Do not change size of window
continue continue
# sss += 1
# if sss != 220:
# continue
# Instance object to be able to execute on it specific functions and later delete to prevent memory leak if it is a Node # Instance object to be able to execute on it specific functions and later delete to prevent memory leak if it is a Node
var object : Object = ClassDB.instance(name_of_class) var object: Object = ClassDB.instance(name_of_class)
# if object is Node: assert(object != null) # This should be checked before when collectiong functions
# add_child(object) if add_to_tree:
assert(object != null) # This should be checked before when collectiong functions if object is Node:
var method_list : Array = ClassDB.class_get_method_list(name_of_class, !use_parent_methods) add_child(object)
var method_list: Array = ClassDB.class_get_method_list(name_of_class, ! use_parent_methods)
## Exception
for exception in BasicData.function_exceptions: for exception in BasicData.function_exceptions:
var index : int = -1 var index: int = -1
for method_index in range(method_list.size()): for method_index in range(method_list.size()):
if method_list[method_index]["name"] == exception: if method_list[method_index]["name"] == exception:
index = method_index index = method_index
@ -39,48 +33,53 @@ func tests_all_functions() -> void:
if index != -1: if index != -1:
method_list.remove(index) method_list.remove(index)
if debug_print:
print("############### CLASS ############### - " + name_of_class)
for _i in range(number_of_loops): for method_data in method_list:
for method_data in method_list: # Function is virtual, so we just skip it
# Function is virtual, so we just skip it if method_data["flags"] == method_data["flags"] | METHOD_FLAG_VIRTUAL:
if method_data["flags"] == method_data["flags"] | METHOD_FLAG_VIRTUAL: continue
continue
if debug_print: if debug_print:
print("##### - " + name_of_class) print(method_data["name"])
# print(method_data)
print(method_data["name"])
# print(method_data["args"])
var arguments : Array = return_for_all(method_data) var arguments: Array = return_for_all(method_data)
object.callv(method_data["name"], arguments) object.callv(method_data["name"], arguments)
for argument in arguments: for argument in arguments:
if argument is Node: assert(argument != null)
argument.queue_free() if argument is Node:
argument.queue_free()
elif argument is Object && ! (argument is Reference):
argument.free()
if use_always_new_object: if use_always_new_object:
if object is Node: assert(object != null)
object.queue_free() if object is Node:
object = ClassDB.instance(name_of_class) object.queue_free()
if object is Node: # Just prevent memory leak elif object is Object && ! (object is Reference):
object.free()
object = ClassDB.instance(name_of_class)
if object is Node: # Just prevent memory leak
object.queue_free() object.queue_free()
elif object is Object && ! (object is Reference):
object.free()
# TODO add option to generate random data or only basic data e.g. Vector2() instead Vector(2.52,525.2)
func return_for_all(method_data : Dictionary) -> Array: func return_for_all(method_data: Dictionary) -> Array:
var arguments_array : Array = [] var arguments_array: Array = []
ValueCreator.number = 10 ValueCreator.number = 10
ValueCreator.random = false ValueCreator.random = false
ValueCreator.should_be_always_valid = false
for argument in method_data["args"]: for argument in method_data["args"]:
# print(argument)
match argument.type: match argument.type:
TYPE_NIL: # Looks that this means VARIANT not null TYPE_NIL: # Looks that this means VARIANT not null
arguments_array.push_back(false) # TODO Add some randomization arguments_array.push_back(false) # TODO randomize this
# assert(false)
TYPE_MAX:
assert(false)
TYPE_AABB: TYPE_AABB:
arguments_array.push_back(ValueCreator.get_aabb()) arguments_array.push_back(ValueCreator.get_aabb())
TYPE_ARRAY: TYPE_ARRAY:
@ -102,7 +101,7 @@ func return_for_all(method_data : Dictionary) -> Array:
TYPE_NODE_PATH: TYPE_NODE_PATH:
arguments_array.push_back(ValueCreator.get_nodepath()) arguments_array.push_back(ValueCreator.get_nodepath())
TYPE_OBJECT: TYPE_OBJECT:
arguments_array.push_back(ValueCreator.get_object("TODO")) # Maybe add a proper type variable if needed arguments_array.push_back(ValueCreator.get_object(argument["class_name"]))
TYPE_PLANE: TYPE_PLANE:
arguments_array.push_back(ValueCreator.get_plane()) arguments_array.push_back(ValueCreator.get_plane())
TYPE_QUAT: TYPE_QUAT:
@ -134,8 +133,8 @@ func return_for_all(method_data : Dictionary) -> Array:
TYPE_VECTOR3_ARRAY: TYPE_VECTOR3_ARRAY:
arguments_array.push_back(ValueCreator.get_pool_vector3_array()) arguments_array.push_back(ValueCreator.get_pool_vector3_array())
_: _:
assert(false) # Missed some types, add it assert(false) # Missed some types, add it
# print("Parameters " + str(arguments_array)) if debug_print:
print("Parameters " + str(arguments_array))
return arguments_array return arguments_array

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://AutomaticBugs/FunctionExecutor.gd" type="Script" id=1]
[node name="FunctionExecutor" type="Node2D"]
script = ExtResource( 1 )

View File

@ -1,6 +0,0 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://AutomaticBugs/RealFunctionExecutor.gd" type="Script" id=1]
[node name="RealFunctionExecutor" type="Node2D"]
script = ExtResource( 1 )

View File

@ -1,9 +1,15 @@
extends Node extends Node
var number : float = 0.0 var number: float = 0.0
var random : bool = false var random: bool = false
var should_be_always_valid: bool = true # Generate only valid values e.g. to Node generate Node2D instead
var max_array_size: int = 15
func _ready() -> void:
randomize()
var max_array_size : int = 15
func get_int() -> int: func get_int() -> int:
if random: if random:
@ -13,26 +19,30 @@ func get_int() -> int:
else: else:
return int(number) return int(number)
func get_int_string() -> String: func get_int_string() -> String:
if random: if random:
if int(number) == 0: if int(number) == 0:
return "0" return "0"
return "(randi() % int(number)) - int(number / 2.0)".replace("number",str(number)) return "(randi() % int(number)) - int(number / 2.0)".replace("number", str(number))
else: else:
return str(int(number)) return str(int(number))
func get_float() -> float: func get_float() -> float:
if random: if random:
return (randf() * number) - (number / 2.0) return (randf() * number) - (number / 2.0)
else: else:
return number return number
func get_float_string() -> String: func get_float_string() -> String:
if random: if random:
return "(randf() * number) - (number / 2.0)".replace("number", str(number)) return "(randf() * number) - (number / 2.0)".replace("number", str(number))
else: else:
return str(number) return str(number)
func get_bool() -> bool: func get_bool() -> bool:
if random: if random:
if number < 2: if number < 2:
@ -41,6 +51,7 @@ func get_bool() -> bool:
else: else:
return bool() return bool()
func get_bool_string() -> String: func get_bool_string() -> String:
if random: if random:
if number < 2: if number < 2:
@ -49,66 +60,126 @@ func get_bool_string() -> String:
else: else:
return str(bool()) return str(bool())
func get_vector2() -> Vector2: func get_vector2() -> Vector2:
return Vector2(get_float(), get_float()) return Vector2(get_float(), get_float())
func get_vector2_string() -> String: func get_vector2_string() -> String:
return "Vector2(" + get_float_string() + ", " + get_float_string() + ")" return "Vector2(" + get_float_string() + ", " + get_float_string() + ")"
func get_vector2_string_csharp() -> String:
return "new Vector2(" + get_float_string() + ", " + get_float_string() + ")"
func get_vector3() -> Vector3: func get_vector3() -> Vector3:
return Vector3(get_float(),get_float(),get_float()) return Vector3(get_float(), get_float(), get_float())
func get_vector3_string() -> String: func get_vector3_string() -> String:
return "Vector3(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")" return "Vector3(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
func get_vector3_string_csharp() -> String:
return "new Vector3(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
func get_aabb() -> AABB: func get_aabb() -> AABB:
return AABB(get_vector3(),get_vector3()) return AABB(get_vector3(), get_vector3())
func get_aabb_string() -> String: func get_aabb_string() -> String:
return "AABB(" + get_vector3_string() + ", " + get_vector3_string() + ")" return "AABB(" + get_vector3_string() + ", " + get_vector3_string() + ")"
func get_aabb_string_csharp() -> String:
return "new AABB(" + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ")"
func get_transform() -> Transform: func get_transform() -> Transform:
return Transform(get_vector3(),get_vector3(),get_vector3(),get_vector3()) return Transform(get_vector3(), get_vector3(), get_vector3(), get_vector3())
func get_transform_string() -> String: func get_transform_string() -> String:
return "Transform(" + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ")" return "Transform(" + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ")"
func get_transform_string_csharp() -> String:
return "new Transform(" + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ", " + get_vector3_string() + ")"
func get_transform2D() -> Transform2D: func get_transform2D() -> Transform2D:
return Transform2D(get_vector2(),get_vector2(),get_vector2()) return Transform2D(get_vector2(), get_vector2(), get_vector2())
func get_transform2D_string() -> String: func get_transform2D_string() -> String:
return "Transform2D(" + get_vector2_string() + ", " + get_vector2_string()+ ", " + get_vector2_string() + ")" return "Transform2D(" + get_vector2_string() + ", " + get_vector2_string() + ", " + get_vector2_string() + ")"
func get_transform2D_string_csharp() -> String:
return "new Transform2D(" + get_vector2_string_csharp() + ", " + get_vector2_string_csharp() + ", " + get_vector2_string_csharp() + ")"
func get_plane() -> Plane: func get_plane() -> Plane:
return Plane(get_vector3(),get_vector3(),get_vector3()) return Plane(get_vector3(), get_vector3(), get_vector3())
func get_plane_string() -> String: func get_plane_string() -> String:
return "Plane(" + get_vector3_string() + ", " + get_vector3_string()+ ", " + get_vector3_string() + ")" return "Plane(" + get_vector3_string() + ", " + get_vector3_string() + ", " + get_vector3_string() + ")"
func get_plane_string_csharp() -> String:
return "new Plane(" + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ", " + get_vector3_string_csharp() + ")"
func get_quat() -> Quat: func get_quat() -> Quat:
return Quat(get_vector3()) return Quat(get_vector3())
func get_quat_string() -> String: func get_quat_string() -> String:
return "Quat(" + get_vector3_string() + ")" return "Quat(" + get_vector3_string() + ")"
func get_quat_string_csharp() -> String:
return "new Quat(" + get_vector3_string_csharp() + ")"
func get_basis() -> Basis: func get_basis() -> Basis:
return Basis(get_vector3()) return Basis(get_vector3())
func get_basis_string() -> String: func get_basis_string() -> String:
return "Basis(" + get_vector3_string() + ")" return "Basis(" + get_vector3_string() + ")"
func get_basis_string_csharp() -> String:
return "new Basis(" + get_vector3_string_csharp() + ")"
func get_rect2() -> Rect2: func get_rect2() -> Rect2:
return Rect2(get_vector2(), get_vector2()) return Rect2(get_vector2(), get_vector2())
func get_rect2_string() -> String: func get_rect2_string() -> String:
return "Rect2(" + get_vector2_string() + ", " + get_vector2_string()+ ")" return "Rect2(" + get_vector2_string() + ", " + get_vector2_string() + ")"
func get_rect2_string_csharp() -> String:
return "new Rect2(" + get_vector2_string_csharp() + ", " + get_vector2_string_csharp() + ")"
func get_color() -> Color: func get_color() -> Color:
return Color(get_float(), get_float(),get_float()) return Color(get_float(), get_float(), get_float())
func get_color_string() -> String: func get_color_string() -> String:
return "Color(" + get_float_string() + ", " + get_float_string()+ ", " + get_float_string() + ")" return "Color(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
func get_color_string_csharp() -> String:
return "new Color(" + get_float_string() + ", " + get_float_string() + ", " + get_float_string() + ")"
# TODO # TODO
func get_string() -> String: func get_string() -> String:
@ -119,81 +190,199 @@ func get_string() -> String:
return str(randi()) return str(randi())
return String() return String()
func get_string_string() -> String: func get_string_string() -> String:
if random: if random:
if randi() % 2 == 0: if randi() % 3 == 0:
return "\".\"" return "\".\""
elif randi() % 3 == 0:
return "\"\""
else: else:
return "\"randi())\"" return "str(randi() / 100)"
return "\"\"" return "\"\""
# TODO # TODO
func get_nodepath() -> NodePath: func get_nodepath() -> NodePath:
return NodePath(get_string()) return NodePath(get_string())
# TODO
func get_nodepath_string_csharp() -> String:
return "new NodePath(\".\")"
# TODO # TODO
func get_array() -> Array: func get_array() -> Array:
var array : Array = [] var array: Array = []
for _i in range(int(min(max_array_size,number))): for _i in range(int(min(max_array_size, number))):
array.append([]) array.append([])
return Array([]) return Array([])
# TODO # TODO
func get_dictionary() -> Dictionary: func get_dictionary() -> Dictionary:
return Dictionary({}) return Dictionary({})
func get_pool_string_array() -> PoolStringArray: func get_pool_string_array() -> PoolStringArray:
var array : Array = [] var array: Array = []
for _i in range(int(min(max_array_size,number))): for _i in range(int(min(max_array_size, number))):
array.append(get_string()) array.append(get_string())
return PoolStringArray(array) return PoolStringArray(array)
func get_pool_int_array() -> PoolIntArray: func get_pool_int_array() -> PoolIntArray:
var array : Array = [] var array: Array = []
for _i in range(int(min(max_array_size,number))): for _i in range(int(min(max_array_size, number))):
array.append(get_int()) array.append(get_int())
return PoolIntArray(array) return PoolIntArray(array)
func get_pool_byte_array() -> PoolByteArray: func get_pool_byte_array() -> PoolByteArray:
var array : Array = [] var array: Array = []
for _i in range(int(min(max_array_size,number))): for _i in range(int(min(max_array_size, number))):
array.append(get_int()) array.append(get_int())
return PoolByteArray(array) return PoolByteArray(array)
func get_pool_real_array() -> PoolRealArray: func get_pool_real_array() -> PoolRealArray:
var array : Array = [] var array: Array = []
for _i in range(int(min(max_array_size,number))): for _i in range(int(min(max_array_size, number))):
array.append(get_float()) array.append(get_float())
return PoolRealArray(array) return PoolRealArray(array)
func get_pool_vector2_array() -> PoolVector2Array: func get_pool_vector2_array() -> PoolVector2Array:
var array : Array = [] var array: Array = []
for _i in range(int(min(max_array_size,number))): for _i in range(int(min(max_array_size, number))):
array.append(get_vector2()) array.append(get_vector2())
return PoolVector2Array(array) return PoolVector2Array(array)
func get_pool_vector3_array() -> PoolVector3Array: func get_pool_vector3_array() -> PoolVector3Array:
var array : Array = [] var array: Array = []
for _i in range(int(min(max_array_size,number))): for _i in range(int(min(max_array_size, number))):
array.append(get_vector3()) array.append(get_vector3())
return PoolVector3Array(array) return PoolVector3Array(array)
func get_pool_color_array() -> PoolColorArray: func get_pool_color_array() -> PoolColorArray:
var array : Array = [] var array: Array = []
for _i in range(int(min(max_array_size,number))): for _i in range(int(min(max_array_size, number))):
array.append(get_color()) array.append(get_color())
return PoolColorArray(array) return PoolColorArray(array)
func get_object(object_name : String) -> Object: func get_object(object_name: String) -> Object:
if random: assert(ClassDB.class_exists(object_name))
var classes = ClassDB.get_class_list()
while true:
var choosen_class : String = classes[randi()%classes.size()]
if ClassDB.is_class(choosen_class) && ClassDB.can_instance(choosen_class) && (ClassDB.is_parent_class(choosen_class,"Node")||(ClassDB.is_parent_class(choosen_class,"Reference"))):
return ClassDB.instance(choosen_class)
else:
if ClassDB.is_class(object_name) && ClassDB.can_instance(object_name):
return ClassDB.instance(object_name)
else:
return BoxShape.new()
var a = 0
if random:
var classes = ClassDB.get_inheriters_from_class("Node") + ClassDB.get_inheriters_from_class("Reference")
if object_name == "Object":
while true:
var choosen_class: String = classes[randi() % classes.size()]
if (
ClassDB.can_instance(choosen_class)
&& (ClassDB.is_parent_class(choosen_class, "Node") || ClassDB.is_parent_class(choosen_class, "Reference"))
&& ! (choosen_class in BasicData.disabled_classes)
):
return ClassDB.instance(choosen_class)
if ClassDB.is_parent_class(object_name, "Node") || ClassDB.is_parent_class(object_name, "Reference"):
if should_be_always_valid:
var to_use_classes = ClassDB.get_inheriters_from_class(object_name)
to_use_classes.append(object_name)
if ! ClassDB.can_instance(object_name) && object_name in BasicData.disabled_classes:
assert(to_use_classes.size() > 0)
while true:
a += 1
if a > 50:
# Object doesn't have children which can be instanced
# This shouldn't happens, but sadly happen with e.g. SpatialGizmo
assert(false)
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
if ClassDB.can_instance(choosen_class) && ! (choosen_class in BasicData.disabled_classes):
return ClassDB.instance(choosen_class)
else:
while true:
a += 1
if a > 50:
assert(false)
var choosen_class: String = classes[randi() % classes.size()]
if ClassDB.can_instance(choosen_class) && ! ClassDB.is_parent_class(choosen_class, object_name) && ! (choosen_class in BasicData.disabled_classes):
return ClassDB.instance(choosen_class)
assert(false) # Other argument types are not supported
else:
if ClassDB.can_instance(object_name): # E.g. Texture is not instantable or shouldn't be, but LargeTexture is
return ClassDB.instance(object_name)
else: # Found child of non instantable object
var list_of_class = ClassDB.get_inheriters_from_class(object_name)
assert(list_of_class.size() > 0) # Number of inherited class of non instantable class must be greater than 0, otherwise this function would be useless
for i in list_of_class:
if ClassDB.can_instance(i) && (ClassDB.is_parent_class(i, "Node") || ClassDB.is_parent_class(i, "Reference")):
return ClassDB.instance(i)
assert(false)
assert(false)
return BoxShape.new() return BoxShape.new()
# TODO Update this with upper implementation
func get_object_string(object_name: String) -> String:
assert(ClassDB.class_exists(object_name))
var a = 0
if random:
var classes = ClassDB.get_inheriters_from_class("Node") + ClassDB.get_inheriters_from_class("Reference")
if object_name == "Object":
while true:
var choosen_class: String = classes[randi() % classes.size()]
if ClassDB.can_instance(choosen_class) && (ClassDB.is_parent_class(choosen_class, "Node") || ClassDB.is_parent_class(choosen_class, "Reference")):
return choosen_class
if ClassDB.is_parent_class(object_name, "Node") || ClassDB.is_parent_class(object_name, "Reference"):
if should_be_always_valid:
var to_use_classes = ClassDB.get_inheriters_from_class(object_name)
to_use_classes.append(object_name)
if ! ClassDB.can_instance(object_name):
assert(to_use_classes.size() > 0)
while true:
a += 1
if a > 30:
# Object doesn't have children which can be instanced
# This shouldn't happens, but sadly happen with e.g. SpatialGizmo
assert(false)
var choosen_class: String = to_use_classes[randi() % to_use_classes.size()]
if ClassDB.can_instance(choosen_class):
return choosen_class
else:
while true:
a += 1
if a > 30:
assert(false)
var choosen_class: String = classes[randi() % classes.size()]
if ! ClassDB.is_parent_class(choosen_class, object_name):
return choosen_class
assert(false) # Other argument types are not supported
else:
if ClassDB.can_instance(object_name): # E.g. Texture is not instantable or shouldn't be, but LargeTexture is
return object_name
else: # Found child of non instantable object
var list_of_class = ClassDB.get_inheriters_from_class(object_name)
assert(list_of_class.size() > 0) # Number of inherited class of non instantable class must be greater than 0, otherwise this function would be useless
for i in list_of_class:
if ClassDB.can_instance(i) && (ClassDB.is_parent_class(i, "Node") || ClassDB.is_parent_class(i, "Reference")):
return i
assert(false)
assert(false)
return "BoxMesh"

View File

@ -0,0 +1,16 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://MainScenes/Spatial.tscn" type="PackedScene" id=1]
[ext_resource path="res://MainScenes/Other.tscn" type="PackedScene" id=2]
[ext_resource path="res://MainScenes/Control.tscn" type="PackedScene" id=3]
[ext_resource path="res://MainScenes/Node2D.tscn" type="PackedScene" id=4]
[node name="MainScenes" type="Node"]
[node name="GridContainer" parent="." instance=ExtResource( 3 )]
[node name="Node2D" parent="." instance=ExtResource( 4 )]
[node name="Node" parent="." instance=ExtResource( 2 )]
[node name="Spatial" parent="." instance=ExtResource( 1 )]

View File

@ -6,9 +6,9 @@ It aims to be complex project, which will allow to find crashes, leaks and inval
Sadly it can't find automatically any logic errors. Sadly it can't find automatically any logic errors.
## Reproduce bugs ## Reproduce bugs
If CI find bug, you can easily without much effort check which scene cause problems. If CI find bug, you can easily without much effort check which scene cause problems(stacktrace, address or leak sanitizer log will be available).
Each scene is independent of the other, so it is easy to disable some for testing. All main scenes are independent of each other(only `Autoload.gd` is required), so it is easy to disable some for testing.
To create minimal test scene: To create minimal test scene:
- Look at the console output - there is printed info about current used scene - Look at the console output - there is printed info about current used scene
@ -24,7 +24,7 @@ When opening any scene, automatically time to exit is set.
If running projet with e.g. this parameters If running projet with e.g. this parameters
``` ```
godot 20 -v godot 20
``` ```
Then time is set to 20 seconds so it means that if scenes is 10 (EACH in `alone_steps` array + one for ALL scenes in `all_in_one` array), then each scene will be show for 2 seconds Then time is set to 20 seconds so it means that if scenes is 10 (EACH in `alone_steps` array + one for ALL scenes in `all_in_one` array), then each scene will be show for 2 seconds
@ -33,18 +33,32 @@ There are two scenes which opens all scenes:
- All.tscn - opens all scenes at once - All.tscn - opens all scenes at once
- Start.tscn - opens each scene one by one - Start.tscn - opens each scene one by one
### "Safe" Fuzzer
Available inside `AutomaticBugs` directory, check all methods with specific arguments in allowed classes.
During calculations, to output should be written informations about current classes and executed functions with arguments e.g.
```
############### CLASS ############### - PopupMenu
add_icon_radio_check_shortcut
Parameters [[InputEventMouseMotion:12379], [SoftBody:12380], -109, True]
```
This fuzzer should in most situations be safe to use, because always use same set of arguments in functions, and objects are cleared before executing next function.
This tool is developed in external repository - https://github.com/qarmin/Qarminer.
### AIO ### AIO
This are scenes which only opens once, because there is no need to open it more times(no scripts or only with `_ready` function). This are scenes which only opens once, because there is no need to open it more times - used to check loading of specific types of nodes or executing its `_ready` functions.
### MainScenes
Collections of all nodes, which are after some time simply removed and added to scene.
### ReparentingDeleting
This scene randomly reparent, add or delete nodes inside it, to check correctness this operations.
### Other Scenes ### Other Scenes
Each other scenes checks specific types of nodes like lights, rendering, physics, text or reparenting. Each other scenes checks specific types of nodes like lights, rendering, physics, text.
## Contributions
Contributions are welcome.
For now there is no requirements to format code.
New functionalities(e.g. physics checks) should be done in different folders(cleaner view to resources)
## Epilepsy Warning ## Epilepsy Warning
Due using by project a lot of functions from each type of Node, screen may flicker, images and objects may change randomly color and size which may lead some users to health problems. Due using by project a lot of functions from each type of Node, screen may flicker, images and objects may change randomly color and size which may lead some users to health problems.
## Problems with project
If you have problem with this project e.g. in CI, just ping me -> @qarmin <- and after that I will try help to fix issues which you have with it or add exception to project.

View File

@ -34,6 +34,10 @@ BasicData="*res://AutomaticBugs/BasicData.gd"
gdscript/warnings/enable=false gdscript/warnings/enable=false
gdscript/warnings/standalone_expression=false gdscript/warnings/standalone_expression=false
[logging]
file_logging/enable_file_logging.pc=false
[memory] [memory]
limits/message_queue/max_size_kb=131072 limits/message_queue/max_size_kb=131072