Merge remote branch 'github/topic/regression_testing'
This commit is contained in:
commit
d24b4dc10b
9
mce.py
Normal file → Executable file
9
mce.py
Normal file → Executable file
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
import mclevel
|
||||
import sys
|
||||
import os
|
||||
@ -10,6 +11,8 @@ class BlockMatchError(RuntimeError): pass
|
||||
class PlayerNotFound(RuntimeError): pass
|
||||
|
||||
class mce(object):
|
||||
random_seed = os.getenv('MCE_RANDOM_SEED', None)
|
||||
last_played = os.getenv("MCE_LAST_PLAYED", None)
|
||||
"""
|
||||
Usage:
|
||||
|
||||
@ -369,7 +372,7 @@ class mce(object):
|
||||
filename = command.pop(0)
|
||||
destPoint = self.readPoint(command)
|
||||
|
||||
importLevel = mclevel.fromFile(filename)
|
||||
importLevel = mclevel.fromFile(filename, last_played=self.last_played, random_seed=self.random_seed)
|
||||
self.level.copyBlocksFrom(importLevel, importLevel.getWorldBounds(), destPoint);
|
||||
|
||||
|
||||
@ -652,7 +655,7 @@ class mce(object):
|
||||
self.loadWorld(command[0])
|
||||
|
||||
def _reload(self, command):
|
||||
self.level = mclevel.fromFile(self.filename);
|
||||
self.level = mclevel.fromFile(self.filename, last_played=self.last_played, random_seed=self.random_seed);
|
||||
|
||||
def _help(self, command):
|
||||
if len(command):
|
||||
@ -706,7 +709,7 @@ class mce(object):
|
||||
try:
|
||||
worldNum = int(world)
|
||||
except ValueError:
|
||||
self.level = mclevel.fromFile(world)
|
||||
self.level = mclevel.fromFile(world, last_played=self.last_played, random_seed=self.random_seed)
|
||||
|
||||
self.filename = self.level.filename
|
||||
|
||||
|
15
mclevel.py
15
mclevel.py
@ -582,7 +582,7 @@ class MCLevel(object):
|
||||
def saveInPlace(self):
|
||||
self.saveToFile(self.filename);
|
||||
@classmethod
|
||||
def fromFile(cls, filename, loadInfinite=True):
|
||||
def fromFile(cls, filename, loadInfinite=True, random_seed=None, last_played=None):
|
||||
''' The preferred method for loading Minecraft levels of any type.
|
||||
pass False to loadInfinite if you'd rather not load infdev levels.'''
|
||||
info( "Identifying " + filename )
|
||||
@ -599,7 +599,7 @@ class MCLevel(object):
|
||||
raise;
|
||||
try:
|
||||
info( "Can't read, attempting to open directory" )
|
||||
lev = MCInfdevOldLevel(filename=filename)
|
||||
lev = MCInfdevOldLevel(filename=filename, random_seed=random_seed, last_played=last_played)
|
||||
info( "Detected Alpha world." )
|
||||
return lev;
|
||||
except Exception, ex:
|
||||
@ -1499,7 +1499,7 @@ class MCInfdevOldLevel(MCLevel):
|
||||
def __str__(self):
|
||||
return "MCInfdevOldLevel(" + os.path.split(self.worldDir)[1] + ")"
|
||||
|
||||
def __init__(self, filename = None, root_tag = None):
|
||||
def __init__(self, filename = None, root_tag = None, random_seed=None, last_played=None):
|
||||
#pass level.dat's root tag and filename to read an existing level.
|
||||
#pass only filename to create a new one
|
||||
#filename should be the path to the world dir
|
||||
@ -1526,8 +1526,13 @@ class MCInfdevOldLevel(MCLevel):
|
||||
root_tag[Data][SpawnY] = TAG_Int(2)
|
||||
root_tag[Data][SpawnZ] = TAG_Int(0)
|
||||
|
||||
root_tag[Data]['LastPlayed'] = TAG_Long(long(time.time()))
|
||||
root_tag[Data]['RandomSeed'] = TAG_Long(int(random.random() * ((2<<31))))
|
||||
if last_played is None:
|
||||
last_played = time.time()
|
||||
if random_seed is None:
|
||||
random_seed = random.random() * ((2<<31))
|
||||
|
||||
root_tag[Data]['LastPlayed'] = TAG_Long(long(last_played))
|
||||
root_tag[Data]['RandomSeed'] = TAG_Long(int(random_seed))
|
||||
root_tag[Data]['SizeOnDisk'] = TAG_Long(long(1048576))
|
||||
root_tag[Data]['Time'] = TAG_Long(1)
|
||||
root_tag[Data]['SnowCovered'] = TAG_Byte(0);
|
||||
|
BIN
regression_test/alpha.tar.gz
Normal file
BIN
regression_test/alpha.tar.gz
Normal file
Binary file not shown.
113
run_regression_test.py
Executable file
113
run_regression_test.py
Executable file
@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import tempfile
|
||||
import sys
|
||||
import subprocess
|
||||
import shutil
|
||||
import os
|
||||
import mclevel
|
||||
import hashlib
|
||||
import contextlib
|
||||
import gzip
|
||||
import fnmatch
|
||||
import tarfile
|
||||
import zipfile
|
||||
|
||||
def generate_file_list(directory):
|
||||
for dirpath, dirnames, filenames in os.walk(directory):
|
||||
for filename in filenames:
|
||||
yield os.path.join(dirpath, filename)
|
||||
|
||||
def sha1_file(name, checksum=None):
|
||||
CHUNKSIZE=1024
|
||||
if checksum is None:
|
||||
checksum = hashlib.sha1()
|
||||
if fnmatch.fnmatch(name, "*.dat"):
|
||||
opener = gzip.open
|
||||
else:
|
||||
opener = open
|
||||
|
||||
with contextlib.closing(opener(name, 'rb')) as data:
|
||||
chunk = data.read(CHUNKSIZE)
|
||||
while len(chunk) == CHUNKSIZE:
|
||||
checksum.update(chunk)
|
||||
chunk = data.read(CHUNKSIZE)
|
||||
else:
|
||||
checksum.update(chunk)
|
||||
return checksum
|
||||
|
||||
def calculate_result(directory):
|
||||
checksum = hashlib.sha1()
|
||||
for filename in sorted(generate_file_list(directory)):
|
||||
sha1_file(filename, checksum)
|
||||
return checksum.hexdigest()
|
||||
|
||||
@contextlib.contextmanager
|
||||
def temporary_directory(prefix='regr'):
|
||||
name = tempfile.mkdtemp(prefix)
|
||||
try:
|
||||
yield name
|
||||
finally:
|
||||
shutil.rmtree(name)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def directory_clone(src):
|
||||
with temporary_directory('regr') as name:
|
||||
subdir = os.path.join(name, "subdir")
|
||||
shutil.copytree(src, subdir)
|
||||
yield subdir
|
||||
|
||||
@contextlib.contextmanager
|
||||
def unzipped_content(src):
|
||||
with temporary_directory() as dest:
|
||||
f = zipfile.ZipFile.open(name)
|
||||
f.extractall(dest)
|
||||
yield dest
|
||||
|
||||
@contextlib.contextmanager
|
||||
def untared_content(src):
|
||||
with temporary_directory() as dest:
|
||||
f = tarfile.TarFile.open(src)
|
||||
f.extractall(dest)
|
||||
yield dest
|
||||
|
||||
class RegressionError(Exception): pass
|
||||
|
||||
def do_test(test_data, result_check, arguments=[]):
|
||||
"""Run a regression test on the given world.
|
||||
|
||||
result_check - sha1 of the recursive tree generated
|
||||
arguments - arguments to give to mce.py on execution
|
||||
"""
|
||||
result_check = result_check.lower()
|
||||
|
||||
env = {
|
||||
'MCE_RANDOM_SEED' : '42',
|
||||
'MCE_LAST_PLAYED' : '42'
|
||||
}
|
||||
|
||||
with directory_clone(test_data) as directory:
|
||||
proc = subprocess.Popen([
|
||||
"./mce.py",
|
||||
directory] + arguments, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
|
||||
proc.stdin.close()
|
||||
result = proc.wait()
|
||||
|
||||
if os.WIFEXITED(result) and os.WEXITSTATUS(result):
|
||||
raise RegressionError("Program execution failed!")
|
||||
|
||||
checksum = calculate_result(directory).lower()
|
||||
if checksum != result_check.lower():
|
||||
raise RegressionError("Checksum mismatch: {0!r} != {1!r}".format(checksum, result_check))
|
||||
print "[OK]"
|
||||
|
||||
|
||||
def main(argv):
|
||||
with untared_content("regression_test/alpha.tar.gz") as directory:
|
||||
test_data = os.path.join(directory, "alpha")
|
||||
do_test(test_data, 'ca66277d8037fde5aea3a135dd186f91e4bf4bef')
|
||||
do_test(test_data, '0f4cbb81f7f109cee10606b82f27fb2681a22f50', ['degrief'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
||||
|
Reference in New Issue
Block a user