summaryrefslogtreecommitdiff
path: root/source4/torture
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2008-02-09 20:06:54 +0100
committerJelmer Vernooij <jelmer@samba.org>2008-02-09 20:06:54 +0100
commitec106a14216ee034b7e04c177c89703e63dfd107 (patch)
tree59c56cd663ee3dc03d0ce63bf4405ee87c14834a /source4/torture
parent4075a2ba982ea56ff925e0a33839f0760fd71911 (diff)
parent1a2544a24c064e9eecb973439ccd0e7126e06e77 (diff)
downloadsamba-ec106a14216ee034b7e04c177c89703e63dfd107.tar.gz
samba-ec106a14216ee034b7e04c177c89703e63dfd107.tar.bz2
samba-ec106a14216ee034b7e04c177c89703e63dfd107.zip
Merge branch 'v4-0-trivial' into v4-0-python
(This used to be commit b874f07175ae38a041f53f0e4ac6a4050dcefeae)
Diffstat (limited to 'source4/torture')
-rw-r--r--source4/torture/config.mk10
-rw-r--r--source4/torture/libnet/libnet_BecomeDC.c60
-rw-r--r--source4/torture/raw/offline.c508
-rw-r--r--source4/torture/raw/open.c5
-rw-r--r--source4/torture/raw/raw.c1
-rw-r--r--source4/torture/rpc/spoolss_notify.c11
-rw-r--r--source4/torture/torture.pc.in12
-rw-r--r--source4/torture/util.c73
-rw-r--r--source4/torture/util_smb.c39
9 files changed, 605 insertions, 114 deletions
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index dd0ca83f7d..e9ef18ac07 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -1,8 +1,8 @@
# TORTURE subsystem
[LIBRARY::torture]
-DESCRIPTION = Samba torture (test) suite
SO_VERSION = 0
VERSION = 0.0.1
+PC_FILE = torture.pc
PUBLIC_HEADERS = torture.h ui.h
PUBLIC_PROTO_HEADER = proto.h
OBJ_FILES = \
@@ -14,7 +14,7 @@ PUBLIC_DEPENDENCIES = \
LIBTALLOC
[SUBSYSTEM::TORTURE_UTIL]
-OBJ_FILES = util.o util_smb.o
+OBJ_FILES = util_smb.o
PRIVATE_DEPENDENCIES = LIBCLI_RAW
PUBLIC_PROTO_HEADER = util.h
PUBLIC_DEPENDENCIES = POPT_CREDENTIALS
@@ -88,7 +88,8 @@ OBJ_FILES = \
raw/samba3hide.o \
raw/samba3misc.o \
raw/composite.o \
- raw/raw.o
+ raw/raw.o \
+ raw/offline.o
PRIVATE_DEPENDENCIES = \
LIBCLI_SMB LIBCLI_LSA LIBCLI_SMB_COMPOSITE \
POPT_CREDENTIALS TORTURE_UTIL
@@ -296,7 +297,8 @@ PRIVATE_DEPENDENCIES = \
LIBSAMBA-NET \
smbcalls \
POPT_CREDENTIALS \
- torture_rpc
+ torture_rpc \
+ LIBPYTHON
# End SUBSYSTEM TORTURE_NET
#################################
diff --git a/source4/torture/libnet/libnet_BecomeDC.c b/source4/torture/libnet/libnet_BecomeDC.c
index 10625b25de..0ef6a03a6a 100644
--- a/source4/torture/libnet/libnet_BecomeDC.c
+++ b/source4/torture/libnet/libnet_BecomeDC.c
@@ -60,7 +60,9 @@ struct test_become_dc_state {
const char *configdn_ldb;
const char *schemadn_ldb;
const char *secrets_ldb;
+ const char *templates_ldb;
const char *secrets_keytab;
+ const char *dns_keytab;
} path;
};
@@ -88,7 +90,6 @@ static NTSTATUS test_become_dc_check_options(void *private_data,
return NT_STATUS_OK;
}
-#ifndef PROVISION_PYTHON
#include "lib/appweb/ejs/ejs.h"
#include "lib/appweb/ejs/ejsInternal.h"
#include "scripting/ejs/smbcalls.h"
@@ -146,14 +147,16 @@ failed:
return ejs_error;
}
-static NTSTATUS test_become_dc_prepare_db(void *private_data,
- const struct libnet_BecomeDC_PrepareDB *p)
+static NTSTATUS test_become_dc_prepare_db_ejs(void *private_data,
+ const struct libnet_BecomeDC_PrepareDB *p)
{
struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
char *ejs;
int ret;
bool ok;
+ DEBUG(0,("Provision for Become-DC test using EJS\n"));
+
DEBUG(0,("New Server[%s] in Site[%s]\n",
p->dest_dsa->dns_name, p->dest_dsa->site_name));
@@ -195,26 +198,10 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
"subobj.SCHEMADN = \"%s\";\n"
"subobj.SCHEMADN_LDB = \"%s\";\n"
"subobj.HOSTNAME = \"%s\";\n"
- "subobj.DNSNAME = \"%s\";\n"
+ "subobj.REALM = \"%s\";\n"
+ "subobj.DOMAIN = \"%s\";\n"
"subobj.DEFAULTSITE = \"%s\";\n"
"\n"
- "modules_list = new Array(\"rootdse\",\n"
- " \"kludge_acl\",\n"
- " \"paged_results\",\n"
- " \"server_sort\",\n"
- " \"extended_dn\",\n"
- " \"asq\",\n"
- " \"samldb\",\n"
- " \"operational\",\n"
- " \"objectclass\",\n"
- " \"rdn_name\",\n"
- " \"show_deleted\",\n"
- " \"partition\");\n"
- "subobj.MODULES_LIST = join(\",\", modules_list);\n"
- "subobj.DOMAINDN_MOD = \"pdc_fsmo,password_hash,repl_meta_data\";\n"
- "subobj.CONFIGDN_MOD = \"naming_fsmo,repl_meta_data\";\n"
- "subobj.SCHEMADN_MOD = \"schema_fsmo,repl_meta_data\";\n"
- "\n"
"subobj.KRBTGTPASS = \"_NOT_USED_\";\n"
"subobj.MACHINEPASS = \"%s\";\n"
"subobj.ADMINPASS = \"_NOT_USED_\";\n"
@@ -222,7 +209,9 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
"var paths = provision_default_paths(subobj);\n"
"paths.samdb = \"%s\";\n"
"paths.secrets = \"%s\";\n"
+ "paths.templates = \"%s\";\n"
"paths.keytab = \"%s\";\n"
+ "paths.dns_keytab = \"%s\";\n"
"\n"
"var system_session = system_session();\n"
"\n"
@@ -238,12 +227,15 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
p->forest->schema_dn_str, /* subobj.SCHEMADN */
s->path.schemadn_ldb, /* subobj.SCHEMADN_LDB */
p->dest_dsa->netbios_name, /* subobj.HOSTNAME */
- p->dest_dsa->dns_name, /* subobj.DNSNAME */
+ torture_join_dom_dns_name(s->tj),/* subobj.REALM */
+ torture_join_dom_netbios_name(s->tj),/* subobj.DOMAIN */
p->dest_dsa->site_name, /* subobj.DEFAULTSITE */
cli_credentials_get_password(s->machine_account),/* subobj.MACHINEPASS */
s->path.samdb_ldb, /* paths.samdb */
+ s->path.templates_ldb, /* paths.templates */
s->path.secrets_ldb, /* paths.secrets */
- s->path.secrets_keytab); /* paths.keytab */
+ s->path.secrets_keytab, /* paths.keytab */
+ s->path.dns_keytab); /* paths.dns_keytab */
NT_STATUS_HAVE_NO_MEMORY(ejs);
ret = test_run_ejs(ejs);
@@ -283,18 +275,20 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
return NT_STATUS_OK;
}
-#else
+#ifdef HAVE_WORKING_PYTHON
#include "param/param.h"
#include <Python.h>
#include "scripting/python/modules.h"
-static NTSTATUS test_become_dc_prepare_db(void *private_data,
- const struct libnet_BecomeDC_PrepareDB *p)
+static NTSTATUS test_become_dc_prepare_db_py(void *private_data,
+ const struct libnet_BecomeDC_PrepareDB *p)
{
struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state);
bool ok;
PyObject *provision_fn, *result, *parameters;
+ DEBUG(0,("Provision for Become-DC test using PYTHON\n"));
+
py_load_samba_modules();
Py_Initialize();
@@ -387,8 +381,7 @@ static NTSTATUS test_become_dc_prepare_db(void *private_data,
return NT_STATUS_OK;
}
-
-#endif
+#endif /* HAVE_WORKING_PYTHON */
static NTSTATUS test_apply_schema(struct test_become_dc_state *s,
const struct libnet_BecomeDC_StoreChunk *c)
@@ -854,8 +847,12 @@ bool torture_net_become_dc(struct torture_context *torture)
if (!s->path.schemadn_ldb) return false;
s->path.secrets_ldb = talloc_asprintf(s, "%s_secrets.ldb", s->netbios_name);
if (!s->path.secrets_ldb) return false;
+ s->path.templates_ldb = talloc_asprintf(s, "%s_templates.ldb", s->netbios_name);
+ if (!s->path.templates_ldb) return false;
s->path.secrets_keytab = talloc_asprintf(s, "%s_secrets.keytab", s->netbios_name);
if (!s->path.secrets_keytab) return false;
+ s->path.dns_keytab = talloc_asprintf(s, "%s_dns.keytab", s->netbios_name);
+ if (!s->path.dns_keytab) return false;
/* Join domain as a member server. */
s->tj = torture_join_domain(torture, s->netbios_name,
@@ -881,7 +878,12 @@ bool torture_net_become_dc(struct torture_context *torture)
b.in.callbacks.private_data = s;
b.in.callbacks.check_options = test_become_dc_check_options;
- b.in.callbacks.prepare_db = test_become_dc_prepare_db;
+ b.in.callbacks.prepare_db = test_become_dc_prepare_db_ejs;
+#ifdef HAVE_WORKING_PYTHON
+ if (getenv("PROVISION_PYTHON")) {
+ b.in.callbacks.prepare_db = test_become_dc_prepare_db_py;
+ }
+#endif
b.in.callbacks.schema_chunk = test_become_dc_schema_chunk;
b.in.callbacks.config_chunk = test_become_dc_store_chunk;
b.in.callbacks.domain_chunk = test_become_dc_store_chunk;
diff --git a/source4/torture/raw/offline.c b/source4/torture/raw/offline.c
new file mode 100644
index 0000000000..1340692faa
--- /dev/null
+++ b/source4/torture/raw/offline.c
@@ -0,0 +1,508 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Andrew Tridgell 2008
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ test offline files
+ */
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "libcli/raw/libcliraw.h"
+#include "system/time.h"
+#include "system/filesys.h"
+#include "libcli/libcli.h"
+#include "torture/util.h"
+#include "lib/events/events.h"
+#include "lib/cmdline/popt_common.h"
+#include "libcli/composite/composite.h"
+#include "libcli/smb_composite/smb_composite.h"
+#include "libcli/resolve/resolve.h"
+#include "param/param.h"
+
+#define BASEDIR "\\testoffline"
+
+static int nconnections;
+static int numstates;
+static int num_connected;
+static int test_failed;
+extern int torture_numops;
+extern int torture_entries;
+static bool test_finished;
+
+enum offline_op {OP_LOADFILE, OP_SAVEFILE, OP_SETOFFLINE, OP_GETOFFLINE, OP_ENDOFLIST};
+
+static double latencies[OP_ENDOFLIST];
+static double worst_latencies[OP_ENDOFLIST];
+
+#define FILE_SIZE 8192
+
+
+struct offline_state {
+ struct torture_context *tctx;
+ struct event_context *ev;
+ struct smbcli_tree *tree;
+ TALLOC_CTX *mem_ctx;
+ int client;
+ int fnum;
+ uint32_t count;
+ uint32_t lastcount;
+ uint32_t fnumber;
+ uint32_t offline_count;
+ uint32_t online_count;
+ char *fname;
+ struct smb_composite_loadfile *loadfile;
+ struct smb_composite_savefile *savefile;
+ struct smbcli_request *req;
+ enum offline_op op;
+ struct timeval tv_start;
+};
+
+static void test_offline(struct offline_state *state);
+
+
+static char *filename(TALLOC_CTX *ctx, int i)
+{
+ char *s = talloc_asprintf(ctx, BASEDIR "\\file%u.dat", i);
+ return s;
+}
+
+
+/*
+ called when a loadfile completes
+ */
+static void loadfile_callback(struct composite_context *ctx)
+{
+ struct offline_state *state = ctx->async.private_data;
+ NTSTATUS status;
+ int i;
+
+ status = smb_composite_loadfile_recv(ctx, state->mem_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Failed to read file '%s' - %s\n",
+ state->loadfile->in.fname, nt_errstr(status));
+ test_failed++;
+ }
+
+ /* check the data is correct */
+ if (state->loadfile->out.size != FILE_SIZE) {
+ printf("Wrong file size %u - expected %u\n",
+ state->loadfile->out.size, FILE_SIZE);
+ test_failed++;
+ return;
+ }
+
+ for (i=0;i<FILE_SIZE;i++) {
+ if (state->loadfile->out.data[i] != state->fnumber % 256) {
+ printf("Bad data in file %u\n", state->fnumber);
+ test_failed++;
+ return;
+ }
+ }
+
+ talloc_steal(state->loadfile, state->loadfile->out.data);
+
+ state->count++;
+ talloc_free(state->loadfile);
+ state->loadfile = NULL;
+
+ if (!test_finished) {
+ test_offline(state);
+ }
+}
+
+
+/*
+ called when a savefile completes
+ */
+static void savefile_callback(struct composite_context *ctx)
+{
+ struct offline_state *state = ctx->async.private_data;
+ NTSTATUS status;
+
+ status = smb_composite_savefile_recv(ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Failed to save file '%s' - %s\n",
+ state->savefile->in.fname, nt_errstr(status));
+ test_failed++;
+ }
+
+ state->count++;
+ talloc_free(state->savefile);
+ state->savefile = NULL;
+
+ if (!test_finished) {
+ test_offline(state);
+ }
+}
+
+
+/*
+ called when a setoffline completes
+ */
+static void setoffline_callback(struct smbcli_request *req)
+{
+ struct offline_state *state = req->async.private;
+ NTSTATUS status;
+
+ status = smbcli_request_simple_recv(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Failed to set offline file '%s' - %s\n",
+ state->fname, nt_errstr(status));
+ test_failed++;
+ }
+
+ state->req = NULL;
+ state->count++;
+
+ if (!test_finished) {
+ test_offline(state);
+ }
+}
+
+
+/*
+ called when a getoffline completes
+ */
+static void getoffline_callback(struct smbcli_request *req)
+{
+ struct offline_state *state = req->async.private;
+ NTSTATUS status;
+ union smb_fileinfo io;
+
+ io.getattr.level = RAW_FILEINFO_GETATTR;
+
+ status = smb_raw_pathinfo_recv(req, state->mem_ctx, &io);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Failed to get offline file '%s' - %s\n",
+ state->fname, nt_errstr(status));
+ test_failed++;
+ }
+
+ if (io.getattr.out.attrib & FILE_ATTRIBUTE_OFFLINE) {
+ state->offline_count++;
+ } else {
+ state->online_count++;
+ }
+
+ state->req = NULL;
+ state->count++;
+
+ if (!test_finished) {
+ test_offline(state);
+ }
+}
+
+
+/*
+ send the next offline file fetch request
+*/
+static void test_offline(struct offline_state *state)
+{
+ struct composite_context *ctx;
+ double lat;
+
+ lat = timeval_elapsed(&state->tv_start);
+ if (latencies[state->op] < lat) {
+ latencies[state->op] = lat;
+ }
+
+ state->op = (enum offline_op) (random() % OP_ENDOFLIST);
+
+ state->fnumber = random() % torture_numops;
+ talloc_free(state->fname);
+ state->fname = filename(state->mem_ctx, state->fnumber);
+
+ state->tv_start = timeval_current();
+
+ switch (state->op) {
+ case OP_LOADFILE:
+ state->loadfile = talloc_zero(state->mem_ctx, struct smb_composite_loadfile);
+ state->loadfile->in.fname = state->fname;
+
+ ctx = smb_composite_loadfile_send(state->tree, state->loadfile);
+ if (ctx == NULL) {
+ printf("Failed to setup loadfile for %s\n", state->fname);
+ test_failed = true;
+ }
+
+ talloc_steal(state->loadfile, ctx);
+
+ ctx->async.fn = loadfile_callback;
+ ctx->async.private_data = state;
+ break;
+
+ case OP_SAVEFILE:
+ state->savefile = talloc_zero(state->mem_ctx, struct smb_composite_savefile);
+
+ state->savefile->in.fname = state->fname;
+ state->savefile->in.data = talloc_size(state->savefile, FILE_SIZE);
+ state->savefile->in.size = FILE_SIZE;
+ memset(state->savefile->in.data, state->fnumber, FILE_SIZE);
+
+ ctx = smb_composite_savefile_send(state->tree, state->savefile);
+ if (ctx == NULL) {
+ printf("Failed to setup savefile for %s\n", state->fname);
+ test_failed = true;
+ }
+
+ talloc_steal(state->savefile, ctx);
+
+ ctx->async.fn = savefile_callback;
+ ctx->async.private_data = state;
+ break;
+
+ case OP_SETOFFLINE: {
+ union smb_setfileinfo io;
+ ZERO_STRUCT(io);
+ io.setattr.level = RAW_SFILEINFO_SETATTR;
+ io.setattr.in.attrib = FILE_ATTRIBUTE_OFFLINE;
+ io.setattr.in.file.path = state->fname;
+ /* make the file 1 hour old, to get past mininum age restrictions
+ for HSM systems */
+ io.setattr.in.write_time = time(NULL) - 60*60;
+
+ state->req = smb_raw_setpathinfo_send(state->tree, &io);
+ if (state->req == NULL) {
+ printf("Failed to setup setoffline for %s\n", state->fname);
+ test_failed = true;
+ }
+
+ state->req->async.fn = setoffline_callback;
+ state->req->async.private = state;
+ break;
+ }
+
+ case OP_GETOFFLINE: {
+ union smb_fileinfo io;
+ ZERO_STRUCT(io);
+ io.getattr.level = RAW_FILEINFO_GETATTR;
+ io.getattr.in.file.path = state->fname;
+
+ state->req = smb_raw_pathinfo_send(state->tree, &io);
+ if (state->req == NULL) {
+ printf("Failed to setup getoffline for %s\n", state->fname);
+ test_failed = true;
+ }
+
+ state->req->async.fn = getoffline_callback;
+ state->req->async.private = state;
+ break;
+ }
+
+ default:
+ printf("bad operation??\n");
+ break;
+ }
+}
+
+
+
+
+static void echo_completion(struct smbcli_request *req)
+{
+ struct offline_state *state = (struct offline_state *)req->async.private;
+ NTSTATUS status = smbcli_request_simple_recv(req);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_LOCAL_DISCONNECT)) {
+ talloc_free(state->tree);
+ state->tree = NULL;
+ num_connected--;
+ DEBUG(0,("lost connection\n"));
+ test_failed++;
+ }
+}
+
+static void report_rate(struct event_context *ev, struct timed_event *te,
+ struct timeval t, void *private_data)
+{
+ struct offline_state *state = talloc_get_type(private_data,
+ struct offline_state);
+ int i;
+ uint32_t total=0, total_offline=0, total_online=0;
+ for (i=0;i<numstates;i++) {
+ total += state[i].count - state[i].lastcount;
+ if (timeval_elapsed(&state[i].tv_start) > latencies[state[i].op]) {
+ latencies[state[i].op] = timeval_elapsed(&state[i].tv_start);
+ }
+ state[i].lastcount = state[i].count;
+ total_online += state[i].online_count;
+ total_offline += state[i].offline_count;
+ }
+ printf("ops/s=%4u offline=%5u online=%4u set_lat=%.1f get_lat=%.1f save_lat=%.1f load_lat=%.1f\r",
+ total, total_offline, total_online,
+ latencies[OP_SETOFFLINE],
+ latencies[OP_GETOFFLINE],
+ latencies[OP_SAVEFILE],
+ latencies[OP_LOADFILE]);
+ fflush(stdout);
+ event_add_timed(ev, state, timeval_current_ofs(1, 0), report_rate, state);
+
+ for (i=0;i<OP_ENDOFLIST;i++) {
+ if (latencies[i] > worst_latencies[i]) {
+ worst_latencies[i] = latencies[i];
+ }
+ latencies[i] = 0;
+ }
+
+ /* send an echo on each interface to ensure it stays alive - this helps
+ with IP takeover */
+ for (i=0;i<numstates;i++) {
+ struct smb_echo p;
+ struct smbcli_request *req;
+
+ if (!state[i].tree) {
+ continue;
+ }
+
+ p.in.repeat_count = 1;
+ p.in.size = 0;
+ p.in.data = NULL;
+ req = smb_raw_echo_send(state[i].tree->session->transport, &p);
+ req->async.private = &state[i];
+ req->async.fn = echo_completion;
+ }
+}
+
+/*
+ test offline file handling
+*/
+bool torture_test_offline(struct torture_context *torture)
+{
+ bool ret = true;
+ TALLOC_CTX *mem_ctx = talloc_new(torture);
+ int i;
+ int timelimit = torture_setting_int(torture, "timelimit", 10);
+ struct timeval tv;
+ struct event_context *ev = event_context_find(mem_ctx);
+ struct offline_state *state;
+ struct smbcli_state *cli;
+ bool progress;
+ progress = torture_setting_bool(torture, "progress", true);
+
+ nconnections = torture_setting_int(torture, "nprocs", 4);
+ numstates = nconnections * torture_entries;
+
+ state = talloc_zero_array(mem_ctx, struct offline_state, numstates);
+
+ printf("Opening %d connections with %d simultaneous operations and %u files\n", nconnections, numstates, torture_numops);
+ for (i=0;i<nconnections;i++) {
+ state[i].tctx = torture;
+ state[i].mem_ctx = talloc_new(state);
+ state[i].ev = ev;
+ if (!torture_open_connection_ev(&cli, i, torture, ev)) {
+ return false;
+ }
+ state[i].tree = cli->tree;
+ state[i].client = i;
+ /* allow more time for offline files */
+ state[i].tree->session->transport->options.request_timeout = 200;
+ }
+
+ /* the others are repeats on the earlier connections */
+ for (i=nconnections;i<numstates;i++) {
+ state[i].tctx = torture;
+ state[i].mem_ctx = talloc_new(state);
+ state[i].ev = ev;
+ state[i].tree = state[i % nconnections].tree;
+ state[i].client = i;
+ }
+
+ num_connected = i;
+
+ if (!torture_setup_dir(cli, BASEDIR)) {
+ goto failed;
+ }
+
+ /* pre-create files */
+ printf("Pre-creating %u files ....\n", torture_numops);
+ for (i=0;i<torture_numops;i++) {
+ int fnum;
+ char *fname = filename(mem_ctx, i);
+ char buf[FILE_SIZE];
+ NTSTATUS status;
+
+ memset(buf, i % 256, sizeof(buf));
+
+ fnum = smbcli_open(state[0].tree, fname, O_RDWR|O_CREAT, DENY_NONE);
+ if (fnum == -1) {
+ printf("Failed to open %s on connection %d\n", fname, i);
+ goto failed;
+ }
+
+ if (smbcli_write(state[0].tree, fnum, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
+ printf("Failed to write file of size %u\n", FILE_SIZE);
+ goto failed;
+ }
+
+ status = smbcli_close(state[0].tree, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Close failed - %s\n", nt_errstr(status));
+ goto failed;
+ }
+
+ talloc_free(fname);
+ }
+
+ /* start the async ops */
+ for (i=0;i<numstates;i++) {
+ state[i].tv_start = timeval_current();
+ test_offline(&state[i]);
+ }
+
+ tv = timeval_current();
+
+ if (progress) {
+ event_add_timed(ev, state, timeval_current_ofs(1, 0), report_rate, state);
+ }
+
+ printf("Running for %d seconds\n", timelimit);
+ while (timeval_elapsed(&tv) < timelimit) {
+ event_loop_once(ev);
+
+ if (test_failed) {
+ DEBUG(0,("test failed\n"));
+ goto failed;
+ }
+ }
+
+ printf("\nWaiting for completion\n");
+ test_finished = true;
+ for (i=0;i<numstates;i++) {
+ while (state[i].loadfile ||
+ state[i].savefile ||
+ state[i].req) {
+ event_loop_once(ev);
+ }
+ }
+
+ printf("worst latencies: set_lat=%.1f get_lat=%.1f save_lat=%.1f load_lat=%.1f\n",
+ worst_latencies[OP_SETOFFLINE],
+ worst_latencies[OP_GETOFFLINE],
+ worst_latencies[OP_SAVEFILE],
+ worst_latencies[OP_LOADFILE]);
+
+ smbcli_deltree(state[0].tree, BASEDIR);
+ talloc_free(mem_ctx);
+ printf("\n");
+ return ret;
+
+failed:
+ talloc_free(mem_ctx);
+ return false;
+}
diff --git a/source4/torture/raw/open.c b/source4/torture/raw/open.c
index 47f32b619b..76bc0ca53d 100644
--- a/source4/torture/raw/open.c
+++ b/source4/torture/raw/open.c
@@ -1367,7 +1367,7 @@ static bool test_raw_open_multi(struct torture_context *tctx)
return false;
}
- cli->tree->session->transport->options.request_timeout = 60000;
+ cli->tree->session->transport->options.request_timeout = 60;
for (i=0; i<num_files; i++) {
if (!torture_open_connection_share(mem_ctx, &(clients[i]),
@@ -1375,8 +1375,7 @@ static bool test_raw_open_multi(struct torture_context *tctx)
DEBUG(0, ("Could not open %d'th connection\n", i));
return false;
}
- clients[i]->tree->session->transport->
- options.request_timeout = 60000;
+ clients[i]->tree->session->transport->options.request_timeout = 60;
}
/* cleanup */
diff --git a/source4/torture/raw/raw.c b/source4/torture/raw/raw.c
index 112c34d299..bb3dde728f 100644
--- a/source4/torture/raw/raw.c
+++ b/source4/torture/raw/raw.c
@@ -33,6 +33,7 @@ NTSTATUS torture_raw_init(void)
torture_suite_add_simple_test(suite, "PING-PONG", torture_ping_pong);
torture_suite_add_simple_test(suite, "BENCH-LOCK", torture_bench_lock);
torture_suite_add_simple_test(suite, "BENCH-OPEN", torture_bench_open);
+ torture_suite_add_simple_test(suite, "OFFLINE", torture_test_offline);
torture_suite_add_1smb_test(suite, "QFSINFO", torture_raw_qfsinfo);
torture_suite_add_1smb_test(suite, "QFILEINFO", torture_raw_qfileinfo);
torture_suite_add_1smb_test(suite, "QFILEINFO-IPC", torture_raw_qfileinfo_pipe);
diff --git a/source4/torture/rpc/spoolss_notify.c b/source4/torture/rpc/spoolss_notify.c
index 0065101447..96db7d1ec5 100644
--- a/source4/torture/rpc/spoolss_notify.c
+++ b/source4/torture/rpc/spoolss_notify.c
@@ -69,7 +69,8 @@ static NTSTATUS spoolss__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_
return NT_STATUS_OK;
}
-/* FIXME: What context does this belong in ? -- JRV20070903 */
+/* Note that received_packets are allocated in talloc_autofree_context(),
+ * because no other context appears to stay around long enough. */
static struct received_packet {
uint16_t opnum;
void *r;
@@ -82,9 +83,9 @@ static NTSTATUS spoolss__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_
uint16_t opnum = dce_call->pkt.u.request.opnum;
struct received_packet *rp;
- rp = talloc_zero(mem_ctx, struct received_packet);
+ rp = talloc_zero(talloc_autofree_context(), struct received_packet);
rp->opnum = opnum;
- rp->r = talloc_reference(mem_ctx, r);
+ rp->r = talloc_reference(rp, r);
DLIST_ADD_END(received_packets, rp, struct received_packet *);
@@ -195,6 +196,8 @@ static bool test_RFFPCNEx(struct torture_context *tctx,
const char *address;
struct interface *ifaces;
+ received_packets = NULL;
+
ntvfs_init(tctx->lp_ctx);
ZERO_STRUCT(q);
@@ -239,7 +242,6 @@ static bool test_RFFPCNEx(struct torture_context *tctx,
torture_assert_ntstatus_ok(tctx, status,
"unable to initialize DCE/RPC server");
-
r.in.flags = 0;
r.in.str = talloc_asprintf(tctx, "\\\\%s", address);
r.in.options = 0;
@@ -261,7 +263,6 @@ static bool test_RFFPCNEx(struct torture_context *tctx,
r.in.t1 = &t1;
r.in.handle = &handle;
-
status = dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "FFPCNEx failed");
diff --git a/source4/torture/torture.pc.in b/source4/torture/torture.pc.in
new file mode 100644
index 0000000000..6582816cb5
--- /dev/null
+++ b/source4/torture/torture.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+modulesdir=${prefix}/modules/torture
+
+Name: torture
+Description: Samba torture (test) suite
+Requires: talloc
+Version: 0.0.1
+Libs: -L${libdir} -ltorture
+Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1
diff --git a/source4/torture/util.c b/source4/torture/util.c
deleted file mode 100644
index 0e9dda42fa..0000000000
--- a/source4/torture/util.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB torture tester utility functions
- Copyright (C) Jelmer Vernooij 2006
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "system/filesys.h"
-#include "system/wait.h"
-#include "torture/torture.h"
-#include "libcli/raw/interfaces.h"
-#include "libcli/raw/libcliraw.h"
-
-/**
- check if 2 NTTIMEs are equal.
-*/
-bool nt_time_equal(NTTIME *t1, NTTIME *t2)
-{
- return *t1 == *t2;
-}
-
-NTSTATUS torture_second_tcon(TALLOC_CTX *mem_ctx,
- struct smbcli_session *session,
- const char *sharename,
- struct smbcli_tree **res)
-{
- union smb_tcon tcon;
- struct smbcli_tree *result;
- TALLOC_CTX *tmp_ctx;
- NTSTATUS status;
-
- if ((tmp_ctx = talloc_new(mem_ctx)) == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- result = smbcli_tree_init(session, tmp_ctx, false);
- if (result == NULL) {
- talloc_free(tmp_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- tcon.generic.level = RAW_TCON_TCONX;
- tcon.tconx.in.flags = 0;
-
- /* Ignore share mode security here */
- tcon.tconx.in.password = data_blob(NULL, 0);
- tcon.tconx.in.path = sharename;
- tcon.tconx.in.device = "?????";
-
- status = smb_raw_tcon(result, tmp_ctx, &tcon);
- if (!NT_STATUS_IS_OK(status)) {
- talloc_free(tmp_ctx);
- return status;
- }
-
- result->tid = tcon.tconx.out.tid;
- *res = talloc_steal(mem_ctx, result);
- talloc_free(tmp_ctx);
- return NT_STATUS_OK;
-}
diff --git a/source4/torture/util_smb.c b/source4/torture/util_smb.c
index de7303bac8..ddf7b85c63 100644
--- a/source4/torture/util_smb.c
+++ b/source4/torture/util_smb.c
@@ -863,3 +863,42 @@ _PUBLIC_ struct torture_test *torture_suite_add_1smb_test(
}
+NTSTATUS torture_second_tcon(TALLOC_CTX *mem_ctx,
+ struct smbcli_session *session,
+ const char *sharename,
+ struct smbcli_tree **res)
+{
+ union smb_tcon tcon;
+ struct smbcli_tree *result;
+ TALLOC_CTX *tmp_ctx;
+ NTSTATUS status;
+
+ if ((tmp_ctx = talloc_new(mem_ctx)) == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ result = smbcli_tree_init(session, tmp_ctx, false);
+ if (result == NULL) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ tcon.generic.level = RAW_TCON_TCONX;
+ tcon.tconx.in.flags = 0;
+
+ /* Ignore share mode security here */
+ tcon.tconx.in.password = data_blob(NULL, 0);
+ tcon.tconx.in.path = sharename;
+ tcon.tconx.in.device = "?????";
+
+ status = smb_raw_tcon(result, tmp_ctx, &tcon);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(tmp_ctx);
+ return status;
+ }
+
+ result->tid = tcon.tconx.out.tid;
+ *res = talloc_steal(mem_ctx, result);
+ talloc_free(tmp_ctx);
+ return NT_STATUS_OK;
+}