Package lxml :: Package tests :: Module test_threading
[hide private]
[frames] | no frames]

Source Code for Module lxml.tests.test_threading

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4  Tests for thread usage in lxml.etree. 
  5  """ 
  6   
  7  import unittest, threading, sys, os.path 
  8   
  9  this_dir = os.path.dirname(__file__) 
 10  if this_dir not in sys.path: 
 11      sys.path.insert(0, this_dir) # needed for Py3 
 12   
 13  from common_imports import etree, HelperTestCase, BytesIO, _bytes 
 14   
15 -class ThreadingTestCase(HelperTestCase):
16 """Threading tests""" 17 etree = etree 18
19 - def _run_thread(self, func):
20 thread = threading.Thread(target=func) 21 thread.start() 22 thread.join()
23
24 - def test_subtree_copy_thread(self):
25 tostring = self.etree.tostring 26 XML = self.etree.XML 27 xml = _bytes("<root><threadtag/></root>") 28 main_root = XML(_bytes("<root/>")) 29 30 def run_thread(): 31 thread_root = XML(xml) 32 main_root.append(thread_root[0]) 33 del thread_root
34 35 self._run_thread(run_thread) 36 self.assertEquals(xml, tostring(main_root))
37
38 - def test_main_xslt_in_thread(self):
39 XML = self.etree.XML 40 style = XML(_bytes('''\ 41 <xsl:stylesheet version="1.0" 42 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 43 <xsl:template match="*"> 44 <foo><xsl:copy><xsl:value-of select="/a/b/text()" /></xsl:copy></foo> 45 </xsl:template> 46 </xsl:stylesheet>''')) 47 st = etree.XSLT(style) 48 49 result = [] 50 51 def run_thread(): 52 root = XML(_bytes('<a><b>B</b><c>C</c></a>')) 53 result.append( st(root) )
54 55 self._run_thread(run_thread) 56 self.assertEquals('''\ 57 <?xml version="1.0"?> 58 <foo><a>B</a></foo> 59 ''', 60 str(result[0])) 61
62 - def test_thread_xslt(self):
63 XML = self.etree.XML 64 tostring = self.etree.tostring 65 root = XML(_bytes('<a><b>B</b><c>C</c></a>')) 66 67 def run_thread(): 68 style = XML(_bytes('''\ 69 <xsl:stylesheet version="1.0" 70 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 71 <xsl:template match="*"> 72 <foo><xsl:copy><xsl:value-of select="/a/b/text()" /></xsl:copy></foo> 73 </xsl:template> 74 </xsl:stylesheet>''')) 75 st = etree.XSLT(style) 76 root.append( st(root).getroot() )
77 78 self._run_thread(run_thread) 79 self.assertEquals(_bytes('<a><b>B</b><c>C</c><foo><a>B</a></foo></a>'), 80 tostring(root)) 81
82 - def test_thread_create_xslt(self):
83 XML = self.etree.XML 84 tostring = self.etree.tostring 85 root = XML(_bytes('<a><b>B</b><c>C</c></a>')) 86 87 stylesheets = [] 88 89 def run_thread(): 90 style = XML(_bytes('''\ 91 <xsl:stylesheet 92 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 93 version="1.0"> 94 <xsl:output method="xml" /> 95 <xsl:template match="/"> 96 <div id="test"> 97 <xsl:apply-templates/> 98 </div> 99 </xsl:template> 100 </xsl:stylesheet>''')) 101 stylesheets.append( etree.XSLT(style) )
102 103 self._run_thread(run_thread) 104 105 st = stylesheets[0] 106 result = tostring( st(root) ) 107 108 self.assertEquals(_bytes('<div id="test">BC</div>'), 109 result) 110
111 - def test_thread_mix(self):
112 XML = self.etree.XML 113 Element = self.etree.Element 114 SubElement = self.etree.SubElement 115 tostring = self.etree.tostring 116 xml = _bytes('<a><b>B</b><c xmlns="test">C</c></a>') 117 root = XML(xml) 118 fragment = XML(_bytes("<other><tags/></other>")) 119 120 result = self.etree.Element("{myns}root", att = "someval") 121 122 def run_XML(): 123 thread_root = XML(xml) 124 result.append(thread_root[0]) 125 result.append(thread_root[-1])
126 127 def run_parse(): 128 thread_root = self.etree.parse(BytesIO(xml)).getroot() 129 result.append(thread_root[0]) 130 result.append(thread_root[-1]) 131 132 def run_move_main(): 133 result.append(fragment[0]) 134 135 def run_build(): 136 result.append( 137 Element("{myns}foo", attrib={'{test}attr':'val'})) 138 SubElement(result, "{otherns}tasty") 139 140 def run_xslt(): 141 style = XML(_bytes('''\ 142 <xsl:stylesheet version="1.0" 143 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 144 <xsl:template match="*"> 145 <foo><xsl:copy><xsl:value-of select="/a/b/text()" /></xsl:copy></foo> 146 </xsl:template> 147 </xsl:stylesheet>''')) 148 st = etree.XSLT(style) 149 result.append( st(root).getroot()[0] ) 150 151 for test in (run_XML, run_parse, run_move_main, run_xslt): 152 tostring(result) 153 self._run_thread(test) 154 155 self.assertEquals( 156 _bytes('<ns0:root xmlns:ns0="myns" att="someval"><b>B</b><c xmlns="test">C</c><b>B</b><c xmlns="test">C</c><tags/><a>B</a></ns0:root>'), 157 tostring(result)) 158 159 def strip_first(): 160 root = Element("newroot") 161 root.append(result[0]) 162 163 while len(result): 164 self._run_thread(strip_first) 165 166 self.assertEquals( 167 _bytes('<ns0:root xmlns:ns0="myns" att="someval"/>'), 168 tostring(result)) 169
170 - def test_concurrent_proxies(self):
171 XML = self.etree.XML 172 root = XML(_bytes('<root><a>A</a><b xmlns="test">B</b><c/></root>')) 173 child_count = len(root) 174 def testrun(): 175 for i in range(10000): 176 el = root[i%child_count] 177 del el
178 threads = [ threading.Thread(target=testrun) 179 for _ in range(10) ] 180 for thread in threads: 181 thread.start() 182 for thread in threads: 183 thread.join() 184
185 - def test_concurrent_class_lookup(self):
186 XML = self.etree.XML 187 188 class TestElement(etree.ElementBase): 189 pass
190 191 class MyLookup(etree.CustomElementClassLookup): 192 repeat = range(100) 193 def lookup(self, t, d, ns, name): 194 count = 0 195 for i in self.repeat: 196 # allow other threads to run 197 count += 1 198 return TestElement 199 200 parser = self.etree.XMLParser() 201 parser.set_element_class_lookup(MyLookup()) 202 203 root = XML(_bytes('<root><a>A</a><b xmlns="test">B</b><c/></root>'), 204 parser) 205 206 child_count = len(root) 207 def testrun(): 208 for i in range(1000): 209 el = root[i%child_count] 210 del el 211 threads = [ threading.Thread(target=testrun) 212 for _ in range(10) ] 213 for thread in threads: 214 thread.start() 215 for thread in threads: 216 thread.join() 217
218 -def test_suite():
219 suite = unittest.TestSuite() 220 suite.addTests([unittest.makeSuite(ThreadingTestCase)]) 221 return suite
222 223 if __name__ == '__main__': 224 print('to test use test.py %s' % __file__) 225