Skip to content
Freek Dijkstra edited this page May 14, 2018 · 12 revisions

Unit tests

The NBT library comes with a number of unit tests, although they have been added later and do not cover all possible methods and options available. These teste are automatically executed by the Travis continuous integration service.

Requirements

The unit tests are written with help of unittest2. This package is available in the standard library (as unittest) starting with Python 2.7. Python 2.6 includes an older version of unittest, and unittest2 need to be manually installed:

pip install unittest2

Due to insecurity of HTTPS in urllib2, it does no longer work for Python up to 2.7.9. In that case, the external curl program is used to download a sample file. Note that urllib2 before 2.7.9 or 3.4.2 never checked the HTTPS (x509) certificates. A SHA256 checksum is calculated to check the validity of the downloaded files.

downloadsample script

Download a Minecraft sample world from GitHub and verify the SHA256 checksum.

downloadsample.URL = 'https://github.com/downloads/twoolie/NBT/Sample_World.tar.gz'

URL to retrieve

downloadsample.workdir = '/Users/freek/Repository/NBT/tests'

Directory for download and extracting the sample files

downloadsample.worlddir = '/Users/freek/Repository/NBT/tests/Sample World'

Destination folder for the sample world.

downloadsample.checksums = {'Sample World': Non ... 57a5b3256b437af0d7dba'}

SHA256 checksums for each file in the tar file. Directories MUST also be included (without trailing slash), with None as the checksum

downloadsample.download(url, destination)

Download the file from the specified URL, and extract the contents.

Uses urllib2.

WARNING: urllib2 does not verify the certificate for Python earlier than 2.7.9 or 3.4.2 (!). Verify the checksums before using the downloaded files.

Warning: Before Python 2.7.9, urllib2 can’t download over HTTPS, since it effectively only supports SSLv3, which is nowadays deprecated by websites. In these cases, the following SSLError is raised: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

May raise an IOError or SSLError.

downloadsample.download_with_external_tool(url, destination)

Download the file from the specified URL, and extract the contents.

Uses the external curl program. wget fails if it is compiled with older version of OpenSSL. Hence we use curl.

May raise an OSError (or one of it’s subclasses).

downloadsample.extract(filename, workdir, filelist)

Extract contents of a tar file in workdir. The tar file may be compressed using gzip or bzip2.

For security, only files listed in filelist are extracted. Extraneous files will be logged as warning.

downloadsample.verify(checksums)

Verify if all given files are present and their SHA256 checksum is correct. Any files not explicitly listed are deleted.

checksums is a dict of file => checksum, with file a file relative to dir.

Returns a boolean indicating that all checksums are correct, and all files are present.

Any warnings and errors are printer to logger. Errors or exceptions result in a return value of False.

downloadsample.install(url='https://github.com/downloads/twoolie/NBT/Sample_World.tar.gz', workdir='/Users/freek/Repository/NBT/tests', checksums={'Sample World': None, 'Sample World/data': None, 'Sample World/level.dat': 'f252cf8b938fa1e41c9335ea1bdc70fca73ac5c63c2cf2db4b2ddc4cb2fa4d91', 'Sample World/level.dat_mcr': '933238e89a9f7f94c72f236da0d81d44d966c7a1544490e51e682ab42ccc50ff', 'Sample World/level.dat_old': 'c4b5a5c355d4f85c369604ca27ee349dba41adc4712a43a6f8c8399fe44071e7', 'Sample World/region': None, 'Sample World/region/r.-1.0.mca': '6e8ec8698e2e68ca3ee2090da72e4f24c85f9db3f36191e5e33ebc8cafb209f2', 'Sample World/region/r.-1.0.mcr': '3a9ccafc6f64b98c0424814f44f1d0d3429cbb33448ff97e2e84ca649bfa16ae', 'Sample World/region/r.-1.1.mca': 'c5f6fb5c72ca534d0f73662f2199dca977d2de1521b4823f73384aa6826c4b74', 'Sample World/region/r.-1.1.mcr': '8e8b545b412a6a2bb519aee0259a63e6a918cd25a49538451e752e3bf90d4cf1', 'Sample World/region/r.0.0.mca': 'd86e51c2adf35f82492e974f75fe83e9e5db56a267a3fe76150dc42f0aeb07c7', 'Sample World/region/r.0.0.mcr': 'a8e7fea4e40a70e0d70dea7ebb1328c7623ed01b77d8aff34d01e530fbdad9d5', 'Sample World/region/r.0.1.mca': '8a03d910c7fd185ae5efb1409c592e4a9688dfab1fbd31f8c736461157a7675d', 'Sample World/region/r.0.1.mcr': '08fcd50748d4633a3b1d52e1b323c7dd9c4299a28ec095d0261fd195d3c9a537', 'Sample World/session.lock': 'd05da686dd04cd2ad1f660ddaa7645abc9fd9af396357a5b3256b437af0d7dba'})

Download and extract a sample world, used for testing. The download file and sample world are stored in workdir.

Verifies the checksum of all files. Files without a checksum are not extracted.

downloadsample.temp_mcregion_world(worldfolder='/Users/freek/Repository/NBT/tests/Sample World')

Create a McRegion worldfolder in a temporary directory, based on the files in the given mixed worldfolder. Returns the temporary directory path.

downloadsample.temp_anvil_world(worldfolder='/Users/freek/Repository/NBT/tests/Sample World')

Create a Anvil worldfolder in a temporary directory, based on the files in the given mixed worldfolder. Returns the temporary directory path.

downloadsample.cleanup_temp_world(tmpfolder)

Remove a temporary directory

nbttests unit test

Unit tests for nbt.nbt Module

class nbttests.BugfixTest(methodName='runTest')

Bases: unittest.case.TestCase

Bugfix regression tests.

testEmptyFiles()

Opening an empty file causes an uncaught exception. https://github.com/twoolie/NBT/issue/4

class nbttests.ReadWriteTest(methodName='runTest')

Bases: unittest.case.TestCase

test that we can read the test file correctly

setUp()

Hook method for setting up the test fixture before exercising it.

tearDown()

Hook method for deconstructing the test fixture after testing it.

testReadBig()

testWriteBig()

testWriteback()

testProperlyClosed()

test that files opened from a file name are closed after being written to. i.e. will read correctly in the future

class nbttests.TreeManipulationTest(methodName='runTest')

Bases: unittest.case.TestCase

setUp()

Hook method for setting up the test fixture before exercising it.

testRootNodeSetup()

testTagNumeric()

tearDown()

Hook method for deconstructing the test fixture after testing it.

class nbttests.EmptyStringTest(methodName='runTest')

Bases: unittest.case.TestCase

setUp()

Hook method for setting up the test fixture before exercising it.

testReadEmptyString()

testWriteEmptyString()

chunktests unit test

Unit tests for nbt.chunk Module

No tests available (yet)

regiontests unit test

Unit tests for nbt.region Module

regiontests.generate_level(bytesize=4)

Generate a level, which is a given size in bytes.

regiontests.generate_compressed_level(minsize=2000, maxsize=None)

Generate a level, which -when zlib compressed- is the given size in bytes. Note: this returns the UNCOMPRESSED NBT file.

class regiontests.PedanticFileWrapper(stream)

Bases: object

Pedantic wrapper around a file object. Is guaranteed to raise an IOError if an attempt is made to: - seek to a location larger than the file - read behind the file boundary Only works for random access files that support seek() and tell().

__init__(stream)

Create a new wrapper. stream must be a file object.

seek(offset, whence=0)

read(size=-1)

__str__()

Return str(self).

__repr__()

Return repr(self).

class regiontests.ReadWriteTest(methodName='runTest')

Bases: unittest.case.TestCase

Test to read, write and relocate chunks in a region file.

setUp()

Hook method for setting up the test fixture before exercising it.

tearDown()

Hook method for deconstructing the test fixture after testing it.

test000MethodFileSize()

Test of the get_size() method. The regionfile has 27 sectors.

test001MethodChunkCount()

Test of the chunk_count() method. The regionfile has 21 chunks, including 3-out of file chunks.

test002MethodGetChunkCoords()

Test of get_chunk_coords() method. Note: this function may be deprecated in a later version of NBT.

test003MethodIterChunks()

Test of iter_chunks() method.

test004SyntaxIterChunks()

Test of iter(RegionFile) syntax.

test005ParameterHeaders()

read headers of chunk 9,0: sector 6, 1 sector length, timestamp 1334530101, status STATUS_CHUNK_OK. read chunk headers of chunk 9,0: length (incl. compression byte): 3969 bytes, zlip (2) compression, status STATUS_CHUNK_OK.

test006ParameterHeadersUndefinedChunk()

read headers & chunk_headers of chunk 2,2

test010ReadChunkZlibCompression()

chunk 9,0: regular Zlib compression. Should be read OK.

test011ReadChunkGzipCompression()

chunk 10,0: deprecated GZip compression. Should be read OK.

test012ReadChunkUncompressed()

chunk 2,0: no compression. Should be read OK.

test013ReadUnknownEncoding()

chunk 11,0 has unknown encoding (3). Reading should raise a ChunkDataError.

test014ReadMalformedEncoding()

chunk 3,0 has malformed content. Reading should raise a ChunkDataError. This should not raise a MalformedFileError.

test015ReadMalformedNBT()

read chunk 5,1: valid compression, but not a valid NBT file. Reading should raise a ChunkDataError, not a nbt.nbt.MalformedFileError.

test016ReadChunkNonExistent()

read chunk 2,2: does not exist. Reading should raise a InconceivedChunk.

test017ReadableChunks()

Test which chunks are readable.

test020ReadInHeader()

read chunk 14,0: supposedly located in the header. Reading should raise a RegionHeaderError.

test021ReadOutOfFile()

read chunk 15,0: error (out of file)

test022ReadZeroLengthHeader()

read chunk 13,0: error (zero-length)

test023ReadInvalidLengthChunk()

zero-byte lengths in chunk. (4,1) read chunk 4,1: error (invalid)

test024ReadZeroLengthChunk()

read chunk 8,1: error (zero-length chunk)

test025ReadChunkSizeExceedsSectorSize()

read chunk 3,1: can be read, despite that the chunk content is longer than the allocated sectors. In general, reading should either succeeds, or raises a ChunkDataError. The status should be STATUS_CHUNK_MISMATCHED_LENGTHS.

test026ReadChunkOverlapping()

chunk 4,0 and chunk 12,0 overlap: status should be STATUS_CHUNK_OVERLAPPING

test030GetTimestampOK()

get_timestamp read chunk 9,0: OK

test031GetTimestampBadChunk()

read chunk 15,0: OK Data is out-out-of-file, but timestamp is still there.

test032GetTimestampNoChunk()

read chunk 17,0: OK no data, but a timestamp

test033GetTimestampMissing()

read chunk 7,1: OK data, but no timestamp

test040WriteNewChunk()

read chunk 0,2: InconceivedError write 1 sector chunk 0,2 - read location (<= 026), size (001), timestamp (non-zero).

test041WriteAndReadNewChunk()

write 1 sector chunk 0,2 read chunk 0,2: OK - compare writen and read NBT file

test042WriteExistingChunk()

write 1 sector chunk 9,0 (should stay in 006) - read location (006) and size (001).

test043DeleteChunk()

read chunk 6,0: OK unlink chunk 6,0 - check location, size, timestamp (all should be 0) read chunk 6,0: InconceivedError

test044UseEmptyChunks()

write 1 sector chunk 1,2 (should go to 004) write 1 sector chunk 2,2 (should go to 010) write 1 sector chunk 3,2 (should go to 011) verify file size remains 027*4096

test050WriteNewChunk2sector()

write 2 sector chunk 1,2 (should go to 010-011)

test051WriteNewChunk4096byte()

write 4091+5-byte (1 sector) chunk 1,2 (should go to 004)

test052WriteNewChunk4097byte()

write 4092+5-byte (2 sector) chunk 1,2 (should go to 010-011)

test053WriteNewChunkIncreaseFile()

write 3 sector chunk 2,2 (should go to 026-028 or 027-029) (increase file size) verify file size is 29*4096

test054WriteExistingChunkDecreaseSector()

write 1 sector chunk 16,0 (should go to existing 017) (should free sector 018) write 1 sector chunk 1,2 (should go to 004) write 1 sector chunk 2,2 (should go to 010) write 1 sector chunk 3,2 (should go to 011) write 1 sector chunk 4,2 (should go to freed 018) write 1 sector chunk 5,2 (should go to 026) verify file size remains 027*4096

test055WriteChunkTooLarge()

Chunks of size >= 256 sectors are not supported by the file format attempt to write a chunk 256 sectors in size should raise Exception

test060WriteExistingChunkIncreaseSectorSameLocation()

write 2 sector chunk 7,0 (should go to 003-004) (increase chunk size)

test061WriteExistingChunkCorrectSize()

write 2 sector chunk 3,1 (should go to 025-026) (increase sector size)

test062WriteExistingChunkIncreaseSectorNewLocation()

write 2 sector chunk 8,0 (should go to 004-005 or 010-011) verify chunk_count remains 18 write 2 sector chunk 2,2 (should go to 010-011 or 004-005) verify that file size is not increased <= 027*4096 verify chunk_count is 19

test063WriteNewChunkFreedSectors()

unlink chunk 6,0 unlink chunk 7,0 write 3 sector chunk 2,2 (should go to 002-004) (file size should remain the same)

test070WriteOutOfFileChunk()

write 1 sector chunk 13,0 (should go to 004) Should not go to sector 30 (out-of-file location)

test071WriteZeroLengthSectorChunk()

write 1 sector chunk 13,0 (should go to 004) Verify sector 19 remains untouched.

test072WriteOverlappingChunkLong()

write 2 sector chunk 4,0 (should go to 010-011) (free 014 & 016) verify location is NOT 014 (because of overlap) write 1 sector chunk 1,2 (should go to 004) write 1 sector chunk 2,2 (should go to freed 014) write 1 sector chunk 3,2 (should go to freed 016) write 1 sector chunk 4,2 (should go to 018) write 1 sector chunk 5,2 (should go to 026) verify file size remains 027*4096

test073WriteOverlappingChunkSmall()

write 1 sector chunk 12,0 (should go to 004) (“free” 015 for use by 4,0) verify location is NOT 015 verify sectors 15 and 16 are not marked as “free”, but remain in use by 4,0

test074WriteOverlappingChunkSameLocation()

write 1 sector chunk 12,0 (should go to 004) (“free” 012 for use by 4,0) write 3 sector chunk 4,0 (should stay in 014-016) verify file size remains <= 027*4096

test080FileTruncateLastChunkDecrease()

write 1 sector chunk 3,1 (should remain in 025) (free 026) verify file size is truncated: 26*4096 bytes

test081FileTruncateFreeTail()

delete chunk 3,1 (free 025: truncate file size) verify file size: 25*4096 bytes

test082FileTruncateMergeFree()

delete chunk 8,1 (free 024) delete chunk 3,1 (free 025: truncate file size, including 024) verify file size: 24*4096 bytes

test090DeleteNonExistingChunk()

delete chunk 2,2

test091DeleteNonInHeaderChunk()

delete chunk 14,0. This should leave sector 1 untouched. verify sector 1 is unmodified, with the exception of timestamp for chunk 14,0.

test092DeleteOutOfFileChunk()

delete chunk 15,1 verify file size is not increased.

test093DeleteChunkZeroTimestamp()

delete chunk 17,0 verify timestamp is zeroed. both in get_timestamp() and get_metadata()

test100WriteZeroPadding()

write 1 sector chunk 16,0 (should go to existing 017) (should free sector 018) Check if unused bytes in sector 017 and all bytes in sector 018 are zeroed.

test101DeleteZeroPadding()

unlink chunk 7,1 Check if all bytes in sector 022 are zeroed.

test102DeleteOverlappingNoZeroPadding()

unlink chunk 4,0. Due to overlapping chunks, bytes should not be zeroed. Check if bytes in sector 015 are not all zeroed.

test103MoveOverlappingNoZeroPadding()

write 2 sector chunk 4,0 to a different location. Due to overlapping chunks, bytes should not be zeroed. Check if bytes in sector 015 are not all zeroed.

test104DeleteZeroPaddingMismatchLength()

unlink chunk 3,1. (which has a length mismatch) Check if bytes in sector 025 are all zeroed. Check if first byte in sector 026 is not zeroed.

class regiontests.EmptyFileTest(methodName='runTest')

Bases: unittest.case.TestCase

Test for 0-byte file support. These files should be treated as a valid region file without any stored chunk.

static generate_level()

setUp()

Hook method for setting up the test fixture before exercising it.

test01ReadFile()

test02WriteFile()

class regiontests.RegionFileInitTest(methodName='runTest')

Bases: unittest.case.TestCase

Tests for the various init parameters provided for RegionFile().

testCreateFromFilename()

Creating a RegionFile with filename, and deleting the instance should close the underlying file.

testCreateFromFileobject()

Creating RegionFile with file object, and deleting the instance should not close the underlying file.

testNoParameters()

Calling RegionFile without parameters should raise a ValueError

testTwoParameters()

Calling RegionFile with both filename and fileobject should ignore the fileobject.

class regiontests.TruncatedFileTest(methodName='runTest')

Bases: unittest.case.TestCase

Test for truncated file support. This files should be treated as a valid region file, as all data is present. Only the padding bytes are missing.

setUp()

Hook method for setting up the test fixture before exercising it.

tearDown()

Hook method for deconstructing the test fixture after testing it.

test00FileProperties()

test01ReadChunk()

Test if a block can be read, even when the file is truncated right after the block data.

test02ReplaceChunk()

Test if writing the last block in a truncated file will extend the file size to the sector boundary.

test03WriteChunk()

Test if a new chunk extends the file to sector sizes.

class regiontests.LengthTest(methodName='runTest')

Bases: unittest.case.TestCase

Test for length calculations for blocks with inconsistent lengths.

This operates on a simple testfile with: file length: 4 sectors (00-03, inclusive) chunk 0,0: header length 4 sectors; chunk length 10240 bytes (3 sectors); sector 02-05 chunk 1,0: header length 3 sectors; chunk length 613566756 bytes (149797 sectors); sector 03-149799

setUp()

Hook method for setting up the test fixture before exercising it.

tearDown()

Hook method for deconstructing the test fixture after testing it.

test00FileProperties()

testSectors()

Test if RegionFile._sectors() detects the correct overlap.

testMetaDataLengths()

testMetaDataLengthCalculations()

testMetaDataStatus()

testChunkRead()

Perform a low-level read, ensure it does not read past the file length and does not modify the file.

testDeleteChunk()

Try to remove the chunk 1,0 with ridiculous large size. This should be reasonably fast.

worldtests unit test

Unit tests for nbt.world Module

No tests available (yet)

Clone this wiki locally