blob: b2e883ca743400daa9d7c20e4c5f35614d47a371 [file] [log] [blame]
import unittest
from unittest.mock import patch, mock_open, Mock, MagicMock
from target_lib import BuildInfo, TargetLib
import zipfile
import os
import sqlite3
from tempfile import NamedTemporaryFile
class CreateTestBuild():
def __init__(self, include_build_prop=True, include_ab_partitions=True):
self.file = NamedTemporaryFile(dir='test/')
self.test_path = self.file.name
with zipfile.ZipFile(self.file, mode='w') as package:
if include_build_prop:
package.write('test/test_build.prop', 'SYSTEM/build.prop')
if include_ab_partitions:
package.write('test/test_ab_partitions.txt',
'META/ab_partitions.txt')
self.test_info = {
'file_name': self.test_path.split('/')[-1],
'path': self.test_path,
'time': 1628698830,
'build_id': 'AOSP.MASTER',
'build_version': '7392671',
'build_flavor': 'aosp_cf_x86_64_phone-userdebug',
'partitions': ['system', 'vendor'],
}
if not include_build_prop:
self.test_info['build_id'] = ''
self.test_info['build_version'] = ''
self.test_info['build_flavor'] = ''
if not include_ab_partitions:
self.test_info['partitions'] = []
def clean(self):
self.file.close()
class TestBuildInfo(unittest.TestCase):
def setUp(self):
"""
Create a virtual Android build, which only have build.prop
and ab_partitions.txt
"""
self.test_build = CreateTestBuild()
self.build_info = BuildInfo(
self.test_build.test_info['file_name'],
self.test_build.test_info['path'],
self.test_build.test_info['time']
)
self.build_info.analyse_buildprop()
def tearDown(self):
self.test_build.clean()
def test_analyse_buildprop(self):
# Test if the build.prop and ab_partitions are not empty
for key, value in self.test_build.test_info.items():
self.assertEqual(value, self.build_info.__dict__[key],
'The ' + key + ' is not parsed correctly.'
)
# Test if the ab_partitions is empty
test_build_no_partitions = CreateTestBuild(include_ab_partitions=False)
build_info = BuildInfo(
test_build_no_partitions.test_info['file_name'],
test_build_no_partitions.test_info['path'],
test_build_no_partitions.test_info['time']
)
build_info.analyse_buildprop()
self.assertEqual(build_info.partitions,
test_build_no_partitions.test_info['partitions'],
'The partition list is not empty if ab_partitions is not provided.'
)
test_build_no_partitions.clean()
def test_to_sql_form_dict(self):
sql_dict = self.build_info.to_sql_form_dict()
for key, value in self.test_build.test_info.items():
if key != 'partitions':
self.assertEqual(value, sql_dict[key],
'The ' + key + ' is not parsed correctly.'
)
else:
self.assertEqual(','.join(value), sql_dict[key],
'The partition list is not coverted to sql form properly.'
)
def test_to_dict(self):
ordinary_dict = self.build_info.to_dict()
for key, value in self.test_build.test_info.items():
self.assertEqual(value, ordinary_dict[key],
'The ' + key + ' is not parsed correctly.'
)
class TestTargetLib(unittest.TestCase):
def setUp(self):
self.test_path = 'test/test_target_lib.db'
self.tearDown()
self.target_build = TargetLib(path=self.test_path)
def tearDown(self):
if os.path.isfile(self.test_path):
os.remove(self.test_path)
def test_init(self):
# Test the database is created successfully
self.assertTrue(os.path.isfile(self.test_path))
test_columns = [
{'name': 'FileName','type':'TEXT'},
{'name': 'Path','type':'TEXT'},
{'name': 'BuildID','type':'TEXT'},
{'name': 'BuildVersion','type':'TEXT'},
{'name': 'BuildFlavor','type':'TEXT'},
{'name': 'Partitions','type':'TEXT'},
{'name': 'UploadTime','type':'INTEGER'},
]
connect = sqlite3.connect(self.test_path)
cursor = connect.cursor()
cursor.execute("PRAGMA table_info(Builds)")
columns = cursor.fetchall()
for column in test_columns:
column_found = list(filter(lambda x: x[1]==column['name'], columns))
self.assertEqual(len(column_found), 1,
'The column ' + column['name'] + ' is not found in database'
)
self.assertEqual(column_found[0][2], column['type'],
'The column ' + column['name'] + ' has a wrong type'
)
def test_new_build(self):
test_build = CreateTestBuild()
self.target_build.new_build(
filename=test_build.test_info['file_name'],
path=test_build.test_path
)
connect = sqlite3.connect(self.test_path)
cursor = connect.cursor()
cursor.execute("SELECT * FROM BUILDS")
entries = cursor.fetchall()
self.assertEqual(len(entries), 1,
'The test build cannot be added into the database.'
)
test_build.clean()
def test_get_builds(self):
test_build = CreateTestBuild()
# time.time() has to be mocked, otherwise it will be the current time
mock_time = Mock(return_value=test_build.test_info['time'])
with patch('time.time', mock_time):
self.target_build.new_build(
filename=test_build.test_info['file_name'],
path=test_build.test_path
)
# build_list is read and parsed from the database
# build_info is directly parsed from the package
# Test if the read/write database process changes the data entry
build_list = self.target_build.get_builds()
build_info = BuildInfo(
test_build.test_info['file_name'],
test_build.test_info['path'],
test_build.test_info['time']
)
build_info.analyse_buildprop()
self.assertEqual(build_list[0], build_info,
'The list of build info cannot be extracted from database.'
)
test_build.clean()
def test_get_build_by_path(self):
test_build = CreateTestBuild()
# time.time() has to be mocked, otherwise it will be the current time
mock_time = Mock(return_value=test_build.test_info['time'])
with patch('time.time', mock_time):
self.target_build.new_build(
filename=test_build.test_info['file_name'],
path=test_build.test_path
)
build = self.target_build.get_build_by_path(test_build.test_info['path'])
build_info = BuildInfo(
test_build.test_info['file_name'],
test_build.test_info['path'],
test_build.test_info['time']
)
build_info.analyse_buildprop()
self.assertEqual(build, build_info,
'Build info cannot be extracted by path.'
)
test_build.clean()
if __name__ == '__main__':
unittest.main()