[PATCH v2 2/4] torture: add timeout sleeps to fsrvp create helper

David Disseldorp ddiss at samba.org
Fri Jun 20 11:14:13 MDT 2014


Attempt to trip message sequence timeouts at various points in the FSRVP
shadow-copy creation state machine.

The default timeout-injection sleep durations correspond to those
documented in MS-FSRVP (+500ms). They can also be manually set using the
"fss: sequence timeout" parameter.

Signed-off-by: David Disseldorp <ddiss at samba.org>
---
 source4/torture/rpc/fsrvp.c | 98 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 92 insertions(+), 6 deletions(-)

diff --git a/source4/torture/rpc/fsrvp.c b/source4/torture/rpc/fsrvp.c
index 85d188e..42247fd 100644
--- a/source4/torture/rpc/fsrvp.c
+++ b/source4/torture/rpc/fsrvp.c
@@ -130,9 +130,21 @@ static bool test_fsrvp_set_ctx(struct torture_context *tctx,
 	return true;
 }
 
+enum test_fsrvp_inject {
+	TEST_FSRVP_TOUT_NONE = 0,
+	TEST_FSRVP_TOUT_SET_CTX,
+	TEST_FSRVP_TOUT_START_SET,
+	TEST_FSRVP_TOUT_ADD_TO_SET,
+	TEST_FSRVP_TOUT_PREPARE,
+	TEST_FSRVP_TOUT_COMMIT,
+
+	TEST_FSRVP_STOP_B4_EXPOSE,
+};
+
 static bool test_fsrvp_sc_create(struct torture_context *tctx,
 				 struct dcerpc_pipe *p,
 				 const char *share,
+				 enum test_fsrvp_inject inject,
 				 struct fssagent_share_mapping_1 **sc_map)
 {
 	struct fss_IsPathSupported r_pathsupport_get;
@@ -149,7 +161,8 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx,
 	NTSTATUS status;
 	time_t start_time;
 	TALLOC_CTX *tmp_ctx = talloc_new(tctx);
-	struct fssagent_share_mapping_1 *map;
+	struct fssagent_share_mapping_1 *map = NULL;
+	int sleep_time;
 
 	/*
 	 * PrepareShadowCopySet & CommitShadowCopySet often exceed the default
@@ -181,16 +194,37 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx,
 	torture_assert_int_equal(tctx, r_context_set.out.result, 0,
 				 "failed SetContext response");
 
+	if (inject == TEST_FSRVP_TOUT_SET_CTX) {
+		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
+					    "sequence timeout", 180);
+		torture_comment(tctx, "sleeping for %d\n", sleep_time);
+		smb_msleep((sleep_time * 1000) + 500);
+	}
+
 	ZERO_STRUCT(r_scset_start);
 	r_scset_start.in.ClientShadowCopySetId = GUID_random();
 	status = dcerpc_fss_StartShadowCopySet_r(b, tmp_ctx, &r_scset_start);
 	torture_assert_ntstatus_ok(tctx, status,
 				   "StartShadowCopySet failed");
+	if (inject == TEST_FSRVP_TOUT_SET_CTX) {
+		/* expect error due to message sequence timeout after set_ctx */
+		torture_assert_int_equal(tctx, r_scset_start.out.result,
+					 FSRVP_E_BAD_STATE,
+					 "StartShadowCopySet timeout response");
+		goto done;
+	}
 	torture_assert_int_equal(tctx, r_scset_start.out.result, 0,
 				 "failed StartShadowCopySet response");
 	torture_comment(tctx, "%s: shadow-copy set created\n",
 			GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId));
 
+	if (inject == TEST_FSRVP_TOUT_START_SET) {
+		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
+					    "sequence timeout", 180);
+		torture_comment(tctx, "sleeping for %d\n", sleep_time);
+		smb_msleep((sleep_time * 1000) + 500);
+	}
+
 	ZERO_STRUCT(r_scset_add1);
 	r_scset_add1.in.ClientShadowCopyId = GUID_random();
 	r_scset_add1.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
@@ -198,6 +232,12 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx,
 	status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add1);
 	torture_assert_ntstatus_ok(tctx, status,
 				   "AddToShadowCopySet failed");
+	if (inject == TEST_FSRVP_TOUT_START_SET) {
+		torture_assert_int_equal(tctx, r_scset_add1.out.result,
+					 HRES_ERROR_V(HRES_E_INVALIDARG),
+					 "AddToShadowCopySet timeout response");
+		goto done;
+	}
 	torture_assert_int_equal(tctx, r_scset_add1.out.result, 0,
 				 "failed AddToShadowCopySet response");
 	torture_comment(tctx, "%s(%s): %s added to shadow-copy set\n",
@@ -217,6 +257,13 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx,
 				 FSRVP_E_OBJECT_ALREADY_EXISTS,
 				 "failed AddToShadowCopySet response");
 
+	if (inject == TEST_FSRVP_TOUT_ADD_TO_SET) {
+		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
+					    "sequence timeout", 1800);
+		torture_comment(tctx, "sleeping for %d\n", sleep_time);
+		smb_msleep((sleep_time * 1000) + 500);
+	}
+
 	start_time = time_mono(NULL);
 	ZERO_STRUCT(r_scset_prep);
 	r_scset_prep.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
@@ -225,12 +272,25 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx,
 	status = dcerpc_fss_PrepareShadowCopySet_r(b, tmp_ctx, &r_scset_prep);
 	torture_assert_ntstatus_ok(tctx, status,
 				   "PrepareShadowCopySet failed");
