Skip to content

Commit

Permalink
Relational denormalized data model which seems functional.
Browse files Browse the repository at this point in the history
  • Loading branch information
tarpas committed Dec 7, 2016
1 parent 848b16f commit c872041
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 52 deletions.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pytest>=2.7,<2.9
pytest>=2.8,<3.1
coverage>=4
20 changes: 8 additions & 12 deletions test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from _pytest import runner


pytest_plugins = "pytester",

Block = namedtuple('Block', 'checksums')
Expand All @@ -35,13 +34,16 @@ def test_read_nonexistent(testdir):


def test_write_read_data2(testdir):
original = ({'a.py': 1.0}, {'n1': {'a.py': [1]}}, ['n1'])
n1_node_data = {'a.py': [1]}
original = ({'a.py': 1.0}, ['n1'])
td = CoreTestmonData(testdir.tmpdir.strpath, 'default')
td.mtimes, td.node_data, td.lastfailed = original
td.mtimes, td.lastfailed = original
td.write_data()
td.set_dependencies('n1', n1_node_data, )
td2 = CoreTestmonData(testdir.tmpdir.strpath, 'default')
td2.read_data()
assert original == (td2.mtimes, td2.node_data, td2.lastfailed)
assert td2.node_data['n1'] == n1_node_data
assert original == (td2.mtimes, td2.lastfailed)


class TestDepGraph():
Expand Down Expand Up @@ -186,8 +188,10 @@ def test_flip():
files = flip_dictionary(node_data)
assert files == {'a': {'X': [1, 2, 3]}, 'b': {'X': [3, 4, 5], 'Y': [3, 6, 7]}}


global_reports = []


def serialize_report(rep):
import py
d = rep.__dict__.copy()
Expand All @@ -203,33 +207,26 @@ def serialize_report(rep):
return d



def test_serialize(testdir):


class PlugWrite:

def pytest_runtest_logreport(self, report):
global global_reports
global_reports.append(report)

class PlugRereport:

def pytest_runtest_protocol(self, item, nextitem):
hook = getattr(item.ihook, 'pytest_runtest_logreport')
for g in global_reports:
hook(report=g)
return True


testdir.makepyfile("""
def test_a():
raise Exception('exception from test_a')
""")

testdir.runpytest_inprocess(plugins=[PlugWrite()])


testdir.makepyfile("""
def test_a():
pass
Expand All @@ -238,4 +235,3 @@ def test_a():
result = testdir.runpytest_inprocess(plugins=[PlugRereport()])

print(result)

2 changes: 1 addition & 1 deletion test/test_testmon.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def track_it(testdir, func):
testmon.start()
func()
testmon.stop_and_save(testmon_data, testdir.tmpdir.strpath, 'testnode')
return testmon_data.changed_node_data['testnode']
return testmon_data._fetch_node_data()['testnode']


def test_subprocesss(testdir, monkeypatch):
Expand Down
63 changes: 26 additions & 37 deletions testmon/testmon_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,26 +104,14 @@ def stop_and_save(self, testmon_data, rootdir, nodeid):
if hasattr(self, 'sub_cov_file'):
self.cov.combine()

testmon_data.set_dependencies(nodeid, self.cov.get_data(), rootdir)
testmon_data.set_dependencies(nodeid, testmon_data.get_nodedata(nodeid, self.cov.get_data(), rootdir))

def close(self):
if hasattr(self, 'sub_cov_file'):
os.remove(self.sub_cov_file + "_rc")
os.environ.pop('COVERAGE_PROCESS_START', None)


class ExtTestmon(Testmon):

def track_dependencies(self, callable_to_track, testmon_data, rootdir, nodeid):
pass


class ExtExtTestmon(ExtTestmon):

def track_dependencies(self, callable_to_track, testmon_data, rootdir, nodeid):
pass


def eval_variant(run_variant, **kwargs):
if not run_variant:
return ''
Expand Down Expand Up @@ -191,6 +179,13 @@ def _fetch_attribute(self, attribute, default=None):
else:
return default

def _fetch_node_data(self):
result = defaultdict(lambda: {})
for row in self.connection.execute("SELECT node_name, file_name, checksums FROM node_file WHERE node_variant=?",
(self.variant,)):
result[row[0]][row[1]] = json.loads(row[2])
return result

def _write_attribute(self, attribute, data):
dataid = self.variant + ':' + attribute
json_data = json.dumps(data).encode('utf-8')
Expand All @@ -210,28 +205,21 @@ def init_tables(self):
result TEXT,
PRIMARY KEY (variant, name))
""")
self.connection.execute("""
CREATE TABLE file (
name TEXT PRIMARY KEY,
mtime LONG)
""")

