2 Unix SMB/CIFS implementation.
3 test suite for rpc witness operations
5 Copyright (C) Guenther Deschner 2015
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "torture/rpc/torture_rpc.h"
24 #include "librpc/gen_ndr/ndr_witness_c.h"
25 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
26 #include "librpc/gen_ndr/ndr_clusapi_c.h"
27 #include "param/param.h"
29 #include "lib/cmdline/cmdline.h"
31 struct torture_test_clusapi_state
{
32 struct dcerpc_pipe
*p
;
35 struct torture_test_witness_state
{
37 const char *share_name
;
38 struct witness_interfaceList
*list
;
39 struct policy_handle context_handle
;
40 struct torture_test_clusapi_state clusapi
;
43 static bool test_witness_GetInterfaceList(struct torture_context
*tctx
,
44 struct dcerpc_pipe
*p
,
47 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
48 struct witness_GetInterfaceList r
;
49 struct witness_interfaceList
*l
;
50 struct torture_test_witness_state
*state
=
51 (struct torture_test_witness_state
*)data
;
53 r
.out
.interface_list
= &l
;
55 torture_assert_ntstatus_ok(tctx
,
56 dcerpc_witness_GetInterfaceList_r(b
, tctx
, &r
),
57 "GetInterfaceList failed");
59 torture_assert_werr_ok(tctx
,
61 "GetInterfaceList failed");
68 static bool find_sofs_share(struct torture_context
*tctx
,
69 const char **sofs_sharename
)
71 struct dcerpc_pipe
*p
;
72 struct dcerpc_binding_handle
*b
;
73 struct srvsvc_NetShareEnumAll r
;
74 struct srvsvc_NetShareInfoCtr info_ctr
;
75 struct srvsvc_NetShareCtr1 ctr1
;
76 uint32_t resume_handle
= 0;
77 uint32_t totalentries
= 0;
80 torture_assert_ntstatus_ok(tctx
,
81 torture_rpc_connection_transport(tctx
, &p
, &ndr_table_srvsvc
,
83 "failed to setup srvsvc connection");
85 b
= p
->binding_handle
;
90 info_ctr
.ctr
.ctr1
= &ctr1
;
92 r
.in
.server_unc
= dcerpc_server_name(p
);
94 r
.in
.info_ctr
= &info_ctr
;
95 r
.in
.resume_handle
= &resume_handle
;
96 r
.out
.totalentries
= &totalentries
;
97 r
.out
.info_ctr
= &info_ctr
;
98 r
.out
.resume_handle
= &resume_handle
;
100 torture_assert_ntstatus_ok(tctx
,
101 dcerpc_srvsvc_NetShareEnumAll_r(b
, tctx
, &r
),
102 "failed to call srvsvc_NetShareEnumAll");
104 torture_assert_werr_ok(tctx
,
106 "failed to call srvsvc_NetShareEnumAll");
108 for (i
=0; i
< r
.out
.info_ctr
->ctr
.ctr1
->count
; i
++) {
110 if (r
.out
.info_ctr
->ctr
.ctr1
->array
[i
].type
== STYPE_CLUSTER_SOFS
) {
111 *sofs_sharename
= talloc_strdup(tctx
, r
.out
.info_ctr
->ctr
.ctr1
->array
[i
].name
);
112 if (*sofs_sharename
== NULL
) {
115 torture_comment(tctx
, "using SOFS share: %s\n", *sofs_sharename
);
118 if (r
.out
.info_ctr
->ctr
.ctr1
->array
[i
].type
== STYPE_DISKTREE
) {
119 *sofs_sharename
= talloc_strdup(tctx
, r
.out
.info_ctr
->ctr
.ctr1
->array
[i
].name
);
120 if (*sofs_sharename
== NULL
) {
123 torture_comment(tctx
, "assuming SOFS share: %s\n", *sofs_sharename
);
131 static bool init_witness_test_state(struct torture_context
*tctx
,
132 struct dcerpc_pipe
*p
,
133 struct torture_test_witness_state
*state
)
135 if (state
->net_name
== NULL
) {
136 state
->net_name
= lpcfg_parm_string(tctx
->lp_ctx
, NULL
, "torture", "net_name");
139 if (state
->list
== NULL
) {
141 test_witness_GetInterfaceList(tctx
, p
, state
),
142 "failed to retrieve GetInterfaceList");
145 if (state
->share_name
== NULL
) {
146 find_sofs_share(tctx
, &state
->share_name
);
152 static bool test_witness_UnRegister_with_handle(struct torture_context
*tctx
,
153 struct dcerpc_pipe
*p
,
154 struct policy_handle
*context_handle
)
156 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
157 struct witness_UnRegister r
;
159 r
.in
.context_handle
= *context_handle
;
161 torture_assert_ntstatus_ok(tctx
,
162 dcerpc_witness_UnRegister_r(b
, tctx
, &r
),
163 "UnRegister failed");
165 torture_assert_werr_ok(tctx
,
167 "UnRegister failed");
169 /* make sure we are not able/allowed to reuse context handles after they
170 * have been unregistered */
172 torture_assert_ntstatus_ok(tctx
,
173 dcerpc_witness_UnRegister_r(b
, tctx
, &r
),
174 "UnRegister failed");
176 torture_assert_werr_equal(tctx
,
178 WERR_INVALID_PARAMETER
,
179 "UnRegister failed");
184 static bool test_witness_UnRegister(struct torture_context
*tctx
,
185 struct dcerpc_pipe
*p
,
188 /* acquire handle and free afterwards */
192 static bool get_ip_address_from_interface(struct torture_context
*tctx
,
193 struct witness_interfaceInfo
*i
,
194 const char **ip_address
)
196 if (i
->flags
& WITNESS_INFO_IPv4_VALID
) {
197 *ip_address
= talloc_strdup(tctx
, i
->ipv4
);
198 torture_assert(tctx
, *ip_address
, "talloc_strdup failed");
202 if (i
->flags
& WITNESS_INFO_IPv6_VALID
) {
203 *ip_address
= talloc_strdup(tctx
, i
->ipv6
);
204 torture_assert(tctx
, *ip_address
, "talloc_strdup failed");
211 static bool check_valid_interface(struct torture_context
*tctx
,
212 struct witness_interfaceInfo
*i
)
214 /* continue looking for an interface that allows witness
216 if (!(i
->flags
& WITNESS_INFO_WITNESS_IF
)) {
220 /* witness should be available of course */
221 if (i
->state
!= WITNESS_STATE_AVAILABLE
) {
228 static bool test_witness_Register(struct torture_context
*tctx
,
229 struct dcerpc_pipe
*p
,
232 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
233 struct witness_Register r
;
234 struct policy_handle context_handle
;
235 struct torture_test_witness_state
*state
=
236 (struct torture_test_witness_state
*)data
;
240 enum witness_version version
;
241 const char *net_name
;
242 const char *ip_address
;
243 const char *client_computer_name
;
244 NTSTATUS expected_status
;
245 WERROR expected_result
;
249 .expected_status
= NT_STATUS_OK
,
250 .expected_result
= WERR_REVISION_MISMATCH
253 .expected_status
= NT_STATUS_OK
,
254 .expected_result
= WERR_REVISION_MISMATCH
257 .expected_status
= NT_STATUS_OK
,
258 .expected_result
= WERR_REVISION_MISMATCH
261 .expected_status
= NT_STATUS_OK
,
262 .expected_result
= WERR_REVISION_MISMATCH
264 .version
= WITNESS_V2
,
265 .expected_status
= NT_STATUS_OK
,
266 .expected_result
= WERR_REVISION_MISMATCH
268 .version
= WITNESS_V1
,
271 .client_computer_name
= "",
272 .expected_status
= NT_STATUS_OK
,
273 .expected_result
= WERR_INVALID_PARAMETER
275 .version
= WITNESS_V1
,
278 .client_computer_name
= lpcfg_netbios_name(tctx
->lp_ctx
),
279 .expected_status
= NT_STATUS_OK
,
280 .expected_result
= WERR_INVALID_PARAMETER
282 .version
= WITNESS_V2
,
285 .client_computer_name
= lpcfg_netbios_name(tctx
->lp_ctx
),
286 .expected_status
= NT_STATUS_OK
,
287 .expected_result
= WERR_REVISION_MISMATCH
289 .version
= WITNESS_V1
,
290 .net_name
= dcerpc_server_name(p
),
292 .client_computer_name
= lpcfg_netbios_name(tctx
->lp_ctx
),
293 .expected_status
= NT_STATUS_OK
,
294 .expected_result
= WERR_INVALID_PARAMETER
299 for (i
=0; i
< ARRAY_SIZE(tests
); i
++) {
303 r
.out
.context_handle
= &context_handle
;
305 r
.in
.version
= tests
[i
].version
;
306 r
.in
.net_name
= tests
[i
].net_name
;
307 r
.in
.ip_address
= tests
[i
].ip_address
;
308 r
.in
.client_computer_name
= tests
[i
].client_computer_name
;
310 torture_assert_ntstatus_equal(tctx
,
311 dcerpc_witness_Register_r(b
, tctx
, &r
),
312 tests
[i
].expected_status
,
315 torture_assert_werr_equal(tctx
,
317 tests
[i
].expected_result
,
320 if (W_ERROR_IS_OK(r
.out
.result
)) {
322 /* we have a handle, make sure to unregister it */
324 test_witness_UnRegister_with_handle(tctx
, p
, r
.out
.context_handle
),
325 "Failed to unregister");
329 init_witness_test_state(tctx
, p
, state
);
331 for (i
=0; state
->list
&& i
< state
->list
->num_interfaces
; i
++) {
333 const char *ip_address
;
334 struct witness_interfaceInfo interface
= state
->list
->interfaces
[i
];
336 if (!check_valid_interface(tctx
, &interface
)) {
341 get_ip_address_from_interface(tctx
, &interface
, &ip_address
),
342 "failed to get ip_address from interface");
344 r
.in
.version
= WITNESS_V1
;
345 r
.in
.net_name
= state
->net_name
;
346 r
.in
.ip_address
= ip_address
;
348 torture_assert_ntstatus_ok(tctx
,
349 dcerpc_witness_Register_r(b
, tctx
, &r
),
352 torture_assert_werr_ok(tctx
,
357 test_witness_UnRegister_with_handle(tctx
, p
, r
.out
.context_handle
),
358 "Failed to unregister");
364 static bool test_witness_RegisterEx(struct torture_context
*tctx
,
365 struct dcerpc_pipe
*p
,
368 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
369 struct witness_RegisterEx r
;
370 struct policy_handle context_handle
;
371 struct torture_test_witness_state
*state
=
372 (struct torture_test_witness_state
*)data
;
376 enum witness_version version
;
377 const char *net_name
;
378 const char *ip_address
;
379 const char *client_computer_name
;
380 NTSTATUS expected_status
;
381 WERROR expected_result
;
385 .expected_status
= NT_STATUS_OK
,
386 .expected_result
= WERR_REVISION_MISMATCH
389 .expected_status
= NT_STATUS_OK
,
390 .expected_result
= WERR_REVISION_MISMATCH
393 .expected_status
= NT_STATUS_OK
,
394 .expected_result
= WERR_REVISION_MISMATCH
397 .expected_status
= NT_STATUS_OK
,
398 .expected_result
= WERR_REVISION_MISMATCH
400 .version
= WITNESS_V1
,
401 .expected_status
= NT_STATUS_OK
,
402 .expected_result
= WERR_REVISION_MISMATCH
404 .version
= WITNESS_V2
,
407 .client_computer_name
= "",
408 .expected_status
= NT_STATUS_OK
,
409 .expected_result
= WERR_INVALID_PARAMETER
411 .version
= WITNESS_V2
,
414 .client_computer_name
= lpcfg_netbios_name(tctx
->lp_ctx
),
415 .expected_status
= NT_STATUS_OK
,
416 .expected_result
= WERR_INVALID_PARAMETER
418 .version
= WITNESS_V1
,
421 .client_computer_name
= lpcfg_netbios_name(tctx
->lp_ctx
),
422 .expected_status
= NT_STATUS_OK
,
423 .expected_result
= WERR_REVISION_MISMATCH
425 .version
= WITNESS_V2
,
426 .net_name
= dcerpc_server_name(p
),
428 .client_computer_name
= lpcfg_netbios_name(tctx
->lp_ctx
),
429 .expected_status
= NT_STATUS_OK
,
430 .expected_result
= WERR_INVALID_PARAMETER
435 for (i
=0; i
< ARRAY_SIZE(tests
); i
++) {
439 r
.out
.context_handle
= &context_handle
;
441 r
.in
.version
= tests
[i
].version
;
442 r
.in
.net_name
= tests
[i
].net_name
;
443 r
.in
.ip_address
= tests
[i
].ip_address
;
444 r
.in
.client_computer_name
= tests
[i
].client_computer_name
;
446 torture_assert_ntstatus_equal(tctx
,
447 dcerpc_witness_RegisterEx_r(b
, tctx
, &r
),
448 tests
[i
].expected_status
,
449 "RegisterEx failed");
451 torture_assert_werr_equal(tctx
,
453 tests
[i
].expected_result
,
454 "RegisterEx failed");
456 if (W_ERROR_IS_OK(r
.out
.result
)) {
458 /* we have a handle, make sure to unregister it */
460 test_witness_UnRegister_with_handle(tctx
, p
, r
.out
.context_handle
),
461 "Failed to unregister");
465 init_witness_test_state(tctx
, p
, state
);
467 for (i
=0; state
->list
&& i
< state
->list
->num_interfaces
; i
++) {
469 const char *ip_address
;
470 struct witness_interfaceInfo interface
= state
->list
->interfaces
[i
];
472 if (!check_valid_interface(tctx
, &interface
)) {
477 get_ip_address_from_interface(tctx
, &interface
, &ip_address
),
478 "failed to get ip_address from interface");
480 r
.in
.version
= WITNESS_V2
;
481 r
.in
.net_name
= state
->net_name
;
482 r
.in
.ip_address
= ip_address
;
485 * a valid request with an invalid sharename fails with
488 r
.in
.share_name
= "any_invalid_share_name";
490 torture_assert_ntstatus_ok(tctx
,
491 dcerpc_witness_RegisterEx_r(b
, tctx
, &r
),
492 "RegisterEx failed");
494 torture_assert_werr_equal(tctx
,
497 "RegisterEx failed");
499 r
.in
.share_name
= NULL
;
501 torture_assert_ntstatus_ok(tctx
,
502 dcerpc_witness_RegisterEx_r(b
, tctx
, &r
),
503 "RegisterEx failed");
505 torture_assert_werr_ok(tctx
,
507 "RegisterEx failed");
510 test_witness_UnRegister_with_handle(tctx
, p
, r
.out
.context_handle
),
511 "Failed to unregister");
517 static bool setup_clusapi_connection(struct torture_context
*tctx
,
518 struct torture_test_witness_state
*s
)
520 struct dcerpc_binding
*binding
;
526 torture_assert_ntstatus_ok(tctx
,
527 torture_rpc_binding(tctx
, &binding
),
528 "failed to retrieve torture binding");
530 torture_assert_ntstatus_ok(tctx
,
531 dcerpc_binding_set_transport(binding
, NCACN_IP_TCP
),
532 "failed to set transport");
534 torture_assert_ntstatus_ok(tctx
,
535 dcerpc_binding_set_flags(binding
, DCERPC_SEAL
, 0),
536 "failed to set dcerpc flags");
538 torture_assert_ntstatus_ok(tctx
,
539 dcerpc_pipe_connect_b(tctx
, &s
->clusapi
.p
, binding
,
541 samba_cmdline_get_creds(),
542 tctx
->ev
, tctx
->lp_ctx
),
543 "failed to connect dcerpc pipe");
549 static bool cluster_get_nodes(struct torture_context
*tctx
,
550 struct torture_test_witness_state
*s
)
552 struct clusapi_CreateEnum r
;
553 struct ENUM_LIST
*ReturnEnum
;
555 struct dcerpc_binding_handle
*b
;
558 setup_clusapi_connection(tctx
, s
),
559 "failed to setup clusapi connection");
561 b
= s
->clusapi
.p
->binding_handle
;
563 r
.in
.dwType
= CLUSTER_ENUM_NODE
;
564 r
.out
.ReturnEnum
= &ReturnEnum
;
565 r
.out
.rpc_status
= &rpc_status
;
567 torture_assert_ntstatus_ok(tctx
,
568 dcerpc_clusapi_CreateEnum_r(b
, tctx
, &r
),
569 "failed to enumerate nodes");
575 static bool test_GetResourceState_int(struct torture_context
*tctx
,
576 struct dcerpc_pipe
*p
,
577 struct policy_handle
*hResource
,
578 enum clusapi_ClusterResourceState
*State
)
580 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
581 struct clusapi_GetResourceState r
;
582 const char *NodeName
;
583 const char *GroupName
;
586 r
.in
.hResource
= *hResource
;
588 r
.out
.NodeName
= &NodeName
;
589 r
.out
.GroupName
= &GroupName
;
590 r
.out
.rpc_status
= &rpc_status
;
592 torture_assert_ntstatus_ok(tctx
,
593 dcerpc_clusapi_GetResourceState_r(b
, tctx
, &r
),
594 "GetResourceState failed");
595 torture_assert_werr_ok(tctx
,
597 "GetResourceState failed");
602 static bool toggle_cluster_resource_state(struct torture_context
*tctx
,
603 struct dcerpc_pipe
*p
,
604 const char *resource_name
,
605 enum clusapi_ClusterResourceState
*old_state
,
606 enum clusapi_ClusterResourceState
*new_state
)
608 struct policy_handle hResource
;
609 enum clusapi_ClusterResourceState State
;
612 test_OpenResource_int(tctx
, p
, resource_name
, &hResource
),
613 "failed to open resource");
615 test_GetResourceState_int(tctx
, p
, &hResource
, &State
),
616 "failed to query resource state");
623 case ClusterResourceOffline
:
624 if (!test_OnlineResource_int(tctx
, p
, &hResource
)) {
625 test_CloseResource_int(tctx
, p
, &hResource
);
626 torture_warning(tctx
, "failed to set resource online");
630 case ClusterResourceOnline
:
631 if (!test_OfflineResource_int(tctx
, p
, &hResource
)) {
632 test_CloseResource_int(tctx
, p
, &hResource
);
633 torture_warning(tctx
, "failed to set resource offline");
643 test_GetResourceState_int(tctx
, p
, &hResource
, &State
),
644 "failed to query resource state");
650 test_CloseResource_int(tctx
, p
, &hResource
);
655 static bool test_witness_AsyncNotify(struct torture_context
*tctx
,
656 struct dcerpc_pipe
*p
,
659 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
660 struct witness_AsyncNotify r
;
661 struct witness_notifyResponse
*response
;
662 struct torture_test_witness_state
*state
=
663 (struct torture_test_witness_state
*)data
;
666 init_witness_test_state(tctx
, p
, state
);
668 setup_clusapi_connection(tctx
, state
);
670 for (i
=0; state
->list
&& i
< state
->list
->num_interfaces
; i
++) {
672 const char *ip_address
;
673 struct witness_interfaceInfo interface
= state
->list
->interfaces
[i
];
674 struct witness_Register reg
;
675 struct tevent_req
*req
;
676 enum clusapi_ClusterResourceState old_state
, new_state
;
678 if (!check_valid_interface(tctx
, &interface
)) {
683 get_ip_address_from_interface(tctx
, &interface
, &ip_address
),
684 "failed to get ip_address from interface");
686 reg
.in
.version
= WITNESS_V1
;
687 reg
.in
.net_name
= state
->net_name
;
688 reg
.in
.ip_address
= ip_address
;
689 reg
.in
.client_computer_name
= lpcfg_netbios_name(tctx
->lp_ctx
);
690 reg
.out
.context_handle
= &state
->context_handle
;
692 torture_assert_ntstatus_ok(tctx
,
693 dcerpc_witness_Register_r(b
, tctx
, ®
),
696 torture_assert_werr_ok(tctx
,
700 r
.in
.context_handle
= state
->context_handle
;
701 r
.out
.response
= &response
;
703 req
= dcerpc_witness_AsyncNotify_r_send(tctx
, tctx
->ev
, b
, &r
);
704 torture_assert(tctx
, req
, "failed to create request");
707 toggle_cluster_resource_state(tctx
, state
->clusapi
.p
, state
->net_name
, &old_state
, &new_state
),
708 "failed to toggle cluster resource state");
709 torture_assert(tctx
, old_state
!= new_state
, "failed to change cluster resource state");
712 tevent_req_poll(req
, tctx
->ev
),
713 "failed to call event loop");
715 torture_assert_ntstatus_ok(tctx
,
716 dcerpc_witness_AsyncNotify_r_recv(req
, tctx
),
717 "failed to receive reply");
719 torture_assert_int_equal(tctx
, response
->num
, 1, "num");
720 torture_assert_int_equal(tctx
, response
->type
, WITNESS_NOTIFY_RESOURCE_CHANGE
, "type");
723 * TODO: find out how ClusterResourceOfflinePending and
724 * ClusterResourceOnlinePending are represented as witness
728 if (new_state
== ClusterResourceOffline
) {
729 torture_assert_int_equal(tctx
, response
->messages
[0].resource_change
.type
, WITNESS_RESOURCE_STATE_UNAVAILABLE
, "resource_change.type");
731 if (new_state
== ClusterResourceOnline
) {
732 torture_assert_int_equal(tctx
, response
->messages
[0].resource_change
.type
, WITNESS_RESOURCE_STATE_AVAILABLE
, "resource_change.type");
735 test_witness_UnRegister_with_handle(tctx
, p
, &state
->context_handle
),
736 "Failed to unregister");
738 ZERO_STRUCT(state
->context_handle
);
741 toggle_cluster_resource_state(tctx
, state
->clusapi
.p
, state
->net_name
, &old_state
, &new_state
),
742 "failed to toggle cluster resource state");
743 torture_assert(tctx
, old_state
!= new_state
, "failed to change cluster resource state");
749 static bool test_do_witness_RegisterEx(struct torture_context
*tctx
,
750 struct dcerpc_binding_handle
*b
,
752 const char *net_name
,
753 const char *share_name
,
754 const char *ip_address
,
755 const char *client_computer_name
,
758 struct policy_handle
*context_handle
)
760 struct witness_RegisterEx r
;
762 r
.in
.version
= version
;
763 r
.in
.net_name
= net_name
;
764 r
.in
.share_name
= NULL
;
765 r
.in
.ip_address
= ip_address
;
766 r
.in
.client_computer_name
= client_computer_name
;
768 r
.in
.timeout
= timeout
;
769 r
.out
.context_handle
= context_handle
;
771 torture_assert_ntstatus_ok(tctx
,
772 dcerpc_witness_RegisterEx_r(b
, tctx
, &r
),
773 "RegisterEx failed");
775 torture_assert_werr_ok(tctx
,
777 "RegisterEx failed");
782 static void torture_subunit_report_time(struct torture_context
*tctx
)
788 if (clock_gettime(CLOCK_REALTIME
, &tp
) != 0) {
789 torture_comment(tctx
, "failed to call clock_gettime");
793 tmp
= gmtime(&tp
.tv_sec
);
795 torture_comment(tctx
, "failed to call gmtime");
799 if (strftime(timestr
, sizeof(timestr
), "%Y-%m-%d %H:%M:%S", tmp
) <= 0) {
800 torture_comment(tctx
, "failed to call strftime");
804 torture_comment(tctx
, "time: %s.%06ld\n", timestr
, tp
.tv_nsec
/ 1000);
807 static bool test_witness_AsyncNotify_timeouts(struct torture_context
*tctx
,
808 struct dcerpc_pipe
*p
,
811 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
812 struct witness_AsyncNotify r
;
813 struct witness_notifyResponse
*response
;
814 struct torture_test_witness_state
*state
=
815 (struct torture_test_witness_state
*)data
;
818 init_witness_test_state(tctx
, p
, state
);
820 setup_clusapi_connection(tctx
, state
);
822 for (i
=0; state
->list
&& i
< state
->list
->num_interfaces
; i
++) {
824 const char *ip_address
;
825 struct witness_interfaceInfo interface
= state
->list
->interfaces
[i
];
826 uint32_t timeouts
[] = {
830 uint32_t old_timeout
;
832 if (!check_valid_interface(tctx
, &interface
)) {
837 get_ip_address_from_interface(tctx
, &interface
, &ip_address
),
838 "failed to get ip_address from interface");
840 for (t
=0; t
< ARRAY_SIZE(timeouts
); t
++) {
842 torture_comment(tctx
, "Testing Async Notify with timeout of %d milliseconds", timeouts
[t
]);
845 test_do_witness_RegisterEx(tctx
, b
,
850 lpcfg_netbios_name(tctx
->lp_ctx
),
853 &state
->context_handle
),
854 "failed to RegisterEx");
856 r
.in
.context_handle
= state
->context_handle
;
857 r
.out
.response
= &response
;
859 old_timeout
= dcerpc_binding_handle_set_timeout(b
, UINT_MAX
);
861 torture_subunit_report_time(tctx
);
863 torture_assert_ntstatus_ok(tctx
,
864 dcerpc_witness_AsyncNotify_r(b
, tctx
, &r
),
865 "AsyncNotify failed");
866 torture_assert_werr_equal(tctx
,
869 "AsyncNotify failed");
871 torture_subunit_report_time(tctx
);
873 dcerpc_binding_handle_set_timeout(b
, old_timeout
);
876 test_witness_UnRegister_with_handle(tctx
, p
, &state
->context_handle
),
877 "Failed to unregister");
879 ZERO_STRUCT(state
->context_handle
);
886 struct torture_suite
*torture_rpc_witness(TALLOC_CTX
*mem_ctx
)
888 struct torture_rpc_tcase
*tcase
;
889 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "witness");
890 struct torture_test_witness_state
*state
;
892 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "witness",
895 state
= talloc_zero(tcase
, struct torture_test_witness_state
);
897 torture_rpc_tcase_add_test_ex(tcase
, "GetInterfaceList",
898 test_witness_GetInterfaceList
, state
);
899 torture_rpc_tcase_add_test_ex(tcase
, "Register",
900 test_witness_Register
, state
);
901 torture_rpc_tcase_add_test_ex(tcase
, "UnRegister",
902 test_witness_UnRegister
, state
);
903 torture_rpc_tcase_add_test_ex(tcase
, "RegisterEx",
904 test_witness_RegisterEx
, state
);
905 torture_rpc_tcase_add_test_ex(tcase
, "AsyncNotify",
906 test_witness_AsyncNotify
, state
);
907 torture_rpc_tcase_add_test_ex(tcase
, "AsyncNotify_timeouts",
908 test_witness_AsyncNotify_timeouts
, state
);