Rev426, Fix for nonce error on bigsites asking, Dont display error details on 404 error, Dont log Websocket close errors, Add travis pip caching and osx test, Add build status to readme, Test for site files after cloning, Test for json to db mapping, Test site deleteFiles command, Test user certificate and auth address generation, Exclude debug lines from coverage, Dont run webtests every time
This commit is contained in:
parent
6a153a48d5
commit
9ac8f7f63c
12 changed files with 89 additions and 34 deletions
|
@ -1,6 +1,10 @@
|
|||
language: python
|
||||
cache: pip
|
||||
python:
|
||||
- "2.7"
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
install:
|
||||
- pip install -r requirements.txt
|
||||
script:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# ZeroNet
|
||||
# ZeroNet [](https://travis-ci.org/HelloZeroNet/ZeroNet)
|
||||
|
||||
Decentralized websites using Bitcoin crypto and the BitTorrent network - http://zeronet.io
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ class Config(object):
|
|||
|
||||
def __init__(self, argv):
|
||||
self.version = "0.3.2"
|
||||
self.rev = 423
|
||||
self.rev = 426
|
||||
self.argv = argv
|
||||
self.action = None
|
||||
self.createParser()
|
||||
|
|
|
@ -4,7 +4,7 @@ import Config
|
|||
|
||||
|
||||
@pytest.mark.usefixtures("resetSettings")
|
||||
class TestUser:
|
||||
class TestConfig:
|
||||
def testParse(self):
|
||||
# Defaults
|
||||
config_test = Config.Config("zeronet.py".split(" "))
|
||||
|
|
|
@ -25,6 +25,8 @@ class TestSite:
|
|||
assert new_site.storage.isFile("index.html")
|
||||
assert new_site.storage.isFile("data/users/content.json")
|
||||
assert new_site.storage.isFile("data/zeroblog.db")
|
||||
assert new_site.storage.verifyFiles() == [] # No bad files allowed
|
||||
assert new_site.storage.query("SELECT * FROM keyvalue WHERE key = 'title'").fetchone()["value"] == "MyZeroBlog"
|
||||
|
||||
# Test re-cloning (updating)
|
||||
|
||||
|
@ -41,6 +43,9 @@ class TestSite:
|
|||
changed_data["title"] = "UpdateTest"
|
||||
new_site.storage.writeJson("data/data.json", changed_data)
|
||||
|
||||
# The update should be reflected to database
|
||||
assert new_site.storage.query("SELECT * FROM keyvalue WHERE key = 'title'").fetchone()["value"] == "UpdateTest"
|
||||
|
||||
# Re-clone the site
|
||||
site.clone("159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL")
|
||||
|
||||
|
@ -49,6 +54,5 @@ class TestSite:
|
|||
assert new_site.storage.read("index.html") != "this will be overwritten"
|
||||
|
||||
# Delete created files
|
||||
if os.path.isdir("src/Test/testdata/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL"):
|
||||
new_site.storage.closeDb()
|
||||
shutil.rmtree("src/Test/testdata/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL")
|
||||
new_site.storage.deleteFiles()
|
||||
assert not os.path.isdir("src/Test/testdata/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL")
|
||||
|
|
|
@ -5,14 +5,14 @@ from Crypt import CryptBitcoin
|
|||
|
||||
@pytest.mark.usefixtures("resetSettings")
|
||||
class TestUser:
|
||||
def testNewsite(self, user):
|
||||
user.sites = {} # Reset user data
|
||||
def testAddress(self, user):
|
||||
assert user.master_address == "15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc"
|
||||
address_index = 1458664252141532163166741013621928587528255888800826689784628722366466547364755811L
|
||||
assert user.getAddressAuthIndex("15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc") == address_index
|
||||
|
||||
# Re-generate privatekey based on address_index
|
||||
address, address_index, site_data = user.getNewSiteData()
|
||||
# Re-generate privatekey based on address_index
|
||||
def testNewSite(self, user):
|
||||
address, address_index, site_data = user.getNewSiteData() # Create a new random site
|
||||
assert CryptBitcoin.hdPrivatekey(user.master_seed, address_index) == site_data["privatekey"]
|
||||
|
||||
user.sites = {} # Reset user data
|
||||
|
@ -21,3 +21,30 @@ class TestUser:
|
|||
assert user.getSiteData(address)["auth_address"] != address
|
||||
# Re-generate auth_privatekey for site
|
||||
assert user.getSiteData(address)["auth_privatekey"] == site_data["auth_privatekey"]
|
||||
|
||||
def testAuthAddress(self, user):
|
||||
# Auth address without Cert
|
||||
auth_address = user.getAuthAddress("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr")
|
||||
assert auth_address == "1MyJgYQjeEkR9QD66nkfJc9zqi9uUy5Lr2"
|
||||
auth_privatekey = user.getAuthPrivatekey("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr")
|
||||
assert CryptBitcoin.privatekeyToAddress(auth_privatekey) == auth_address
|
||||
|
||||
def testCert(self, user):
|
||||
cert_auth_address = user.getAuthAddress("1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz") # Add site to user's registry
|
||||
# Add cert
|
||||
user.addCert(cert_auth_address, "zeroid.bit", "faketype", "fakeuser", "fakesign")
|
||||
user.setCert("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr", "zeroid.bit")
|
||||
|
||||
# By using certificate the auth address should be same as the certificate provider
|
||||
assert user.getAuthAddress("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") == cert_auth_address
|
||||
auth_privatekey = user.getAuthPrivatekey("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr")
|
||||
assert CryptBitcoin.privatekeyToAddress(auth_privatekey) == cert_auth_address
|
||||
|
||||
# Test delete site data
|
||||
assert "1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr" in user.sites
|
||||
user.deleteSiteData("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr")
|
||||
assert "1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr" not in user.sites
|
||||
|
||||
# Re-create add site should generate normal, unique auth_address
|
||||
assert not user.getAuthAddress("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") == cert_auth_address
|
||||
assert user.getAuthAddress("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") == "1MyJgYQjeEkR9QD66nkfJc9zqi9uUy5Lr2"
|
||||
|
|
|
@ -22,6 +22,7 @@ class WaitForPageLoad(object):
|
|||
|
||||
|
||||
@pytest.mark.usefixtures("resetSettings")
|
||||
@pytest.mark.webtest
|
||||
class TestWeb:
|
||||
def testFileSecurity(self, site_url):
|
||||
assert "Forbidden" in urllib.urlopen("%s/media/./sites.json" % site_url).read()
|
||||
|
|
|
@ -50,6 +50,7 @@ def site():
|
|||
@pytest.fixture(scope="session")
|
||||
def user():
|
||||
user = UserManager.user_manager.get()
|
||||
user.sites = {} # Reset user data
|
||||
return user
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
|
|
|
@ -3,4 +3,15 @@ branch = True
|
|||
omit =
|
||||
src/lib/*
|
||||
src/Test/*
|
||||
|
||||
[report]
|
||||
exclude_lines =
|
||||
pragma: no cover
|
||||
|
||||
if __name__ == .__main__.:
|
||||
|
||||
if config.debug:
|
||||
|
||||
if config.debug_socket:
|
||||
|
||||
if self.logging:
|
|
@ -1,4 +1,5 @@
|
|||
[pytest]
|
||||
python_files = Test*.py
|
||||
addopts = -rsxX -v
|
||||
|
||||
markers =
|
||||
webtest: mark a test as a webtest.
|
|
@ -152,7 +152,7 @@ class UiRequest(object):
|
|||
|
||||
if status == 200 and cacheable_type: # Cache Css, Js, Image files for 10min
|
||||
headers.append(("Cache-Control", "public, max-age=600")) # Cache 10 min
|
||||
else: # Images, Css, Js
|
||||
else:
|
||||
headers.append(("Cache-Control", "no-cache, no-store, private, must-revalidate, max-age=0")) # No caching at all
|
||||
headers.append(("Content-Type", content_type))
|
||||
for extra_header in extra_headers:
|
||||
|
@ -327,16 +327,17 @@ class UiRequest(object):
|
|||
from Debug import DebugMedia
|
||||
DebugMedia.merge(file_path)
|
||||
if os.path.isfile(file_path): # File exits
|
||||
# self.sendHeader(content_type=self.getContentType(file_path)) # ?? Get Exception without this
|
||||
return self.actionFile(file_path)
|
||||
else: # File not exits, try to download
|
||||
site = SiteManager.site_manager.need(address, all_file=False)
|
||||
result = site.needFile(match.group("inner_path"), priority=1) # Wait until file downloads
|
||||
if result:
|
||||
# self.sendHeader(content_type=self.getContentType(file_path))
|
||||
return self.actionFile(file_path)
|
||||
else:
|
||||
self.log.debug("File not found: %s" % match.group("inner_path"))
|
||||
# Site larger than allowed, re-add wrapper nonce to allow reload
|
||||
if site.settings.get("size", 0) > site.getSizeLimit()*1024*1024:
|
||||
self.server.wrapper_nonces.append(self.get.get("wrapper_nonce"))
|
||||
return self.error404(match.group("inner_path"))
|
||||
|
||||
else: # Bad url
|
||||
|
@ -460,7 +461,7 @@ class UiRequest(object):
|
|||
# Send file not found error
|
||||
def error404(self, path=""):
|
||||
self.sendHeader(404)
|
||||
return self.formatError("Not Found", path.encode("utf8"))
|
||||
return self.formatError("Not Found", path.encode("utf8"), details=False)
|
||||
|
||||
# Internal server error
|
||||
def error500(self, message=":("):
|
||||
|
@ -471,24 +472,30 @@ class UiRequest(object):
|
|||
import sys
|
||||
import gevent
|
||||
|
||||
details = {key: val for key, val in self.env.items() if hasattr(val, "endswith") and "COOKIE" not in key}
|
||||
details["version_zeronet"] = "%s r%s" % (config.version, config.rev)
|
||||
details["version_python"] = sys.version
|
||||
details["version_gevent"] = gevent.__version__
|
||||
details["plugins"] = PluginManager.plugin_manager.plugin_names
|
||||
arguments = {key: val for key, val in vars(config.arguments).items() if "password" not in key}
|
||||
details["arguments"] = arguments
|
||||
return """
|
||||
<h1>%s</h1>
|
||||
<h2>%s</h3>
|
||||
<h3>Please <a href="https://github.com/HelloZeroNet/ZeroNet/issues" target="_blank">report it</a> if you think this an error.</h3>
|
||||
<h4>Details:</h4>
|
||||
<pre>%s</pre>
|
||||
<style>
|
||||
* { font-family: Consolas, Monospace; color: #333 }
|
||||
pre { padding: 10px; background-color: #EEE }
|
||||
</style>
|
||||
""" % (title, message, json.dumps(details, indent=4, sort_keys=True))
|
||||
if details:
|
||||
details = {key: val for key, val in self.env.items() if hasattr(val, "endswith") and "COOKIE" not in key}
|
||||
details["version_zeronet"] = "%s r%s" % (config.version, config.rev)
|
||||
details["version_python"] = sys.version
|
||||
details["version_gevent"] = gevent.__version__
|
||||
details["plugins"] = PluginManager.plugin_manager.plugin_names
|
||||
arguments = {key: val for key, val in vars(config.arguments).items() if "password" not in key}
|
||||
details["arguments"] = arguments
|
||||
return """
|
||||
<style>
|
||||
* { font-family: Consolas, Monospace; color: #333 }
|
||||
pre { padding: 10px; background-color: #EEE }
|
||||
</style>
|
||||
<h1>%s</h1>
|
||||
<h2>%s</h3>
|
||||
<h3>Please <a href="https://github.com/HelloZeroNet/ZeroNet/issues" target="_blank">report it</a> if you think this an error.</h3>
|
||||
<h4>Details:</h4>
|
||||
<pre>%s</pre>
|
||||
""" % (title, message, json.dumps(details, indent=4, sort_keys=True))
|
||||
else:
|
||||
return """
|
||||
<h1>%s</h1>
|
||||
<h2>%s</h3>
|
||||
""" % (title, message)
|
||||
|
||||
|
||||
# - Reload for eaiser developing -
|
||||
|
|
|
@ -58,7 +58,6 @@ class UiWebsocket(object):
|
|||
try:
|
||||
message = ws.receive()
|
||||
except Exception, err:
|
||||
self.log.error("WebSocket receive error: %s" % err)
|
||||
return "Bye." # Close connection
|
||||
|
||||
if message:
|
||||
|
|
Loading…
Reference in a new issue