Add PEP8 check and fix related issues

- Add PEP8 section to tox.ini
- Add hacking to requirements to enforce OpenStack style requirements
- Fix formatting issues flagged by flake8 check
- Add copyright notices to all remaining files
- Update .gitignore file

Change-Id: I7e9a0203ddf2002c08ac96800fe30c1c46ebba88
This commit is contained in:
Levi Blackstone 2015-05-05 07:43:00 -05:00
parent 542545468b
commit 3b7e69c972
13 changed files with 206 additions and 76 deletions

6
.gitignore vendored
View File

@ -26,6 +26,7 @@ pip-log.txt
.coverage .coverage
.tox .tox
nosetests.xml nosetests.xml
test_temp/*
# Translations # Translations
*.mo *.mo
@ -34,3 +35,8 @@ nosetests.xml
.mr.developer.cfg .mr.developer.cfg
.project .project
.pydevproject .pydevproject
# IDE Project Files
*.project
*.pydev*
*.idea

View File

@ -1,3 +1,4 @@
hacking>=0.10.0,<0.11
notigen notigen
notification_utils notification_utils
python-dateutil python-dateutil

View File

@ -30,7 +30,9 @@ class Archive(object):
class ArchiveWriter(Archive): class ArchiveWriter(Archive):
"""The active Archive for appending. """The active Archive for appending.
""" """
def __init__(self, filename): def __init__(self, filename):
super(ArchiveWriter, self).__init__(filename) super(ArchiveWriter, self).__init__(filename)
self._open_file(filename) self._open_file(filename)
@ -47,7 +49,9 @@ class ArchiveWriter(Archive):
class ArchiveReader(Archive): class ArchiveReader(Archive):
"""The active Archive for consuming. """The active Archive for consuming.
""" """
def __init__(self, filename): def __init__(self, filename):
super(ArchiveReader, self).__init__(filename) super(ArchiveReader, self).__init__(filename)
self._open_file(filename) self._open_file(filename)

View File

@ -1,6 +1,18 @@
import calendar # Copyright (c) 2014 Dark Secret Software Inc.
import datetime #
import json # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import struct import struct
@ -156,6 +168,7 @@ class Version1(Version0):
VERSIONS = {1: Version1()} VERSIONS = {1: Version1()}
CURRENT_VERSION = 1 CURRENT_VERSION = 1
def get_version_handler(version=CURRENT_VERSION): def get_version_handler(version=CURRENT_VERSION):
global VERSIONS global VERSIONS

View File

@ -34,6 +34,7 @@ class ArchiveCallback(object):
def on_close(self, filename): def on_close(self, filename):
"""Called when an Archive is closed. """Called when an Archive is closed.
If you move/change the file/name return the If you move/change the file/name return the
new location so subsequent callbacks will new location so subsequent callbacks will
have the right location. have the right location.
@ -50,8 +51,10 @@ class CallbackList(ArchiveCallback):
callback_str_list = [x.strip() for x in callback_str.split(",")] callback_str_list = [x.strip() for x in callback_str.split(",")]
self.callbacks = [simport.load(c)(**self.config) self.callbacks = [simport.load(c)(**self.config)
for c in callback_str_list] for c in callback_str_list]
# TODO(Sandy): Need some exception handling around these. # TODO(Sandy): Need some exception handling around these.
# The failure of one shouldn't stop processing. # The failure of one shouldn't stop processing.
def on_open(self, filename): def on_open(self, filename):
for c in self.callbacks: for c in self.callbacks:
c.on_open(filename) c.on_open(filename)
@ -63,6 +66,7 @@ class CallbackList(ArchiveCallback):
class ChangeExtensionCallback(ArchiveCallback): class ChangeExtensionCallback(ArchiveCallback):
"""filename.dat becomes filename.dat.done""" """filename.dat becomes filename.dat.done"""
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(ChangeExtensionCallback, self).__init__(**kwargs) super(ChangeExtensionCallback, self).__init__(**kwargs)
self.new_extension = kwargs.get('new_extension', '.done') self.new_extension = kwargs.get('new_extension', '.done')

View File

@ -114,7 +114,9 @@ class WritingRollManager(RollManager):
self.roll_checker = roll_checker self.roll_checker = roll_checker
def write(self, metadata, payload): def write(self, metadata, payload):
"""metadata is string:string dict. """Write metadata
metadata is string:string dict.
payload must be encoded as string. payload must be encoded as string.
""" """
a = self.get_active_archive() a = self.get_active_archive()
@ -143,11 +145,15 @@ class WritingRollManager(RollManager):
class WritingJSONRollManager(object): class WritingJSONRollManager(object):
"""No archiver. No roll checker. Just write 1 file line per json payload. """Simple event archival.
No archiver. No roll checker. Just write 1 file line per json payload.
Once the file gets big enough, gzip the file and move Once the file gets big enough, gzip the file and move
into the destination_directory. into the destination_directory.
Expects an external tool like rsync to move the file. Expects an external tool like rsync to move the file.
A SHA-256 of the payload may be included in the archive filename.""" A SHA-256 of the payload may be included in the archive filename.
"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.filename_template = args[0] self.filename_template = args[0]
self.directory = kwargs.get('directory', '.') self.directory = kwargs.get('directory', '.')

View File

@ -1,8 +1,21 @@
# Copyright (c) 2014 Dark Secret Software Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import datetime import datetime
import gzip import gzip
import hashlib
import json import json
import mock
import os import os
import shutil import shutil
import unittest import unittest
@ -39,7 +52,8 @@ class TestDirectory(unittest.TestCase):
if events: if events:
for event in events: for event in events:
metadata = {} metadata = {}
json_event = json.dumps(event, json_event = json.dumps(
event,
cls=notification_utils.DateTimeEncoder) cls=notification_utils.DateTimeEncoder)
manager.write(metadata, json_event) manager.write(metadata, json_event)
msg_id = event['message_id'] msg_id = event['message_id']
@ -49,7 +63,7 @@ class TestDirectory(unittest.TestCase):
manager.close() manager.close()
manager._archive_working_files() manager._archive_working_files()
print "Starting entries:", len(entries) print("Starting entries:", len(entries))
actual = len(entries) actual = len(entries)
@ -68,8 +82,8 @@ class TestDirectory(unittest.TestCase):
num = len(file_content) - 1 num = len(file_content) - 1
total += num total += num
print "In %s: %d of %d Remaining: %d" % (f, num, actual, print("In %s: %d of %d Remaining: %d"
actual - total) % (f, num, actual, actual - total))
if actual != total: if actual != total:
raise Exception("Num generated != actual") raise Exception("Num generated != actual")

View File

@ -1,6 +1,20 @@
# Copyright (c) 2014 Dark Secret Software Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import datetime import datetime
import json import json
import mock
import os import os
import shutil import shutil
import unittest import unittest
@ -8,7 +22,6 @@ import unittest
import notification_utils import notification_utils
import notigen import notigen
from shoebox import disk_storage
from shoebox import roll_checker from shoebox import roll_checker
from shoebox import roll_manager from shoebox import roll_manager
@ -64,13 +77,15 @@ class TestSizeRolling(unittest.TestCase):
events = g.generate(now) events = g.generate(now)
if events: if events:
for event in events: for event in events:
metadata = {'event': event['event_type'], metadata = {
'event': event['event_type'],
'request_id': event['_context_request_id'], 'request_id': event['_context_request_id'],
'generated': str(event['timestamp']), 'generated': str(event['timestamp']),
'uuid': event.get('payload', {} 'uuid': event.get('payload', {}).get(
).get("instance_id", ""), "instance_id", ""),
} }
json_event = json.dumps(event, json_event = json.dumps(
event,
cls=notification_utils.DateTimeEncoder) cls=notification_utils.DateTimeEncoder)
manager.write(metadata, json_event) manager.write(metadata, json_event)
entries.append((metadata, json_event)) entries.append((metadata, json_event))

View File

@ -1,5 +1,19 @@
import unittest # Copyright (c) 2014 Dark Secret Software Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from shoebox import handlers from shoebox import handlers
@ -26,4 +40,3 @@ class TestCallbackList(unittest.TestCase):
self.assertTrue(isinstance(c.callbacks[1], self.assertTrue(isinstance(c.callbacks[1],
handlers.ChangeExtensionCallback)) handlers.ChangeExtensionCallback))
self.assertTrue(isinstance(c.callbacks[2], BlahCallback)) self.assertTrue(isinstance(c.callbacks[2], BlahCallback))

View File

@ -1,11 +1,23 @@
import datetime # Copyright (c) 2014 Dark Secret Software Inc.
import mock #
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json import json
import mock
import struct import struct
import unittest import unittest
import dateutil.tz
from shoebox import disk_storage from shoebox import disk_storage
@ -24,8 +36,10 @@ class TestVersion0(unittest.TestCase):
def test_load_preamble(self): def test_load_preamble(self):
file_handle = mock.Mock() file_handle = mock.Mock()
file_handle.read.return_value = struct.pack("ih", file_handle.read.return_value = struct.pack(
disk_storage.BOR_MAGIC_NUMBER, 99) "ih",
disk_storage.BOR_MAGIC_NUMBER,
99)
self.assertEqual(99, self.v0.load_preamble(file_handle)) self.assertEqual(99, self.v0.load_preamble(file_handle))
@ -76,7 +90,7 @@ class TestVersion1(unittest.TestCase):
blocks = blocks[1:] # Remove preamble blocks = blocks[1:] # Remove preamble
# break the EOR marker # break the EOR marker
print len(blocks[0]) print(len(blocks[0]))
newblock = blocks[0][:8] + '\x00\x00\x01\x02' newblock = blocks[0][:8] + '\x00\x00\x01\x02'
blocks = list(blocks) blocks = list(blocks)
blocks[0] = newblock blocks[0] = newblock
@ -110,8 +124,10 @@ class TestHelpers(unittest.TestCase):
def test_unpack_notification(self): def test_unpack_notification(self):
file_handle = mock.Mock() file_handle = mock.Mock()
file_handle.read.return_value = struct.pack("ih", file_handle.read.return_value = struct.pack(
disk_storage.BOR_MAGIC_NUMBER, 99) "ih",
disk_storage.BOR_MAGIC_NUMBER,
99)
with mock.patch('shoebox.disk_storage.get_version_handler') as h: with mock.patch('shoebox.disk_storage.get_version_handler') as h:
fake_handler = mock.Mock() fake_handler = mock.Mock()

View File

@ -1,3 +1,18 @@
# Copyright (c) 2014 Dark Secret Software Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import datetime import datetime
import mock import mock
import unittest import unittest

View File

@ -1,10 +1,23 @@
# Copyright (c) 2014 Dark Secret Software Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import datetime import datetime
import mock
import os
import unittest import unittest
import mock
import notification_utils import notification_utils
from shoebox import archive from shoebox import archive
from shoebox import roll_checker from shoebox import roll_checker
from shoebox import roll_manager from shoebox import roll_manager
@ -53,7 +66,7 @@ class TestWritingRollManager(unittest.TestCase):
def test_correct_archiver(self): def test_correct_archiver(self):
x = roll_manager.WritingRollManager("foo", None) x = roll_manager.WritingRollManager("foo", None)
print x.archive_class print(x.archive_class)
self.assertEqual(x.archive_class, archive.ArchiveWriter) self.assertEqual(x.archive_class, archive.ArchiveWriter)
def test_get_active_archive(self): def test_get_active_archive(self):
@ -63,8 +76,8 @@ class TestWritingRollManager(unittest.TestCase):
x = roll_manager.WritingRollManager(filename_template, checker, x = roll_manager.WritingRollManager(filename_template, checker,
archive_callback=callback, archive_callback=callback,
archive_class=FakeArchive) archive_class=FakeArchive)
with mock.patch("shoebox.archive.ArchiveWriter._open_file") as of: with mock.patch("shoebox.archive.ArchiveWriter._open_file"):
arc = x.get_active_archive() x.get_active_archive()
self.assertTrue(checker.start.called) self.assertTrue(checker.start.called)
self.assertTrue(callback.on_open.called) self.assertTrue(callback.on_open.called)
@ -127,7 +140,8 @@ class TestJSONRollManager(unittest.TestCase):
self.assertFalse(rm._should_roll(9 * 1048576)) self.assertFalse(rm._should_roll(9 * 1048576))
self.assertTrue(rm._should_roll(10 * 1048576)) self.assertTrue(rm._should_roll(10 * 1048576))
rm = roll_manager.WritingJSONRollManager("template.foo", roll_minutes=10) rm = roll_manager.WritingJSONRollManager("template.foo",
roll_minutes=10)
self.assertFalse(rm._should_roll(0)) self.assertFalse(rm._should_roll(0))
self.assertFalse(rm._should_roll(1)) self.assertFalse(rm._should_roll(1))
with mock.patch.object(rm, "_get_time") as gt: with mock.patch.object(rm, "_get_time") as gt:

11
tox.ini
View File

@ -1,5 +1,5 @@
[tox] [tox]
envlist = py26, py27 envlist = py26, py27, pep8
[testenv] [testenv]
deps = deps =
@ -12,3 +12,12 @@ deps =
simport simport
commands = nosetests -d -v --with-coverage --cover-inclusive --cover-package shoebox [] commands = nosetests -d -v --with-coverage --cover-inclusive --cover-package shoebox []
[testenv:pep8]
commands =
flake8
[flake8]
ignore =
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg
show-source = True