class DatabaseService: """ Singleton class controlling all database related processes """ __instance = None logger = QGISLogHandler("DatabaseService") @staticmethod def get_instance() -> "DatabaseService": """ Creates a new object instance if no object exists or updates the existing one. :return: The single instance of this class """ if DatabaseService.__instance is None: DatabaseService.logger.debug("Create new DatabaseService instance") DatabaseService() else: DatabaseService.logger.debug( "Returning existing DatabaseService instance") return DatabaseService.__instance def __init__(self): """ Virtually private constructor. """ super().__init__() if DatabaseService.__instance is not None: raise BaseException( "The DatabaseService-class is a singleton and can't be called directly. " + "Use DatabaseService.get_instance() instead!") else: DatabaseService.__instance = self self.__connection = "" self.__db_type = "" self.__password = "" self.__username = "" self.__handler = None self.__session = None # # setter and getter # @property def connection(self) -> str: """ Getter for the current connection string :return: returns the current connection string """ return self.__connection @connection.setter def connection(self, value: str) -> None: """ setter for the current connection string :return: Nothing """ self.__connection = str(value) @property def db_type(self) -> str: """ Getter for the database type :return: returns the current database type """ return self.__db_type @db_type.setter def db_type(self, value: str) -> None: """ setter for the database type :return: Nothing :raises ValueError: if value is not "SQLite" or "PostgreSQL" """ value = str(value) if value.lower() not in ("sqlite", "postgresql"): raise ValueError("Unknown database format: {}".format(value)) self.__db_type = value.lower() @property def password(self) -> str: """ Getter for the current password :return: returns the current password """ return self.__password @password.setter def password(self, value: str) -> None: """ setter for the current password :return: Nothing """ self.__password = str(value) @property def username(self) -> str: """ Getter for the current username :return: returns the current username """ return self.__username @username.setter def username(self, value: str) -> None: """ setter for the current username :return: Nothing """ self.__username = str(value) # # public functions # def connect(self) -> None: """ Connect a GeologicalToolbox-DBHandler :return: Nothing :raises ValueError: if database type is unknown """ self.logger.debug("Connecting to a database: [{}]: {}".format( self.db_type, self.connection)) # noinspection SpellCheckingInspection if self.db_type == "postgresql": # connection string: postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...] connection = "postgresql+psycopg2://{}:{}@{}".format( self.username, self.password, self.connection) elif self.db_type == "sqlite": connection = "sqlite:///{}".format(self.connection) else: self.__handler = None raise ValueError("Unknown DB Format: {}".format(self.db_type)) self.__handler = DBHandler(connection=connection, echo=False) def get_session(self) -> Session: """ return a sqlalchemy database session :return: a sqlalchemy database session :raises ConnectionError: if no database handler is connected """ self.logger.debug("get or create a session") if self.__handler is None: self.__session = None raise ConnectionError( "No database handler found, please connect first") self.__session = self.__handler.get_session() return self.__session def close_session(self) -> None: """ close the current session if existing :return: Nothing """ self.logger.debug("Closing session") if self.__session is not None: self.__session.close() def check_connection(self) -> str: """ Check database connection :return: Error message if test fails, else empty string """ self.logger.debug("check_connection called") try: self.connect() self.get_session() self.close_session() return "" except DBAPIError as e: # ExceptionHandler(e).log(only_logfile=True) return str(e)
class TestWellClass(unittest.TestCase): """ a unittest for Well class """ def setUp(self): # type: () -> None """ Initialise a temporary database connection for all test cases and fill the database with test data :return: None """ # initialise a in-memory sqlite database # self.handler = DBHandler(connection="sqlite:///D:\\data.db", echo=False) self.handler = DBHandler(connection="sqlite://", echo=False) # self.handler = DBHandler(connection="mysql://*****:*****@localhost:3306/stdonn") self.session = self.handler.get_session() # add test data to the database self.wells = [ { "name": "Well_1", "short_name": "W1", "comment": "A drilled well", "east": 1234.56, "north": 123.45, "altitude": 10.5, "depth": 555, "marker": ((10, "mu", 4, ""), (15, "so", 3, "Comment 1"), (16, "sm", 2, ""), (17, "su", 1, "Comment 2"), (5, "mm", 5, "Comment 3")) }, { "name": "Well_2", "short_name": "W2", "comment": "", "east": 1000.23, "north": 2300.34, "altitude": 342.23, "depth": 341, "marker": ((12, "mo", 6, ""), (120, "mm", 5, "Comment 1"), (300, "Fault", 0, "Comment 2"), (320, "mo", 6, "")) }, { "name": "Well_3", "short_name": "W3", "comment": "A third well", "east": 3454.34, "north": 2340.22, "altitude": 342.20, "depth": 645.21, "marker": ((34, "mu", 4, ""), (234, "so", 3, "Comment 1"), (345, "Fault", 0, "Comment 2"), (635, "mu", 4, "Comment 3")) } ] for well in self.wells: new_well = Well(well["name"], well["short_name"], well["depth"], "spatial_reference_unknown", well["east"], well["north"], well["altitude"], self.session, "well_set", well["comment"]) new_well.save_to_db() for mark in well["marker"]: new_well.marker.append( WellMarker(mark[0], StratigraphicObject.init_stratigraphy(self.session, mark[1], mark[2], False), self.session, well["name"], mark[3])) new_well.marker[-1].save_to_db() def test_init(self): # type: () -> None """ Test the initialisation of the database :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ result = self.session.query(Well).all() self.assertEqual(len(result), 3, "Wrong number of drill holes ({}). Should be {}". format(len(result), len(self.wells))) self.assertEqual(result[1].well_name, "Well_2") self.assertEqual(result[1].short_name, "W2") self.assertEqual(result[2].comment, "A third well") self.assertTrue(math.fabs(float(result[0].easting) - 1234.56) < float_precision) self.assertTrue(math.fabs(float(result[1].northing) - 2300.34) < float_precision) self.assertTrue(math.fabs(float(result[0].altitude) - 10.5) < float_precision) self.assertTrue(math.fabs(float(result[2].depth) - 645.21) < float_precision) self.assertEqual(len(result[1].marker), 4) self.assertEqual(result[0].marker[2].horizon.statigraphic_name, "so") self.assertEqual(result[2].marker[2].horizon.statigraphic_name, "Fault") self.assertEqual(result[2].marker[2].horizon.age, 0) self.assertEqual(result[2].marker[2].comment, "Comment 2") self.assertEqual(result[0].marker[0].horizon.statigraphic_name, "mm") self.assertEqual(result[0].marker[1].horizon.statigraphic_name, "mu") self.assertEqual(result[0].marker[2].horizon.statigraphic_name, "so") self.assertEqual(result[0].marker[3].horizon.statigraphic_name, "sm") self.assertEqual(result[0].marker[4].horizon.statigraphic_name, "su") def test_loading(self): # type: () -> None """ Test the different types of loading of lines from the db. Part 1: load all wells from the database Part 2: load well by name Part 3: load wells in given extent Part 4: load wells with minimal depth :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ # Part 1: load all wells from the database wells = Well.load_all_from_db(self.session) self.assertEqual(len(wells), 3) self.assertEqual(wells[0].well_name, "Well_1") self.assertEqual(wells[1].well_name, "Well_2") self.assertEqual(wells[2].well_name, "Well_3") self.assertEqual(len(wells[1].marker), 4) self.assertTrue(wells[1].marker[0].horizon == wells[1].marker[3].horizon) del wells # Part 2: load well by name well = Well.load_by_wellname_from_db("Well_2", self.session) self.assertEqual(well.well_name, "Well_2") self.assertEqual(well.short_name, "W2") self.assertEqual(well.depth, 341) self.assertEqual(len(well.marker), 4) self.assertEqual(well.marker[1].horizon.statigraphic_name, "mm") self.assertEqual(well.marker[1].depth, 120) del well # Part 3: load wells in given extent # extent x: 500 - 1,300 # extent y: 0 - 2,400 # result: "Well_1" and "Well_2" wells = Well.load_in_extent_from_db(self.session, 500, 1300, 0, 2400) self.assertEqual(len(wells), 2) self.assertEqual(wells[0].well_name, "Well_1") self.assertEqual(wells[1].well_name, "Well_2") self.assertEqual(len(wells[0].marker), 5) self.assertEqual(len(wells[1].marker), 4) del wells # Part 4: load wells with minimal depth wells = Well.load_deeper_than_value_from_db(self.session, 395.23) self.assertEqual(len(wells), 2) self.assertEqual(wells[0].well_name, "Well_1") self.assertEqual(wells[1].well_name, "Well_3") self.assertTrue(wells[0].depth >= 395.23) self.assertTrue(wells[1].depth >= 395.23) del wells def test_insertion(self): # type: () -> None """ Test the insert functions of class Well :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ wells = Well.load_all_from_db(self.session) marker_1 = WellMarker(301.43, StratigraphicObject.init_stratigraphy(self.session, "ku"), self.session, "Comment 1") marker_2 = WellMarker(351.65, StratigraphicObject.init_stratigraphy(self.session, "mo"), self.session) marker_3 = WellMarker(934.23, StratigraphicObject.init_stratigraphy(self.session, "mm"), self.session, "Comment 3") wells[0].insert_marker(marker_1) self.assertEqual(len(wells[0].marker), 6) self.assertEqual(wells[0].marker[5], marker_1) self.assertRaises(ValueError, wells[1].insert_marker, marker_3) wells[2].insert_multiple_marker([marker_1, marker_2]) self.assertEqual(len(wells[2].marker), 6) self.assertEqual(wells[2].marker[2], marker_1) self.assertEqual(wells[2].marker[4], marker_2) del wells wells = Well.load_all_from_db(self.session) self.assertEqual(wells[2].marker[2], marker_1) self.assertEqual(wells[2].marker[4], marker_2) del wells wells = Well.load_all_from_db(self.session) self.assertRaises(ValueError, wells[1].insert_multiple_marker, [marker_1, marker_2, marker_3]) def test_get_marker_by_depth(self): # type: () -> None """ Test the Well.get_marker_by_depth function :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ well = Well.load_by_wellname_from_db("Well_1", self.session) self.assertEqual(well.get_marker_by_depth(16).horizon.statigraphic_name, "sm") self.assertRaises(ValueError, well.get_marker_by_depth, 100) def test_delete_marker(self): # type: () -> None """ Test the Well.get_marker_by_depth function :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ well = Well.load_by_wellname_from_db("Well_1", self.session) marker = well.get_marker_by_depth(16) self.assertEqual(marker.horizon.statigraphic_name, "sm") self.assertRaises(ValueError, well.get_marker_by_depth, 100) well.delete_marker(marker) well.save_to_db() self.assertEqual(len(well.marker), 4) del well well = Well.load_by_wellname_from_db("Well_1", self.session) self.assertEqual(len(well.marker), 4) new_marker = WellMarker(23423, StratigraphicObject.init_stratigraphy(self.session, "so"), self.session, "Nothing") self.assertRaises(ValueError, well.delete_marker, new_marker) self.assertRaises(TypeError, well.delete_marker, "test") def test_setter_and_getter(self): # type: () -> None """ Test setter and getter functionality :return: Nothing :raises AssertionError: Raises Assertion Error if a test fails """ # first part: test setter wells = Well.load_all_from_db(self.session) test_string = "abcdefghijklmnopqrstuvwxyz1234567890" wells[0].comment = "new comment set" wells[1].comment = 4 * test_string wells[0].easting = "-344.3" wells[1].easting = -1234.34 # self.assertRaises(ValueError, setattr, wells[2], "easting", "test") # python >= 2.7 => not included in all ArcGIS versions... with(self.assertRaises(ValueError)): # python <= 2.6 wells[2].easting = "test" wells[0].northing = -234.56 wells[1].northing = "-2345.356" with(self.assertRaises(ValueError)): wells[2].northing = "test" wells[0].altitude = -343.67 wells[1].altitude = "-235.34" with(self.assertRaises(ValueError)): wells[2].altitude = "test" wells[0].depth = 235.65 wells[1].depth = "3456.14" with(self.assertRaises(ValueError)): wells[2].depth = "test" with(self.assertRaises(ValueError)): wells[2].depth = -123.43 with(self.assertRaises(WellMarkerDepthException)): wells[2].depth = 500 wells[0].well_name = "new Well Name" wells[1].well_name = 4 * test_string wells[0].short_name = "NWN" wells[1].short_name = test_string # changes are stored automatically to the database through SQLAlchemy del wells # second part: test getters wells = Well.load_all_from_db(self.session) self.assertEqual(wells[0].comment, "new comment set") self.assertEqual(len(wells[1].comment), 100) self.assertEqual(wells[0].easting, -344.3) self.assertEqual(wells[1].easting, -1234.34) self.assertEqual(wells[2].easting, 3454.34) self.assertEqual(wells[0].northing, -234.56) self.assertEqual(wells[1].northing, -2345.356) self.assertEqual(wells[2].northing, 2340.22) self.assertEqual(wells[0].altitude, -343.67) self.assertEqual(wells[1].altitude, -235.34) self.assertEqual(wells[2].altitude, 342.2) self.assertEqual(wells[0].depth, 235.65) self.assertEqual(wells[1].depth, 3456.14) self.assertEqual(wells[2].depth, 645.21) self.assertEqual(wells[0].well_name, "new Well Name") self.assertEqual(len(wells[1].well_name), 100) self.assertEqual(wells[0].short_name, "NWN") self.assertEqual(len(wells[1].short_name), 20) # setter and getter for session wells[2].session = wells[1].session def test_log_handling(self): # type: () -> None """ Tests the log handling functionality :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ log_values = ( ( (10, 4, "", ""), (15, "45.4", "name 1", "Comment 1"), (16, 34.3, "", ""), (17, 234, "", "Comment 2"), (5, "34.4", "", "Comment 3") ), ( (34.3, 4, "", ""), (13, 234, "", "Comment 2"), (34, "34.4", "", "Comment 3") ) ) well = Well.load_by_wellname_from_db("Well_2", self.session) for i in range(len(log_values)): log = WellLog("log {}".format(i), "unit name", self.session, "", "") log.save_to_db() well.add_log(log) for value in log_values[i]: log.insert_log_value(WellLogValue(value[0], value[1], self.session, value[2], value[3])) del log del well well = Well.load_by_wellname_from_db("Well_2", self.session) self.assertEqual(2, len(well.logs)) self.assertEqual(5, len(well.logs[0].log_values)) self.assertEqual("log 0", well.logs[0].property_name) self.assertEqual(3, len(well.logs[1].log_values)) self.assertEqual("log 1", well.logs[1].property_name) well.delete_log(well.logs[1]) del well well = Well.load_by_wellname_from_db("Well_2", self.session) self.assertEqual(1, len(well.logs)) self.assertEqual(5, len(well.logs[0].log_values)) self.assertEqual("log 0", well.logs[0].property_name) logs = WellLog.load_all_from_db(self.session) self.assertEqual(1, len(logs)) def tearDown(self): # type: () -> None """ Empty function, nothing to shutdown after the testing process :return: Nothing """ pass
class TestWellMarkerClass(unittest.TestCase): """ a unittest for WellMarker class """ def setUp(self): # type: () -> None """ Initialise a temporary database connection for all test cases and fill the database with test data :return: None """ # initialise a in-memory sqlite database self.handler = DBHandler(connection="sqlite://", echo=False) self.session = self.handler.get_session() # add test data to the database self.wells = [ { "name": "Well_1", "short_name": "W1", "comment": "A drilled well", "east": 1234.56, "north": 123.45, "altitude": 10.5, "depth": 555, "marker": ((10, "mu", 4, ""), (15, "so", 3, "Comment 1"), (16, "sm", 2, ""), (17, "su", 1, "Comment 2"), (5, "mm", 5, "Comment 3")) }, { "name": "Well_2", "short_name": "W2", "comment": "", "east": 1000.23, "north": 2300.34, "altitude": 342.23, "depth": 341, "marker": ((12, "mo", 6, ""), (120, "mm", 5, "Comment 1"), (300, "Fault", 0, "Comment 2"), (320, "mo", 6, "")) }, { "name": "Well_3", "short_name": "W3", "comment": "A third well", "east": 3454.34, "north": 2340.22, "altitude": 342.20, "depth": 645.21, "marker": ((34, "mu", 4, ""), (234, "so", 3, "Comment 1"), (345, "Fault", 0, "Comment 2"), (635, "mu", 4, "Comment 3")) } ] for well in self.wells: new_well = Well(well["name"], well["short_name"], well["depth"], "spatial_reference_unknown", well["east"], well["north"], well["altitude"], self.session, "well_set", well["comment"]) new_well.save_to_db() for mark in well["marker"]: new_well.marker.append( WellMarker(mark[0], StratigraphicObject.init_stratigraphy(self.session, mark[1], mark[2], False), self.session, well["name"], mark[3])) new_well.marker[-1].save_to_db() def test_WellMarker_init(self): # type: () -> None """ Test the initialisation of the database :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ marker = self.session.query(WellMarker).all() self.assertEqual(len(marker), 13) self.assertEqual(marker[3].horizon.statigraphic_name, "su") self.assertEqual(marker[4].horizon.statigraphic_name, "mm") def test_WellMarker_setter_and_getter(self): # type: () -> None """ Test setter and getter functionality :return: Nothing :raises AssertionError: Raises Assertion Error if a test fails """ marker = WellMarker.load_all_from_db(self.session) self.assertEqual(len(marker), 13) test_string = "abcdefghijklmnopqrstuvwxyz1234567890" # first part: test setter functionality marker[0].comment = "This is a new comment" marker[1].comment = 4 * test_string marker[2].depth = 123.43 marker[3].depth = "2345.54" with (self.assertRaises(ValueError)): marker[4].depth = "Test" marker[4].horizon = StratigraphicObject.init_stratigraphy(self.session, "z", 50, False) with (self.assertRaises(TypeError)): marker[5].horizon = "test" # second part: getter functionality marker = WellMarker.load_all_from_db(self.session) self.assertEqual(marker[0].comment, "This is a new comment") self.assertEqual(len(marker[1].comment), 100) self.assertEqual(marker[3].comment, "Comment 2") self.assertEqual(marker[2].depth, 123.43) self.assertEqual(marker[1].depth, 15) self.assertEqual(marker[4].horizon.statigraphic_name, "z") self.assertEqual(marker[5].horizon.statigraphic_name, "mo") def test_WellMarker_to_GeoPoint(self): # type: () -> None """ Test WellMarker.to_GeoPoint functionality :return: Nothing :raises AssertionError: Raises Assertion Error if a test fails """ marker = WellMarker.load_all_from_db(self.session)[0] point = marker.to_geopoint() self.assertEqual(point.easting, 1234.56) self.assertEqual(point.northing, 123.45) self.assertEqual(point.altitude, 0.5) self.assertEqual(point.name, "Well_1") self.assertEqual(point.horizon.statigraphic_name, "mu") def tearDown(self): # type: () -> None """ Close session after testruns :return: Nothing """ self.handler.close_last_session()
class TestWellLogValueClass(unittest.TestCase): """ a unittest for WellLogValue class """ def setUp(self): # type: () -> None """ Initialise a temporary database connection for all test cases and fill the database with test data :return: None """ # initialise a in-memory sqlite database self.handler = DBHandler(connection="sqlite://", echo=False) self.session = self.handler.get_session() # add test data to the database self.log_values = [ { "depth": 200, "value": 123, "name": "log name", "comment": "unknown" }, { "depth": 200.324, "value": 12.5455, "name": "log name 2", "comment": "unknown" }, { "depth": "2345.54", "value": "641.54", "name": "", "comment": "" } ] for value in self.log_values: well_log_value = WellLogValue(value["depth"], value["value"], self.session, value["name"], value["comment"]) well_log_value.save_to_db() def test_WellLogValue_init(self): # type: () -> None """ Test the initialisation of the database :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ log_values = self.session.query(WellLogValue).all() self.assertEqual(len(log_values), 3) self.assertEqual(log_values[0].depth, 200) self.assertEqual(log_values[1].value, 12.5455) self.assertEqual(log_values[1].name, "log name 2") self.assertEqual(log_values[2].depth, 2345.54) self.assertEqual(log_values[2].value, 641.54) self.assertEqual(log_values[0].comment, "unknown") def test_setter_and_getter(self): # type: () -> None """ Tests the setter and getter functionality of the WellLogValue class :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ log_values = WellLogValue.load_all_from_db(self.session) self.assertEqual(len(log_values), 3) self.assertEqual(log_values[0].depth, 200) self.assertEqual(log_values[1].value, 12.5455) log_values[2].depth = 123.4 log_values[0].depth = "54356.45" with (self.assertRaises(ValueError)): log_values[1].depth = "string" log_values[0].value = 4345.4 log_values[1].value = "3245.4" with (self.assertRaises(ValueError)): log_values[2].value = "string" del log_values log_values = WellLogValue.load_all_from_db(self.session) self.assertEqual(log_values[0].depth, 54356.45) self.assertEqual(log_values[1].depth, 200.324) self.assertEqual(log_values[2].depth, 123.4) self.assertEqual(log_values[0].value, 4345.4) self.assertEqual(log_values[1].value, 3245.4) self.assertEqual(log_values[2].value, 641.54) def tearDown(self): # type: () -> None """ Empty function, nothing to shutdown after the testing process :return: Nothing """ pass
class TestPropertyClass(unittest.TestCase): """ a unittest for Property class """ def setUp(self): # type: () -> None """ Initialise a temporary database connection for all test cases and fill the database with test data :return: None """ # initialise a in-memory sqlite database self.handler = DBHandler(connection="sqlite://", echo=False) self.session = self.handler.get_session() # add test data to the database point = GeoPoint(StratigraphicObject.init_stratigraphy(self.session, "mu", 1), True, "", 1, 2, 3, self.session, "test", "") point.save_to_db() point.add_property(Property(0, PropertyTypes.INT, "test prop", "test unit", self.session)) point.add_property(Property(0, PropertyTypes.FLOAT, "test prop 2", "test unit 2", self.session)) point.add_property(Property(0, PropertyTypes.STRING, "test prop 3", "test unit 3", self.session)) def test_init(self): # type: () -> None """ Test the initialisation of the class :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ point = GeoPoint.load_all_from_db(self.session)[0] self.assertEqual(3, len(point.properties)) self.assertEqual("test prop", point.properties[0].property_name) self.assertEqual("test prop 2", point.properties[1].property_name) self.assertEqual("test prop 3", point.properties[2].property_name) self.assertEqual("test unit", point.properties[0].property_unit) self.assertEqual("test unit 2", point.properties[1].property_unit) self.assertEqual("test unit 3", point.properties[2].property_unit) self.assertEqual(PropertyTypes.INT, point.properties[0].property_type) self.assertEqual(PropertyTypes.FLOAT, point.properties[1].property_type) self.assertEqual(PropertyTypes.STRING, point.properties[2].property_type) def test_setter_and_getter(self): # type: () -> None """ Test the setter and getter functionality :return: Nothing :raises AssertionError: Raises Assertion Error when a test fails """ point = GeoPoint.load_all_from_db(self.session)[0] point.properties[0].property_value = 342 point.properties[1].property_value = "345.34" point.properties[2].property_value = "Test" point.properties[1].name = "some text information" point.properties[1].comment = "unused" point.properties[2].property_type = PropertyTypes.FLOAT with self.assertRaises(ValueError): point.properties[0].property_value = "string" with self.assertRaises(ValueError): point.properties[0].property_value = 234.34 del point point = GeoPoint.load_all_from_db(self.session)[0] self.assertEqual(342, point.properties[0].property_value) self.assertEqual(345.34, point.properties[1].property_value) self.assertEqual(None, point.properties[2].property_value) # type changed to PropertyTypes.FLOAT point.properties[2].property_type = PropertyTypes.STRING self.assertEqual("Test", point.properties[2].property_value) self.assertEqual("some text information", point.properties[1].name) self.assertEqual("unused", point.properties[1].comment) def tearDown(self): # type: () -> None """ Close session after testruns :return: Nothing """ self.handler.close_last_session()
class TestWellLogClass(unittest.TestCase): """ a unittest for WellLog class """ def setUp(self): # type: () -> None """ Initialise a temporary database connection for all test cases and fill the database with test data :return: None """ # initialise a in-memory sqlite database self.handler = DBHandler(connection="sqlite://", echo=False) self.session = self.handler.get_session() # add test data to the database self.well = { "well_name": "Well_1", "short_name": "W1", "reference": "none", "east": 1234.56, "north": 123.45, "altitude": 10.5, "depth": 555, "log_values": ((10, 4, "", ""), (15, "45.4", "name 1", "Comment 1"), (16, 34.3, "", ""), (17, 234, "", "Comment 2"), (5, "34.4", "", "Comment 3")) } well = Well(self.well["well_name"], self.well["short_name"], self.well["depth"], self.well["reference"], self.well["east"], self.well["north"], self.well["altitude"], self.session, "", "") well.save_to_db() logging = WellLog("logging", "unit name", self.session, "", "") logging.save_to_db() well.add_log(logging) for value in self.well["log_values"]: logging.insert_log_value(WellLogValue(value[0], value[1], self.session, value[2], value[3])) def test_WellLogValue_init(self): # type: () -> None """ Test the initialisation of the database :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ logging = self.session.query(WellLog).one() self.assertEqual(len(logging.log_values), 5) self.assertEqual(logging.log_values[0].depth, 5) self.assertEqual(logging.log_values[1].value, 4) self.assertEqual(logging.log_values[2].name, "name 1") self.assertEqual(logging.log_values[2].depth, 15) self.assertEqual(logging.log_values[2].value, 45.4) self.assertEqual(logging.log_values[4].comment, "Comment 2") def test_setter_and_getter(self): # type: () -> None """ Tests the setter and getter functionality of the WellLogValue class :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ logging = WellLog.load_all_from_db(self.session) self.assertEqual(len(logging), 1) logging = logging[0] self.assertEqual(logging.log_values[0].depth, 5) self.assertEqual(logging.log_values[1].value, 4) self.assertEqual(logging.log_values[2].name, "name 1") self.assertEqual(logging.log_values[4].comment, "Comment 2") self.assertEqual(logging.property_name, "logging") self.assertEqual(logging.property_unit, "unit name") logging.property_name = "new log name" logging.property_unit = u"km²" del logging logging = WellLog.load_all_from_db(self.session)[0] self.assertEqual(logging.property_name, "new log name") self.assertEqual(logging.property_unit, u"km²") longname = 4 * "abcdefghijklmnopqrstuvwxyz" logging.property_name = longname logging.property_unit = longname del logging logging = WellLog.load_all_from_db(self.session)[0] self.assertEqual(logging.property_name, longname[:100]) self.assertEqual(logging.property_unit, longname[:100]) def test_insert_and_delete_logvalue(self): # type: () -> None """ Test insertion and deletion functionality of class WellLog :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ logging = WellLog.load_all_from_db(self.session)[0] logging.insert_log_value(WellLogValue(14.3, 1234, self.session, "", "")) self.assertRaises(ValueError, logging.insert_log_value, WellLogValue(556, 1234, self.session, "", "")) del logging logging = WellLog.load_all_from_db(self.session)[0] self.assertEqual(6, len(logging.log_values)) self.assertEqual(14.3, logging.log_values[2].depth) self.assertEqual(1234, logging.get_value_by_depth(14.3).value) self.assertRaises(ValueError, logging.get_value_by_depth, 13) self.assertRaises(ValueError, logging.get_value_by_depth, "test") self.assertRaises(TypeError, logging.insert_log_value, "abcde") # noinspection PyTypeChecker logvalues = [ WellLogValue(123, 4152, self.session, "", ""), WellLogValue(156.34, 3456, self.session, "", ""), WellLogValue(16.2, 34.43, self.session, "", ""), WellLogValue(15.8, "234.2", self.session, "", "") ] logging.insert_multiple_log_values(logvalues) # noinspection PyTypeChecker self.assertRaises(TypeError, logging.insert_multiple_log_values, logvalues.append("abcde")) logvalues.pop() logvalues.append(WellLogValue(1234, 345, self.session, "", "")) self.assertRaises(ValueError, logging.insert_multiple_log_values, logvalues) del logging logging = WellLog.load_all_from_db(self.session)[0] self.assertEqual(10, len(logging.log_values)) self.assertEqual(14.3, logging.log_values[2].depth) self.assertEqual(3456, logging.get_value_by_depth(156.34).value) self.assertListEqual([5, 10, 14.3, 15, 15.8, 16, 16.2, 17, 123, 156.34], [x.depth for x in logging.log_values]) self.assertEqual(34.43, logging.log_values[6].value) logging.delete_value(logging.get_value_by_depth(16)) del logging logging = WellLog.load_all_from_db(self.session)[0] self.assertEqual(9, len(logging.log_values)) self.assertEqual(14.3, logging.log_values[2].depth) self.assertEqual(234, logging.log_values[6].value) self.assertRaises(ValueError, logging.get_value_by_depth, 16) self.assertListEqual([5, 10, 14.3, 15, 15.8, 16.2, 17, 123, 156.34], [x.depth for x in logging.log_values]) def tearDown(self): # type: () -> None """ Empty function, nothing to shutdown after the testing process :return: Nothing """ pass
class TestWellClass(unittest.TestCase): """ a unittest for Well class """ def setUp(self): # type: () -> None """ Initialise a temporary database connection for all test cases and fill the database with test data :return: None """ # initialise a in-memory sqlite database # self.handler = DBHandler(connection="sqlite:///D:\\data.db", echo=False) self.handler = DBHandler(connection="sqlite://", echo=False) # self.handler = DBHandler(connection="mysql://*****:*****@localhost:3306/stdonn") self.session = self.handler.get_session() # add test data to the database self.wells = [ { "name" : "Well_1", "short_name": "W1", "comment" : "A drilled well", "east" : 1234.56, "north" : 123.45, "altitude" : 10.5, "depth" : 555, "marker" : ((10, "mu", 4, ""), (15, "so", 3, "Comment 1"), (16, "sm", 2, ""), (17, "su", 1, "Comment 2"), (5, "mm", 5, "Comment 3")) }, { "name" : "Well_2", "short_name": "W2", "comment" : "", "east" : 1000.23, "north" : 2300.34, "altitude" : 342.23, "depth" : 341, "marker" : ((12, "mo", 6, ""), (120, "mm", 5, "Comment 1"), (300, "Fault", 0, "Comment 2"), (320, "mo", 6, "")) }, { "name" : "Well_3", "short_name": "W3", "comment" : "A third well", "east" : 3454.34, "north" : 2340.22, "altitude" : 342.20, "depth" : 751.13, "marker" : ((34, "mu", 4, ""), (234, "so", 3, "Comment 1"), (345, "Fault", 0, "Comment 2"), (635, "mu", 4, "Comment 3"), (636, "Fault", 0, ""), (645, "mu", 4, ""), (665, "Fault", 0, ""), (699, "so", 3, "Comment 1")) }, { "name" : "Well_4", "short_name": "W4", "comment" : "A fourth well", "east" : 234, "north" : 5645.45, "altitude" : 234.63, "depth" : 645.21, "marker" : ((34, "mu", 4, ""), (65, "so", 3, "Comment 1"), (70, "Fault", 0, "Comment 2"), (85, "so", 3, "Comment 1"), (105, "mu", 4, ""), (123, "mu", 4, ""), (201, "so", 3, "Comment 1")) } ] for well in self.wells: new_well = Well(well["name"], well["short_name"], well["depth"], "spatial_reference_unknown", well["east"], well["north"], well["altitude"], self.session, "well_set", well["comment"]) new_well.save_to_db() for mark in well["marker"]: new_well.marker.append(WellMarker(mark[0], StratigraphicObject.init_stratigraphy(self.session, mark[1], mark[2], False), self.session, well["name"], mark[3])) new_well.marker[-1].save_to_db() def test_well_markers_to_thickness(self): # type: () -> None """ Tests the Requests.well_markers_to_thickness(...) function :return: Nothing :raises AssertionError: if a test fails """ result = Requests.well_markers_to_thickness(self.session, "mu", "so", summarise_multiple=False, use_faulted=False, fault_name="Fault", extent=None) self.assertEqual(len(result), 4) self.assertTrue(result[0].has_property("thickness")) self.assertFalse(result[0].has_property("faulted")) self.assertFalse(result[0].has_property("summarised")) self.assertEqual(result[0].get_property("thickness").property_value, 5) self.assertEqual(result[1].get_property("thickness").property_value, 200) self.assertEqual(result[2].get_property("thickness").property_value, 31) self.assertEqual(result[3].get_property("thickness").property_value, 78) self.assertEqual(result[0].easting, 1234.56) self.assertEqual(result[0].northing, 123.45) self.assertEqual(result[0].altitude, 10.5 - 10) self.assertEqual(result[0].name, "Well_1") self.assertEqual(result[1].name, "Well_3") self.assertEqual(result[2].name, "Well_4") self.assertEqual(result[3].name, "Well_4") del result result = Requests.well_markers_to_thickness(self.session, "mu", "so", summarise_multiple=False, use_faulted=True, extent=None) self.assertEqual(len(result), 5) self.assertTrue(result[0].has_property("thickness")) self.assertTrue(result[0].has_property("faulted")) self.assertFalse(result[0].has_property("summarised")) self.assertEqual(result[0].get_property("thickness").property_value, 5) self.assertEqual(result[0].get_property("faulted").property_value, 0) self.assertEqual(result[1].get_property("thickness").property_value, 200) self.assertEqual(result[1].get_property("faulted").property_value, 0) self.assertEqual(result[2].get_property("thickness").property_value, 54) self.assertEqual(result[2].get_property("faulted").property_value, 1) self.assertEqual(result[3].get_property("thickness").property_value, 31) self.assertEqual(result[3].get_property("faulted").property_value, 0) self.assertEqual(result[4].get_property("thickness").property_value, 78) self.assertEqual(result[4].get_property("faulted").property_value, 0) self.assertEqual(result[0].name, "Well_1") self.assertEqual(result[1].easting, 3454.34) self.assertEqual(result[1].northing, 2340.22) self.assertEqual(result[1].altitude, 342.20 - 34) self.assertEqual(result[1].name, "Well_3") self.assertEqual(result[2].altitude, 342.20 - 645) self.assertEqual(result[2].name, "Well_3") self.assertEqual(result[3].name, "Well_4") self.assertEqual(result[4].name, "Well_4") del result result = Requests.well_markers_to_thickness(self.session, "mu", "so", summarise_multiple=True, use_faulted=False, fault_name="Fault", extent=None) self.assertEqual(len(result), 1) self.assertTrue(result[0].has_property("thickness")) self.assertFalse(result[0].has_property("faulted")) self.assertTrue(result[0].has_property("summarised")) self.assertEqual(result[0].get_property("thickness").property_value, 5) self.assertEqual(result[0].get_property("summarised").property_value, 0) self.assertEqual(result[0].easting, 1234.56) self.assertEqual(result[0].northing, 123.45) self.assertEqual(result[0].altitude, 10.5 - 10) self.assertEqual(result[0].name, "Well_1") del result result = Requests.well_markers_to_thickness(self.session, "mu", "so", summarise_multiple=True, use_faulted=True, extent=None) self.assertEqual(len(result), 3) self.assertTrue(result[0].has_property("thickness")) self.assertTrue(result[0].has_property("faulted")) self.assertTrue(result[0].has_property("summarised")) self.assertEqual(result[0].get_property("thickness").property_value, 5) self.assertEqual(result[0].get_property("faulted").property_value, 0) self.assertEqual(result[0].get_property("summarised").property_value, 0) self.assertEqual(result[1].get_property("thickness").property_value, 665) self.assertEqual(result[1].get_property("faulted").property_value, 3) self.assertEqual(result[1].get_property("summarised").property_value, 1) self.assertEqual(result[2].get_property("thickness").property_value, 167) self.assertEqual(result[2].get_property("faulted").property_value, 1) self.assertEqual(result[2].get_property("summarised").property_value, 1) self.assertEqual(result[0].name, "Well_1") self.assertEqual(result[1].name, "Well_3") self.assertEqual(result[2].name, "Well_4") self.assertEqual(result[2].easting, 234) self.assertEqual(result[2].northing, 5645.45) self.assertEqual(result[2].altitude, 234.63 - 34) del result extent = [1000, 1500, 0, 3000] # Well_1 and Well_2, 1 marker from Well_1 result = Requests.well_markers_to_thickness(self.session, "mu", "so", summarise_multiple=True, use_faulted=True, extent=extent) self.assertEqual(len(result), 1) self.assertEqual(result[0].name, "Well_1") del result extent = [1000, 1500, 2000, 3000] # only Well_2, no marker result = Requests.well_markers_to_thickness(self.session, "mu", "so", summarise_multiple=True, use_faulted=True, extent=extent) self.assertEqual(len(result), 0) del result extent = [0, 500, 5000, 6000] # only Well_4 result = Requests.well_markers_to_thickness(self.session, "mu", "so", summarise_multiple=False, use_faulted=True, extent=extent) self.assertEqual(len(result), 2) self.assertEqual(result[0].name, "Well_4") self.assertTrue(result[0].has_property("thickness")) self.assertEqual(result[0].get_property("thickness").property_value, 31) self.assertEqual(result[1].name, "Well_4") self.assertTrue(result[1].has_property("thickness")) self.assertEqual(result[1].get_property("thickness").property_value, 78) del result # test failures and exceptions """ :raises AttributeError: if marker_1 and marker_2 are equal :raises DatabaseException: if the database query results in less than 2 marker of a well_id :raises DatabaseRequestException: if an unexpected query result occurs :raises FaultException: if a fault is inside the section and use_faulted is False :raises TypeError: if session is not an instance of SQLAlchemy session :raises ValueError: if a parameter is not compatible with the required type """ self.assertRaises(AttributeError, Requests.well_markers_to_thickness, self.session, "mu", "mu", summarise_multiple=False, use_faulted=True, extent=None) self.assertRaises(TypeError, Requests.well_markers_to_thickness, "wrong type", "mu", "so", summarise_multiple=False, use_faulted=True, extent=None) self.assertRaises(TypeError, Requests.well_markers_to_thickness, self.session, "mu", "so", summarise_multiple=False, use_faulted=True, extent="ab") self.assertRaises(ValueError, Requests.well_markers_to_thickness, self.session, "mu", "so", summarise_multiple=False, use_faulted=True, extent=[1,2,3]) self.assertRaises(ValueError, Requests.well_markers_to_thickness, self.session, "mu", "so", summarise_multiple=False, use_faulted=True, extent=[1, 2, 3, "ab"]) def tearDown(self): # type: () -> None """ Close session after testruns :return: Nothing """ self.handler.close_last_session()
class TestLineClass(unittest.TestCase): """ This is a unittest class for the Resources.Geometries.Line class """ def setUp(self): # type: () -> None """ Initialise a temporary database connection for all test cases and fill the database with test data :return: None """ # initialise a in-memory sqlite database self.handler = DBHandler(connection="sqlite://", echo=False) self.session = self.handler.get_session() # handler = DBHandler( # connection="sqlite:////Users/stephan/Documents/data.db", # debug=False) # handler = DBHandler(connection="sqlite:///D:\\data.db", debug=False) # add test data to the database self.lines = [{ "closed": False, "horizon": "mu", "age": 3, "update": False, "points": ((1204067.0548148106, 634617.5980860253), (1204067.0548148106, 620742.1035724243), (1215167.4504256917, 620742.1035724243), (1215167.4504256917, 634617.5980860253), (1204067.0548148106, 634617.5980860253)), "name": "Line_1" }, { "closed": True, "horizon": "so", "age": 2, "update": True, "points": ((1179553.6811741155, 647105.5431482664), (1179553.6811741155, 626292.3013778647), (1194354.20865529, 626292.3013778647), (1194354.20865529, 647105.5431482664)), "name": "Line_2" }, { "closed": False, "horizon": "mm", "age": 4, "update": True, "points": ((1179091.1646903288, 712782.8838459781), (1161053.0218226474, 667456.2684348812), (1214704.933941905, 641092.8288590391), (1228580.428455506, 682719.3123998424), (1218405.0658121984, 721108.1805541387)), "name": "Line_3" }, { "closed": False, "horizon": "mo", "age": 5, "update": True, "points": ((1149490.1097279799, 691044.6091080031), (1149490.1097279799, 648030.5761158396), (1191579.1097525698, 648030.5761158396), (1149490.1097279799, 648030.5761158396), (1191579.1097525698, 691044.6091080031), (1149490.1097279799, 691044.6091080031)), "name": "Line_2" }] for line in self.lines: points = list() for point in line["points"]: points.append( GeoPoint(None, False, "", point[0], point[1], 0, self.session, line["name"], "")) new_line = Line( line["closed"], StratigraphicObject.init_stratigraphy(self.session, line["horizon"], line["age"], line["update"]), points, self.session, line["name"], "") new_line.save_to_db() def test_init(self): # type: () -> None """ Test the initialisation of the database :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ pnts = 0 for line in self.lines: pnts += len(line["points"]) # 2 points will be automatically deleted and the lines will be closed pnts -= 2 count_points = self.session.query(GeoPoint).count() lines = self.session.query(Line) count_lines = lines.count() lines = lines.all() stored_horizons = [ x.unit_name for x in self.session.query(StratigraphicObject.unit_name).all() ] # expected number of horizons horizons = set([x["horizon"] for x in self.lines]) self.assertEqual( count_points, pnts, "Number of points {} doesn't match the number of stored database points {}!" .format(count_points, pnts)) self.assertEqual( count_lines, len(self.lines), "Number of lines {} doesn't match the number of stored database lines {}!" .format(count_lines, len(self.lines))) if sys.version_info[0] == 2: self.assertItemsEqual( horizons, stored_horizons, "Horizons doesn't match.\nDatabase: {}\nShould be: {}".format( stored_horizons, horizons)) else: self.assertCountEqual( horizons, stored_horizons, "Horizons doesn't match.\nDatabase: {}\nShould be: {}".format( stored_horizons, horizons)) self.assertEqual( len(lines[0].points), 4, "Number of points of the line with ID 1 should be {}, but is {}". format(4, len(lines[0].points))) self.assertTrue(lines[0].is_closed, "line with ID 1 should be closed...") self.assertEqual( len(lines[1].points), 4, "Number of points of the line with ID 2 should be {}, but is {}". format(4, len(lines[1].points))) self.assertTrue(lines[1].is_closed, "line with ID 2 should be closed...") self.assertEqual( len(lines[2].points), 5, "Number of points of the line with ID 3 should be {}, but is {}". format(5, len(lines[2].points))) self.assertFalse(lines[2].is_closed, "line with ID 3 should not be closed...") self.assertEqual( len(lines[3].points), 5, "Number of points of the line with ID 4 should be {}, but is {}". format(5, len(lines[3].points))) self.assertTrue(lines[3].is_closed, "line with ID 4 should be closed...") def test_insert_one(self): # type: () -> None """ Test the insertion of one point. Additionally test get_point_index(point) function :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ insert_point = GeoPoint( StratigraphicObject.init_stratigraphy(self.session, "mu"), False, "", 1204200, 620800, 0, self.session) line_query = self.session.query(Line).filter_by(id=1) count = line_query.count() self.assertEqual( count, 1, "Get more than one expected result for line-id-request ({})". format(count)) line = line_query.one() line.session = self.session line.insert_point(insert_point, 1) self.assertEqual(line.points[1].line_pos, 1) # point is inserted, now delete insert details del count del line del line_query # test the insertion-process line_query = self.session.query(Line).filter_by(id=1) count = line_query.count() self.assertEqual( count, 1, "Get more than one expected result for line-id-request ({})". format(count)) line = line_query.one() # 20 Point initially, 2 removed, new point is Nr 19 -> id=19 # !!!ATTENTION!!! counting starts with 1 not 0 in sqlite-DB! # line-pos and get_point_index should be 1 self.assertEqual( line.points[1].id, 19, "Wrong id ({}) for new point (should be {})".format( line.points[1].id, 19)) self.assertEqual( line.points[1].line_pos, 1, "Wrong position of the new point ({}) in the line (should be {})". format(line.points[1].line_pos, 1)) self.assertEqual( line.get_point_index(insert_point), 1, "Wrong get_point_index(...) value ({}) in the line (should be {})". format(line.get_point_index(insert_point), 1)) self.assertEqual( line.points[1].easting, 1204200, "Wrong easting ({} / should be {})".format(line.points[1].easting, 1204200)) self.assertEqual( line.points[1].northing, 620800, "Wrong northing ({} / should be {})".format( line.points[1].northing, 620800)) self.assertEqual( line.points[1].altitude, 0, "Wrong altitude ({} / should be {})".format( line.points[1].altitude, 0)) self.assertEqual( line.points[1].has_z, False, "Wrong has_z ({} / should be {})".format(line.points[1].has_z, False)) # test Exception handling self.assertRaises(TypeError, line.insert_point, "string", 1) self.assertRaises(ValueError, line.insert_points, insert_point, "abc") def test_insert_multiple(self): # type: () -> None """ Test the insertion of multiple points. Although test remove of doubled values in a line. :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ insert_point_1 = GeoPoint( StratigraphicObject.init_stratigraphy(self.session, "mu"), False, "", 1204200, 620800, 0, self.session) insert_point_2 = GeoPoint( StratigraphicObject.init_stratigraphy(self.session, "mu"), False, "", 1204500, 621200, 0, self.session) insert_point_3 = GeoPoint( StratigraphicObject.init_stratigraphy(self.session, "mu"), False, "", 1204700, 621000, 0, self.session) insert_point_4 = GeoPoint( StratigraphicObject.init_stratigraphy(self.session, "mu"), False, "", 1204700, 621000, 0, self.session) points = [ insert_point_1, insert_point_2, insert_point_3, insert_point_4 ] line_query = self.session.query(Line).filter_by(id=1) count = line_query.count() self.assertEqual( count, 1, "Get more than one expected result for line-id-request ({})". format(count)) line = line_query.one() line.session = self.session line.insert_points(points, 1) line.save_to_db() # point is inserted, now delete insert details del count del insert_point_1, insert_point_2, insert_point_3 del line del line_query # test the insertion-process line_query = self.session.query(Line).filter_by(id=1) count = line_query.count() self.assertEqual( count, 1, "Get more than one expected result for line-id-request ({})". format(count)) line = line_query.one() # 20 Point initially, 2 removed, new point are Nr 19-21 -> id=19 to 21 # !!!ATTENTION!!! counting starts with 1 not 0 in sqlite-DB! # line-pos should be 1, 2 and 3 self.assertEqual( line.points[1].id, 19, "Wrong id ({}) for new point (should be {})".format( line.points[1].id, 19)) self.assertEqual( line.points[2].id, 20, "Wrong id ({}) for new point (should be {})".format( line.points[2].id, 20)) self.assertEqual( line.points[3].id, 21, "Wrong id ({}) for new point (should be {})".format( line.points[3].id, 21)) self.assertEqual( line.points[4].id, 2, "Wrong id ({}) for point after insert (should be {})".format( line.points[4].id, 2)) self.assertEqual( line.points[1].line_pos, 1, "Wrong position of the new point ({}) in the line (should be {})". format(line.points[1].line_pos, 1)) self.assertEqual( line.points[2].line_pos, 2, "Wrong position of the new point ({}) in the line (should be {})". format(line.points[2].line_pos, 2)) self.assertEqual( line.points[3].line_pos, 3, "Wrong position of the new point ({}) in the line (should be {})". format(line.points[3].line_pos, 3)) self.assertEqual( line.points[1].easting, 1204200, "Wrong easting ({} / should be {})".format(line.points[1].easting, 1204200)) self.assertEqual( line.points[1].northing, 620800, "Wrong northing ({} / should be {})".format( line.points[1].northing, 620800)) self.assertEqual( line.points[1].altitude, 0, "Wrong altitude ({} / should be {})".format( line.points[1].altitude, 0)) self.assertEqual( line.points[1].has_z, False, "Wrong has_z ({} / should be {})".format(line.points[1].has_z, False)) # test Exception handling self.assertRaises(ValueError, line.insert_points, points, "abc") points.append("cde") self.assertRaises(TypeError, line.insert_points, points, 2) def test_delete_point(self): # type: () -> None """ Test the deletion of a point. /1/ the point itself /2/ delete by coordinates /3/ test auto-removal of doubled points after deletion :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ line_query = self.session.query(Line).filter_by(id=2) count = line_query.count() self.assertEqual( count, 1, "Get more than one expected result for line-id-request ({})". format(count)) line = line_query.one() line.session = self.session line.delete_point(line.points[2]) # save deletion and reload line, test afterwards line.save_to_db() del count del line del line_query line = self.session.query(Line).filter_by(id=2).one() self.assertEqual( len(line.points), 3, "Wrong Nr of points ({}), should be {}".format( len(line.points), 3)) # test exception handling self.assertRaises(TypeError, line.delete_point, "string") self.assertRaises( ValueError, line.delete_point, GeoPoint(None, False, "", 1, 2, 0, self.session, "", "")) del line # /2/ test deletion by coordinates line_query = self.session.query(Line).filter_by(id=3) count = line_query.count() self.assertEqual( count, 1, "Get more than one expected result for line-id-request ({})". format(count)) line = line_query.one() line.session = self.session line.delete_point_by_coordinates(1214704.933941905, 641092.8288590391, 0) # save deletion and reload line, test afterwards line.save_to_db() del count del line del line_query line = self.session.query(Line).filter_by(id=3).one() self.assertEqual( len(line.points), 4, "Wrong Nr of points ({}), should be {}".format( len(line.points), 4)) self.assertEqual( line.points[1].id, 10, "First point before deleted point should have id {} but has {}". format(10, line.points[1].id)) self.assertEqual( line.points[2].id, 12, "First point after deleted point should have id {} but has {}". format(12, line.points[2].id)) # test exception handling self.assertRaises(ValueError, line.delete_point_by_coordinates, 123, 456, "test") self.assertRaises(ValueError, line.delete_point_by_coordinates, 123, 456, 789) # /3/ test auto-removal of doubled points after deletion line_query = self.session.query(Line).filter_by(id=4) count = line_query.count() self.assertEqual( count, 1, "Get more than one expected result for line-id-request ({})". format(count)) line = line_query.one() line.session = self.session line.delete_point_by_coordinates(1191579.1097525698, 648030.5761158396, 0) # save deletion and reload line, test afterwards line.save_to_db() del count del line del line_query line = self.session.query(Line).filter_by(id=4).one() self.assertEqual( len(line.points), 3, "Wrong Nr of points ({}), should be {}".format( len(line.points), 3)) self.assertEqual( line.points[1].id, 15, "First point before deleted point should have id {} but has {}". format(15, line.points[1].id)) self.assertEqual( line.points[2].id, 18, "First point after deleted point should have id {} but has {}". format(18, line.points[2].id)) def test_loading(self): # type: () -> None """ Test the different types of loading of lines from the db. Part 1: load all lines from the database Part 2: load line by id Part 3: load lines by ame Part 4: load lines with minimal one point in given extent :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ # Part 1: load all lines from the database lines = Line.load_all_from_db(self.session) self.assertEqual( len(lines), 4, "Wrong number of lines ({}), should be {}".format(len(lines), 4)) self.assertEqual( lines[0].id, 1, "First line has wrong id ({}), should be {}".format( lines[0].id, 1)) self.assertEqual(len(lines[0].points), 4, "Number of points ({}) of the first line is wrong. Should be {}". \ format(len(lines[0].points), 4)) self.assertEqual( lines[3].id, 4, "First line has wrong id ({}), should be {}".format( lines[3].id, 4)) self.assertEqual(len(lines[3].points), 5, "Number of points ({}) of the first line is wrong. Should be {}". \ format(len(lines[3].points), 5)) # test exception handling self.assertRaises(TypeError, Line.load_all_from_db, "test") del lines # Part 2: load line by id line = Line.load_by_id_from_db(2, self.session) self.assertEqual( line.id, 2, "line id is wrong ({}), should be {}".format(line.id, 2)) self.assertEqual(len(line.points), 4, "Number of points ({}) of the line with id=2 is wrong. Should be {}". \ format(len(line.points), 4)) self.assertEqual(line.points[0].id, 5, "first point in line with id=2 should have id {}, is {}". \ format(5, line.points[0].id)) self.assertEqual(line.points[-1].id, 8, "last point in line with id=2 should have id {}, is {}". \ format(8, line.points[-1].id)) # test exception handling self.assertRaises(DatabaseRequestException, Line.load_by_id_from_db, 25, self.session) del line # Part 3: load lines by name lines = Line.load_by_name_from_db("Line_3", self.session) self.assertEqual( len(lines), 1, "Wrong number of lines ({}), should be {}".format(len(lines), 1)) self.assertEqual( lines[0].id, 3, "Returned line has wrong id ({}), should be {}".format( lines[0].id, 3)) del lines lines = Line.load_by_name_from_db("Line_2", self.session) self.assertEqual( len(lines), 2, "Wrong number of lines ({}), should be {}".format(len(lines), 2)) self.assertEqual( lines[0].id, 2, "Returned line has wrong id ({}), should be {}".format( lines[0].id, 2)) self.assertEqual( lines[1].id, 4, "Returned line has wrong id ({}), should be {}".format( lines[0].id, 4)) del lines lines = Line.load_by_name_from_db("Test", self.session) self.assertEqual( len(lines), 0, "Wrong number of lines ({}), should be {}".format(len(lines), 0)) del lines # Part 4: load lines with minimal one point in given extent # x -> 1174000 - 1200000 # y -> 613500 - 651000 # should return 2 lines with id 2 and 4 ("Line_2") lines = Line.load_in_extent_from_db(self.session, 1174000, 1200000, 613500, 651000) self.assertEqual( len(lines), 2, "Wrong number of lines ({}), should be {}".format(len(lines), 2)) self.assertEqual( lines[0].id, 2, "Returned line has wrong id ({}), should be {}".format( lines[0].id, 2)) self.assertEqual( lines[1].id, 4, "Returned line has wrong id ({}), should be {}".format( lines[0].id, 4)) del lines lines = Line.load_in_extent_from_db(self.session, 0, 1, 0, 1) self.assertEqual( len(lines), 0, "Wrong number of lines ({}), should be {}".format(len(lines), 9)) del lines def test_setter_and_getter(self): # type: () -> None """ Test the setter and getter functions of class Line :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ lines = Line.load_all_from_db(self.session) lines[0].is_closed = True lines[1].horizon = StratigraphicObject.init_stratigraphy( self.session, "mu") lines[2].name = "Line_2" session_2 = lines[3].session lines[3].session = session_2 for line in lines: line.save_to_db() del lines lines = Line.load_all_from_db(self.session) line_with_name = Line.load_by_name_from_db("Line_2", self.session) self.assertTrue(lines[0].is_closed, "First line should be changed to closed.") self.assertEqual( lines[1].horizon.statigraphic_name, "mu", "Second line has wrong horizon ({}). Should have {}.".format( lines[1].horizon.statigraphic_name, "mu")) self.assertEqual( lines[2].name, "Line_2", "Third line has wrong line name ({}). Should have {}".format( lines[2].name, "Line_2")) self.assertEqual(len(line_with_name), 3, "Wrong Number of lines with line name 'Line_2' ({}). Should be {}". \ format(len(line_with_name), 3)) def tearDown(self): # type: () -> None """ Close session after testruns :return: Nothing """ self.handler.close_last_session() if __name__ == "__main__": unittest.main()
class TestStratigraphyClass(unittest.TestCase): def setUp(self): # type: () -> None """ Initialise a temporary database connection for all test cases and fill the database with test data :return: None """ # initialise a in-memory sqlite database self.handler = DBHandler(connection='sqlite://', echo=False) self.session = self.handler.get_session() units = [{ 'statigraphic_name': 'mo', 'age': 1, 'update': False }, { 'statigraphic_name': 'mm', 'age': 2, 'update': True }, { 'statigraphic_name': 'mu', 'age': 25, 'update': False }, { 'statigraphic_name': 'so', 'age': 4, 'update': False }, { 'statigraphic_name': 'mu', 'age': 3, 'update': True }, { 'statigraphic_name': 'so', 'age': 5, 'update': False }] for unit in units: new_unit = StratigraphicObject.init_stratigraphy( self.session, unit['statigraphic_name'], unit['age'], unit['update']) new_unit.save_to_db() def test_init(self): # type: () -> None """ Test the initialisation :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ result = self.session.query(StratigraphicObject).all() self.assertEqual( len(result), 4, "Wrong number of entries ({}). Should be {}.".format( len(result), 4)) def test_loading(self): # type: () -> None """ Test the loading functions of the stratigraphy class /1/ load all from database /2/ load by statigraphic_name from database /3/ load in age range from database :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ # /1/ load all from database # additionally update value is tested for mu / so unit result = { unit.statigraphic_name: unit for unit in StratigraphicObject.load_all_from_db(self.session) } self.assertEqual( len(result), 4, "Wrong number of entries ({}). Should be {}.".format( len(result), 4)) self.assertEqual( result['mu'].age, 3, "Wrong age for mu ({}). Should be {}".format(result['mu'].age, 3)) self.assertEqual( result['so'].age, 4, "Wrong age for so ({}). Should be {}".format(result['so'].age, 4)) del result # /2/ load by statigraphic_name from database result = StratigraphicObject.load_by_stratigraphic_name_from_db( 'mo', self.session) self.assertEqual( result.age, 1, "Wrong age for mo ({}). Should be {}".format(result.age, 3)) del result result = StratigraphicObject.load_by_stratigraphic_name_from_db( 'sm', self.session) self.assertIsNone( result, 'Result for sm is not None, but should be: {}'.format(str(result))) del result # /3/ load in age range from database result = StratigraphicObject.load_by_age_from_db(2, 3, self.session) self.assertEqual( len(result), 2, "Wrong number of query results ({}). Should be {}.".format( len(result), 2)) self.assertEqual( result[0].statigraphic_name, 'mm', "Wrong statigraphic_name of first horizon ({}). Should be {}.". format(result[0], 'mm')) self.assertEqual( result[1].statigraphic_name, 'mu', "Wrong statigraphic_name of second horizon ({}). Should be {}.". format(result[1], 'mu')) self.assertEqual( result[1].age, 3, "Wrong age for second horizon ({}). Should be {}.".format( result[1].age, 3)) del result result = StratigraphicObject.load_by_age_from_db(4, 4, self.session) self.assertEqual( len(result), 1, "Wrong number of query results ({}). Should be {}.".format( len(result), 1)) self.assertEqual( result[0].statigraphic_name, 'so', "Wrong statigraphic_name of first horizon ({}). Should be {}.". format(result[0], 'so')) del result result = StratigraphicObject.load_by_age_from_db(5, 10, self.session) self.assertEqual( len(result), 0, "Wrong number of query results ({}). Should be {}.".format( len(result), 0)) def test_setter_and_getter(self): # type: () -> None """ Test setter and getters of class StratigraphicObject :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ result = StratigraphicObject.load_by_stratigraphic_name_from_db( 'mo', self.session) result.age = 10 result.save_to_db() del result result = StratigraphicObject.load_by_stratigraphic_name_from_db( 'mo', self.session) self.assertEqual( result.age, 10, "Wrong age for horizon 'mo' ({}). Should be {}.".format( result.age, 10)) result.statigraphic_name = 'Blubb' result.save_to_db() del result result = StratigraphicObject.load_by_age_from_db(10, 10, self.session) self.assertEqual( len(result), 1, "Wrong number of query results ({}). Should be {}.".format( len(result), 1)) self.assertEqual( result[0].statigraphic_name, 'Blubb', "Wrong statigraphic_name of stratigraphic unit ({}). Should be {}". format(result[0].statigraphic_name, 'Blubb')) def tearDown(self): # type: () -> None """ Close session after testruns :return: Nothing """ self.handler.close_last_session()
class TestGeoPointClass(unittest.TestCase): """ This is a unittest class for the Resources.Geometries.GeoPoint class """ def setUp(self): # type: () -> None """ Initialise a temporary database connection for all test cases and fill the database with test data :return: None """ # initialise a in-memory sqlite database self.handler = DBHandler(connection="sqlite://", echo=False) self.session = self.handler.get_session() # add test data to the database self.points = [{ "coords": (1234134, 5465462, 123), "horizon": "mu", "age": 3, "name": "", "update": False }, { "coords": (1254367, 5443636, 156), "horizon": "so", "age": 23, "name": "", "update": False }, { "coords": (1265469, 5467929, None), "horizon": "sm", "age": 5, "name": "point set", "update": False }, { "coords": (1273456, 5449672, 101), "horizon": "mu", "age": 26, "name": "point set", "update": True }] self.lines = [{ "closed": False, "horizon": "mu", "age": 3, "update": False, "points": ((1204067.0548148106, 634617.5980860253), (1204067.0548148106, 620742.1035724243), (1215167.4504256917, 620742.1035724243), (1215167.4504256917, 634617.5980860253), (1204067.0548148106, 634617.5980860253)), "name": "Line_1" }, { "closed": True, "horizon": "so", "age": 2, "update": True, "points": ((1179553.6811741155, 647105.5431482664), (1179553.6811741155, 626292.3013778647), (1194354.20865529, 626292.3013778647), (1194354.20865529, 647105.5431482664)), "name": "Line_2" }, { "closed": False, "horizon": "mm", "age": 4, "update": True, "points": ((1179091.1646903288, 712782.8838459781), (1161053.0218226474, 667456.2684348812), (1214704.933941905, 641092.8288590391), (1228580.428455506, 682719.3123998424), (1218405.0658121984, 721108.1805541387)), "name": "Line_3" }, { "closed": False, "horizon": "mo", "age": 5, "update": True, "points": ((1149490.1097279799, 691044.6091080031), (1149490.1097279799, 648030.5761158396), (1191579.1097525698, 648030.5761158396), (1149490.1097279799, 648030.5761158396), (1191579.1097525698, 691044.6091080031), (1149490.1097279799, 691044.6091080031)), "name": "Line_2" }] for point in self.points: strat = StratigraphicObject.init_stratigraphy( self.session, point["horizon"], point["age"], point["update"]) new_point = GeoPoint( strat, False if (point["coords"][2] is None) else True, "", point["coords"][0], point["coords"][1], 0 if (point["coords"][2] is None) else point["coords"][2], self.session, point["name"], "") new_point.save_to_db() for line in self.lines: points = list() for point in line["points"]: points.append( GeoPoint(None, False, "", point[0], point[1], 0, self.session, line["name"], "")) new_line = Line( line["closed"], StratigraphicObject.init_stratigraphy(self.session, line["horizon"], line["age"], line["update"]), points, self.session, line["name"], "") new_line.save_to_db() def test_init(self): # type: () -> None """ Test the initialisation of the database :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ pnts = len(self.points) for line in self.lines: pnts += len(line["points"]) # 2 points will be automatically deleted and the lines will be closed pnts -= 2 points = self.session.query(GeoPoint) count_points = points.count() points = points.all() stored_horizons = self.session.query(StratigraphicObject).all() stored_horizons = [x.statigraphic_name for x in stored_horizons] # expected number of horizons horizons = set([x["horizon"] for x in self.lines] + [x["horizon"] for x in self.points]) # for point in points: # print(str(point)) self.assertEqual( count_points, pnts, "Number of points {} doesn't match the number of stored database points {}!" .format(count_points, pnts)) if sys.version_info[0] == 2: self.assertItemsEqual( horizons, stored_horizons, "Horizons doesn't match.\nDatabase: {}\nShould be: {}".format( stored_horizons, horizons)) else: self.assertCountEqual( horizons, stored_horizons, "Horizons doesn't match.\nDatabase: {}\nShould be: {}".format( stored_horizons, horizons)) self.assertEqual( points[0].id, 1, "Wrong ID {} for first point. Should be {}".format( points[0].id, 1)) self.assertEqual( points[0].horizon.statigraphic_name, "mu", "Wrong name of stratigraphic unit ({}) of first point. Should be ". format(points[0].horizon.statigraphic_name, "mu")) self.assertEqual( points[0].horizon.age, 26, "Wrong age for stratigraphic unit ({}) of first point. Should be {}" .format(points[0].horizon.age, 26)) def test_loading(self): # type: () -> None """ Test the loading functions of the GeoPoint class /1/ load all from database /2/ load by name /3/ load in extent :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ # /1/ load all from database points = GeoPoint.load_all_from_db(self.session) pnts_count = len(self.points) for line in self.lines: pnts_count += len(line["points"]) # 2 points have been automatically deleted and the lines will be closed pnts_count -= 2 self.assertEqual( len(points), pnts_count, "Wrong point count ({}). Should be {}.".format( len(points), pnts_count)) self.assertEqual( points[0].id, 1, "First point should have id {}, but has {}.".format( 1, points[0].id)) self.assertTrue( math.fabs(float(points[-1].easting) - 1191579.1097525698) < float_precision, "Wrong easting difference to large ( |{} - {}| = {} > {}).".format( float(points[-1].easting), 1191579.1097525698, math.fabs(float(points[-1].easting) - 1191579.1097525698), float_precision)) self.assertTrue( math.fabs(float(points[-1].northing) - 691044.6091080031) < float_precision, "Wrong northing difference to large ( |{} - {}| = {} > {}).". format(float(points[-1].northing), 691044.6091080031, math.fabs(float(points[-1].northing) - 691044.6091080031), float_precision)) del points points = GeoPoint.load_all_without_lines_from_db(self.session) pnts_count = len( self.points ) # only points which doesn"t belong to a line are loaded self.assertEqual( len(points), pnts_count, "Wrong point count ({}). Should be {}.".format( len(points), pnts_count)) self.assertEqual( points[0].id, 1, "First point should have id {}, but has {}.".format( 1, points[0].id)) self.assertTrue( math.fabs(float(points[-1].easting) - 1273456) < float_precision, "Wrong easting difference to large ( |{} - {}| = {} > {}).".format( float(points[-1].easting), 1273456, math.fabs(float(points[-1].easting) - 1273456), float_precision)) self.assertTrue( math.fabs(float(points[-1].northing) - 5449672) < float_precision, "Wrong northing difference to large ( |{} - {}| = {} > {}).". format(float(points[-1].northing), 5449672, math.fabs(float(points[-1].northing) - 5449672), float_precision)) self.assertEqual( points[-1].horizon.statigraphic_name, "mu", "Wrong horizon ({}). Should be {}.".format( points[-1].horizon.statigraphic_name, "mu")) del points # /2/ load by name points = GeoPoint.load_by_name_from_db("", self.session) pnts_count = len(self.points) # Added line name as points set name, so we have to comment the line points out... # for line in self.lines: # pnts_count += len(line["points"]) # 2 points will be automatically deleted and the lines will be closed # pnts_count -= 2 # 2 points have another name (obviously they have a name) pnts_count -= 2 self.assertEqual( len(points), pnts_count, "Wrong point count ({}). Should be {}.".format( len(points), pnts_count)) self.assertEqual( points[0].id, 1, "First point should have id {}, but has {}.".format( 1, points[0].id)) self.assertTrue( math.fabs(float(points[-1].easting) - 1254367) < float_precision, "Wrong easting difference to large ( |{} - {}| = {} > {}).".format( float(points[-1].easting), 1254367, math.fabs(float(points[-1].easting) - 1254367), float_precision)) self.assertTrue( math.fabs(float(points[-1].northing) - 5443636) < float_precision, "Wrong northing difference to large ( |{} - {}| = {} > {}).". format(float(points[-1].northing), 5443636, math.fabs(float(points[-1].northing) - 5443636), float_precision)) del points points = GeoPoint.load_by_name_without_lines_from_db("", self.session) pnts_count = len(self.points) # 2 points have another name (obviously they have a name) pnts_count -= 2 self.assertEqual( len(points), pnts_count, "Wrong point count ({}). Should be {}.".format( len(points), pnts_count)) self.assertEqual( points[0].id, 1, "First point should have id {}, but has {}.".format( 1, points[0].id)) self.assertTrue( math.fabs(float(points[-1].easting) - 1254367) < float_precision, "Wrong easting difference to large ( |{} - {}| = {} > {}).".format( float(points[-1].easting), 1254367, math.fabs(float(points[-1].easting) - 1254367), float_precision)) self.assertTrue( math.fabs(float(points[-1].northing) - 5443636) < float_precision, "Wrong northing difference to large ( |{} - {}| = {} > {}).". format(float(points[-1].northing), 5443636, math.fabs(float(points[-1].northing) - 5443636), float_precision)) self.assertEqual( points[-1].horizon.statigraphic_name, "so", "Wrong horizon ({}). Should be {}.".format( points[-1].horizon.statigraphic_name, "so")) del points # /3/ load points in given extent # x -> 1174000 - 1200000 # y -> 613500 - 651000 # should return points of 2 lines with line-ids 2 (all points) and 4 (1 point) points = GeoPoint.load_in_extent_from_db(self.session, 1174000, 1200000, 613500, 651000) self.assertEqual( len(points), 5, "Wrong number of points ({}), should be {}".format(len(points), 5)) self.assertTrue( math.fabs(float(points[0].easting) - 1179553.6811741155) < float_precision, "Wrong easting difference to large ( |{} - {}| = {} > {}).".format( float(points[0].easting), 1179553.6811741155, math.fabs(float(points[0].easting) - 1179553.6811741155), float_precision)) self.assertTrue( math.fabs(float(points[0].northing) - 647105.5431482664) < float_precision, "Wrong northing difference to large ( |{} - {}| = {} > {}).". format(float(points[0].northing), 647105.5431482664, math.fabs(float(points[0].northing) - 647105.5431482664), float_precision)) self.assertEqual( points[0].horizon.statigraphic_name, "so", "Wrong horizon ({}). Should be {}.".format( points[-1].horizon.statigraphic_name, "so")) del points points = GeoPoint.load_in_extent_without_lines_from_db( self.session, 0, 1, 0, 1) self.assertEqual( len(points), 0, "Wrong number of points ({}), should be {}".format(len(points), 0)) del points def test_setter_and_getter(self): # type: () -> None """ Test the setter and getter functions of class GeoPoint :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ # points = GeoPoint.load_all_from_db(self.session) points = GeoPoint.load_all_without_lines_from_db(self.session) self.assertEqual( len(points), len(self.points), "Wrong point length ({}). Should be {}.".format( len(points), len(self.points))) points[0].easting = 1 points[1].northing = 2 points[2].altitude = 3 points[2].use_z() points[3].horizon = StratigraphicObject.init_stratigraphy( self.session, "so", 10, False) points[0].name = "point set name" points[1].del_z() for point in points: point.save_to_db() del points points = GeoPoint.load_all_without_lines_from_db(self.session) self.assertEqual( len(points), len(self.points), "Wrong point length ({}). Should be {}.".format( len(points), len(self.points))) self.assertEqual( points[0].easting, 1, "Wrong easting value ({}). Should be {}.".format( points[0].easting, 1)) self.assertEqual( points[1].northing, 2, "Wrong northing value ({}). Should be {}.".format( points[1].northing, 2)) self.assertEqual( points[2].altitude, 3, "Wrong altitude value ({}). Should be {}.".format( points[2].altitude, 3)) self.assertTrue( points[2].has_z, "Third point has no z-value...") # Third point got z-value self.assertEqual( points[3].horizon.statigraphic_name, "so", "Wrong horizon ({}). Should be {}.".format( points[3].horizon.statigraphic_name, "so")) self.assertEqual( points[0].name, "point set name", "Wrong point name ({}). Should be {}.".format( points[0].name, "point set name")) self.assertFalse(points[1].has_z, "Second point has a z-value...") self.assertEqual( points[1].altitude, 0, "Wrong altitude value ({}). Should be {}.".format( points[1].altitude, 0)) def test_add_and_delete_properties(self): # type: () -> None """ Test the add_property and delete_property function :return: Nothing :raises AssertionError: Raises AssertionError if a test fails """ point = GeoPoint.load_all_from_db(self.session)[0] point.add_property( Property(0, PropertyTypes.INT, "test prop", "test unit", self.session)) point.add_property( Property(0, PropertyTypes.INT, "test prop 2", "test unit 2", self.session)) self.assertRaises(TypeError, point.add_property, "string") del point point = GeoPoint.load_all_from_db(self.session)[0] self.assertEqual(2, len(point.properties)) self.assertEqual("test prop", point.properties[0].property_name) self.assertEqual("test prop 2", point.properties[1].property_name) self.assertEqual("test unit", point.properties[0].property_unit) self.assertEqual("test unit 2", point.properties[1].property_unit) self.assertTrue(point.has_property("test prop 2")) self.assertEqual("test unit 2", point.get_property("test prop 2").property_unit) prop = point.properties[0] point.delete_property(prop) self.assertRaises(TypeError, point.delete_property, "string") self.assertRaises(ValueError, point.delete_property, prop) self.assertEqual(1, len(point.properties)) self.assertEqual("test prop 2", point.properties[0].property_name) self.assertEqual("test unit 2", point.properties[0].property_unit) del point point = GeoPoint.load_all_from_db(self.session)[0] self.assertEqual(1, len(point.properties)) self.assertEqual("test prop 2", point.properties[0].property_name) self.assertEqual("test unit 2", point.properties[0].property_unit) def tearDown(self): # type: () -> None """ Close session after testruns :return: Nothing """ self.handler.close_last_session()