WHATSNEW: Update changes since rc3.
[Samba.git] / source4 / torture / rap / printing.c
blobaf76b263dfedc48999c4ebbebee0b49e00139679
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for SMB printing operations
5 Copyright (C) Guenther Deschner 2010
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "libcli/libcli.h"
24 #include "torture/torture.h"
25 #include "torture/util.h"
26 #include "system/filesys.h"
28 #include "torture/smbtorture.h"
29 #include "torture/util.h"
30 #include "libcli/rap/rap.h"
31 #include "torture/rap/proto.h"
32 #include "param/param.h"
34 /* TODO:
36 printing half the file,
37 finding job
38 delete job
39 try writing 2nd half
41 SMBsplretq
45 #define TORTURE_PRINT_FILE "torture_print_file"
47 static bool print_printjob(struct torture_context *tctx,
48 struct smbcli_tree *tree)
50 int fnum;
51 DATA_BLOB data;
52 ssize_t size_written;
53 const char *str;
55 torture_comment(tctx, "creating printjob %s\n", TORTURE_PRINT_FILE);
57 fnum = smbcli_open(tree, TORTURE_PRINT_FILE, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
58 if (fnum == -1) {
59 torture_fail(tctx, "failed to open file");
62 str = talloc_asprintf(tctx, "TortureTestPage: %d\nData\n",0);
64 data = data_blob_string_const(str);
66 size_written = smbcli_write(tree, fnum, 0, data.data, 0, data.length);
67 if (size_written != data.length) {
68 torture_fail(tctx, "failed to write file");
71 torture_assert_ntstatus_ok(tctx,
72 smbcli_close(tree, fnum),
73 "failed to close file");
75 return true;
78 static bool test_raw_print(struct torture_context *tctx,
79 struct smbcli_state *cli)
81 return print_printjob(tctx, cli->tree);
84 static bool test_netprintqenum(struct torture_context *tctx,
85 struct smbcli_state *cli)
87 struct rap_NetPrintQEnum r;
88 int i, q;
89 uint16_t levels[] = { 0, 1, 2, 3, 4, 5 };
91 for (i=0; i < ARRAY_SIZE(levels); i++) {
93 r.in.level = levels[i];
94 r.in.bufsize = 8192;
96 torture_comment(tctx,
97 "Testing rap_NetPrintQEnum level %d\n", r.in.level);
99 torture_assert_ntstatus_ok(tctx,
100 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
101 "smbcli_rap_netprintqenum failed");
102 torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
103 "failed to enum printq");
105 for (q=0; q<r.out.count; q++) {
106 switch (r.in.level) {
107 case 0:
108 printf("%s\n", r.out.info[q].info0.PrintQName);
109 break;
114 return true;
117 static bool test_netprintqgetinfo(struct torture_context *tctx,
118 struct smbcli_state *cli)
120 struct rap_NetPrintQGetInfo r;
121 struct rap_NetPrintQEnum r_enum;
122 int i, p;
123 uint16_t levels[] = { 0, 1, 2, 3, 4, 5 };
125 r.in.level = 0;
126 r.in.bufsize = 0;
127 r.in.PrintQueueName = "";
129 torture_assert_ntstatus_ok(tctx,
130 smbcli_rap_netprintqgetinfo(cli->tree, tctx, &r),
131 "smbcli_rap_netprintqgetinfo failed");
132 torture_assert_werr_equal(tctx,
133 W_ERROR(r.out.status),
134 WERR_INVALID_PARAMETER,
135 "smbcli_rap_netprintqgetinfo failed");
137 r_enum.in.level = 5;
138 r_enum.in.bufsize = 8192;
140 torture_assert_ntstatus_ok(tctx,
141 smbcli_rap_netprintqenum(cli->tree, tctx, &r_enum),
142 "failed to enum printq");
143 torture_assert_werr_ok(tctx, W_ERROR(r_enum.out.status),
144 "failed to enum printq");
146 for (p=0; p < r_enum.out.count; p++) {
148 for (i=0; i < ARRAY_SIZE(levels); i++) {
150 r.in.level = levels[i];
151 r.in.bufsize = 8192;
152 r.in.PrintQueueName = r_enum.out.info[p].info5.PrintQueueName;
154 torture_comment(tctx, "Testing rap_NetPrintQGetInfo(%s) level %d\n",
155 r.in.PrintQueueName, r.in.level);
157 torture_assert_ntstatus_ok(tctx,
158 smbcli_rap_netprintqgetinfo(cli->tree, tctx, &r),
159 "smbcli_rap_netprintqgetinfo failed");
160 torture_assert_werr_ok(tctx,
161 W_ERROR(r.out.status),
162 "smbcli_rap_netprintqgetinfo failed");
164 switch (r.in.level) {
165 case 0:
166 printf("%s\n", r.out.info.info0.PrintQName);
167 break;
172 return true;
175 static bool test_netprintjob_pause(struct torture_context *tctx,
176 struct smbcli_state *cli,
177 uint16_t job_id)
179 struct rap_NetPrintJobPause r;
181 r.in.JobID = job_id;
183 torture_comment(tctx, "Testing rap_NetPrintJobPause(%d)\n", r.in.JobID);
185 torture_assert_ntstatus_ok(tctx,
186 smbcli_rap_netprintjobpause(cli->tree, tctx, &r),
187 "smbcli_rap_netprintjobpause failed");
189 return true;
192 static bool test_netprintjob_continue(struct torture_context *tctx,
193 struct smbcli_state *cli,
194 uint16_t job_id)
196 struct rap_NetPrintJobContinue r;
198 r.in.JobID = job_id;
200 torture_comment(tctx, "Testing rap_NetPrintJobContinue(%d)\n", r.in.JobID);
202 torture_assert_ntstatus_ok(tctx,
203 smbcli_rap_netprintjobcontinue(cli->tree, tctx, &r),
204 "smbcli_rap_netprintjobcontinue failed");
206 return true;
209 static bool test_netprintjob_delete(struct torture_context *tctx,
210 struct smbcli_state *cli,
211 uint16_t job_id)
213 struct rap_NetPrintJobDelete r;
215 r.in.JobID = job_id;
217 torture_comment(tctx, "Testing rap_NetPrintJobDelete(%d)\n", r.in.JobID);
219 torture_assert_ntstatus_ok(tctx,
220 smbcli_rap_netprintjobdelete(cli->tree, tctx, &r),
221 "smbcli_rap_netprintjobdelete failed");
223 return true;
226 static bool test_netprintjob(struct torture_context *tctx,
227 struct smbcli_state *cli)
229 uint16_t job_id = 400;
231 torture_assert(tctx,
232 test_netprintjob_pause(tctx, cli, job_id),
233 "failed to pause job");
234 torture_assert(tctx,
235 test_netprintjob_continue(tctx, cli, job_id),
236 "failed to continue job");
237 torture_assert(tctx,
238 test_netprintjob_delete(tctx, cli, job_id),
239 "failed to delete job");
241 return true;
244 static bool test_netprintq_pause(struct torture_context *tctx,
245 struct smbcli_state *cli,
246 const char *PrintQueueName)
248 struct rap_NetPrintQueuePause r;
250 r.in.PrintQueueName = PrintQueueName;
252 torture_comment(tctx, "Testing rap_NetPrintQueuePause(%s)\n", r.in.PrintQueueName);
254 torture_assert_ntstatus_ok(tctx,
255 smbcli_rap_netprintqueuepause(cli->tree, tctx, &r),
256 "smbcli_rap_netprintqueuepause failed");
257 torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
258 "smbcli_rap_netprintqueuepause failed");
260 return true;
263 static bool test_netprintq_resume(struct torture_context *tctx,
264 struct smbcli_state *cli,
265 const char *PrintQueueName)
267 struct rap_NetPrintQueueResume r;
269 r.in.PrintQueueName = PrintQueueName;
271 torture_comment(tctx, "Testing rap_NetPrintQueueResume(%s)\n", r.in.PrintQueueName);
273 torture_assert_ntstatus_ok(tctx,
274 smbcli_rap_netprintqueueresume(cli->tree, tctx, &r),
275 "smbcli_rap_netprintqueueresume failed");
276 torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
277 "smbcli_rap_netprintqueueresume failed");
279 return true;
282 static bool test_netprintq(struct torture_context *tctx,
283 struct smbcli_state *cli)
285 struct rap_NetPrintQEnum r;
286 int i;
288 r.in.level = 5;
289 r.in.bufsize = 8192;
291 torture_assert_ntstatus_ok(tctx,
292 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
293 "failed to enum printq");
294 torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
295 "failed to enum printq");
297 for (i=0; i < r.out.count; i++) {
299 const char *printqname = r.out.info[i].info5.PrintQueueName;
301 torture_assert(tctx,
302 test_netprintq_pause(tctx, cli, printqname),
303 "failed to pause print queue");
305 torture_assert(tctx,
306 test_netprintq_resume(tctx, cli, printqname),
307 "failed to resume print queue");
310 return true;
313 static bool test_netprintjobenum_args(struct torture_context *tctx,
314 struct smbcli_state *cli,
315 const char *PrintQueueName,
316 uint16_t level,
317 uint16_t *count_p,
318 union rap_printj_info **info_p)
320 struct rap_NetPrintJobEnum r;
322 r.in.PrintQueueName = PrintQueueName;
323 r.in.bufsize = 8192;
324 r.in.level = level;
326 torture_comment(tctx,
327 "Testing rap_NetPrintJobEnum(%s) level %d\n", r.in.PrintQueueName, r.in.level);
329 torture_assert_ntstatus_ok(tctx,
330 smbcli_rap_netprintjobenum(cli->tree, tctx, &r),
331 "smbcli_rap_netprintjobenum failed");
333 if (count_p) {
334 *count_p = r.out.count;
336 if (info_p) {
337 *info_p = r.out.info;
340 return true;
343 static bool test_netprintjobenum_one(struct torture_context *tctx,
344 struct smbcli_state *cli,
345 const char *PrintQueueName)
347 struct rap_NetPrintJobEnum r;
348 int i;
349 uint16_t levels[] = { 0, 1, 2 };
351 r.in.PrintQueueName = PrintQueueName;
352 r.in.bufsize = 8192;
354 for (i=0; i < ARRAY_SIZE(levels); i++) {
356 r.in.level = levels[i];
358 torture_comment(tctx,
359 "Testing rap_NetPrintJobEnum(%s) level %d\n", r.in.PrintQueueName, r.in.level);
361 torture_assert_ntstatus_ok(tctx,
362 smbcli_rap_netprintjobenum(cli->tree, tctx, &r),
363 "smbcli_rap_netprintjobenum failed");
366 return true;
369 static bool test_netprintjobgetinfo_byid(struct torture_context *tctx,
370 struct smbcli_state *cli,
371 uint16_t JobID)
373 struct rap_NetPrintJobGetInfo r;
374 uint16_t levels[] = { 0, 1, 2 };
375 int i;
377 r.in.JobID = JobID;
378 r.in.bufsize = 8192;
380 for (i=0; i < ARRAY_SIZE(levels); i++) {
382 r.in.level = levels[i];
384 torture_comment(tctx, "Testing rap_NetPrintJobGetInfo(%d) level %d\n", r.in.JobID, r.in.level);
386 torture_assert_ntstatus_ok(tctx,
387 smbcli_rap_netprintjobgetinfo(cli->tree, tctx, &r),
388 "smbcli_rap_netprintjobgetinfo failed");
391 return true;
394 static bool test_netprintjobsetinfo_byid(struct torture_context *tctx,
395 struct smbcli_state *cli,
396 uint16_t JobID)
398 struct rap_NetPrintJobSetInfo r;
399 uint16_t levels[] = { 0, 1, 2 };
400 int i;
401 const char *comment = "tortured by samba";
403 r.in.JobID = JobID;
404 r.in.bufsize = strlen(comment);
405 r.in.ParamNum = RAP_PARAM_JOBCOMMENT;
406 r.in.Param.string = comment;
408 for (i=0; i < ARRAY_SIZE(levels); i++) {
410 r.in.level = levels[i];
412 torture_comment(tctx, "Testing rap_NetPrintJobSetInfo(%d) level %d\n", r.in.JobID, r.in.level);
414 torture_assert_ntstatus_ok(tctx,
415 smbcli_rap_netprintjobsetinfo(cli->tree, tctx, &r),
416 "smbcli_rap_netprintjobsetinfo failed");
419 return true;
423 static bool test_netprintjobgetinfo_byqueue(struct torture_context *tctx,
424 struct smbcli_state *cli,
425 const char *PrintQueueName)
427 struct rap_NetPrintJobEnum r;
428 int i;
430 r.in.PrintQueueName = PrintQueueName;
431 r.in.bufsize = 8192;
432 r.in.level = 0;
434 torture_assert_ntstatus_ok(tctx,
435 smbcli_rap_netprintjobenum(cli->tree, tctx, &r),
436 "failed to enumerate jobs");
438 for (i=0; i < r.out.count; i++) {
440 torture_assert(tctx,
441 test_netprintjobgetinfo_byid(tctx, cli, r.out.info[i].info0.JobID),
442 "failed to get job info");
445 return true;
448 static bool test_netprintjobsetinfo_byqueue(struct torture_context *tctx,
449 struct smbcli_state *cli,
450 const char *PrintQueueName)
452 struct rap_NetPrintJobEnum r;
453 int i;
455 r.in.PrintQueueName = PrintQueueName;
456 r.in.bufsize = 8192;
457 r.in.level = 0;
459 torture_assert_ntstatus_ok(tctx,
460 smbcli_rap_netprintjobenum(cli->tree, tctx, &r),
461 "failed to enumerate jobs");
463 for (i=0; i < r.out.count; i++) {
465 torture_assert(tctx,
466 test_netprintjobsetinfo_byid(tctx, cli, r.out.info[i].info0.JobID),
467 "failed to set job info");
470 return true;
473 static bool test_netprintjobenum(struct torture_context *tctx,
474 struct smbcli_state *cli)
476 struct rap_NetPrintQEnum r;
477 int i;
479 r.in.level = 5;
480 r.in.bufsize = 8192;
482 torture_assert_ntstatus_ok(tctx,
483 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
484 "failed to enum printq");
485 torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
486 "failed to enum printq");
488 for (i=0; i < r.out.count; i++) {
490 const char *printqname = r.out.info[i].info5.PrintQueueName;
492 torture_assert(tctx,
493 test_netprintjobenum_one(tctx, cli, printqname),
494 "failed to enumerate printjobs on print queue");
497 return true;
500 static bool test_netprintjobgetinfo(struct torture_context *tctx,
501 struct smbcli_state *cli)
503 struct rap_NetPrintQEnum r;
504 int i;
506 r.in.level = 5;
507 r.in.bufsize = 8192;
509 torture_assert_ntstatus_ok(tctx,
510 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
511 "failed to enum printq");
512 torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
513 "failed to enum printq");
515 for (i=0; i < r.out.count; i++) {
517 const char *printqname = r.out.info[i].info5.PrintQueueName;
519 torture_assert(tctx,
520 test_netprintjobgetinfo_byqueue(tctx, cli, printqname),
521 "failed to enumerate printjobs on print queue");
524 return true;
527 static bool test_netprintjobsetinfo(struct torture_context *tctx,
528 struct smbcli_state *cli)
530 struct rap_NetPrintQEnum r;
531 int i;
533 r.in.level = 5;
534 r.in.bufsize = 8192;
536 torture_assert_ntstatus_ok(tctx,
537 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
538 "failed to enum printq");
539 torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
540 "failed to enum printq");
542 for (i=0; i < r.out.count; i++) {
544 const char *printqname = r.out.info[i].info5.PrintQueueName;
546 torture_assert(tctx,
547 test_netprintjobsetinfo_byqueue(tctx, cli, printqname),
548 "failed to set printjobs on print queue");
551 return true;
554 static bool test_netprintdestenum(struct torture_context *tctx,
555 struct smbcli_state *cli)
557 struct rap_NetPrintDestEnum r;
558 int i;
559 uint16_t levels[] = { 0, 1, 2, 3 };
561 for (i=0; i < ARRAY_SIZE(levels); i++) {
563 r.in.level = levels[i];
564 r.in.bufsize = 8192;
566 torture_comment(tctx,
567 "Testing rap_NetPrintDestEnum level %d\n", r.in.level);
569 torture_assert_ntstatus_ok(tctx,
570 smbcli_rap_netprintdestenum(cli->tree, tctx, &r),
571 "smbcli_rap_netprintdestenum failed");
574 return true;
577 static bool test_netprintdestgetinfo_bydest(struct torture_context *tctx,
578 struct smbcli_state *cli,
579 const char *PrintDestName)
581 struct rap_NetPrintDestGetInfo r;
582 int i;
583 uint16_t levels[] = { 0, 1, 2, 3 };
585 for (i=0; i < ARRAY_SIZE(levels); i++) {
587 r.in.PrintDestName = PrintDestName;
588 r.in.level = levels[i];
589 r.in.bufsize = 8192;
591 torture_comment(tctx,
592 "Testing rap_NetPrintDestGetInfo(%s) level %d\n", r.in.PrintDestName, r.in.level);
594 torture_assert_ntstatus_ok(tctx,
595 smbcli_rap_netprintdestgetinfo(cli->tree, tctx, &r),
596 "smbcli_rap_netprintdestgetinfo failed");
599 return true;
603 static bool test_netprintdestgetinfo(struct torture_context *tctx,
604 struct smbcli_state *cli)
606 struct rap_NetPrintDestEnum r;
607 int i;
609 r.in.level = 2;
610 r.in.bufsize = 8192;
612 torture_comment(tctx,
613 "Testing rap_NetPrintDestEnum level %d\n", r.in.level);
615 torture_assert_ntstatus_ok(tctx,
616 smbcli_rap_netprintdestenum(cli->tree, tctx, &r),
617 "smbcli_rap_netprintdestenum failed");
619 for (i=0; i < r.out.count; i++) {
621 torture_assert(tctx,
622 test_netprintdestgetinfo_bydest(tctx, cli, r.out.info[i].info2.PrinterName),
623 "failed to get printdest info");
627 return true;
630 static bool test_rap_print(struct torture_context *tctx,
631 struct smbcli_state *cli)
633 struct rap_NetPrintQEnum r;
634 int i;
636 r.in.level = 5;
637 r.in.bufsize = 8192;
639 torture_assert_ntstatus_ok(tctx,
640 smbcli_rap_netprintqenum(cli->tree, tctx, &r),
641 "failed to enum printq");
642 torture_assert_werr_ok(tctx, W_ERROR(r.out.status),
643 "failed to enum printq");
645 for (i=0; i < r.out.count; i++) {
647 const char *printqname = r.out.info[i].info5.PrintQueueName;
648 struct smbcli_tree *res_queue = NULL;
649 uint16_t num_jobs;
650 union rap_printj_info *job_info;
651 int j;
653 torture_assert(tctx,
654 test_netprintq_pause(tctx, cli, printqname),
655 "failed to set printjobs on print queue");
657 torture_assert_ntstatus_ok(tctx,
658 torture_second_tcon(tctx, cli->session, printqname, &res_queue),
659 "failed to open 2nd connection");
661 torture_assert(tctx,
662 print_printjob(tctx, res_queue),
663 "failed to print job on 2nd connection");
665 talloc_free(res_queue);
667 torture_assert(tctx,
668 test_netprintjobenum_args(tctx, cli, printqname, 1,
669 &num_jobs, &job_info),
670 "failed to enum printjobs on print queue");
672 for (j=0; j < num_jobs; j++) {
674 uint16_t job_id = job_info[j].info1.JobID;
676 torture_assert(tctx,
677 test_netprintjobgetinfo_byid(tctx, cli, job_id),
678 "failed to getinfo on new printjob");
680 torture_assert(tctx,
681 test_netprintjob_delete(tctx, cli, job_id),
682 "failed to delete job");
685 torture_assert(tctx,
686 test_netprintq_resume(tctx, cli, printqname),
687 "failed to resume print queue");
691 return true;
694 struct torture_suite *torture_rap_printing(TALLOC_CTX *mem_ctx)
696 struct torture_suite *suite = torture_suite_create(mem_ctx, "printing");
698 torture_suite_add_1smb_test(suite, "raw_print", test_raw_print);
699 torture_suite_add_1smb_test(suite, "rap_print", test_rap_print);
700 torture_suite_add_1smb_test(suite, "rap_printq_enum", test_netprintqenum);
701 torture_suite_add_1smb_test(suite, "rap_printq_getinfo", test_netprintqgetinfo);
702 torture_suite_add_1smb_test(suite, "rap_printq", test_netprintq);
703 torture_suite_add_1smb_test(suite, "rap_printjob_enum", test_netprintjobenum);
704 torture_suite_add_1smb_test(suite, "rap_printjob_getinfo", test_netprintjobgetinfo);
705 torture_suite_add_1smb_test(suite, "rap_printjob_setinfo", test_netprintjobsetinfo);
706 torture_suite_add_1smb_test(suite, "rap_printjob", test_netprintjob);
707 torture_suite_add_1smb_test(suite, "rap_printdest_enum", test_netprintdestenum);
708 torture_suite_add_1smb_test(suite, "rap_printdest_getinfo", test_netprintdestgetinfo);
710 return suite;