s4-smbtorture: split spoolss_RemoteFindFirstPrinterChangeNotifyEx test into smaller...
authorGünther Deschner <gd@samba.org>
Tue, 19 Jan 2010 21:18:24 +0000 (22:18 +0100)
committerGünther Deschner <gd@samba.org>
Mon, 25 Jan 2010 10:20:06 +0000 (11:20 +0100)
Guenther

source4/torture/rpc/spoolss_notify.c

index bce85caa200a453b0f061ee17a0008ee565cea0c..e5e52d6b737aa4cb8ade2716022d8d7cb55fc34e 100644 (file)
@@ -3,6 +3,7 @@
    test suite for spoolss rpc notify operations
 
    Copyright (C) Jelmer Vernooij 2007
+   Copyright (C) Guenther Deschner 2010
 
    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
@@ -219,45 +220,100 @@ static NTSTATUS spoolss__op_init_server(struct dcesrv_context *dce_ctx, const st
        return NT_STATUS_OK;
 }
 
-static bool test_RFFPCNEx(struct torture_context *tctx,
-                         struct dcerpc_pipe *p)
+static bool test_OpenPrinter(struct torture_context *tctx,
+                            struct dcerpc_pipe *p,
+                            struct policy_handle *handle)
+{
+       struct spoolss_OpenPrinter r;
+
+       ZERO_STRUCT(r);
+
+       r.in.printername        = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+       r.in.datatype           = NULL;
+       r.in.devmode_ctr.devmode= NULL;
+       r.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
+       r.out.handle            = handle;
+
+       torture_comment(tctx, "Testing OpenPrinter(%s)\n", r.in.printername);
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_OpenPrinter(p, tctx, &r), "OpenPrinter failed");
+       torture_assert_werr_ok(tctx, r.out.result, "OpenPrinter failed");
+
+       return true;
+}
+
+static bool test_RemoteFindFirstPrinterChangeNotifyEx(struct torture_context *tctx,
+                                                     struct dcerpc_pipe *p,
+                                                     struct policy_handle *handle,
+                                                     const char *address)
 {
-       struct spoolss_OpenPrinter q;
        struct spoolss_RemoteFindFirstPrinterChangeNotifyEx r;
-       struct dcesrv_endpoint_server ep_server;
-       NTSTATUS status;
-       struct dcesrv_context *dce_ctx;
-       const char *endpoints[] = { "spoolss", NULL };
-       struct dcesrv_endpoint *e;
        struct spoolss_NotifyOption t1;
-       struct spoolss_ClosePrinter cp;
-       struct received_packet *rp;
 
-       struct policy_handle handle;
-       const char *address;
-       struct interface *ifaces;
+       torture_comment(tctx, "Testing RemoteFindFirstPrinterChangeNotifyEx\n");
 
-       received_packets = NULL;
+       t1.version = 2;
+       t1.flags = 0;
+       t1.count = 2;
+       t1.types = talloc_zero_array(tctx, struct spoolss_NotifyOptionType, 2);
+       t1.types[0].type = PRINTER_NOTIFY_TYPE;
+       t1.types[0].count = 1;
+       t1.types[0].fields = talloc_array(t1.types, union spoolss_Field, 1);
+       t1.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
 
-       ntvfs_init(tctx->lp_ctx);
+       t1.types[1].type = JOB_NOTIFY_TYPE;
+       t1.types[1].count = 1;
+       t1.types[1].fields = talloc_array(t1.types, union spoolss_Field, 1);
+       t1.types[1].fields[0].field = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
+
+       r.in.flags = 0;
+       r.in.local_machine = talloc_asprintf(tctx, "\\\\%s", address);
+       r.in.options = 0;
+       r.in.printer_local = 123;
+       r.in.notify_options = &t1;
+       r.in.handle = handle;
 
-       ZERO_STRUCT(q);
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(p, tctx, &r),
+               "RemoteFindFirstPrinterChangeNotifyEx failed");
+       torture_assert_werr_ok(tctx, r.out.result,
+               "error return code for RemoteFindFirstPrinterChangeNotifyEx");
 
-       q.in.printername        = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
-       q.in.datatype           = NULL;
-       q.in.devmode_ctr.devmode= NULL;
-       q.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
-       q.out.handle            = &handle;
+       return true;
+}
 
-       torture_comment(tctx, "Testing OpenPrinter(%s)\n", q.in.printername);
+static bool test_ClosePrinter(struct torture_context *tctx,
+                             struct dcerpc_pipe *p,
+                             struct policy_handle *handle)
+{
+       struct spoolss_ClosePrinter r;
 
-       status = dcerpc_spoolss_OpenPrinter(p, tctx, &q);
+       r.in.handle = handle;
+       r.out.handle = handle;
 
-       torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
+       torture_comment(tctx, "Testing ClosePrinter\n");
 
-       torture_assert_werr_ok(tctx, q.out.result, "OpenPrinter failed");
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_ClosePrinter(p, tctx, &r),
+               "ClosePrinter failed");
+       torture_assert_werr_ok(tctx, r.out.result,
+               "ClosePrinter failed");
 
