mirror of
https://github.com/Relintai/regression-test-project.git
synced 2024-11-14 10:27:53 +01:00
Update some things (#28)
This commit is contained in:
parent
b52b5368a2
commit
7685576fe3
@ -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]
|
||||
|
@ -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():
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
6
AutomaticBugs/FunctionExecutor.tscn
Normal file
6
AutomaticBugs/FunctionExecutor.tscn
Normal 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 )
|
@ -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 )
|
@ -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"
|
||||
|
16
MainScenes/MainScenes.tscn
Normal file
16
MainScenes/MainScenes.tscn
Normal 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 )]
|
38
README.md
38
README.md
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user