3 Copyright (c) 2011-2014 ARM Limited
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
17 Author: Przemyslaw Wirkus <Przemyslaw.Wirkus@arm.com>
25 """ Class used to connect with test database and store test results
30 # Connection credentials
36 # Test Suite DB scheme (table names)
37 self.TABLE_BUILD_ID = 'mtest_build_id'
38 self.TABLE_BUILD_ID_STATUS = 'mtest_build_id_status'
39 self.TABLE_BUILD_ID_TYPE = 'mtest_build_id_type'
40 self.TABLE_TARGET = 'mtest_target'
41 self.TABLE_TEST_ENTRY = 'mtest_test_entry'
42 self.TABLE_TEST_ID = 'mtest_test_id'
43 self.TABLE_TEST_RESULT = 'mtest_test_result'
44 self.TABLE_TEST_TYPE = 'mtest_test_type'
45 self.TABLE_TOOLCHAIN = 'mtest_toolchain'
47 self.BUILD_ID_STATUS_STARTED = 1 # Started
48 self.BUILD_ID_STATUS_IN_PROGRESS = 2 # In Progress
49 self.BUILD_ID_STATUS_COMPLETED = 3 #Completed
50 self.BUILD_ID_STATUS_FAILED = 4 # Failed
52 self.BUILD_ID_TYPE_TEST = 1 # Test
53 self.BUILD_ID_TYPE_BUILD_ONLY = 2 # Build Only
55 def get_hostname(self):
56 """ Useful when creating build_id in database
57 Function returns (hostname, uname) which can be used as (build_id_name, build_id_desc)
59 # Get hostname from socket
61 hostname = socket.gethostbyaddr(socket.gethostname())[0]
62 # Get uname from platform resources
64 uname = json.dumps(platform.uname())
65 return (hostname, uname)
67 def get_db_type(self):
68 """ Returns database type. E.g. 'mysql', 'sqlLite' etc.
72 def detect_database(self, verbose=False):
73 """ detect database and return VERION data structure or string (verbose=True)
77 def parse_db_connection_string(self, str):
78 """ Parsing SQL DB connection string. String should contain:
79 - DB Name, user name, password, URL (DB host), name
80 Function should return tuple with parsed (db_type, username, password, host, db_name) or None if error
82 (db_type, username, password, host, db_name) = self.parse_db_connection_string(db_url)
84 E.g. connection string: 'mysql://username:password@127.0.0.1/db_name'
87 if type(str) == type(''):
88 PATTERN = '^([\w]+)://([\w]+):([\w]*)@(.*)/([\w]+)'
89 result = re.match(PATTERN, str)
90 if result is not None:
91 result = result.groups() # Tuple (db_name, host, user, passwd, db)
92 return result # (db_type, username, password, host, db_name)
94 def is_connected(self):
95 """ Returns True if we are connected to database
99 def connect(self, host, user, passwd, db):
100 """ Connects to DB and returns DB object
104 def connect_url(self, db_url):
105 """ Connects to database using db_url (database url parsing),
106 store host, username, password, db_name
111 """ Reconnects to DB and returns DB object using stored host name,
112 database name and credentials (user name and password)
116 def disconnect(self):
117 """ Close DB connection
121 def escape_string(self, str):
122 """ Escapes string so it can be put in SQL query between quotes
126 def select_all(self, query):
127 """ Execute SELECT query and get all results
131 def insert(self, query, commit=True):
132 """ Execute INSERT query, define if you want to commit
136 def get_next_build_id(self, name, desc='', location='', type=None, status=None):
137 """ Insert new build_id (DB unique build like ID number to send all test results)
141 def get_table_entry_pk(self, table, column, value, update_db=True):
142 """ Checks for entries in tables with two columns (<TABLE_NAME>_pk, <column>)
143 If update_db is True updates table entry if value in specified column doesn't exist
147 def update_table_entry(self, table, column, value):
148 """ Updates table entry if value in specified column doesn't exist
149 Locks table to perform atomic read + update
153 def update_build_id_info(self, build_id, **kw):
154 """ Update additional data inside build_id table
156 db.update_build_is(build_id, _status_fk=self.BUILD_ID_STATUS_COMPLETED, _shuffle_seed=0.0123456789):
160 def insert_test_entry(self, build_id, target, toolchain, test_type, test_id, test_result, test_time, test_timeout, test_loop, test_extra=''):
161 """ Inserts test result entry to database. All checks regarding existing
162 toolchain names in DB are performed.
163 If some data is missing DB will be updated