-       /* Start DCE/RPC server */
+       return true;
+}
+
+static bool test_start_dcerpc_server(struct torture_context *tctx,
+                                    struct tevent_context *event_ctx,
+                                    struct dcesrv_context **dce_ctx_p,
+                                    const char **address_p)
+{
+       struct dcesrv_endpoint_server ep_server;
+       NTSTATUS status;
+       struct dcesrv_context *dce_ctx;
+       const char *endpoints[] = { "spoolss", NULL };
+       struct dcesrv_endpoint *e;
+       const char *address;
+       struct interface *ifaces;
+
+       ntvfs_init(tctx->lp_ctx);
 
        /* fill in our name */
        ep_server.name = "spoolss";
@@ -275,8 +331,10 @@ static bool test_RFFPCNEx(struct torture_context *tctx,
 
        load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
        address = iface_n_ip(ifaces, 0);
+
        torture_comment(tctx, "Listening for callbacks on %s\n", address);
-       status = smbsrv_add_socket(p->conn->event_ctx, tctx->lp_ctx, &single_ops, address);
+
+       status = smbsrv_add_socket(event_ctx, tctx->lp_ctx, &single_ops, address);
        torture_assert_ntstatus_ok(tctx, status, "starting smb server");
 
        status = dcesrv_init_context(tctx, tctx->lp_ctx, endpoints, &dce_ctx);
@@ -290,56 +348,33 @@ static bool test_RFFPCNEx(struct torture_context *tctx,
                                "unable listen on dcerpc endpoint server");
        }
 
-       r.in.flags = 0;
-       r.in.local_machine = talloc_asprintf(tctx, "\\\\%s", address);
-       r.in.options = 0;
-       r.in.printer_local = 123;
-       t1.version = 2;
-       t1.flags = 0;
-       t1.count = 2;
-       t1.types = talloc_zero_array(tctx, struct spoolss_NotifyOptionType, 2);
-       t1.types[0].type = PRINTER_NOTIFY_TYPE;
-       t1.types[0].count = 1;
-       t1.types[0].fields = talloc_array(t1.types, union spoolss_Field, 1);
-       t1.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
-
-       t1.types[1].type = JOB_NOTIFY_TYPE;
-       t1.types[1].count = 1;
-       t1.types[1].fields = talloc_array(t1.types, union spoolss_Field, 1);
-       t1.types[1].fields[0].field = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
-
-       r.in.notify_options = &t1;
-       r.in.handle = &handle;
-
-       status = dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(p, tctx, &r);
-
-       torture_assert_ntstatus_ok(tctx, status, "FFPCNEx failed");
-
-       torture_assert_werr_ok(tctx, r.out.result, "error return code for FFPCNEx");
-
-       cp.in.handle = &handle;
-       cp.out.handle = &handle;
-
-       torture_comment(tctx, "Testing ClosePrinter\n");
+       *dce_ctx_p = dce_ctx;
+       *address_p = address;
 
-       status = dcerpc_spoolss_ClosePrinter(p, tctx, &cp);
-       torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
+       return true;
+}
 
-       /* We should've had an incoming packet 58 (ReplyOpenPrinter) or 60
-        * (ReplyClosePrinter) */
+static bool test_RFFPCNEx(struct torture_context *tctx,
+                         struct dcerpc_pipe *p)
+{
+       struct dcesrv_context *dce_ctx;
+       struct policy_handle handle;
+       const char *address;
 
-       torture_assert(tctx, received_packets != NULL, "no packets received");
+       received_packets = NULL;
 
-       for (rp = received_packets; rp; rp = rp->next) {
-               switch (rp->opnum) {
-               case 58:
-               case 60:
-                       continue;
-               default:
-                       torture_fail(tctx,
-                               talloc_asprintf(tctx, "unexpected packet opnum %d received", rp->opnum));
-               }
-       }
+       /* Start DCE/RPC server */
+       torture_assert(tctx, test_start_dcerpc_server(tctx, p->conn->event_ctx, &dce_ctx, &address), "");
+
+       torture_assert(tctx, test_OpenPrinter(tctx, p, &handle), "");
+       torture_assert(tctx, test_RemoteFindFirstPrinterChangeNotifyEx(tctx, p, &handle, address), "");
+       torture_assert(tctx, received_packets, "no packets received");
+       torture_assert_int_equal(tctx, received_packets->opnum, NDR_SPOOLSS_REPLYOPENPRINTER,
+               "no ReplyOpenPrinter packet after RemoteFindFirstPrinterChangeNotifyEx");
+       torture_assert(tctx, test_ClosePrinter(tctx, p, &handle), "");
+       torture_assert(tctx, received_packets, "no packets received");
+       torture_assert_int_equal(tctx, received_packets->opnum, NDR_SPOOLSS_REPLYCLOSEPRINTER,
+               "no ReplyClosePrinter packet after ClosePrinter");
 
        /* Shut down DCE/RPC server */
        talloc_free(dce_ctx);