static void signature_verify_file(void) { GError *error = NULL; GBytes *sig = read_file("test/openssl-ca/manifest-r1.sig", NULL); GBytes *isig = read_file("test/random.dat", NULL); g_assert_nonnull(sig); g_assert_nonnull(isig); // Test valid manifest g_assert_true(cms_verify_file("test/openssl-ca/manifest", sig, 0, &error)); g_assert_null(error); // Test non-existing file g_assert_false(cms_verify_file("path/to/nonexisting/file", sig, 0, &error)); g_assert_nonnull(error); g_clear_error(&error); // Test valid manifest against invalid signature g_assert_false(cms_verify_file("test/openssl-ca/manifest", isig, 0, &error)); g_assert_nonnull(error); g_clear_error(&error); g_bytes_unref(sig); g_bytes_unref(isig); }
GRAPHENE_TEST_UNIT_END GRAPHENE_TEST_UNIT_BEGIN (frustum_matrix_contains_point) { #if defined(GRAPHENE_USE_GCC) # if GLIB_CHECK_VERSION (2, 38, 0) g_test_skip ("Disabled when using GCC vectors"); # else if (g_test_verbose ()) g_test_message ("Disabled when using GCC vectors"); # endif #else graphene_matrix_t m; graphene_frustum_t f; graphene_point3d_t p; graphene_matrix_init_frustum (&m, -1.f, 1.f, -1.f, 1.f, 1.f, 100.f); graphene_frustum_init_from_matrix (&f, &m); g_assert_false (graphene_frustum_contains_point (&f, graphene_point3d_init (&p, 0.f, 0.f, 0.f))); g_assert_true (graphene_frustum_contains_point (&f, graphene_point3d_init (&p, 0.f, 0.f, -50.f))); g_assert_true (graphene_frustum_contains_point (&f, graphene_point3d_init (&p, 0.f, 0.f, -1.001f))); g_assert_true (graphene_frustum_contains_point (&f, graphene_point3d_init (&p, -1.f, -1.f, -1.001f))); g_assert_false (graphene_frustum_contains_point (&f, graphene_point3d_init (&p, -1.1f, -1.1f, -1.001f))); g_assert_true (graphene_frustum_contains_point (&f, graphene_point3d_init (&p, 1.f, 1.f, -1.001f))); g_assert_false (graphene_frustum_contains_point (&f, graphene_point3d_init (&p, 1.1f, 1.1f, -1.001f))); #endif }
static void test_copy_fourth_hierarchy_undo (void) { g_autoptr (GFile) root = NULL; g_autoptr (GFile) first_dir = NULL; g_autoptr (GFile) second_dir = NULL; g_autoptr (GFile) third_dir = NULL; g_autoptr (GFile) file = NULL; g_autoptr (GFile) result_file = NULL; g_autolist (GFile) files = NULL; create_fourth_hierarchy ("copy"); root = g_file_new_for_path (g_get_tmp_dir ()); g_assert_true (root != NULL); first_dir = g_file_get_child (root, "copy_first_dir"); files = g_list_prepend (files, g_object_ref (first_dir)); g_assert_true (first_dir != NULL); file = g_file_get_child (first_dir, "copy_first_dir_child"); g_assert_true (file != NULL); second_dir = g_file_get_child (root, "copy_second_dir"); files = g_list_prepend (files, g_object_ref (second_dir)); g_assert_true (second_dir != NULL); file = g_file_get_child (second_dir, "copy_second_dir_child"); g_assert_true (file != NULL); third_dir = g_file_get_child (root, "copy_third_dir"); g_assert_true (third_dir != NULL); nautilus_file_operations_copy_sync (files, third_dir); test_operation_undo (); result_file = g_file_get_child (third_dir, "copy_first_dir"); g_assert_false (g_file_query_exists (result_file, NULL)); file = g_file_get_child (result_file, "copy_first_dir_child"); g_assert_false (g_file_query_exists (file, NULL)); result_file = g_file_get_child (third_dir, "copy_second_dir"); g_assert_false (g_file_query_exists (result_file, NULL)); file = g_file_get_child (result_file, "copy_second_dir_child"); g_assert_false (g_file_query_exists (file, NULL)); file = g_file_get_child (first_dir, "copy_first_dir_child"); g_assert_true (g_file_query_exists (file, NULL)); g_assert_true (g_file_query_exists (first_dir, NULL)); file = g_file_get_child (second_dir, "copy_second_dir_child"); g_assert_true (g_file_query_exists (file, NULL)); g_assert_true (g_file_query_exists (second_dir, NULL)); empty_directory_by_prefix (root, "copy"); }
static void test_wildmatch_multi(void) { g_assert_true(util_wildmatch("foo,?", "foo")); g_assert_true(util_wildmatch("foo,?", "f")); g_assert_true(util_wildmatch("foo,b{a,o,}r,ba?", "foo")); g_assert_true(util_wildmatch("foo,b{a,o,}r,ba?", "bar")); g_assert_true(util_wildmatch("foo,b{a,o,}r,ba?", "bor")); g_assert_true(util_wildmatch("foo,b{a,o,}r,ba?", "br")); g_assert_true(util_wildmatch("foo,b{a,o,}r,ba?", "baz")); g_assert_true(util_wildmatch("foo,b{a,o,}r,ba?", "bat")); g_assert_false(util_wildmatch("foo,b{a,o,}r,ba?", "foo,")); g_assert_false(util_wildmatch("foo,?", "fo")); }
void test_layer_load2() { gchar *old_value = __set_layers_path(); g_assert_false(layerapi2_is_layer_loaded("layer1_label")); g_assert_false(layerapi2_is_layer_loaded("layer2_label")); __layer_load("layer2_label", FALSE, NULL); g_assert_true(layerapi2_is_layer_loaded("layer2_label")); g_assert_true(layerapi2_is_layer_loaded("layer1_label")); layerapi2_layer_unload("layer1_label", NULL); g_assert_false(layerapi2_is_layer_loaded("layer1_label")); g_assert_false(layerapi2_is_layer_loaded("layer2_label")); __restore_layers_path(old_value); g_free(old_value); }
/* Thread function to check that a mutex given in @data is locked */ static gpointer mutex_locked_thread (gpointer data) { GMutex *mutex = (GMutex *) data; g_assert_false (g_mutex_trylock (mutex)); return NULL; }
static void check_vm_display(OvirtVm *vm) { OvirtVmDisplay *display; gint type; char *address; char *proxy_url; guint port; guint secure_port; guint monitor_count; gboolean smartcard; g_object_get(vm, "display", &display, NULL); g_assert_nonnull(display); g_object_get(display, "type", &type, "address", &address, "port", &port, "secure-port", &secure_port, "monitor-count", &monitor_count, "smartcard", &smartcard, "proxy-url", &proxy_url, NULL); g_assert_cmpuint(type, ==, OVIRT_VM_DISPLAY_SPICE); g_assert_cmpstr(address, ==, "10.0.0.123"); g_assert_cmpuint(port, ==, 0); g_assert_cmpuint(secure_port, ==, 5900); g_assert_cmpuint(monitor_count, ==, 1); g_assert_false(smartcard); g_assert_cmpstr(proxy_url, ==, "10.0.0.10"); g_object_unref(display); g_free(address); g_free(proxy_url); }
static void _adg_method_widget_get_realized(void) { GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_assert_false(gtk_widget_get_realized(window)); gtk_widget_destroy(window); }
static void test_sc_do_optional_mount_missing(void) { sc_break("mount", missing_mount); bool ok = sc_do_optional_mount("/foo", "/bar", "ext4", MS_RDONLY, NULL); g_assert_false(ok); sc_reset_faults(); }
void test_initialise_clients(void) { bridge_client *clients[NUMBER_OF_ENDPOINTS]; struct event_base *evbase = (struct event_base*) 12; tca_options *opts = allocate_tca_options(); #ifdef HAVE_IPV6 opts->use_ipv6 = true; #else opts->use_ipv6 = false; #endif int i; for (i = 0; i < NUMBER_OF_ENDPOINTS; i++) { int target_port = i + 10; assert(target_port < UINT16_MAX); opts->connection_endpoints[i]->port = (uint16_t) target_port; } initialise_clients(clients, evbase, opts); g_assert_true(clients[0]->opposite_client == clients[1]); g_assert_true(clients[1]->opposite_client == clients[0]); for (i = 0; i < NUMBER_OF_ENDPOINTS; i++) { #ifdef HAVE_IPV6 g_assert_true(clients[i]->use_ipv6); #else g_assert_false(clients[i]->use_ipv6); #endif g_assert_true(clients[i]->address->port == i + 10); g_assert_true(clients[i]->evbase == (struct event_base*) 12); } free_tca_options(opts); }
static void test_simple(void) { g_remove("/tmp/test.key"); /* we made sure that file is removed */ g_assert_false(g_file_test("/tmp/test.key", G_FILE_TEST_EXISTS)); MConnCrypt *cr = m_conn_crypt_new_for_key_path("/tmp/test.key"); g_assert_nonnull(cr); g_assert_true(g_file_test("/tmp/test.key", G_FILE_TEST_EXISTS)); gchar *pubkey1 = m_conn_crypt_get_public_key_pem(cr); m_conn_crypt_unref(cr); /* file should still exit */ g_assert_true(g_file_test("/tmp/test.key", G_FILE_TEST_EXISTS)); cr = m_conn_crypt_new_for_key_path("/tmp/test.key"); /* key should have been loaded */ g_assert_nonnull(cr); g_assert_true(g_file_test("/tmp/test.key", G_FILE_TEST_EXISTS)); gchar *pubkey2 = m_conn_crypt_get_public_key_pem(cr); m_conn_crypt_unref(cr); g_assert_cmpstr(pubkey1, ==, pubkey2); }
/* Thread function to check that a recursive mutex given in @data is locked */ static gpointer rec_mutex_locked_thread (gpointer data) { GRecMutex *rec_mutex = (GRecMutex *) data; g_assert_false (g_rec_mutex_trylock (rec_mutex)); return NULL; }
static void test_sc_is_ns_group_dir_private() { if (geteuid() != 0) { g_test_skip("this test needs to run as root"); return; } const char *ns_dir = sc_test_use_fake_ns_dir(); g_test_queue_destroy(unmount_dir, (char *)ns_dir); if (g_test_subprocess()) { // The temporary directory should not be private initially g_assert_false(sc_is_ns_group_dir_private()); /// do what "mount --bind /foo /foo; mount --make-private /foo" does. int err; err = mount(ns_dir, ns_dir, NULL, MS_BIND, NULL); g_assert_cmpint(err, ==, 0); err = mount(NULL, ns_dir, NULL, MS_PRIVATE, NULL); g_assert_cmpint(err, ==, 0); // The temporary directory should now be private g_assert_true(sc_is_ns_group_dir_private()); return; } g_test_trap_subprocess(NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDERR); g_test_trap_assert_passed(); }
static void test_handler_remove(void) { handler_add("http", "e"); g_assert_true(handler_remove("http")); g_assert_false(handler_remove("http")); }
static void test_wildmatch_questionmark(void) { g_assert_true(util_wildmatch("wild?atch", "wildmatch")); g_assert_true(util_wildmatch("wild?atch", "wildBatch")); g_assert_true(util_wildmatch("wild?atch", "wild?atch")); g_assert_true(util_wildmatch("?ild?atch", "MildBatch")); g_assert_true(util_wildmatch("foo\\?bar", "foo?bar")); g_assert_true(util_wildmatch("???", "foo")); g_assert_true(util_wildmatch("???", "bar")); g_assert_false(util_wildmatch("foo\\?bar", "foorbar")); g_assert_false(util_wildmatch("?", "")); g_assert_false(util_wildmatch("b??r", "bar")); /* ? does not match / in contrast to * which does */ g_assert_false(util_wildmatch("user?share", "user/share")); }
gboolean headerbarui_volume_changed(gpointer user_data) { float volume = deadbeef->volume_get_min_db()-deadbeef->volume_get_db(); g_assert_false((volume>0)); gtk_scale_button_set_value( GTK_SCALE_BUTTON (volbutton), (int)-volume ); return FALSE; }
gchar* utils_str_capitalise(const gchar* str) { g_assert_false(utils_str_empty(str)); gchar* ret = g_strdup_printf("%c%s", g_ascii_toupper(*str), str+1); return ret; }
static void test_bin (void) { guint8 buf[64]; gchar str[129]; g_assert_false (oio_str_hex2bin ("0", buf, sizeof(buf))); g_assert_false (oio_str_hex2bin ("x", buf, sizeof(buf))); g_assert_false (oio_str_hex2bin ("0x", buf, sizeof(buf))); g_assert_true (oio_str_hex2bin ("00", buf, 1)); g_assert_false (oio_str_hex2bin ("0000", buf, 1)); g_assert_true (oio_str_hex2bin ("00", buf, sizeof(buf))); g_assert_true (buf[0] == 0); g_assert (2 == oio_str_bin2hex (buf, 1, str, sizeof(str))); g_assert (!g_ascii_strcasecmp(str, "00")); }
void test_layer_load() { gchar *old_value = __set_layers_path(); g_assert_true(layerapi2_is_layer_installed("layer1_label")); g_assert_false(layerapi2_is_layer_installed("foobar")); g_assert_false(layerapi2_is_layer_loaded("layer1_label")); GString *gs = g_string_new(NULL); __layer_load("layer1_label", FALSE, &gs); gchar *bash_cmds = g_string_free(gs, FALSE); g_assert_true(strlen(bash_cmds) > 0); g_free(bash_cmds); g_assert_true(layerapi2_is_layer_loaded("layer1_label")); __layer_load("layer1_label", FALSE, NULL); g_assert_true(layerapi2_is_layer_loaded("layer1_label")); layerapi2_layer_unload("layer1_label", NULL); g_assert_false(layerapi2_is_layer_loaded("layer1_label")); __restore_layers_path(old_value); g_free(old_value); }
static void _cpml_behavior_browsing(void) { CpmlSegment segment; CpmlPrimitive primitive, primitive_copy; cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path()); cpml_primitive_from_segment(&primitive, &segment); adg_assert_isapprox((primitive.org)->point.x, 0); adg_assert_isapprox((primitive.org)->point.y, 1); g_assert_cmpint((primitive.data)->header.type, ==, CPML_LINE); g_assert_true(cpml_primitive_next(&primitive)); adg_assert_isapprox((primitive.org)->point.x, 3); adg_assert_isapprox((primitive.org)->point.y, 1); g_assert_cmpint((primitive.data)->header.type, ==, CPML_ARC); g_assert_true(cpml_primitive_next(&primitive)); adg_assert_isapprox((primitive.org)->point.x, 6); adg_assert_isapprox((primitive.org)->point.y, 7); g_assert_cmpint((primitive.data)->header.type, ==, CPML_CURVE); g_assert_true(cpml_primitive_next(&primitive)); adg_assert_isapprox((primitive.org)->point.x, -2); adg_assert_isapprox((primitive.org)->point.y, 2); g_assert_cmpint((primitive.data)->header.type, ==, CPML_CLOSE); g_assert_false(cpml_primitive_next(&primitive)); cpml_primitive_reset(&primitive); g_assert_true(cpml_primitive_next(&primitive)); cpml_primitive_reset(&primitive); cpml_primitive_reset(&primitive); g_assert_true(cpml_primitive_next(&primitive)); g_assert_true(cpml_primitive_next(&primitive)); g_assert_true(cpml_primitive_next(&primitive)); g_assert_false(cpml_primitive_next(&primitive)); cpml_primitive_copy(&primitive_copy, &primitive); g_assert_false(cpml_primitive_next(&primitive_copy)); cpml_primitive_reset(&primitive); g_assert_false(cpml_primitive_next(&primitive_copy)); cpml_primitive_reset(&primitive_copy); g_assert_true(cpml_primitive_next(&primitive_copy)); }
static void _cpml_method_copy(void) { CpmlSegment segment; CpmlPrimitive original; CpmlPrimitive primitive = { NULL, NULL, NULL }; cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path()); cpml_primitive_from_segment(&original, &segment); g_assert_false(original.segment == primitive.segment); g_assert_false(original.org == primitive.org); g_assert_false(original.data == primitive.data); cpml_primitive_copy(&primitive, &original); g_assert_true(original.segment == primitive.segment); g_assert_true(original.org == primitive.org); g_assert_true(original.data == primitive.data); }
static void test_wildmatch_wildcard(void) { g_assert_true(util_wildmatch("*", "")); g_assert_true(util_wildmatch("*", "Match as much as possible")); g_assert_true(util_wildmatch("*match", "prefix match")); g_assert_true(util_wildmatch("match*", "match suffix")); g_assert_true(util_wildmatch("match*", "match*")); g_assert_true(util_wildmatch("match\\*", "match*")); g_assert_true(util_wildmatch("match\\\\*", "match\\*")); g_assert_true(util_wildmatch("do * match", "do a infix match")); /* '*' matches also / in contrast to other implementations */ g_assert_true(util_wildmatch("start*end", "start/something/end")); g_assert_true(util_wildmatch("*://*.io/*", "http://fanglingsu.github.io/vimb/")); /* multiple * should act like a single one */ g_assert_true(util_wildmatch("**", "")); g_assert_true(util_wildmatch("match **", "Match as much as possible")); g_assert_true(util_wildmatch("f***u", "fu")); g_assert_false(util_wildmatch("match\\*", "match fail")); g_assert_false(util_wildmatch("f***u", "full")); }
/* Tests the function for a simple file */ static void test_simple_file (void) { g_autoptr (GFile) root = NULL; g_autoptr (GFile) file = NULL; root = g_file_new_for_path (g_get_tmp_dir ()); file = g_file_get_child (root, "simple_file"); g_file_create (file, G_FILE_CREATE_NONE, NULL, NULL); g_assert_false (dir_has_files (file)); g_assert_true (g_file_delete (file, NULL, NULL)); }
static void checksum_test1(void) { RaucChecksum checksum = {}; GError *error = NULL; checksum.type = 0; checksum.digest = NULL; g_assert_false(verify_checksum(&checksum, "test/install-content/appfs.img", &error)); g_assert_error(error, R_CHECKSUM_ERROR, R_CHECKSUM_ERROR_FAILED); g_clear_error(&error); checksum.type = G_CHECKSUM_SHA256; checksum.digest = g_strdup(TEST_DIGEST_FAIL); g_assert_false(verify_checksum(&checksum, "test/install-content/appfs.img", &error)); g_assert_error(error, R_CHECKSUM_ERROR, R_CHECKSUM_ERROR_SIZE_MISMATCH); g_clear_error(&error); checksum.size = 32768; g_assert_false(verify_checksum(&checksum, "test/install-content/appfs.img", &error)); g_assert_error(error, R_CHECKSUM_ERROR, R_CHECKSUM_ERROR_DIGEST_MISMATCH); g_clear_error(&error); checksum.size = 0; checksum.digest = g_strdup(TEST_DIGEST_GOOD); g_assert_false(verify_checksum(&checksum, "test/install-content/appfs.img", &error)); g_assert_error(error, R_CHECKSUM_ERROR, R_CHECKSUM_ERROR_SIZE_MISMATCH); g_clear_error(&error); checksum.size = 32768; g_assert_true(verify_checksum(&checksum, "test/install-content/appfs.img", &error)); g_assert_no_error(error); g_assert_false(verify_checksum(&checksum, "tesinstall-content/rootfs.img", &error)); g_assert_error(error, G_FILE_ERROR, G_FILE_ERROR_NOENT); g_clear_error(&error); g_assert_false(verify_checksum(&checksum, "test/_MISSING_", &error)); g_assert_error(error, G_FILE_ERROR, G_FILE_ERROR_NOENT); g_clear_error(&error); g_clear_pointer(&checksum.digest, g_free); checksum.size = 0; g_assert_true(compute_checksum(&checksum, "test/install-content/appfs.img", &error)); g_assert_no_error(error); g_assert_cmpstr(checksum.digest, ==, TEST_DIGEST_GOOD); g_assert(checksum.size == 32768); g_clear_pointer(&checksum.digest, g_free); checksum.size = 0; g_assert_false(compute_checksum(&checksum, "tesinstall-content/rootfs.img", &error)); g_assert_error(error, G_FILE_ERROR, G_FILE_ERROR_NOENT); g_clear_error(&error); g_assert_null(checksum.digest); g_assert(checksum.size == 0); }
static void test_is_subdir(void) { // Sensible exaples are sensible g_assert_true(is_subdir("/dir/subdir", "/dir/")); g_assert_true(is_subdir("/dir/subdir", "/dir")); g_assert_true(is_subdir("/dir/", "/dir")); g_assert_true(is_subdir("/dir", "/dir")); // Also without leading slash g_assert_true(is_subdir("dir/subdir", "dir/")); g_assert_true(is_subdir("dir/subdir", "dir")); g_assert_true(is_subdir("dir/", "dir")); g_assert_true(is_subdir("dir", "dir")); // Some more ideas g_assert_true(is_subdir("//", "/")); g_assert_true(is_subdir("/", "/")); g_assert_true(is_subdir("", "")); // but this is not true g_assert_false(is_subdir("/", "/dir")); g_assert_false(is_subdir("/rid", "/dir")); g_assert_false(is_subdir("/different/dir", "/dir")); g_assert_false(is_subdir("/", "")); }
static void _adg_property_has_extension2(void) { AdgADim *adim; gboolean invalid_boolean; gboolean has_extension2; adim = adg_adim_new(); invalid_boolean = (gboolean) 1234; /* Using the public APIs */ adg_adim_switch_extension2(adim, FALSE); has_extension2 = adg_adim_has_extension2(adim); g_assert_false(has_extension2); adg_adim_switch_extension2(adim, invalid_boolean); has_extension2 = adg_adim_has_extension2(adim); g_assert_false(has_extension2); adg_adim_switch_extension2(adim, TRUE); has_extension2 = adg_adim_has_extension2(adim); g_assert_true(has_extension2); /* Using GObject property methods */ g_object_set(adim, "has-extension2", FALSE, NULL); g_object_get(adim, "has-extension2", &has_extension2, NULL); g_assert_false(has_extension2); g_object_set(adim, "has-extension2", invalid_boolean, NULL); g_object_get(adim, "has-extension2", &has_extension2, NULL); g_assert_false(has_extension2); g_object_set(adim, "has-extension2", TRUE, NULL); g_object_get(adim, "has-extension2", &has_extension2, NULL); g_assert_true(has_extension2); adg_entity_destroy(ADG_ENTITY(adim)); }
static void test_str2bool() { int err; bool value; err = str2bool("yes", &value); g_assert_cmpint(err, ==, 0); g_assert_true(value); err = str2bool("1", &value); g_assert_cmpint(err, ==, 0); g_assert_true(value); err = str2bool("no", &value); g_assert_cmpint(err, ==, 0); g_assert_false(value); err = str2bool("0", &value); g_assert_cmpint(err, ==, 0); g_assert_false(value); err = str2bool("", &value); g_assert_cmpint(err, ==, 0); g_assert_false(value); err = str2bool(NULL, &value); g_assert_cmpint(err, ==, 0); g_assert_false(value); err = str2bool("flower", &value); g_assert_cmpint(err, ==, -1); g_assert_cmpint(errno, ==, EINVAL); err = str2bool("yes", NULL); g_assert_cmpint(err, ==, -1); g_assert_cmpint(errno, ==, EFAULT); }
void test_train_not_occupies_tile(test_train_context* test_ctx, const void* data) { #pragma unused(data) sem_train* train = test_ctx->train; sem_coordinate head_position; sem_coordinate_set(&head_position, 2, 0); sem_car head_car; head_car.position = head_position; sem_train_add_car(train, &head_car); sem_coordinate other_tile; sem_coordinate_set(&other_tile, 1, 1); g_assert_false(sem_train_occupies(train, &other_tile)); }
static void _adg_method_window_hide_here(void) { GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); /* I cannot call gtk_widget_show because there likely be no screens * for realizing window. Just commenting for now. * gtk_widget_show(window); * g_assert_true(gtk_widget_get_visible(window)); */ adg_gtk_window_hide_here(GTK_WINDOW(window)); g_assert_false(gtk_widget_get_visible(window)); gtk_widget_destroy(window); }
/* Tests the function for an empty directory */ static void test_empty_directory (void) { g_autoptr (GFile) root = NULL; g_autoptr (GFile) child = NULL; root = g_file_new_for_path (g_get_tmp_dir ()); child = g_file_get_child (root, "empty_dir"); g_assert_true (child != NULL); g_file_make_directory (child, NULL, NULL); g_assert_false (dir_has_files (child)); g_assert_true (g_file_delete (child, NULL, NULL)); }