self.connection.execute("""
CREATE TABLE node_file (
node_variant TEXT,
node_name TEXT,
file_name TEXT,
checksums TEXT,
FOREIGN KEY(node_variant, node_name) REFERENCES node(variant, name) ON DELETE CASCADE,
FOREIGN KEY(file_name) REFERENCES file(name) ON DELETE CASCADE)
FOREIGN KEY(node_variant, node_name) REFERENCES node(variant, name) ON DELETE CASCADE)
""")

def read_data(self):
self.mtimes, \
self.node_data, \
self.reports, \
self.lastfailed = self._fetch_attribute('mtimes', default={}), \
self._fetch_attribute('node_data', default={}), \
self._fetch_node_data(), \
self._fetch_attribute('reports', default={}), \
self._fetch_attribute('lastfailed', default=[])

Expand All @@ -241,7 +229,7 @@ def write_data(self):
self.node_data.update(self.changed_node_data)
self.reports.update(self.changed_reports)
self._write_attribute('mtimes', self.mtimes)
self._write_attribute('node_data', self.node_data)
#self._write_attribute('node_data', self.node_data)
self._write_attribute('lastfailed', self.lastfailed)
self._write_attribute('reports', self.reports)

Expand All @@ -264,23 +252,28 @@ def file_data(self):
# "FROM node_checksum_dep n JOIN file_version f ON n.file_version_id=f.id"
# "GROUP BY ")

def set_dependencies(self, nodeid, coverage_data, rootdir):
result = {}
with self.connection as con:
con.execute("INSERT OR REPLACE INTO "
"node "
"VALUES (?, ?, ?)", (self.variant, nodeid, ''))

def get_nodedata(self, nodeid, coverage_data, rootdir):
result = {}
for filename in coverage_data.measured_files():
lines = coverage_data.lines(filename)
if os.path.exists(filename):
result[filename] = checksum_coverage(self.parse_file(filename).blocks, lines)
self.write_db(con, filename, nodeid, result[filename])
if not result:
if not result: # when testmon kicks-in the test module is already imported. If the test function is skipped
# coverage_data is empty. However, we need to write down, that we depend on the
# file where the test is stored (so that we notice e.g. when the test is no longer skipped.)
filename = os.path.join(rootdir, nodeid).split("::", 1)[0]
result[filename] = checksum_coverage(self.parse_file(filename).blocks, [1])
self.write_db(con, filename, nodeid, result[filename])
self.changed_node_data[nodeid] = result
return result

def set_dependencies(self, nodeid, nodedata):
with self.connection as con:
con.execute("INSERT OR REPLACE INTO "
"node "
"VALUES (?, ?, ?)", (self.variant, nodeid, ''))

for filename in nodedata:
self.write_db(con, filename, nodeid, nodedata[filename])

def parse_file(self, file, new_mtime=None):
if file not in self.changed_files:
Expand All @@ -290,14 +283,10 @@ def parse_file(self, file, new_mtime=None):
return self.changed_files[file]

def write_db(self, con, filename, nodeid, checksums):
fc = con.cursor()
fc.execute("INSERT OR REPLACE INTO file VALUES (?, ?)", (filename, self.mtimes[filename]))
dc = con.cursor()
dc.execute("INSERT INTO node_file VALUES (?, ?, ?, ?)",
(self.variant, nodeid, filename, json.dumps(checksums)))
# import pydevd; pydevd.settrace()

return self.modules_cache[module]

def read_fs(self):
self.read_data()
Expand Down
1 change: 0 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ envlist = py{27,34,35}-pytest{27,28,29,master,features}
commands = py.test --tb=native {posargs:test}
deps =
coverage_pth
pytest27: pytest>=2.7,<2.8
pytest28: pytest>=2.8,<2.9
pytest29: pytest>=2.9,<3.0
# master is current stable version with bugfixes.
Expand Down

0 comments on commit c872041

Please sign in to comment.