[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