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]
animations = [ {
"frames": [ ExtResource( 5 ), ExtResource( 5 ), ExtResource( 5 ) ],
"loop": true,
"name": "New Anim",
"speed": 5.0
}, {
"frames": [ ExtResource( 5 ) ],
"loop": true,
"name": "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]

View File

@ -8,16 +8,13 @@ var last_time : int
const PRINT_TIME_EVERY_MILISECONDS : int = 5000
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
# Each scene runs alone
const alone_steps : Array = [
"res://MainScenes/Control.tscn",
"res://MainScenes/Node2D.tscn",
"res://MainScenes/Other.tscn",
"res://MainScenes/Spatial.tscn",
"res://MainScenes/MainScenes.tscn",
"res://Physics/2D/Physics2D.tscn",
"res://Physics/3D/Physics3D.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
const all_in_one : Array = [
"res://AIO/Operators/Operators.tscn",
"res://AutomaticBugs/RealFunctionExecutor.tscn",
#"res://AIO/AllNodes/ALL.tscn",
"res://AutomaticBugs/FunctionExecutor.tscn",
#"res://AIO/AllNodes/ALL.tscn", # Take too much time - opens ~ 20 seconds in CI inside xvfb-run
]
func _init():

View File

@ -1,6 +1,6 @@
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
"align",# GH 45976
"_screen_pick_pressed",# GH 45977
@ -37,47 +37,117 @@ var function_exceptions = [
"_edit_set_position", #GH 46018
"_edit_set_rect", #GH 46018
"get", #GH 46019
"instance_has", #GH
"", #GH
"", #GH
"", #GH
"", #GH
"", #GH
"instance_has", #GH 46020
"_update_shader", #GH 46062
"generate_tangents", #GH 46059
"get_var", #GH 46096
"force_drag", #GH 46114
"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
"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
"start",
# TODO Check this later
"propagate_notification",
"notification",
# TODO Adds big spam when i>100
# TODO Adds big spam when i>100 - look for possiblity to
"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
"pck_start",
"save",
"save_png",
"save_to_wav",
"save_to_file",
"make_dir",
"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
"warp_mouse",
"warp_mouse_position",
# Looks like a bug in FuncRef, probably but not needed
"call_func",
# OS
"kill",
"shell_open",
"execute",
"delay_usec",
"delay_msec",
"alert", # Stupid alert window opens
# Godot Freeze
"wait_to_finish",
"accept_stream",
"connect_to_stream",
"discover",
"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
"_call_function",
"call",
"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
"replace_by",
"create_instance",
"set_owner",
"set_root_node",
"instance",
"init_ref",
"reference",
"unreference",
@ -85,39 +155,96 @@ var function_exceptions = [
"duplicate",
"queue_free",
"free",
"print_tree",
"print_stray_nodes",
"print_tree_pretty",
"remove_and_skip",
"remove_child",
"move_child",
"raise",
"add_child",
"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
func get_list_of_available_classes() -> Array:
var debug_print : bool = false
var full_class_list : Array = Array(ClassDB.get_class_list())
var classes : Array = []
full_class_list.sort()
var c = 0
var rr = 0
for name_of_class in full_class_list:
if name_of_class == "AudioServer": # Crash GH #45972
continue
if name_of_class == "NetworkedMultiplayerENet": # TODO - create leaked reference instance, look at it later
rr += 1
if name_of_class in disabled_classes:
continue
if name_of_class.find("Server") != -1:
continue
if !ClassDB.is_parent_class(name_of_class, "Node") && !ClassDB.is_parent_class(name_of_class, "Reference"):
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 debug_print:
print(name_of_class)
if ClassDB.can_instance(name_of_class):
classes.push_back(name_of_class)
c+= 1
else:
if debug_print:
push_error("Failed to instance " + str(name_of_class) )
print(str(c) + " choosen classes from all " + str(full_class_list.size()) + " classes.")
return classes

View File

@ -1,37 +1,31 @@
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:
# NoiseTexture::_thread_done
# var aa = BoxShape.new()
# SurfaceTool.new().create_from(aa,0)
# Tree.new().get_column_width(0)
tests_all_functions()
# TODO - Think about adding 'add_child', to test nodes in scene tree
# Test all functions which takes 0 arguments
# Test all functions
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():
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
# 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
var object : Object = ClassDB.instance(name_of_class)
# if object is Node:
# add_child(object)
var object: Object = ClassDB.instance(name_of_class)
assert(object != null) # This should be checked before when collectiong functions
var method_list : Array = ClassDB.class_get_method_list(name_of_class, !use_parent_methods)
if add_to_tree:
if object is Node:
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:
var index : int = -1
var index: int = -1
for method_index in range(method_list.size()):
if method_list[method_index]["name"] == exception:
index = method_index
@ -39,48 +33,53 @@ func tests_all_functions() -> void:
if index != -1:
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:
# Function is virtual, so we just skip it
if method_data["flags"] == method_data["flags"] | METHOD_FLAG_VIRTUAL:
continue
if debug_print:
print("##### - " + name_of_class)
# 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)
for argument in arguments:
assert(argument != null)
if argument is Node:
argument.queue_free()
elif argument is Object && ! (argument is Reference):
argument.free()
if use_always_new_object:
assert(object != null)
if object is Node:
object.queue_free()
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()
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:
var arguments_array : Array = []
func return_for_all(method_data: Dictionary) -> Array:
var arguments_array: Array = []
ValueCreator.number = 10
ValueCreator.random = false
ValueCreator.should_be_always_valid = false
for argument in method_data["args"]:
# print(argument)
match argument.type:
TYPE_NIL: # Looks that this means VARIANT not null
arguments_array.push_back(false) # TODO Add some randomization
# assert(false)
TYPE_MAX:
assert(false)
arguments_array.push_back(false) # TODO randomize this
TYPE_AABB:
arguments_array.push_back(ValueCreator.get_aabb())
TYPE_ARRAY:
@ -102,7 +101,7 @@ func return_for_all(method_data : Dictionary) -> Array:
TYPE_NODE_PATH:
arguments_array.push_back(ValueCreator.get_nodepath())
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:
arguments_array.push_back(ValueCreator.get_plane())
TYPE_QUAT:
@ -136,6 +135,6 @@ func return_for_all(method_data : Dictionary) -> Array:
_:
assert(false) # Missed some types, add it
# print("Parameters " + str(arguments_array))
if debug_print:
print("Parameters " + str(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
var number : float = 0.0
var random : bool = false
var number: float = 0.0
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:
if random:
@ -13,26 +19,30 @@ func get_int() -> int:
else:
return int(number)
func get_int_string() -> String:
if random:
if int(number) == 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:
return str(int(number))
func get_float() -> float:
if random:
return (randf() * number) - (number / 2.0)
else:
return number
func get_float_string() -> String:
if random:
return "(randf() * number) - (number / 2.0)".replace("number", str(number))
else:
return str(number)
func get_bool() -> bool:
if random:
if number < 2:
@ -41,6 +51,7 @@ func get_bool() -> bool:
else:
return bool()
func get_bool_string() -> String:
if random:
if number < 2:
@ -49,66 +60,126 @@ func get_bool_string() -> String:
else:
return str(bool())
func get_vector2() -> Vector2:
return Vector2(get_float(), get_float())
func get_vector2_string() -> 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:
return Vector3(get_float(),get_float(),get_float())
return Vector3(get_float(), get_float(), get_float())
func get_vector3_string() -> 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:
return AABB(get_vector3(),get_vector3())
return AABB(get_vector3(), get_vector3())
func get_aabb_string() -> 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:
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:
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:
return Transform2D(get_vector2(),get_vector2(),get_vector2())
return Transform2D(get_vector2(), get_vector2(), get_vector2())
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:
return Plane(get_vector3(),get_vector3(),get_vector3())
return Plane(get_vector3(), get_vector3(), get_vector3())
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:
return Quat(get_vector3())
func get_quat_string() -> String:
return "Quat(" + get_vector3_string() + ")"
func get_quat_string_csharp() -> String:
return "new Quat(" + get_vector3_string_csharp() + ")"
func get_basis() -> Basis:
return Basis(get_vector3())
func get_basis_string() -> String:
return "Basis(" + get_vector3_string() + ")"
func get_basis_string_csharp() -> String:
return "new Basis(" + get_vector3_string_csharp() + ")"
func get_rect2() -> Rect2:
return Rect2(get_vector2(), get_vector2())
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:
return Color(get_float(), get_float(),get_float())
return Color(get_float(), get_float(), get_float())
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
func get_string() -> String:
@ -119,81 +190,199 @@ func get_string() -> String:
return str(randi())
return String()
func get_string_string() -> String:
if random:
if randi() % 2 == 0:
if randi() % 3 == 0:
return "\".\""
else:
return "\"randi())\""
elif randi() % 3 == 0:
return "\"\""
else:
return "str(randi() / 100)"
return "\"\""
# TODO
func get_nodepath() -> NodePath:
return NodePath(get_string())
# TODO
func get_nodepath_string_csharp() -> String:
return "new NodePath(\".\")"
# TODO
func get_array() -> Array:
var array : Array = []
for _i in range(int(min(max_array_size,number))):
var array: Array = []
for _i in range(int(min(max_array_size, number))):
array.append([])
return Array([])
# TODO
func get_dictionary() -> Dictionary:
return Dictionary({})
func get_pool_string_array() -> PoolStringArray:
var array : Array = []
for _i in range(int(min(max_array_size,number))):
var array: Array = []
for _i in range(int(min(max_array_size, number))):
array.append(get_string())
return PoolStringArray(array)
func get_pool_int_array() -> PoolIntArray:
var array : Array = []
for _i in range(int(min(max_array_size,number))):
var array: Array = []
for _i in range(int(min(max_array_size, number))):
array.append(get_int())
return PoolIntArray(array)
func get_pool_byte_array() -> PoolByteArray:
var array : Array = []
for _i in range(int(min(max_array_size,number))):
var array: Array = []
for _i in range(int(min(max_array_size, number))):
array.append(get_int())
return PoolByteArray(array)
func get_pool_real_array() -> PoolRealArray:
var array : Array = []
for _i in range(int(min(max_array_size,number))):
var array: Array = []
for _i in range(int(min(max_array_size, number))):
array.append(get_float())
return PoolRealArray(array)
func get_pool_vector2_array() -> PoolVector2Array:
var array : Array = []
for _i in range(int(min(max_array_size,number))):
var array: Array = []
for _i in range(int(min(max_array_size, number))):
array.append(get_vector2())
return PoolVector2Array(array)
func get_pool_vector3_array() -> PoolVector3Array:
var array : Array = []
for _i in range(int(min(max_array_size,number))):
var array: Array = []
for _i in range(int(min(max_array_size, number))):
array.append(get_vector3())
return PoolVector3Array(array)
func get_pool_color_array() -> PoolColorArray:
var array : Array = []
for _i in range(int(min(max_array_size,number))):
var array: Array = []
for _i in range(int(min(max_array_size, number))):
array.append(get_color())
return PoolColorArray(array)
func get_object(object_name : String) -> Object:
func get_object(object_name: String) -> Object:
assert(ClassDB.class_exists(object_name))
var a = 0
if random:
var classes = ClassDB.get_class_list()
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.is_class(choosen_class) && ClassDB.can_instance(choosen_class) && (ClassDB.is_parent_class(choosen_class,"Node")||(ClassDB.is_parent_class(choosen_class,"Reference"))):
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:
if ClassDB.is_class(object_name) && ClassDB.can_instance(object_name):
return ClassDB.instance(object_name)
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.
## 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:
- 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
```
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
@ -33,18 +33,32 @@ There are two scenes which opens all scenes:
- All.tscn - opens all scenes at once
- 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
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
Each other scenes checks specific types of nodes like lights, rendering, physics, text or reparenting.
## 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)
Each other scenes checks specific types of nodes like lights, rendering, physics, text.
## 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.
## 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/standalone_expression=false
[logging]
file_logging/enable_file_logging.pc=false
[memory]
limits/message_queue/max_size_kb=131072