[llvm-commits] [zorg] r146774 - in /zorg/trunk/lnt: lnt/server/db/testsuite.py lnt/server/db/testsuitedb.py lnt/server/db/v4db.py tests/server/db/CreateV4TestSuite.py tests/server/db/CreateV4TestSuiteInstance.py
Daniel Dunbar
daniel at zuster.org
Fri Dec 16 15:14:49 PST 2011
Author: ddunbar
Date: Fri Dec 16 17:14:49 2011
New Revision: 146774
URL: http://llvm.org/viewvc/llvm-project?rev=146774&view=rev
Log:
[v0.4] lnt.server.db: Add support for the per-test suite database models.
- This is somewhat magical because we construct the classes dynamically so we
can leverage all the standard SA binding tricks. This makes the documentation
connections a bit non-obvious, but is otherwise pretty easy to use. See test
case for example.
Added:
zorg/trunk/lnt/lnt/server/db/testsuitedb.py
zorg/trunk/lnt/tests/server/db/CreateV4TestSuiteInstance.py
Modified:
zorg/trunk/lnt/lnt/server/db/testsuite.py
zorg/trunk/lnt/lnt/server/db/v4db.py
zorg/trunk/lnt/tests/server/db/CreateV4TestSuite.py
Modified: zorg/trunk/lnt/lnt/server/db/testsuite.py
URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/db/testsuite.py?rev=146774&r1=146773&r2=146774&view=diff
==============================================================================
--- zorg/trunk/lnt/lnt/server/db/testsuite.py (original)
+++ zorg/trunk/lnt/lnt/server/db/testsuite.py Fri Dec 16 17:14:49 2011
@@ -7,8 +7,7 @@
import sqlalchemy.orm
from sqlalchemy import *
from sqlalchemy.schema import Index
-from sqlalchemy.orm import relation, backref
-from sqlalchemy.orm.collections import attribute_mapped_collection
+from sqlalchemy.orm import relation
Base = sqlalchemy.ext.declarative.declarative_base()
class StatusKind(Base):
Added: zorg/trunk/lnt/lnt/server/db/testsuitedb.py
URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/db/testsuitedb.py?rev=146774&view=auto
==============================================================================
--- zorg/trunk/lnt/lnt/server/db/testsuitedb.py (added)
+++ zorg/trunk/lnt/lnt/server/db/testsuitedb.py Fri Dec 16 17:14:49 2011
@@ -0,0 +1,127 @@
+"""
+Database models for the TestSuite databases themselves.
+
+These are a bit magical because the models themselves are driven by the test
+suite metadata, so we only create the classes at runtime.
+"""
+
+import sqlalchemy
+from sqlalchemy import *
+
+import testsuite
+
+class TestSuiteDB(object):
+ def __init__(self, v4db, test_suite):
+ self.v4db = v4db
+ self.test_suite = test_suite
+
+ self.base = sqlalchemy.ext.declarative.declarative_base()
+
+ # Create parameterized model classes for this test suite.
+ db_key_name = self.test_suite.db_key_name
+ class Machine(self.base):
+ __tablename__ = db_key_name + '_Machine'
+
+ id = Column("ID", Integer, primary_key=True)
+ name = Column("Name", String(256))
+ number = Column("Number", Integer)
+ parameters = Column("Parameters", Binary)
+
+ # ... FIXME: Add test suite machine keys ...
+
+ def __init__(self, name, number):
+ self.name = name
+ self.number = number
+
+ def __repr__(self):
+ return '%s_%s%r' % (db_key_name, self.__class__.__name__,
+ (self.name, self.number))
+
+ class Order(self.base):
+ __tablename__ = db_key_name + '_Order'
+
+ id = Column("ID", Integer, primary_key=True)
+
+ # ... FIXME: Add test suite order keys ...
+
+ def __init__(self):
+ pass
+
+ def __repr__(self):
+ return '%s_%s%r' % (db_key_name, self.__class__.__name__,
+ ())
+
+ class Run(self.base):
+ __tablename__ = db_key_name + '_Run'
+
+ id = Column("ID", Integer, primary_key=True)
+ machine_id = Column("MachineID", Integer, ForeignKey(Machine.id))
+ order_id = Column("OrderID", Integer, ForeignKey(Order.id))
+ start_time = Column("StartTime", DateTime)
+ end_time = Column("EndTime", DateTime)
+ parameters = Column("Parameters", Binary)
+
+ machine = sqlalchemy.orm.relation(Machine)
+ order = sqlalchemy.orm.relation(Order)
+
+ # ... FIXME: Add test suite run keys ...
+
+ def __init__(self, machine, order, start_time, end_time):
+ self.machine = machine
+ self.order = order
+ self.start_time = start_time
+ self.end_time = end_time
+
+ def __repr__(self):
+ return '%s_%s%r' % (db_key_name, self.__class__.__name__,
+ (self.machine, self.order, self.start_time,
+ self.end_time))
+
+ class Test(self.base):
+ __tablename__ = db_key_name + '_Test'
+
+ id = Column("ID", Integer, primary_key=True)
+ name = Column("Name", String(256))
+
+ def __init__(self, name):
+ self.name = name
+
+ def __repr__(self):
+ return '%s_%s%r' % (db_key_name, self.__class__.__name__,
+ (self.name))
+
+ class Sample(self.base):
+ __tablename__ = db_key_name + '_Sample'
+
+ id = Column("ID", Integer, primary_key=True)
+ run_id = Column("RunID", Integer, ForeignKey(Run.id))
+ test_id = Column("TestID", Integer, ForeignKey(Test.id))
+ value = Column("Value", Float)
+ status_id = Column("StatusID", Integer, ForeignKey(
+ testsuite.StatusKind.id))
+
+ run = sqlalchemy.orm.relation(Run)
+ test = sqlalchemy.orm.relation(Test)
+
+ def __init__(self, run, test, value):
+ self.run = run
+ self.test = test
+ self.value = value
+
+ def __repr__(self):
+ return '%s_%s%r' % (db_key_name, self.__class__.__name__,
+ (self.run, self.test, self.value))
+
+ self.Machine = Machine
+ self.Run = Run
+ self.Test = Test
+ self.Sample = Sample
+ self.Order = Order
+
+ # Create the test suite database tables in case this is a new database.
+ self.base.metadata.create_all(self.v4db.engine)
+
+ # Add several shortcut aliases, similar to the ones on the v4db.
+ self.add = self.v4db.add
+ self.commit = self.v4db.commit
+ self.query = self.v4db.query
Modified: zorg/trunk/lnt/lnt/server/db/v4db.py
URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/db/v4db.py?rev=146774&r1=146773&r2=146774&view=diff
==============================================================================
--- zorg/trunk/lnt/lnt/server/db/v4db.py (original)
+++ zorg/trunk/lnt/lnt/server/db/v4db.py Fri Dec 16 17:14:49 2011
@@ -1,7 +1,26 @@
import sqlalchemy
import testsuite
+import testsuitedb
class V4DB(object):
+ """
+ Wrapper object for LNT v0.4+ databases.
+ """
+
+ class TestSuiteAccessor(object):
+ def __init__(self, v4db):
+ self.v4db = v4db
+
+ def __getitem__(self, name):
+ # Get the test suite object.
+ ts = self.v4db.query(testsuite.TestSuite).\
+ filter(testsuite.TestSuite.name == name).first()
+ if ts is None:
+ raise IndexError,name
+
+ # Instantiate the per-test suite wrapper object for this test suite.
+ return testsuitedb.TestSuiteDB(self.v4db, ts)
+
def __init__(self, path, echo=False):
assert (path.startswith('mysql://') or
path.startswith('sqlite://')), "invalid database path"
@@ -18,3 +37,13 @@
self.add = self.session.add
self.commit = self.session.commit
self.query = self.session.query
+
+ @property
+ def testsuite(self):
+ # This is the start of "magic" part of V4DB, which allows us to get
+ # fully bound SA instances for databases which are effectively described
+ # by the TestSuites table.
+
+ # The magic starts by returning a object which will allow us to use
+ # array access to get the per-test suite database wrapper.
+ return V4DB.TestSuiteAccessor(self)
Modified: zorg/trunk/lnt/tests/server/db/CreateV4TestSuite.py
URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/tests/server/db/CreateV4TestSuite.py?rev=146774&r1=146773&r2=146774&view=diff
==============================================================================
--- zorg/trunk/lnt/tests/server/db/CreateV4TestSuite.py (original)
+++ zorg/trunk/lnt/tests/server/db/CreateV4TestSuite.py Fri Dec 16 17:14:49 2011
@@ -1,8 +1,11 @@
+# This test just checks that we can construct and manipulate the test suite
+# model itself. The heavy lifting of constructing a test suite's databases,
+# etc. is checked in CreateV4TestSuiteInstance.
+#
# RUN: rm -f %t.db
# RUN: python %s %t.db
import sys
-from lnt.db.perfdb import PerfDB, Run
from lnt.server.db import testsuite
from lnt.server.db import v4db
Added: zorg/trunk/lnt/tests/server/db/CreateV4TestSuiteInstance.py
URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/tests/server/db/CreateV4TestSuiteInstance.py?rev=146774&view=auto
==============================================================================
--- zorg/trunk/lnt/tests/server/db/CreateV4TestSuiteInstance.py (added)
+++ zorg/trunk/lnt/tests/server/db/CreateV4TestSuiteInstance.py Fri Dec 16 17:14:49 2011
@@ -0,0 +1,79 @@
+# Check the model bindings for test suite instances.
+#
+# RUN: rm -f %t.db
+# RUN: python %s %t.db
+
+import datetime
+
+from lnt.server.db import testsuite
+from lnt.server.db import v4db
+
+# Create an in memory database.
+db = v4db.V4DB("sqlite:///:memory:", echo=True)
+
+# Create a new TestSuite.
+ts = testsuite.TestSuite("nt", "NT", 0)
+db.add(ts)
+
+db.commit()
+
+# Get the test suite wrapper.
+ts_db = db.testsuite['nt']
+
+# Check that we can construct and access all of the primary fields for the test
+# suite database objects.
+
+# Create the objects.
+start_time = datetime.datetime.utcnow()
+end_time = datetime.datetime.utcnow()
+
+machine = ts_db.Machine("test-machine", 1)
+order = ts_db.Order()
+run = ts_db.Run(machine, order, start_time, end_time)
+test = ts_db.Test("test-a")
+sample = ts_db.Sample(run, test, 1.0)
+
+# Add and commit.
+ts_db.add(machine)
+ts_db.add(order)
+ts_db.add(run)
+ts_db.add(test)
+ts_db.add(sample)
+ts_db.commit()
+del machine, order, run, test, sample
+
+# Fetch the added objects.
+machines = ts_db.query(ts_db.Machine).all()
+assert len(machines) == 1
+machine = machines[0]
+
+orders = ts_db.query(ts_db.Order).all()
+assert len(orders) == 1
+order = orders[0]
+
+runs = ts_db.query(ts_db.Run).all()
+assert len(runs) == 1
+run = runs[0]
+
+tests = ts_db.query(ts_db.Test).all()
+assert len(tests) == 1
+test = tests[0]
+
+samples = ts_db.query(ts_db.Sample).all()
+assert len(samples) == 1
+sample = samples[0]
+
+# Audit the various fields.
+assert machine.name == "test-machine"
+assert machine.number == 1
+
+assert run.machine is machine
+assert run.order is order
+assert run.start_time == start_time
+assert run.end_time == end_time
+
+assert test.name == "test-a"
+
+assert sample.run is run
+assert sample.test is test
+assert sample.value == 1.0
More information about the llvm-commits
mailing list