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/>.
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"
36 printing half the file,
45 #define TORTURE_PRINT_FILE "torture_print_file"
47 static bool print_printjob(struct torture_context
*tctx
,
48 struct smbcli_tree
*tree
)
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
);
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");
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
;
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
];
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
) {
108 printf("%s\n", r
.out
.info
[q
].info0
.PrintQName
);
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
;
123 uint16_t levels
[] = { 0, 1, 2, 3, 4, 5 };
127 r
.in
.PrintQueueName
= "";
129 torture_assert_ntstatus_ok(tctx
,
130 smbcli_rap_netprintqgetinfo(cli
->tree
, tctx
, &r
),
131 "smbcli_rap_netprintqgetinfo failed");
134 r_enum
.in
.bufsize
= 8192;
136 torture_assert_ntstatus_ok(tctx
,
137 smbcli_rap_netprintqenum(cli
->tree
, tctx
, &r_enum
),
138 "failed to enum printq");
139 torture_assert_werr_ok(tctx
, W_ERROR(r_enum
.out
.status
),
140 "failed to enum printq");
142 for (p
=0; p
< r_enum
.out
.count
; p
++) {
144 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
146 r
.in
.level
= levels
[i
];
148 r
.in
.PrintQueueName
= r_enum
.out
.info
[p
].info5
.PrintQueueName
;
150 torture_comment(tctx
, "Testing rap_NetPrintQGetInfo(%s) level %d\n",
151 r
.in
.PrintQueueName
, r
.in
.level
);
153 torture_assert_ntstatus_ok(tctx
,
154 smbcli_rap_netprintqgetinfo(cli
->tree
, tctx
, &r
),
155 "smbcli_rap_netprintqgetinfo failed");
157 switch (r
.in
.level
) {
159 printf("%s\n", r
.out
.info
.info0
.PrintQName
);
168 static bool test_netprintjob_pause(struct torture_context
*tctx
,
169 struct smbcli_state
*cli
,
172 struct rap_NetPrintJobPause r
;
176 torture_comment(tctx
, "Testing rap_NetPrintJobPause(%d)\n", r
.in
.JobID
);
178 torture_assert_ntstatus_ok(tctx
,
179 smbcli_rap_netprintjobpause(cli
->tree
, tctx
, &r
),
180 "smbcli_rap_netprintjobpause failed");
185 static bool test_netprintjob_continue(struct torture_context
*tctx
,
186 struct smbcli_state
*cli
,
189 struct rap_NetPrintJobContinue r
;
193 torture_comment(tctx
, "Testing rap_NetPrintJobContinue(%d)\n", r
.in
.JobID
);
195 torture_assert_ntstatus_ok(tctx
,
196 smbcli_rap_netprintjobcontinue(cli
->tree
, tctx
, &r
),
197 "smbcli_rap_netprintjobcontinue failed");
202 static bool test_netprintjob_delete(struct torture_context
*tctx
,
203 struct smbcli_state
*cli
,
206 struct rap_NetPrintJobDelete r
;
210 torture_comment(tctx
, "Testing rap_NetPrintJobDelete(%d)\n", r
.in
.JobID
);
212 torture_assert_ntstatus_ok(tctx
,
213 smbcli_rap_netprintjobdelete(cli
->tree
, tctx
, &r
),
214 "smbcli_rap_netprintjobdelete failed");
219 static bool test_netprintjob(struct torture_context
*tctx
,
220 struct smbcli_state
*cli
)
222 uint16_t job_id
= 400;
225 test_netprintjob_pause(tctx
, cli
, job_id
),
226 "failed to pause job");
228 test_netprintjob_continue(tctx
, cli
, job_id
),
229 "failed to continue job");
231 test_netprintjob_delete(tctx
, cli
, job_id
),
232 "failed to delete job");
237 static bool test_netprintq_pause(struct torture_context
*tctx
,
238 struct smbcli_state
*cli
,
239 const char *PrintQueueName
)
241 struct rap_NetPrintQueuePause r
;
243 r
.in
.PrintQueueName
= PrintQueueName
;
245 torture_comment(tctx
, "Testing rap_NetPrintQueuePause(%s)\n", r
.in
.PrintQueueName
);
247 torture_assert_ntstatus_ok(tctx
,
248 smbcli_rap_netprintqueuepause(cli
->tree
, tctx
, &r
),
249 "smbcli_rap_netprintqueuepause failed");
250 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
251 "smbcli_rap_netprintqueuepause failed");
256 static bool test_netprintq_resume(struct torture_context
*tctx
,
257 struct smbcli_state
*cli
,
258 const char *PrintQueueName
)
260 struct rap_NetPrintQueueResume r
;
262 r
.in
.PrintQueueName
= PrintQueueName
;
264 torture_comment(tctx
, "Testing rap_NetPrintQueueResume(%s)\n", r
.in
.PrintQueueName
);
266 torture_assert_ntstatus_ok(tctx
,
267 smbcli_rap_netprintqueueresume(cli
->tree
, tctx
, &r
),
268 "smbcli_rap_netprintqueueresume failed");
269 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
270 "smbcli_rap_netprintqueueresume failed");
275 static bool test_netprintq(struct torture_context
*tctx
,
276 struct smbcli_state
*cli
)
278 struct rap_NetPrintQEnum r
;
284 torture_assert_ntstatus_ok(tctx
,
285 smbcli_rap_netprintqenum(cli
->tree
, tctx
, &r
),
286 "failed to enum printq");
287 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
288 "failed to enum printq");
290 for (i
=0; i
< r
.out
.count
; i
++) {
292 const char *printqname
= r
.out
.info
[i
].info5
.PrintQueueName
;
295 test_netprintq_pause(tctx
, cli
, printqname
),
296 "failed to pause print queue");
299 test_netprintq_resume(tctx
, cli
, printqname
),
300 "failed to resume print queue");
306 static bool test_netprintjobenum_args(struct torture_context
*tctx
,
307 struct smbcli_state
*cli
,
308 const char *PrintQueueName
,
311 union rap_printj_info
**info_p
)
313 struct rap_NetPrintJobEnum r
;
315 r
.in
.PrintQueueName
= PrintQueueName
;
319 torture_comment(tctx
,
320 "Testing rap_NetPrintJobEnum(%s) level %d\n", r
.in
.PrintQueueName
, r
.in
.level
);
322 torture_assert_ntstatus_ok(tctx
,
323 smbcli_rap_netprintjobenum(cli
->tree
, tctx
, &r
),
324 "smbcli_rap_netprintjobenum failed");
327 *count_p
= r
.out
.count
;
330 *info_p
= r
.out
.info
;
336 static bool test_netprintjobenum_one(struct torture_context
*tctx
,
337 struct smbcli_state
*cli
,
338 const char *PrintQueueName
)
340 struct rap_NetPrintJobEnum r
;
342 uint16_t levels
[] = { 0, 1, 2 };
344 r
.in
.PrintQueueName
= PrintQueueName
;
347 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
349 r
.in
.level
= levels
[i
];
351 torture_comment(tctx
,
352 "Testing rap_NetPrintJobEnum(%s) level %d\n", r
.in
.PrintQueueName
, r
.in
.level
);
354 torture_assert_ntstatus_ok(tctx
,
355 smbcli_rap_netprintjobenum(cli
->tree
, tctx
, &r
),
356 "smbcli_rap_netprintjobenum failed");
362 static bool test_netprintjobgetinfo_byid(struct torture_context
*tctx
,
363 struct smbcli_state
*cli
,
366 struct rap_NetPrintJobGetInfo r
;
367 uint16_t levels
[] = { 0, 1, 2 };
373 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
375 r
.in
.level
= levels
[i
];
377 torture_comment(tctx
, "Testing rap_NetPrintJobGetInfo(%d) level %d\n", r
.in
.JobID
, r
.in
.level
);
379 torture_assert_ntstatus_ok(tctx
,
380 smbcli_rap_netprintjobgetinfo(cli
->tree
, tctx
, &r
),
381 "smbcli_rap_netprintjobgetinfo failed");
387 static bool test_netprintjobsetinfo_byid(struct torture_context
*tctx
,
388 struct smbcli_state
*cli
,
391 struct rap_NetPrintJobSetInfo r
;
392 uint16_t levels
[] = { 0, 1, 2 };
394 const char *comment
= "tortured by samba";
397 r
.in
.bufsize
= strlen(comment
);
398 r
.in
.ParamNum
= RAP_PARAM_JOBCOMMENT
;
399 r
.in
.Param
.string
= comment
;
401 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
403 r
.in
.level
= levels
[i
];
405 torture_comment(tctx
, "Testing rap_NetPrintJobSetInfo(%d) level %d\n", r
.in
.JobID
, r
.in
.level
);
407 torture_assert_ntstatus_ok(tctx
,
408 smbcli_rap_netprintjobsetinfo(cli
->tree
, tctx
, &r
),
409 "smbcli_rap_netprintjobsetinfo failed");
416 static bool test_netprintjobgetinfo_byqueue(struct torture_context
*tctx
,
417 struct smbcli_state
*cli
,
418 const char *PrintQueueName
)
420 struct rap_NetPrintJobEnum r
;
423 r
.in
.PrintQueueName
= PrintQueueName
;
427 torture_assert_ntstatus_ok(tctx
,
428 smbcli_rap_netprintjobenum(cli
->tree
, tctx
, &r
),
429 "failed to enumerate jobs");
431 for (i
=0; i
< r
.out
.count
; i
++) {
434 test_netprintjobgetinfo_byid(tctx
, cli
, r
.out
.info
[i
].info0
.JobID
),
435 "failed to get job info");
441 static bool test_netprintjobsetinfo_byqueue(struct torture_context
*tctx
,
442 struct smbcli_state
*cli
,
443 const char *PrintQueueName
)
445 struct rap_NetPrintJobEnum r
;
448 r
.in
.PrintQueueName
= PrintQueueName
;
452 torture_assert_ntstatus_ok(tctx
,
453 smbcli_rap_netprintjobenum(cli
->tree
, tctx
, &r
),
454 "failed to enumerate jobs");
456 for (i
=0; i
< r
.out
.count
; i
++) {
459 test_netprintjobsetinfo_byid(tctx
, cli
, r
.out
.info
[i
].info0
.JobID
),
460 "failed to set job info");
466 static bool test_netprintjobenum(struct torture_context
*tctx
,
467 struct smbcli_state
*cli
)
469 struct rap_NetPrintQEnum r
;
475 torture_assert_ntstatus_ok(tctx
,
476 smbcli_rap_netprintqenum(cli
->tree
, tctx
, &r
),
477 "failed to enum printq");
478 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
479 "failed to enum printq");
481 for (i
=0; i
< r
.out
.count
; i
++) {
483 const char *printqname
= r
.out
.info
[i
].info5
.PrintQueueName
;
486 test_netprintjobenum_one(tctx
, cli
, printqname
),
487 "failed to enumerate printjobs on print queue");
493 static bool test_netprintjobgetinfo(struct torture_context
*tctx
,
494 struct smbcli_state
*cli
)
496 struct rap_NetPrintQEnum r
;
502 torture_assert_ntstatus_ok(tctx
,
503 smbcli_rap_netprintqenum(cli
->tree
, tctx
, &r
),
504 "failed to enum printq");
505 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
506 "failed to enum printq");
508 for (i
=0; i
< r
.out
.count
; i
++) {
510 const char *printqname
= r
.out
.info
[i
].info5
.PrintQueueName
;
513 test_netprintjobgetinfo_byqueue(tctx
, cli
, printqname
),
514 "failed to enumerate printjobs on print queue");
520 static bool test_netprintjobsetinfo(struct torture_context
*tctx
,
521 struct smbcli_state
*cli
)
523 struct rap_NetPrintQEnum r
;
529 torture_assert_ntstatus_ok(tctx
,
530 smbcli_rap_netprintqenum(cli
->tree
, tctx
, &r
),
531 "failed to enum printq");
532 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
533 "failed to enum printq");
535 for (i
=0; i
< r
.out
.count
; i
++) {
537 const char *printqname
= r
.out
.info
[i
].info5
.PrintQueueName
;
540 test_netprintjobsetinfo_byqueue(tctx
, cli
, printqname
),
541 "failed to set printjobs on print queue");
547 static bool test_netprintdestenum(struct torture_context
*tctx
,
548 struct smbcli_state
*cli
)
550 struct rap_NetPrintDestEnum r
;
552 uint16_t levels
[] = { 0, 1, 2, 3 };
554 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
556 r
.in
.level
= levels
[i
];
559 torture_comment(tctx
,
560 "Testing rap_NetPrintDestEnum level %d\n", r
.in
.level
);
562 torture_assert_ntstatus_ok(tctx
,
563 smbcli_rap_netprintdestenum(cli
->tree
, tctx
, &r
),
564 "smbcli_rap_netprintdestenum failed");
570 static bool test_netprintdestgetinfo_bydest(struct torture_context
*tctx
,
571 struct smbcli_state
*cli
,
572 const char *PrintDestName
)
574 struct rap_NetPrintDestGetInfo r
;
576 uint16_t levels
[] = { 0, 1, 2, 3 };
578 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
580 r
.in
.PrintDestName
= PrintDestName
;
581 r
.in
.level
= levels
[i
];
584 torture_comment(tctx
,
585 "Testing rap_NetPrintDestGetInfo(%s) level %d\n", r
.in
.PrintDestName
, r
.in
.level
);
587 torture_assert_ntstatus_ok(tctx
,
588 smbcli_rap_netprintdestgetinfo(cli
->tree
, tctx
, &r
),
589 "smbcli_rap_netprintdestgetinfo failed");
596 static bool test_netprintdestgetinfo(struct torture_context
*tctx
,
597 struct smbcli_state
*cli
)
599 struct rap_NetPrintDestEnum r
;
605 torture_comment(tctx
,
606 "Testing rap_NetPrintDestEnum level %d\n", r
.in
.level
);
608 torture_assert_ntstatus_ok(tctx
,
609 smbcli_rap_netprintdestenum(cli
->tree
, tctx
, &r
),
610 "smbcli_rap_netprintdestenum failed");
612 for (i
=0; i
< r
.out
.count
; i
++) {
615 test_netprintdestgetinfo_bydest(tctx
, cli
, r
.out
.info
[i
].info2
.PrinterName
),
616 "failed to get printdest info");
623 static bool test_rap_print(struct torture_context
*tctx
,
624 struct smbcli_state
*cli
)
626 struct rap_NetPrintQEnum r
;
632 torture_assert_ntstatus_ok(tctx
,
633 smbcli_rap_netprintqenum(cli
->tree
, tctx
, &r
),
634 "failed to enum printq");
635 torture_assert_werr_ok(tctx
, W_ERROR(r
.out
.status
),
636 "failed to enum printq");
638 for (i
=0; i
< r
.out
.count
; i
++) {
640 const char *printqname
= r
.out
.info
[i
].info5
.PrintQueueName
;
641 struct smbcli_tree
*res_queue
= NULL
;
643 union rap_printj_info
*job_info
;
647 test_netprintq_pause(tctx
, cli
, printqname
),
648 "failed to set printjobs on print queue");
650 torture_assert_ntstatus_ok(tctx
,
651 torture_second_tcon(tctx
, cli
->session
, printqname
, &res_queue
),
652 "failed to open 2nd connection");
655 print_printjob(tctx
, res_queue
),
656 "failed to print job on 2nd connection");
658 talloc_free(res_queue
);
661 test_netprintjobenum_args(tctx
, cli
, printqname
, 1,
662 &num_jobs
, &job_info
),
663 "failed to enum printjobs on print queue");
665 for (j
=0; j
< num_jobs
; j
++) {
667 uint16_t job_id
= job_info
[j
].info1
.JobID
;
670 test_netprintjobgetinfo_byid(tctx
, cli
, job_id
),
671 "failed to getinfo on new printjob");
674 test_netprintjob_delete(tctx
, cli
, job_id
),
675 "failed to delete job");
679 test_netprintq_resume(tctx
, cli
, printqname
),
680 "failed to resume print queue");
687 struct torture_suite
*torture_rap_printing(TALLOC_CTX
*mem_ctx
)
689 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "printing");
691 torture_suite_add_1smb_test(suite
, "raw_print", test_raw_print
);
692 torture_suite_add_1smb_test(suite
, "rap_print", test_rap_print
);
693 torture_suite_add_1smb_test(suite
, "rap_printq_enum", test_netprintqenum
);
694 torture_suite_add_1smb_test(suite
, "rap_printq_getinfo", test_netprintqgetinfo
);
695 torture_suite_add_1smb_test(suite
, "rap_printq", test_netprintq
);
696 torture_suite_add_1smb_test(suite
, "rap_printjob_enum", test_netprintjobenum
);
697 torture_suite_add_1smb_test(suite
, "rap_printjob_getinfo", test_netprintjobgetinfo
);
698 torture_suite_add_1smb_test(suite
, "rap_printjob_setinfo", test_netprintjobsetinfo
);
699 torture_suite_add_1smb_test(suite
, "rap_printjob", test_netprintjob
);
700 torture_suite_add_1smb_test(suite
, "rap_printdest_enum", test_netprintdestenum
);
701 torture_suite_add_1smb_test(suite
, "rap_printdest_getinfo", test_netprintdestgetinfo
);