1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

s4: torture: Add compound_async.write_write test to show we don't go async on the last write in a compound.

Add knownfail.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Jeremy Allison 2022-11-17 15:39:16 -08:00 committed by Ralph Boehme
parent fc6c76e6da
commit ffd9b94fe0
2 changed files with 105 additions and 0 deletions

View File

@ -0,0 +1 @@
^samba3.smb2.compound_async.write_write\(fileserver\)

View File

@ -20,6 +20,7 @@
*/
#include "includes.h"
#include "tevent.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
#include "torture/torture.h"
@ -44,6 +45,13 @@
ret = false; \
}} while (0)
#define WAIT_FOR_ASYNC_RESPONSE(req) \
while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) { \
if (tevent_loop_once(tctx->ev) != 0) { \
break; \
} \
}
static struct {
struct smb2_handle handle;
uint8_t level;
@ -2317,6 +2325,100 @@ static bool test_compound_async_flush_flush(struct torture_context *tctx,
return ret;
}
/*
* For Samba/smbd this test must be run against the aio_delay_inject share
* as we need to ensure the last write in the compound takes longer than
* 500 us, which is the threshold for going async in smbd SMB2 writes.
*/
static bool test_compound_async_write_write(struct torture_context *tctx,
struct smb2_tree *tree)
{
struct smb2_handle fhandle = { .data = { 0, 0 } };
struct smb2_handle relhandle = { .data = { UINT64_MAX, UINT64_MAX } };
struct smb2_write w1;
struct smb2_write w2;
const char *fname = "compound_async_write_write";
struct smb2_request *req[2];
NTSTATUS status;
bool is_smbd = torture_setting_bool(tctx, "smbd", true);
bool ret = false;
/* Start clean. */
smb2_util_unlink(tree, fname);
/* Create a file. */
status = torture_smb2_testfile_access(tree,
fname,
&fhandle,
SEC_RIGHTS_FILE_ALL);
CHECK_STATUS(status, NT_STATUS_OK);
/* Now do a compound write + write handle. */
smb2_transport_compound_start(tree->session->transport, 2);
ZERO_STRUCT(w1);
w1.in.file.handle = fhandle;
w1.in.offset = 0;
w1.in.data = data_blob_talloc_zero(tctx, 64);
req[0] = smb2_write_send(tree, &w1);
torture_assert_not_null_goto(tctx, req[0], ret, done,
"smb2_write_send (1) failed\n");
smb2_transport_compound_set_related(tree->session->transport, true);
ZERO_STRUCT(w2);
w2.in.file.handle = relhandle;
w2.in.offset = 64;
w2.in.data = data_blob_talloc_zero(tctx, 64);
req[1] = smb2_write_send(tree, &w2);
torture_assert_not_null_goto(tctx, req[0], ret, done,
"smb2_write_send (2) failed\n");
status = smb2_write_recv(req[0], &w1);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_write_recv (1) failed.");
if (!is_smbd) {
/*
* Windows and other servers don't go async.
*/
status = smb2_write_recv(req[1], &w2);
} else {
/*
* For smbd, the second write should go async
* as it's the last element of a compound.
*/
WAIT_FOR_ASYNC_RESPONSE(req[1]);
CHECK_VALUE(req[1]->cancel.can_cancel, true);
/*
* Now pick up the real return.
*/
status = smb2_write_recv(req[1], &w2);
}
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_write_recv (2) failed.");
status = smb2_util_close(tree, fhandle);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_util_close failed.");
ZERO_STRUCT(fhandle);
ret = true;
done:
if (fhandle.data[0] != 0) {
smb2_util_close(tree, fhandle);
}
smb2_util_unlink(tree, fname);
return ret;
}
struct torture_suite *torture_smb2_compound_init(TALLOC_CTX *ctx)
{
struct torture_suite *suite = torture_suite_create(ctx, "compound");
@ -2377,6 +2479,8 @@ struct torture_suite *torture_smb2_compound_async_init(TALLOC_CTX *ctx)
test_compound_async_flush_close);
torture_suite_add_1smb2_test(suite, "flush_flush",
test_compound_async_flush_flush);
torture_suite_add_1smb2_test(suite, "write_write",
test_compound_async_write_write);
suite->description = talloc_strdup(suite, "SMB2-COMPOUND-ASYNC tests");