s4:torture:smb2: add test open-oplock-all
authorGregor Beck <gbeck@sernet.de>
Thu, 22 Aug 2013 10:08:10 +0000 (12:08 +0200)
committerMichael Adam <obnox@samba.org>
Fri, 9 May 2014 10:58:19 +0000 (12:58 +0200)
source4/torture/smb2/durable_v2_open.c

index a0a07dfd2d6e60975350ec770fd057f6d8ad8ac5..84f0872e3c3205416f53bde99b9df9454f73ac05 100644 (file)
@@ -1788,6 +1788,123 @@ bool test_persistent_open_lease(struct torture_context *tctx,
        return ret;
 }
 
+static const char* OPLOCK_LEVEL[] = {"", "s", "x", "b", NULL};
+static const char* LEASE_TYPE[] = {"", "R", "RW", "RH", "RWH", NULL};
+static const char* SHARE_MODE[] = {"", "R", "W", "D", "RD", "RW", "WD", "RWD", NULL};
+
+struct open_oplock_result {
+       const char *level;
+       bool durable;
+       bool persistent;
+};
+
+static struct open_oplock_result
+open_oplock_result(struct smbXcli_tcon *tcon, const char *level,
+                  const char *share_mode, bool persistent)
+{
+       const uint32_t share_capabilities = smb2cli_tcon_capabilities(tcon);
+       const bool share_is_ca = share_capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
+       const bool share_is_sofs = share_capabilities & SMB2_SHARE_CAP_SCALEOUT;
+       const bool batch = (level[0] == 'b');
+
+       struct open_oplock_result ret = {
+               .level = (share_is_sofs && batch) ? "s" : level,
+               .durable = (share_is_ca && persistent) || (!share_is_sofs && batch),
+               .persistent = persistent && share_is_ca,
+       };
+
+       (void)share_mode;
+       return ret;
+}
+
+static bool test_open_oplock(struct torture_context *tctx,
+                            struct smb2_tree *tree,
+                            const char *fname,
+                            const char *level,
+                            const char *share_mode,
+                            bool persistent)
+{
+       NTSTATUS status;
+       TALLOC_CTX *mem_ctx = talloc_new(tctx);
+       struct smb2_handle _h;
+       struct smb2_handle *h = NULL;
+       bool ret = true;
+       struct smb2_create io;
+       struct open_oplock_result exp = open_oplock_result(tree->smbXcli, level, share_mode, persistent);
+
+       torture_result(tctx, TORTURE_OK,
+                      "durable_v2_open_oplock: level: \"%3s\" shm: \"%3s\" %s",
+                      level, share_mode, persistent ? "persistent" : "");
+
+
+       smb2_util_unlink(tree, fname);
+
+       smb2_oplock_create_share(&io, fname,
+                                smb2_util_share_access(share_mode),
+                                smb2_util_oplock_level(level));
+       io.in.durable_open = false;
+       io.in.durable_open_v2 = true;
+       io.in.persistent_open = persistent;
+       io.in.create_guid = GUID_random();
+
+       status = smb2_create(tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       _h = io.out.file.handle;
+       h = &_h;
+
+
+       CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
+       CHECK_VAL(io.out.durable_open, false);
+       CHECK_VAL(io.out.durable_open_v2, exp.durable);
+       CHECK_VAL(io.out.persistent_open, exp.persistent);
+       CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level(exp.level));
+
+       if (!ret) {
+               torture_result(tctx, TORTURE_FAIL, "durable_v2_open_oplock failed, "
+                              "expected durable: %d persistent: %d level \"%s\"",
+                              exp.durable, exp.persistent, exp.level);
+       }
+done:
+       if (h != NULL) {
+               smb2_util_close(tree, *h);
+       }
+       smb2_util_unlink(tree, fname);
+       talloc_free(mem_ctx);
+
+       return ret;
+}
+
+static bool test_open_oplock_all(struct torture_context *tctx,
+                               struct smb2_tree *tree)
+{
+       bool ret = true;
+       uint32_t share_capabilities = smb2cli_tcon_capabilities(tree->smbXcli);
+       uint32_t server_capabilities = smb2cli_conn_server_capabilities(tree->session->transport->conn);
+       TALLOC_CTX *frame = talloc_stackframe();
+       const char *fname = talloc_asprintf(frame, "open_oplock_all_%s.dat", generate_random_str(frame, 8));
+       int persistent;
+
+       torture_comment(tctx, "server capabilities: 0x%08x\n", server_capabilities);
+       torture_comment(tctx, "share capabilities: 0x%08x\n", share_capabilities);
+
+       for (persistent=0; persistent <2; persistent++) {
+               const char **level;
+               for (level=&OPLOCK_LEVEL[0]; *level; level++) {
+                       const char **shm;
+                       for (shm=&SHARE_MODE[0]; *shm; shm++) {
+                               ret &= test_open_oplock(tctx, tree, fname,
+                                                       *level, *shm, persistent);
+                       }
+               }
+       }
+       if (!ret) {
+               torture_result(tctx, TORTURE_FAIL, "durable_v2_open_oplock_all failed\n");
+       }
+       talloc_free(frame);
+       return ret;
+
+}
+
 struct torture_suite *torture_smb2_durable_v2_open_init(void)
 {
        struct torture_suite *suite =
@@ -1806,6 +1923,7 @@ struct torture_suite *torture_smb2_durable_v2_open_init(void)
        torture_suite_add_2smb2_test(suite, "app-instance", test_durable_v2_open_app_instance);
        torture_suite_add_1smb2_test(suite, "persistent-open-oplock", test_persistent_open_oplock);
        torture_suite_add_1smb2_test(suite, "persistent-open-lease", test_persistent_open_lease);
+       torture_suite_add_1smb2_test(suite, "open-oplock-all", test_open_oplock_all);
 
        suite->description = talloc_strdup(suite, "SMB2-DURABLE-V2-OPEN tests");