Файл: Лабораторная работа 05 по в. 24 программирование критических сервисов Студент гр. Ист111 П. П. Иванов.docx
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 03.12.2023
Просмотров: 104
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
МИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ,СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА» (СПбГУТ)Кафедра информационных управляющих систем
получившуюся ER-диаграмму в нотации IDEF1X упорядочить, чтобы не было пересечений линий и добавить в отчет.2. Зарегистрироваться на ресурсе "облачной" загрузки и управления БД MySQL (можно выбрать любой другой бесплатный ресурс; загрузка на 2й ресурс проводится на случай "падения" 1го ресурса):2.1) нажать https://db4free.net/ , нажать Database -> Sign In:MySQL Database name: указать вида sql7609115MySQL User name: указать вида sql7609115Ввести свою почту 2.2) аналогично перейти к своей базе данных: по ссылке phpMyAdmin (или https://db4free.net/phpMyAdmin/ ) и заполнить ее.2.3) также отобразить получившуюся ER-диаграмму в нотации IDEF1X упорядочить, чтобы не было пересечений линий и добавить в отчет.3. Для проверки работы функций добавления строк составить 3 класса по 2 функции-теста в каждом (успешный и неуспешный); реализацию выполнить в виде файла testconsole _10.py (вместо 10 подставить название своего сервиса): также можно выполнить с другой СУБД и не обязательно на языке Python (в этом случае разбираемся самостоятельно с синтаксисом JavaScript, TypeScript и т.д.).3.1) В таблицу подставить функции добавления строк в "свою" таблицу БД MySQL; составить функции чтения/добавления данных и дополнить эти функции значениями return.3.2) Выполнить юнит-тестирование 6 функций чтения и добавления строк в удаленную базу данных.Отчет оформить примерно как в шаблоне; можно по-своему, но не менее информативноФайл отчета переименовать.]Зарегистрирован аккаунт на сайте https://www.freemysqlhosting.net/ , создана на этому онлайн-ресурсе базу данных sql7609144 (рис. 1).Рис. 1. Личный кабинет на сайте https://www.freemysqlhosting.net/После регистрации аккаунта выполнено подключение к базе данных с помощью онлайн-ресурса https://www.phpmyadmin.co (рис. 2).Рис. 2. Личный кабинет phpMyAdmin в онлайн-ресурсе онлайн-ресурса https://www.phpmyadmin.coПосле регистрации на сайте
https://www.freemysqlhosting.net/ произведена загрузка скрипта для создания и заполнения таблиц базы данных sql7609144 с помощью онлайн-ресурса https://www.phpmyadmin.co (рис. 3).Рис. 3. Результат выполнения скрипта по индивидуальному заданиюПосле выполнения скрипта по индивидуальному заданию в базе данных созданы и заполнены данными таблицы: ER-диаграмма в нотации IDEF1X представлена на рис. 4.Рис. 4. Представление базы данных sql7609144 в виде ER-диаграммы с помощью онлайн-ресурса https://www.phpmyadmin.coПеречень таблиц базы данных представлена на рис. 5.Рис. 5. Перечень таблиц базы данных sql7609144После выполнения аналогичных действий на сайте https://db4free.net/ и выполнения скрипта MySQL в СУБД phpMyAdmin в онлайн-ресурсе https://db4free.net/phpMyAdmin/, также получена IDEF1X-диаграмма (рис. 6).Рис. 6. Представление базы данных sql7609144 в виде ER-диаграммы в онлайн-ресурсе Далее в среде PyCharm создан прототип функций по чтению/добавлению записей в таблицу … базы данных создаваемого сервиса с помощью консольного приложения в файле main.py; для функций чтения и добавления записей указаны коды возврата для их последующего тестирования:import timeimport jsonimport pymysqlfrom decimal import *# для распознавания типа Decimal из формата JSONdef decimal_default(obj): if isinstance(obj, Decimal): return float(obj) raise TypeError("Ошибка сериализации JSON: '%s'" % type(obj).__name__)class dbase_mysql: def __init__(self): db = self.mysql_connect('sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') if db is not None: print("Проверка чтения") self.select_data("1002") def mysql_connect(self, Host, User, Password, Database): db = None try: db = pymysql.connect( host=Host, user=User, password=Password, database=Database) print("Подключение к БД успешно установлено!) (время: {})".format(time.localtime())) except Exception as e: print("Подключение к БД не установлено!( \n{}\n{}\n(время: {})". e.__repr__(), e.args, format(time.localtime())) return 1
return db def insert_data(self, values, db): try: if db is not None: cur = db.cursor() sql = "INSERT INTO CPU(CPU_id, CPU_coreCount, CPU_rate, CPU_brand, CPU_name) VALUES(%s, %s, %s, %s, %s)".format(values) print("Запрос {} успешно подготовлен!)".format(sql)) else: print("Не удалось подключиться к БД!(") return 1 except: print("Запрос {} не удалось подготовить!(".format(sql)) return 2 try: # inserting the values into the table cur.execute(sql, values) # commit the transaction db.commit() except: db.rollback() return 3 print(cur.rowcount, "record inserted!") db.close() return 0 def select_data(self, index): db = self.mysql_connect() ret = None try: if db is not None: cur = db.cursor() sql = "SELECT * FROM SU_list WHERE SystemUnit_RAM = {}".format(index) print("Запрос {} успешно подготовлен!)".format(sql)) else: print("Не удалось подключиться к БД!(") return ret except: print("Запрос {} не удалось подготовить!(".format(sql)) return ret try: cur.execute(sql) print("Выполнено: cur.execute(sql)") rows = cur.fetchall() print("Выполнено: rows = cur.fetchall()") row_headers = [x[0] for x in cur.description] print("Выполнено: row_headers = [x[0] for x in cur.description]") json_data = [] for row in rows: json_data.append(dict(zip(row_headers, row))) print("Выполнено: json_data.append(dict(zip(row_headers, row)))") print("json_data = \n{}".format(json_data)) ret = json.dumps(json_data, skipkeys=False, ensure_ascii=False, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=decimal_default, sort_keys=False) print("Успешно получен результат на запрос:\n{}".format(ret)) except Exception as e: print("Запрос {} не удалось выполнить на сервере!( Ошибка:\n{}\n{}". format(sql), e.__repr__(), e.args) finally: db.close() return retif __name__ == '__main__': activate = dbase_mysql() val = (10, 4, 2.9, 'AMD', 'Ryzen 5') db = activate.mysql_connect() count_request = activate.insert_data(val, db)Для проверки работы прототипа функции по чтению и добавлению строк составлены 3 тестовых класса по 2 тестовых метода в каждом (успешный и неуспешный); реализация выполнена в виде файла testconsole_10.py: [составить 3 тестовых класса по 2 тестовых метода в каждом, дополнив вариант, представленный в примере]import unittestimport main
class SuccesfullyTestCreate(unittest.TestCase): def test_create(self): test_create = main.dbase_mysql val = (12, 6, 2.9, 'AMD', 'Ryzen 5600') db = test_create.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') self.assertEqual(0, test_create.insert_data(self, val, db))# add assertion here def test_connect(self): test_connect = main.dbase_mysql db = test_connect.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') val = (13, 8, 3.3, 'AMD', 'Ryzen 7600') self.assertEqual(0, test_connect.insert_data(self, val, db))class UnsuccesfullyTestCreate(unittest.TestCase): def test_create(self): test_create = main.dbase_mysql db = test_create.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') val = (11, 8, 3.9, 'Intel', 'core I7') self.assertEqual(0, test_create.insert_data(self, val, db)) def test_connect(self): test_connect = main.dbase_mysql db = test_connect.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') val = (13, 8, 3.1, 'AMD', 'Ryzen 7700') self.assertEqual(0, test_connect.insert_data(self, val, db))if __name__ == '__main__': unittest.main()Таблица 1Результаты юнит-тестирования функций по добавлению записей в базу данных сервиса
В табл. 1 показаны следующие тесты:
Лабораторная работа № 05
по Б1.В.24 «ПРОГРАММИРОВАНИЕ КРИТИЧЕСКИХ СЕРВИСОВ»Студент гр. ИСТ-111_____________________________ П.П. Иванов(подпись)Проверил ___________________________ А. В. Параничев(оценка и подпись)Санкт-Петербург2023 год Программная реализация и тестирование функций чтения и записей из базы данных и добавления в базу данных сервиса в консольном режиме[желтым - для подстановки своих значений; зеленым - прочитать комментарии и удалить перед отправкой; все выделение убрать перед отправкой; файл переименовать по шаблону][Критерии оценок:+1 балл: при выполнении типовых действий без применения DesignPatterns;+2 и +3 балла: при применении, соответственно, 1 и 2 шаблонов проектирования (выбираются на занятии)1. Зарегистрироваться на ресурсе "облачной" загрузки и управления БД MySQL (можно использовать другую реляционную СУБД в онлайн-режиме с бесплатным доступом):1.1) нажать https://www.freemysqlhosting.net/ , нажать "Start Free Account", введя свою почту;1.2) нажать "MySQLHosting" и выбрать "Europe (MainLand)", нажать "SaveLocation";1.3) нажать CreateDatabase, получив имя сервера-логин-пароль:имя сервера вида: sql7.freemysqlhosting.netимя пользователя / имя базы данных вида: sql7609115пароль: <отправляется на почту>.1.4) нажать на ссылку "Follow this link for phpMyAdmin" (или https://www.phpmyadmin.co )1.5) перейти в раздел "SQL", скопировать в окно свой скрипт из 2й лабораторной работы, добавить в скрипт 1ю строку с именем базы данных вида:USEsql76091151.6) нажать "галочку" RetainQueryBox (сохранить окно запроса), отжать "галочку" EnableForeignKeyCheck (включить проверку внешних ключей);1.7) нажать Go (вперед), убедиться, что скрипт выполнен (зеленые "галочки" на странице выполнения скрипта);1.8) перейти Databases (Базы данных) -> выбрать свою базу данных вида sql7609115; -> перейти More -> Designer;получившуюся ER-диаграмму в нотации IDEF1X упорядочить, чтобы не было пересечений линий и добавить в отчет.2. Зарегистрироваться на ресурсе "облачной" загрузки и управления БД MySQL (можно выбрать любой другой бесплатный ресурс; загрузка на 2й ресурс проводится на случай "падения" 1го ресурса):2.1) нажать https://db4free.net/ , нажать Database -> Sign In:MySQL Database name: указать вида sql7609115MySQL User name: указать вида sql7609115Ввести свою почту 2.2) аналогично перейти к своей базе данных: по ссылке phpMyAdmin (или https://db4free.net/phpMyAdmin/ ) и заполнить ее.2.3) также отобразить получившуюся ER-диаграмму в нотации IDEF1X упорядочить, чтобы не было пересечений линий и добавить в отчет.3. Для проверки работы функций добавления строк составить 3 класса по 2 функции-теста в каждом (успешный и неуспешный); реализацию выполнить в виде файла testconsole _10.py (вместо 10 подставить название своего сервиса): также можно выполнить с другой СУБД и не обязательно на языке Python (в этом случае разбираемся самостоятельно с синтаксисом JavaScript, TypeScript и т.д.).3.1) В таблицу подставить функции добавления строк в "свою" таблицу БД MySQL; составить функции чтения/добавления данных и дополнить эти функции значениями return.3.2) Выполнить юнит-тестирование 6 функций чтения и добавления строк в удаленную базу данных.Отчет оформить примерно как в шаблоне; можно по-своему, но не менее информативноФайл отчета переименовать.]Зарегистрирован аккаунт на сайте https://www.freemysqlhosting.net/ , создана на этому онлайн-ресурсе базу данных sql7609144 (рис. 1).Рис. 1. Личный кабинет на сайте https://www.freemysqlhosting.net/После регистрации аккаунта выполнено подключение к базе данных с помощью онлайн-ресурса https://www.phpmyadmin.co (рис. 2).Рис. 2. Личный кабинет phpMyAdmin в онлайн-ресурсе онлайн-ресурса https://www.phpmyadmin.coПосле регистрации на сайте
https://www.freemysqlhosting.net/ произведена загрузка скрипта для создания и заполнения таблиц базы данных sql7609144 с помощью онлайн-ресурса https://www.phpmyadmin.co (рис. 3).Рис. 3. Результат выполнения скрипта по индивидуальному заданиюПосле выполнения скрипта по индивидуальному заданию в базе данных созданы и заполнены данными таблицы: ER-диаграмма в нотации IDEF1X представлена на рис. 4.Рис. 4. Представление базы данных sql7609144 в виде ER-диаграммы с помощью онлайн-ресурса https://www.phpmyadmin.coПеречень таблиц базы данных представлена на рис. 5.Рис. 5. Перечень таблиц базы данных sql7609144После выполнения аналогичных действий на сайте https://db4free.net/ и выполнения скрипта MySQL в СУБД phpMyAdmin в онлайн-ресурсе https://db4free.net/phpMyAdmin/, также получена IDEF1X-диаграмма (рис. 6).Рис. 6. Представление базы данных sql7609144 в виде ER-диаграммы в онлайн-ресурсе Далее в среде PyCharm создан прототип функций по чтению/добавлению записей в таблицу … базы данных создаваемого сервиса с помощью консольного приложения в файле main.py; для функций чтения и добавления записей указаны коды возврата для их последующего тестирования:import timeimport jsonimport pymysqlfrom decimal import *# для распознавания типа Decimal из формата JSONdef decimal_default(obj): if isinstance(obj, Decimal): return float(obj) raise TypeError("Ошибка сериализации JSON: '%s'" % type(obj).__name__)class dbase_mysql: def __init__(self): db = self.mysql_connect('sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') if db is not None: print("Проверка чтения") self.select_data("1002") def mysql_connect(self, Host, User, Password, Database): db = None try: db = pymysql.connect( host=Host, user=User, password=Password, database=Database) print("Подключение к БД успешно установлено!) (время: {})".format(time.localtime())) except Exception as e: print("Подключение к БД не установлено!( \n{}\n{}\n(время: {})". e.__repr__(), e.args, format(time.localtime())) return 1
return db def insert_data(self, values, db): try: if db is not None: cur = db.cursor() sql = "INSERT INTO CPU(CPU_id, CPU_coreCount, CPU_rate, CPU_brand, CPU_name) VALUES(%s, %s, %s, %s, %s)".format(values) print("Запрос {} успешно подготовлен!)".format(sql)) else: print("Не удалось подключиться к БД!(") return 1 except: print("Запрос {} не удалось подготовить!(".format(sql)) return 2 try: # inserting the values into the table cur.execute(sql, values) # commit the transaction db.commit() except: db.rollback() return 3 print(cur.rowcount, "record inserted!") db.close() return 0 def select_data(self, index): db = self.mysql_connect() ret = None try: if db is not None: cur = db.cursor() sql = "SELECT * FROM SU_list WHERE SystemUnit_RAM = {}".format(index) print("Запрос {} успешно подготовлен!)".format(sql)) else: print("Не удалось подключиться к БД!(") return ret except: print("Запрос {} не удалось подготовить!(".format(sql)) return ret try: cur.execute(sql) print("Выполнено: cur.execute(sql)") rows = cur.fetchall() print("Выполнено: rows = cur.fetchall()") row_headers = [x[0] for x in cur.description] print("Выполнено: row_headers = [x[0] for x in cur.description]") json_data = [] for row in rows: json_data.append(dict(zip(row_headers, row))) print("Выполнено: json_data.append(dict(zip(row_headers, row)))") print("json_data = \n{}".format(json_data)) ret = json.dumps(json_data, skipkeys=False, ensure_ascii=False, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=decimal_default, sort_keys=False) print("Успешно получен результат на запрос:\n{}".format(ret)) except Exception as e: print("Запрос {} не удалось выполнить на сервере!( Ошибка:\n{}\n{}". format(sql), e.__repr__(), e.args) finally: db.close() return retif __name__ == '__main__': activate = dbase_mysql() val = (10, 4, 2.9, 'AMD', 'Ryzen 5') db = activate.mysql_connect() count_request = activate.insert_data(val, db)Для проверки работы прототипа функции по чтению и добавлению строк составлены 3 тестовых класса по 2 тестовых метода в каждом (успешный и неуспешный); реализация выполнена в виде файла testconsole_10.py: [составить 3 тестовых класса по 2 тестовых метода в каждом, дополнив вариант, представленный в примере]import unittestimport main
class SuccesfullyTestCreate(unittest.TestCase): def test_create(self): test_create = main.dbase_mysql val = (12, 6, 2.9, 'AMD', 'Ryzen 5600') db = test_create.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') self.assertEqual(0, test_create.insert_data(self, val, db))# add assertion here def test_connect(self): test_connect = main.dbase_mysql db = test_connect.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') val = (13, 8, 3.3, 'AMD', 'Ryzen 7600') self.assertEqual(0, test_connect.insert_data(self, val, db))class UnsuccesfullyTestCreate(unittest.TestCase): def test_create(self): test_create = main.dbase_mysql db = test_create.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') val = (11, 8, 3.9, 'Intel', 'core I7') self.assertEqual(0, test_create.insert_data(self, val, db)) def test_connect(self): test_connect = main.dbase_mysql db = test_connect.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144') val = (13, 8, 3.1, 'AMD', 'Ryzen 7700') self.assertEqual(0, test_connect.insert_data(self, val, db))if __name__ == '__main__': unittest.main()Таблица 1Результаты юнит-тестирования функций по добавлению записей в базу данных сервиса
| Номер теста п/п | Тестовая функция и значения параметров | Ожидаемый результат | Фактический результат | Результат теста |
| 1 | val = (11, 8, 3.9, 'Intel', 'core I7') assertEqual(0, test_create.insert_data(self, val, db)) | 0 | 0 | OK |
| 2 | val = (11, 8, 3.9, 'Intel', 'core I7') assertEqual(0, test_create.insert_data(self, val, db)) | 0 | 3 | Failed |
| 3 | val = (12, 8, 3.3, 'AMD', 'Ryzen 7600') self.assertEqual(0, test_connect.insert_data(self, val, db)) | 0 | 0 | OK |
| 4 | val = (13, 8, 3.1, 'AMD', 'Ryzen 7700') self.assertEqual(0, test_connect.insert_data(self, val, db)) | 0 | 1 | Failed |
| 5 | | | | |
| 6 | | | | |
-
№ 1 и 3 выполнен успешно (ОК), т.к. ожидаемое значение и фактическое совпали. -
№ 2 и 4 выполнен неуспешно (Failed), т.к. данный тесты не проходят проверку на правильность и в случае если бы здесь тесты выполнялись успешно, то при работе с реальной программе пользователь бы смог сломать базу данных указывая некорректные данные. Во 2ом тесте мы пытаемся добавить строчку с уже занятым первичным ключом, так как первичный ключ должен быть уникальным SQL выдаёт ошибку и передаёт в функцию, которая в свою очередь оповещает об этом. В 4ом мы пытаемся добавить строчку с неправильным паролем в базе данных, соответственно мы получаем ошибку и возвращается значение 1, 1 не равен 0 поэтому тест не выполнен.