17db96d56Sopenharmony_ciimport unittest 27db96d56Sopenharmony_cifrom test import support 37db96d56Sopenharmony_cifrom test.support import os_helper 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ciimport io # C implementation. 67db96d56Sopenharmony_ciimport _pyio as pyio # Python implementation. 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci# Simple test to ensure that optimizations in the IO library deliver the 97db96d56Sopenharmony_ci# expected results. For best testing, run this under a debug-build Python too 107db96d56Sopenharmony_ci# (to exercise asserts in the C code). 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_cilengths = list(range(1, 257)) + [512, 1000, 1024, 2048, 4096, 8192, 10000, 137db96d56Sopenharmony_ci 16384, 32768, 65536, 1000000] 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ciclass BufferSizeTest: 167db96d56Sopenharmony_ci def try_one(self, s): 177db96d56Sopenharmony_ci # Write s + "\n" + s to file, then open it and ensure that successive 187db96d56Sopenharmony_ci # .readline()s deliver what we wrote. 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ci # Ensure we can open TESTFN for writing. 217db96d56Sopenharmony_ci os_helper.unlink(os_helper.TESTFN) 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci # Since C doesn't guarantee we can write/read arbitrary bytes in text 247db96d56Sopenharmony_ci # files, use binary mode. 257db96d56Sopenharmony_ci f = self.open(os_helper.TESTFN, "wb") 267db96d56Sopenharmony_ci try: 277db96d56Sopenharmony_ci # write once with \n and once without 287db96d56Sopenharmony_ci f.write(s) 297db96d56Sopenharmony_ci f.write(b"\n") 307db96d56Sopenharmony_ci f.write(s) 317db96d56Sopenharmony_ci f.close() 327db96d56Sopenharmony_ci f = open(os_helper.TESTFN, "rb") 337db96d56Sopenharmony_ci line = f.readline() 347db96d56Sopenharmony_ci self.assertEqual(line, s + b"\n") 357db96d56Sopenharmony_ci line = f.readline() 367db96d56Sopenharmony_ci self.assertEqual(line, s) 377db96d56Sopenharmony_ci line = f.readline() 387db96d56Sopenharmony_ci self.assertFalse(line) # Must be at EOF 397db96d56Sopenharmony_ci f.close() 407db96d56Sopenharmony_ci finally: 417db96d56Sopenharmony_ci os_helper.unlink(os_helper.TESTFN) 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci def drive_one(self, pattern): 447db96d56Sopenharmony_ci for length in lengths: 457db96d56Sopenharmony_ci # Repeat string 'pattern' as often as needed to reach total length 467db96d56Sopenharmony_ci # 'length'. Then call try_one with that string, a string one larger 477db96d56Sopenharmony_ci # than that, and a string one smaller than that. Try this with all 487db96d56Sopenharmony_ci # small sizes and various powers of 2, so we exercise all likely 497db96d56Sopenharmony_ci # stdio buffer sizes, and "off by one" errors on both sides. 507db96d56Sopenharmony_ci q, r = divmod(length, len(pattern)) 517db96d56Sopenharmony_ci teststring = pattern * q + pattern[:r] 527db96d56Sopenharmony_ci self.assertEqual(len(teststring), length) 537db96d56Sopenharmony_ci self.try_one(teststring) 547db96d56Sopenharmony_ci self.try_one(teststring + b"x") 557db96d56Sopenharmony_ci self.try_one(teststring[:-1]) 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci def test_primepat(self): 587db96d56Sopenharmony_ci # A pattern with prime length, to avoid simple relationships with 597db96d56Sopenharmony_ci # stdio buffer sizes. 607db96d56Sopenharmony_ci self.drive_one(b"1234567890\00\01\02\03\04\05\06") 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci def test_nullpat(self): 637db96d56Sopenharmony_ci self.drive_one(b'\0' * 1000) 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ciclass CBufferSizeTest(BufferSizeTest, unittest.TestCase): 677db96d56Sopenharmony_ci open = io.open 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ciclass PyBufferSizeTest(BufferSizeTest, unittest.TestCase): 707db96d56Sopenharmony_ci open = staticmethod(pyio.open) 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ciif __name__ == "__main__": 747db96d56Sopenharmony_ci unittest.main() 75