+	if (inject == TEST_FSRVP_TOUT_ADD_TO_SET) {
+		torture_assert_int_equal(tctx, r_scset_prep.out.result,
+					 HRES_ERROR_V(HRES_E_INVALIDARG),
+					 "PrepareShadowCopySet tout response");
+		goto done;
+	}
 	torture_assert_int_equal(tctx, r_scset_prep.out.result, 0,
 				 "failed PrepareShadowCopySet response");
 	torture_comment(tctx, "%s: prepare completed in %llu secs\n",
 			GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
 			(unsigned long long)(time_mono(NULL) - start_time));
 
+	if (inject == TEST_FSRVP_TOUT_PREPARE) {
+		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
+					    "sequence timeout", 1800);
+		torture_comment(tctx, "sleeping for %d\n", sleep_time);
+		smb_msleep((sleep_time * 1000) + 500);
+	}
+
 	start_time = time_mono(NULL);
 	ZERO_STRUCT(r_scset_commit);
 	r_scset_commit.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
@@ -238,12 +298,31 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx,
 	status = dcerpc_fss_CommitShadowCopySet_r(b, tmp_ctx, &r_scset_commit);
 	torture_assert_ntstatus_ok(tctx, status,
 				   "CommitShadowCopySet failed");
+	if (inject == TEST_FSRVP_TOUT_PREPARE) {
+		torture_assert_int_equal(tctx, r_scset_commit.out.result,
+					 HRES_ERROR_V(HRES_E_INVALIDARG),
+					 "CommitShadowCopySet tout response");
+		goto done;
+	}
 	torture_assert_int_equal(tctx, r_scset_commit.out.result, 0,
 				 "failed CommitShadowCopySet response");
 	torture_comment(tctx, "%s: commit completed in %llu secs\n",
 			GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
 			(unsigned long long)(time_mono(NULL) - start_time));
 
+	if (inject == TEST_FSRVP_TOUT_COMMIT) {
+		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
+					    "sequence timeout", 180);
+		torture_comment(tctx, "sleeping for %d\n", sleep_time);
+		smb_msleep((sleep_time * 1000) + 500);
+	} else if (inject == TEST_FSRVP_STOP_B4_EXPOSE) {
+		/* return partial snapshot information */
+		map = talloc_zero(tctx, struct fssagent_share_mapping_1);
+		map->ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
+		map->ShadowCopyId = *r_scset_add1.out.pShadowCopyId;
+		goto done;
+	}
+
 	start_time = time_mono(NULL);
 	ZERO_STRUCT(r_scset_expose);
 	r_scset_expose.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
@@ -251,6 +330,12 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx,
 	status = dcerpc_fss_ExposeShadowCopySet_r(b, tmp_ctx, &r_scset_expose);
 	torture_assert_ntstatus_ok(tctx, status,
 				   "ExposeShadowCopySet failed");
+	if (inject == TEST_FSRVP_TOUT_COMMIT) {
+		torture_assert_int_equal(tctx, r_scset_expose.out.result,
+					 HRES_ERROR_V(HRES_E_INVALIDARG),
+					 "ExposeShadowCopySet tout response");
+		goto done;
+	}
 	torture_assert_int_equal(tctx, r_scset_expose.out.result, 0,
 				 "failed ExposeShadowCopySet response");
 	torture_comment(tctx, "%s: expose completed in %llu secs\n",
@@ -289,6 +374,7 @@ static bool test_fsrvp_sc_create(struct torture_context *tctx,
 					   &map->ShadowCopyId),
 		       "sc GUID missmatch in GetShareMapping");
 
+done:
 	talloc_free(tmp_ctx);
 	*sc_map = map;
 
@@ -323,7 +409,7 @@ static bool test_fsrvp_sc_create_simple(struct torture_context *tctx,
 	char *share_unc = talloc_asprintf(tctx, "\\\\%s\\%s",
 					  dcerpc_server_name(p), FSHARE);
 
-	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, &sc_map),
+	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
 		       "sc create");
 
 	torture_assert(tctx, test_fsrvp_sc_delete(tctx, p, sc_map), "sc del");
@@ -405,7 +491,7 @@ static bool test_fsrvp_bad_id(struct torture_context *tctx,
 	char *share_unc = talloc_asprintf(tmp_ctx, "\\\\%s\\%s\\",
 					  dcerpc_server_name(p), FSHARE);
 
-	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, &sc_map),
+	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
 		       "sc create");
 
 	ZERO_STRUCT(r_sharemap_del);
@@ -477,7 +563,7 @@ static bool test_fsrvp_sc_share_io(struct torture_context *tctx,
 	torture_assert_ntstatus_ok(tctx, status, "src write");
 
 
-	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, &sc_map),
+	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
 		       "sc create");
 
 	status = smb2_util_write(tree_base, base_fh, "post-snap", 0,
@@ -607,7 +693,7 @@ static bool test_fsrvp_enum_created(struct torture_context *tctx,
 		       "count");
 	torture_assert_int_equal(tctx, count, 0, "num snaps");
 
-	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, &sc_map),
+	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
 		       "sc create");
 	talloc_free(sc_map);
 
@@ -622,7 +708,7 @@ static bool test_fsrvp_enum_created(struct torture_context *tctx,
 	torture_assert_int_equal(tctx, count, 1, "num snaps");
 
 	smb_msleep(1100);	/* @GMT tokens have a 1 second resolution */
-	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, &sc_map),
+	torture_assert(tctx, test_fsrvp_sc_create(tctx, p, share_unc, TEST_FSRVP_TOUT_NONE, &sc_map),
 		       "sc create");
 	talloc_free(sc_map);
 
-- 
1.8.4.5



More information about the samba-technical mailing list