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");
132 torture_assert_werr_equal(tctx
,
133 W_ERROR(r
.out
.status
),
134 WERR_INVALID_PARAMETER
,
135 "smbcli_rap_netprintqgetinfo failed");
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
];
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
) {
166 printf("%s\n", r
.out
.info
.info0
.PrintQName
);
175 static bool test_netprintjob_pause(struct torture_context
*tctx
,
176 struct smbcli_state
*cli
,
179 struct rap_NetPrintJobPause r
;
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");
192 static bool test_netprintjob_continue(struct torture_context
*tctx
,
193 struct smbcli_state
*cli
,
196 struct rap_NetPrintJobContinue r
;
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");
209 static bool test_netprintjob_delete(struct torture_context
*tctx
,
210 struct smbcli_state
*cli
,
213 struct rap_NetPrintJobDelete r
;
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");
226 static bool test_netprintjob(struct torture_context
*tctx
,
227 struct smbcli_state
*cli
)
229 uint16_t job_id
= 400;
232 test_netprintjob_pause(tctx
, cli
, job_id
),
233 "failed to pause job");
235 test_netprintjob_continue(tctx
, cli
, job_id
),
236 "failed to continue job");
238 test_netprintjob_delete(tctx
, cli
, job_id
),
239 "failed to delete job");
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");
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");
282 static bool test_netprintq(struct torture_context
*tctx
,
283 struct smbcli_state
*cli
)
285 struct rap_NetPrintQEnum r
;
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
;
302 test_netprintq_pause(tctx
, cli
, printqname
),
303 "failed to pause print queue");
306 test_netprintq_resume(tctx
, cli
, printqname
),
307 "failed to resume print queue");
313 static bool test_netprintjobenum_args(struct torture_context
*tctx
,
314 struct smbcli_state
*cli
,
315 const char *PrintQueueName
,
318 union rap_printj_info
**info_p
)
320 struct rap_NetPrintJobEnum r
;
322 r
.in
.PrintQueueName
= PrintQueueName
;
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");
334 *count_p
= r
.out
.count
;
337 *info_p
= r
.out
.info
;
343 static bool test_netprintjobenum_one(struct torture_context
*tctx
,
344 struct smbcli_state
*cli
,
345 const char *PrintQueueName
)
347 struct rap_NetPrintJobEnum r
;
349 uint16_t levels
[] = { 0, 1, 2 };
351 r
.in
.PrintQueueName
= PrintQueueName
;
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");
369 static bool test_netprintjobgetinfo_byid(struct torture_context
*tctx
,
370 struct smbcli_state
*cli
,
373 struct rap_NetPrintJobGetInfo r
;
374 uint16_t levels
[] = { 0, 1, 2 };
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");
394 static bool test_netprintjobsetinfo_byid(struct torture_context
*tctx
,
395 struct smbcli_state
*cli
,
398 struct rap_NetPrintJobSetInfo r
;
399 uint16_t levels
[] = { 0, 1, 2 };
401 const char *comment
= "tortured by samba";
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");
423 static bool test_netprintjobgetinfo_byqueue(struct torture_context
*tctx
,
424 struct smbcli_state
*cli
,
425 const char *PrintQueueName
)
427 struct rap_NetPrintJobEnum r
;
430 r
.in
.PrintQueueName
= PrintQueueName
;
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
++) {
441 test_netprintjobgetinfo_byid(tctx
, cli
, r
.out
.info
[i
].info0
.JobID
),
442 "failed to get job info");
448 static bool test_netprintjobsetinfo_byqueue(struct torture_context
*tctx
,
449 struct smbcli_state
*cli
,
450 const char *PrintQueueName
)
452 struct rap_NetPrintJobEnum r
;
455 r
.in
.PrintQueueName
= PrintQueueName
;
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
++) {
466 test_netprintjobsetinfo_byid(tctx
, cli
, r
.out
.info
[i
].info0
.JobID
),
467 "failed to set job info");
473 static bool test_netprintjobenum(struct torture_context
*tctx
,
474 struct smbcli_state
*cli
)
476 struct rap_NetPrintQEnum r
;
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
;
493 test_netprintjobenum_one(tctx
, cli
, printqname
),
494 "failed to enumerate printjobs on print queue");
500 static bool test_netprintjobgetinfo(struct torture_context
*tctx
,
501 struct smbcli_state
*cli
)
503 struct rap_NetPrintQEnum r
;
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
;
520 test_netprintjobgetinfo_byqueue(tctx
, cli
, printqname
),
521 "failed to enumerate printjobs on print queue");
527 static bool test_netprintjobsetinfo(struct torture_context
*tctx
,
528 struct smbcli_state
*cli
)
530 struct rap_NetPrintQEnum r
;
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
;
547 test_netprintjobsetinfo_byqueue(tctx
, cli
, printqname
),
548 "failed to set printjobs on print queue");
554 static bool test_netprintdestenum(struct torture_context
*tctx
,
555 struct smbcli_state
*cli
)
557 struct rap_NetPrintDestEnum r
;
559 uint16_t levels
[] = { 0, 1, 2, 3 };
561 for (i
=0; i
< ARRAY_SIZE(levels
); i
++) {
563 r
.in
.level
= levels
[i
];
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");
577 static bool test_netprintdestgetinfo_bydest(struct torture_context
*tctx
,
578 struct smbcli_state
*cli
,
579 const char *PrintDestName
)
581 struct rap_NetPrintDestGetInfo r
;
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
];
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");
603 static bool test_netprintdestgetinfo(struct torture_context
*tctx
,
604 struct smbcli_state
*cli
)
606 struct rap_NetPrintDestEnum r
;
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
++) {
622 test_netprintdestgetinfo_bydest(tctx
, cli
, r
.out
.info
[i
].info2
.PrinterName
),
623 "failed to get printdest info");
630 static bool test_rap_print(struct torture_context
*tctx
,
631 struct smbcli_state
*cli
)
633 struct rap_NetPrintQEnum r
;
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
;
650 union rap_printj_info
*job_info
;
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");
662 print_printjob(tctx
, res_queue
),
663 "failed to print job on 2nd connection");
665 talloc_free(res_queue
);
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
;
677 test_netprintjobgetinfo_byid(tctx
, cli
, job_id
),
678 "failed to getinfo on new printjob");
681 test_netprintjob_delete(tctx
, cli
, job_id
),
682 "failed to delete job");
686 test_netprintq_resume(tctx
, cli
, printqname
),
687 "failed to resume print queue");
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
);