5 from samba
import spoolss
7 class PrintServerTest(comfychair
.TestCase
):
8 """An abstract class requiring a print server."""
10 # TODO: create a test printer
11 self
.server
= stf
.get_server(platform
= "nt")
12 self
.require(self
.server
!= None, "print server required")
13 # TODO: remove hardcoded printer name
14 self
.printername
= "p"
15 self
.uncname
= "\\\\%s\\%s" % \
16 (self
.server
["hostname"], self
.printername
)
18 class W2kPrintServerTest(comfychair
.TestCase
):
19 """An abstract class requiring a print server."""
21 # TODO: create a test printer
22 self
.server
= stf
.get_server(platform
= "nt5")
23 self
.require(self
.server
!= None, "print server required")
24 # TODO: remove hardcoded printer name
25 self
.printername
= "p"
26 self
.uncname
= "\\\\%s\\%s" % \
27 (self
.server
["hostname"], self
.printername
)
29 class CredentialTest(PrintServerTest
):
30 """An class that calls a function with various sets of credentials."""
33 bad_user_creds
= {"username": "spotty",
37 cases
= ((self
.server
["administrator"], "Admin credentials", 1),
38 (bad_user_creds
, "Bad credentials", 0))
40 # TODO: add unpriv user case
42 for creds
, testname
, result
in cases
:
44 self
.runTestArg(creds
)
49 self
.fail("rpc with creds %s failed when it "
50 "should have suceeded" % creds
)
54 self
.fail("rpc with creds %s suceeded when it should "
55 "have failed" % creds
)
57 class ArgTestServer(PrintServerTest
):
58 """Test a RPC that takes a UNC print server name."""
61 # List of test cases, %s substituted for server name
63 cases
= (("", "No server name", 0),
64 ("\\\\%s", "Valid server name", 1),
65 ("\\%s", "Invalid unc server name", 0),
66 ("\\\\%s__", "Invalid unc server name", 0))
68 for unc
, testname
, result
in cases
:
69 unc
= re
.sub("%s", self
.server
["hostname"], unc
)
74 self
.fail("rpc(\"%s\") failed when it should have "
79 # Suceeded when we should have failed
80 self
.fail("rpc(\"%s\") suceeded when it should have "
83 class ArgTestServerAndPrinter(ArgTestServer
):
84 """Test a RPC that takes a UNC print server or UNC printer name."""
87 ArgTestServer
.runTest(self
)
89 # List of test cases, %s substituted for server name, %p substituted
92 cases
= (("\\\\%s\\%p", "Valid server and printer name", 1),
93 ("\\\\%s\\%p__", "Valid server, invalid printer name", 0),
94 ("\\\\%s__\\%p", "Invalid server, valid printer name", 0))
96 for unc
, testname
, result
in cases
:
97 unc
= re
.sub("%s", self
.server
["hostname"], unc
)
98 unc
= re
.sub("%p", self
.printername
, unc
)
103 self
.fail("openprinter(\"%s\") failed when it should have "
108 # Suceeded when we should have failed
109 self
.fail("openprinter(\"%s\") suceeded when it should have "
112 class OpenPrinterArg(ArgTestServerAndPrinter
):
113 """Test the OpenPrinter RPC with combinations of valid and invalid
114 server and printer names."""
115 def runTestArg(self
, unc
):
116 spoolss
.openprinter(unc
)
118 class OpenPrinterCred(CredentialTest
):
119 """Test opening printer with good and bad credentials."""
120 def runTestArg(self
, creds
):
121 spoolss
.openprinter(self
.uncname
, creds
= creds
)
123 class ClosePrinter(PrintServerTest
):
124 """Test the ClosePrinter RPC on a printer handle."""
126 hnd
= spoolss
.openprinter(self
.uncname
)
127 spoolss
.closeprinter(hnd
)
129 class ClosePrinterServer(PrintServerTest
):
130 """Test the ClosePrinter RPC on a print server handle."""
132 hnd
= spoolss
.openprinter("\\\\%s" % self
.server
["hostname"])
133 spoolss
.closeprinter(hnd
)
135 class GetPrinterInfo(PrintServerTest
):
136 """Retrieve printer info at various levels."""
138 # Sample printer data
141 0: {'printer_errors': 0, 'unknown18': 0, 'unknown13': 0, 'unknown26': 0, 'cjobs': 0, 'unknown11': 0, 'server_name': '\\\\win2kdc1', 'total_pages': 0, 'unknown15': 586, 'unknown16': 0, 'month': 2, 'unknown20': 0, 'second': 23, 'unknown22': 983040, 'unknown25': 0, 'total_bytes': 0, 'unknown27': 0, 'year': 2003, 'build_version': 2195, 'unknown28': 0, 'global_counter': 4, 'day': 13, 'minute': 53, 'total_jobs': 0, 'unknown29': 1114112, 'name': '\\\\win2kdc1\\p', 'hour': 2, 'level': 0, 'c_setprinter': 0, 'change_id': 522454169, 'major_version': 5, 'unknown23': 15, 'day_of_week': 4, 'unknown14': 1, 'session_counter': 2, 'status': 1, 'unknown7': 1, 'unknown8': 0, 'unknown9': 0, 'milliseconds': 421, 'unknown24': 0},
142 1: {'comment': "I'm a teapot!", 'level': 1, 'flags': 8388608, 'name': '\\\\win2kdc1\\p', 'description': '\\\\win2kdc1\\p,HP LaserJet 4,Canberra office'},
143 2: {'comment': "I'm a teapot!", 'status': 1, 'print_processor': 'WinPrint', 'until_time': 0, 'share_name': 'p', 'start_time': 0, 'device_mode': {'icm_method': 1, 'bits_per_pel': 0, 'log_pixels': 0, 'orientation': 1, 'panning_width': 0, 'color': 2, 'pels_width': 0, 'print_quality': 600, 'driver_version': 24, 'display_flags': 0, 'y_resolution': 600, 'media_type': 0, 'display_frequency': 0, 'icm_intent': 0, 'pels_height': 0, 'reserved1': 0, 'size': 220, 'scale': 100, 'dither_type': 0, 'panning_height': 0, 'default_source': 7, 'duplex': 1, 'fields': 16131, 'spec_version': 1025, 'copies': 1, 'device_name': '\\\\win2kdc1\\p', 'paper_size': 1, 'paper_length': 0, 'private': 'private', 'collate': 0, 'paper_width': 0, 'form_name': 'Letter', 'reserved2': 0, 'tt_option': 0}, 'port_name': 'LPT1:', 'sepfile': '', 'parameters': '', 'security_descriptor': {'group_sid': 'S-1-5-21-1606980848-1677128483-854245398-513', 'sacl': None, 'dacl': {'ace_list': [{'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-544'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-544'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1121'}, {'flags': 10, 'type': 0, 'mask': 131072, 'trustee': 'S-1-3-0'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-3-0'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1124'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-1-0'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-550'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-550'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-549'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-549'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1106'}], 'revision': 2}, 'owner_sid': 'S-1-5-32-544', 'revision': 1}, 'name': '\\\\win2kdc1\\p', 'server_name': '\\\\win2kdc1', 'level': 2, 'datatype': 'RAW', 'cjobs': 0, 'average_ppm': 0, 'priority': 1, 'driver_name': 'HP LaserJet 4', 'location': 'Canberra office', 'attributes': 8776, 'default_priority': 0},
144 3: {'flags': 4, 'security_descriptor': {'group_sid': 'S-1-5-21-1606980848-1677128483-854245398-513', 'sacl': None, 'dacl': {'ace_list': [{'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-544'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-544'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1121'}, {'flags': 10, 'type': 0, 'mask': 131072, 'trustee': 'S-1-3-0'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-3-0'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1124'}, {'flags': 0, 'type': 0, 'mask': 131080, 'trustee': 'S-1-1-0'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-550'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-550'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-32-549'}, {'flags': 9, 'type': 0, 'mask': 983056, 'trustee': 'S-1-5-32-549'}, {'flags': 0, 'type': 0, 'mask': 983052, 'trustee': 'S-1-5-21-1606980848-1677128483-854245398-1106'}], 'revision': 2}, 'owner_sid': 'S-1-5-32-544', 'revision': 1}, 'level': 3}
148 self
.hnd
= spoolss
.openprinter(self
.uncname
)
150 # Everyone should have getprinter levels 0-3
152 for i
in (0, 1, 2, 3):
153 info
= self
.hnd
.getprinter(level
= i
)
155 stf
.dict_check(self
.sample_info
[i
], info
)
156 except ValueError, msg
:
157 raise "info%d: %s" % (i
, msg
)
159 class EnumPrinters(PrintServerTest
):
160 """Enumerate print info at various levels."""
164 0: {'q': {'printer_errors': 0, 'unknown18': 0, 'unknown13': 0, 'unknown26': 0, 'cjobs': 0, 'unknown11': 0, 'server_name': '', 'total_pages': 0, 'unknown15': 586, 'unknown16': 0, 'month': 2, 'unknown20': 0, 'second': 23, 'unknown22': 983040, 'unknown25': 0, 'total_bytes': 0, 'unknown27': 0, 'year': 2003, 'build_version': 2195, 'unknown28': 0, 'global_counter': 4, 'day': 13, 'minute': 53, 'total_jobs': 0, 'unknown29': -1833435136, 'name': 'q', 'hour': 2, 'level': 0, 'c_setprinter': 0, 'change_id': 522454169, 'major_version': 5, 'unknown23': 15, 'day_of_week': 4, 'unknown14': 1, 'session_counter': 1, 'status': 0, 'unknown7': 1, 'unknown8': 0, 'unknown9': 0, 'milliseconds': 421, 'unknown24': 0}, 'p': {'printer_errors': 0, 'unknown18': 0, 'unknown13': 0, 'unknown26': 0, 'cjobs': 0, 'unknown11': 0, 'server_name': '', 'total_pages': 0, 'unknown15': 586, 'unknown16': 0, 'month': 2, 'unknown20': 0, 'second': 23, 'unknown22': 983040, 'unknown25': 0, 'total_bytes': 0, 'unknown27': 0, 'year': 2003, 'build_version': 2195, 'unknown28': 0, 'global_counter': 4, 'day': 13, 'minute': 53, 'total_jobs': 0, 'unknown29': -1831337984, 'name': 'p', 'hour': 2, 'level': 0, 'c_setprinter': 0, 'change_id': 522454169, 'major_version': 5, 'unknown23': 15, 'day_of_week': 4, 'unknown14': 1, 'session_counter': 1, 'status': 1, 'unknown7': 1, 'unknown8': 0, 'unknown9': 0, 'milliseconds': 421, 'unknown24': 0}, 'magpie': {'printer_errors': 0, 'unknown18': 0, 'unknown13': 0, 'unknown26': 0, 'cjobs': 0, 'unknown11': 0, 'server_name': '', 'total_pages': 0, 'unknown15': 586, 'unknown16': 0, 'month': 2, 'unknown20': 0, 'second': 23, 'unknown22': 983040, 'unknown25': 0, 'total_bytes': 0, 'unknown27': 0, 'year': 2003, 'build_version': 2195, 'unknown28': 0, 'global_counter': 4, 'day': 13, 'minute': 53, 'total_jobs': 0, 'unknown29': 1114112, 'name': 'magpie', 'hour': 2, 'level': 0, 'c_setprinter': 0, 'change_id': 522454169, 'major_version': 5, 'unknown23': 15, 'day_of_week': 4, 'unknown14': 1, 'session_counter': 1, 'status': 0, 'unknown7': 1, 'unknown8': 0, 'unknown9': 0, 'milliseconds': 421, 'unknown24': 0}},
166 1: {'q': {'comment': 'cheepy birds', 'level': 1, 'flags': 8388608, 'name': 'q', 'description': 'q,HP LaserJet 4,'}, 'p': {'comment': "I'm a teapot!", 'level': 1, 'flags': 8388608, 'name': 'p', 'description': 'p,HP LaserJet 4,Canberra office'}, 'magpie': {'comment': '', 'level': 1, 'flags': 8388608, 'name': 'magpie', 'description': 'magpie,Generic / Text Only,'}}
171 info
= spoolss
.enumprinters(
172 "\\\\%s" % self
.server
["hostname"], level
= i
)
174 stf
.dict_check(self
.sample_info
[i
], info
)
175 except ValueError, msg
:
176 raise "info%d: %s" % (i
, msg
)
178 class EnumPrintersArg(ArgTestServer
):
179 def runTestArg(self
, unc
):
180 spoolss
.enumprinters(unc
)
182 class EnumPrintersCred(CredentialTest
):
183 """Test opening printer with good and bad credentials."""
184 def runTestArg(self
, creds
):
185 spoolss
.enumprinters(
186 "\\\\%s" % self
.server
["hostname"], creds
= creds
)
188 class EnumPrinterdrivers(PrintServerTest
):
191 1: {'Okipage 10ex (PCL5E) : STANDARD': {'name': 'Okipage 10ex (PCL5E) : STANDARD', 'level': 1}, 'Generic / Text Only': {'name': 'Generic / Text Only', 'level': 1}, 'Brother HL-1030 series': {'name': 'Brother HL-1030 series', 'level': 1}, 'Brother HL-1240 series': {'name': 'Brother HL-1240 series', 'level': 1}, 'HP DeskJet 1220C Printer': {'name': 'HP DeskJet 1220C Printer', 'level': 1}, 'HP LaserJet 4100 PCL 6': {'name': 'HP LaserJet 4100 PCL 6', 'level': 1}, 'HP LaserJet 4': {'name': 'HP LaserJet 4', 'level': 1}},
192 2: {'Okipage 10ex (PCL5E) : STANDARD': {'version': 2, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\2\\RASDDUI.DLL', 'name': 'Okipage 10ex (PCL5E) : STANDARD', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\2\\RASDD.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\2\\OKIPAGE.DLL', 'level': 2, 'architecture': 'Windows NT x86'}, 'Generic / Text Only': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\UNIDRVUI.DLL', 'name': 'Generic / Text Only', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\UNIDRV.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\TTY.GPD', 'level': 2, 'architecture': 'Windows NT x86'}, 'Brother HL-1030 series': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BRUHL99A.DLL', 'name': 'Brother HL-1030 series', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BROHL99A.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BROHL103.PPD', 'level': 2, 'architecture': 'Windows NT x86'}, 'Brother HL-1240 series': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BRUHL99A.DLL', 'name': 'Brother HL-1240 series', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BROHL99A.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\BROHL124.PPD', 'level': 2, 'architecture': 'Windows NT x86'}, 'HP DeskJet 1220C Printer': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPW8KMD.DLL', 'name': 'HP DeskJet 1220C Printer', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPW8KMD.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPW8KMD.DLL', 'level': 2, 'architecture': 'Windows NT x86'}, 'HP LaserJet 4100 PCL 6': {'version': 3, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPBF042E.DLL', 'name': 'HP LaserJet 4100 PCL 6', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPBF042G.DLL', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\3\\HPBF042I.PMD', 'level': 2, 'architecture': 'Windows NT x86'}, 'HP LaserJet 4': {'version': 2, 'config_file': '\\\\WIN2KDC1\\print$\\W32X86\\2\\hpblff0.dll', 'name': 'HP LaserJet 4', 'driver_path': '\\\\WIN2KDC1\\print$\\W32X86\\2\\hpblff2.dll', 'data_file': '\\\\WIN2KDC1\\print$\\W32X86\\2\\hpblff39.pmd', 'level': 2, 'architecture': 'Windows NT x86'}}
197 info
= spoolss
.enumprinterdrivers(
198 "\\\\%s" % self
.server
["hostname"], level
= i
)
200 if not self
.sample_info
.has_key(i
):
201 self
.log("%s" % info
)
203 stf
.dict_check(self
.sample_info
[i
], info
)
204 except ValueError, msg
:
205 raise "info%d: %s" % (i
, msg
)
207 class EnumPrinterdriversArg(ArgTestServer
):
208 def runTestArg(self
, unc
):
209 spoolss
.enumprinterdrivers(unc
)
211 class EnumPrinterdriversCred(CredentialTest
):
212 """Test opening printer with good and bad credentials."""
213 def runTestArg(self
, creds
):
214 spoolss
.enumprinterdrivers(
215 "\\\\%s" % self
.server
["hostname"], creds
= creds
)
218 print "Usage: spoolss.py [options] [test1[,test2...]]"
219 print "\t -v/--verbose Display debugging information"
220 print "\t -l/--list-tests List available tests"
222 print "A list of comma separated test names or regular expressions"
223 print "can be used to filter the tests performed."
225 def test_match(subtest_list
, test_name
):
226 """Return true if a test matches a comma separated list of regular
227 expression of test names."""
228 # re.match does an implicit ^ at the start of the pattern.
229 # Explicitly anchor to end to avoid matching substrings.
230 for s
in string
.split(subtest_list
, ","):
231 if re
.match(s
+ "$", test_name
):
235 if __name__
== "__main__":
236 import os
, sys
, string
240 opts
, args
= getopt
.getopt(sys
.argv
[1:], "vl", \
241 ["verbose", "list-tests"])
242 except getopt
.GetoptError
:
249 for opt
, arg
in opts
:
250 if opt
in ("-v", "--verbose"):
252 if opt
in ("-l", "--list-tests"):
269 EnumPrinterdriversCred
,
270 EnumPrinterdriversArg
,
275 for test
in test_list
:
276 if test_match(args
[0], test
.__name
__):
280 if os
.environ
.has_key("SAMBA_DEBUG"):
281 spoolss
.setup_logging(interactive
= 1)
282 spoolss
.set_debuglevel(10)
285 for test
in test_list
:
288 comfychair
.runtests(test_list
, verbose
= verbose
)