CC-5709: Airtime Analyzer

* Added unit test coverage report stuff
* Added more unit tests
* 98% test coverage :-)
* Fixed a few bugs and removed some dead code
This commit is contained in:
Albert Santoni 2014-03-26 15:06:48 -04:00
parent 9e9e676b54
commit 58a38ffd3a
8 changed files with 66 additions and 13 deletions

View File

@ -68,4 +68,6 @@ a test, run:
$ nosetests -s
To run the unit tests and generate a code coverage report, run:
$ nosetests --with-coverage --cover-package=airtime_analyzer

View File

@ -5,6 +5,8 @@ class Analyzer:
def analyze(filename, metadata):
raise NotImplementedError
'''
class AnalyzerError(Exception):
def __init__(self):
super.__init__(self)
'''

View File

@ -5,10 +5,6 @@ from filemover_analyzer import FileMoverAnalyzer
class AnalyzerPipeline:
# Constructor
def __init__(self):
pass
# Take message dictionary and perform the necessary analysis.
@staticmethod
def run_analysis(queue, audio_file_path, import_directory, original_filename):

View File

@ -10,9 +10,6 @@ from analyzer import Analyzer
class FileMoverAnalyzer(Analyzer):
def __init__(self):
pass
@staticmethod
def analyze(audio_file_path, metadata):
raise Exception("Use FileMoverAnalyzer.move() instead.")
@ -35,8 +32,8 @@ class FileMoverAnalyzer(Analyzer):
final_file_path = import_directory
if metadata.has_key("artist_name"):
final_file_path += "/" + metadata["artist_name"]
if metadata.has_key("album"):
final_file_path += "/" + metadata["album"]
if metadata.has_key("album_title"):
final_file_path += "/" + metadata["album_title"]
final_file_path += "/" + original_filename
#Ensure any redundant slashes are stripped
@ -71,6 +68,8 @@ class FileMoverAnalyzer(Analyzer):
return metadata
def mkdir_p(path):
if path == "":
return
try:
os.makedirs(path)
except OSError as exc: # Python >2.5

View File

@ -6,9 +6,6 @@ from analyzer import Analyzer
class MetadataAnalyzer(Analyzer):
def __init__(self):
pass
@staticmethod
def analyze(filename, metadata):
if not isinstance(filename, unicode):
@ -33,6 +30,9 @@ class MetadataAnalyzer(Analyzer):
#Use the python-magic module to get the MIME type.
mime_magic = magic.Magic(mime=True)
metadata["mime"] = mime_magic.from_file(filename)
if isinstance(info, mutagen.mp3.MPEGInfo):
print "mode is: " + str(info.mode)
#Try to get the number of channels if mutagen can...
try:

View File

@ -14,6 +14,8 @@ setup(name='airtime_analyzer',
'python-magic',
'pika',
'nose',
'coverage',
'mock',
'python-daemon',
'requests',
],

View File

@ -2,11 +2,12 @@ from nose.tools import *
import os
import shutil
import multiprocessing
import Queue
import datetime
from airtime_analyzer.analyzer_pipeline import AnalyzerPipeline
DEFAULT_AUDIO_FILE = u'tests/test_data/44100Hz-16bit-mono.mp3'
DEFAULT_IMPORT_DEST = u'Test Artist/44100Hz-16bit-mono.mp3'
DEFAULT_IMPORT_DEST = u'Test Artist/Test Album/44100Hz-16bit-mono.mp3'
def setup():
pass
@ -32,3 +33,19 @@ def test_basic():
assert results["length"] == str(datetime.timedelta(seconds=results["length_seconds"]))
assert os.path.exists(DEFAULT_IMPORT_DEST)
@raises(TypeError)
def test_wrong_type_queue_param():
AnalyzerPipeline.run_analysis(Queue.Queue(), u'', u'', u'')
@raises(TypeError)
def test_wrong_type_string_param2():
AnalyzerPipeline.run_analysis(multiprocessing.queues.Queue(), '', u'', u'')
@raises(TypeError)
def test_wrong_type_string_param3():
AnalyzerPipeline.run_analysis(multiprocessing.queues.Queue(), u'', '', u'')
@raises(TypeError)
def test_wrong_type_string_param4():
AnalyzerPipeline.run_analysis(multiprocessing.queues.Queue(), u'', u'', '')

View File

@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
import datetime
import mutagen
import mock
from nose.tools import *
from airtime_analyzer.metadata_analyzer import MetadataAnalyzer
@ -112,3 +114,36 @@ def test_mp3_utf8():
assert metadata['mime'] == 'audio/mpeg'
assert metadata['track_total'] == u'10' # MP3s can have a track_total
# Make sure the parameter checking works
@raises(TypeError)
def test_move_wrong_string_param1():
not_unicode = 'asdfasdf'
MetadataAnalyzer.analyze(not_unicode, dict())
@raises(TypeError)
def test_move_wrong_metadata_dict():
not_a_dict = list()
MetadataAnalyzer.analyze(u'asdfasdf', not_a_dict)
# Test an mp3 file where the number of channels is invalid or missing:
def test_mp3_bad_channels():
filename = u'tests/test_data/44100Hz-16bit-mono.mp3'
'''
It'd be a pain in the ass to construct a real MP3 with an invalid number
of channels by hand because that value is stored in every MP3 frame in the file
'''
print "testing bad channels..."
audio_file = mutagen.File(filename, easy=True)
audio_file.info.mode = 1777
with mock.patch('airtime_analyzer.metadata_analyzer.mutagen') as mock_mutagen:
mock_mutagen.File.return_value = audio_file
#mock_mutagen.side_effect = lambda *args, **kw: audio_file #File(*args, **kw)
metadata = MetadataAnalyzer.analyze(filename, dict())
check_default_metadata(metadata)
assert metadata['channels'] == 1
assert metadata['bit_rate'] == 64000
assert metadata['length_seconds'] == 3.90925
assert metadata['mime'] == 'audio/mpeg' # Not unicode because MIMEs aren't.
assert metadata['track_total'] == u'10' # MP3s can have a track_total
#Mutagen doesn't extract comments from mp3s it seems