def setUp(self): suffix = self._testMethodName.split('_')[-2] if 'user' == suffix.lower(): self.table = UserTable elif 'good' == suffix.lower(): self.table = GoodTable elif 'order' == suffix.lower(): self.table = OrderTable self.table.drop(ENGINE, checkfirst=True) self.table.create(ENGINE, checkfirst=True) self.db = CoreDBServer(self.table)
def add_good_data(self): self.table = CoreDBServer(GoodTable) data_list = [] with open(good_data_file, 'w') as f: for _ in range(1000): godd_name, inventory, price = self.fake.good_name( ), self.fake.pyint(), self.fake.pyint() data_list.append( {"name": godd_name, "inventory": inventory, "price": price}) f.write(godd_name+","+str(inventory) + ","+str(price)+os.linesep) self.table.many_insert(data_list=data_list)
class PayServer(Server): def __init__(self): self.dbser = CoreDBServer(OrderTable) super().__init__() def pay(self, username, order_no): # 实际上应该还有第三方支付 # 这里直接变更订单状态,没有单号校验 # 模拟回调产生的消耗 200 +/- 50ms wheres = [ ['order_no', 'eq', order_no], ] order = OrderServer().order_detail(username, order_no) if 0 == order['code']: status = order['order']['status'] else: return order if 0 == status: sec = 0.2 + random.randint(0, 50) * 10**-3 sleep(sec) values = {'status': 0} if 99999 > random.randint(0, 10**5): values['status'] = 1 values['pay_id'] = 'wx' + ranstr() else: values['status'] = 2 ret = self.dbser.update(wheres=wheres, **values).rowcount return {'code': 0, 'msg': '支付成功'} elif 3 == status: return {'code': 1, 'msg': "订单已过期"} elif 1 == status: return {'code': 1, 'msg': '订单已支付,请勿重复支付'}
def add_user_data(self): self.table = CoreDBServer(UserTable) data_list = [] with open(user_data_file, 'w') as f: name_set = set([]) for _ in range(10000): while True: cur_len = len(name_set) username, password = self.fake.email(), self.fake.password() name_set.add(username) if len(name_set) > cur_len: break data_list.append( {"username": username, "password": md5_text(password) } ) f.write(username+','+password+os.linesep) self.table.many_insert(data_list=data_list)
class test_db_module(unittest.TestCase): def setUpClass(cls): return super().setUpClass() def setUp(self): self.db = CoreDBServer(UserTable) return super().setUp() def test_select(self): wheres = [['username', 'eq', '*****@*****.**'], ['id', 'eq', 2]] row = self.db.select(wheres).first() self.assertEqual('*****@*****.**', row['username']) def test_update(self): new_values = {'money': 0} wheres = [['username', 'eq', '*****@*****.**']] ret = self.db.update(wheres=wheres, **new_values) ret = self.db.select(wheres).first() self.assertEqual(0, ret['money'])
class init_faker_data(): def __init__(self): self.fake = Faker('zh-CN') self.fake.add_provider(GoodProvider) Faker.seed(0) def add_user_data(self): self.table = CoreDBServer(UserTable) data_list = [] with open(user_data_file, 'w') as f: name_set = set([]) for _ in range(10000): while True: cur_len = len(name_set) username, password = self.fake.email(), self.fake.password() name_set.add(username) if len(name_set) > cur_len: break data_list.append( {"username": username, "password": md5_text(password) } ) f.write(username+','+password+os.linesep) self.table.many_insert(data_list=data_list) def add_good_data(self): self.table = CoreDBServer(GoodTable) data_list = [] with open(good_data_file, 'w') as f: for _ in range(1000): godd_name, inventory, price = self.fake.good_name( ), self.fake.pyint(), self.fake.pyint() data_list.append( {"name": godd_name, "inventory": inventory, "price": price}) f.write(godd_name+","+str(inventory) + ","+str(price)+os.linesep) self.table.many_insert(data_list=data_list)
class create_db_testcase(unittest.TestCase): @classmethod def setUpClass(cls): create_schema() set_time_zone() def setUp(self): suffix = self._testMethodName.split('_')[-2] if 'user' == suffix.lower(): self.table = UserTable elif 'good' == suffix.lower(): self.table = GoodTable elif 'order' == suffix.lower(): self.table = OrderTable self.table.drop(ENGINE, checkfirst=True) self.table.create(ENGINE, checkfirst=True) self.db = CoreDBServer(self.table) # @unittest.skip('skip') def test_create_user_table(self): values = {"username": '******', "password": '******'} self.db.insert(**values) # @unittest.skip('skip') def test_create_good_table(self): values = {'name': 'test_good'} self.db.insert(**values) # @unittest.skip('skip') def test_create_order_table(self): values = {'username': '******', 'order_no': '202001250159591234', 'good_ids': '[1,2]'} self.db.insert(**values) def tearDown(self): self.db.clear() return super().tearDown() @classmethod def tearDownClass(cls): return super().tearDownClass()
class GoodServer(Server): def __init__(self): self.dbser = CoreDBServer(GoodTable) super().__init__() def app_goods_list(self, page, page_size, sorts_by, *args, **kwargs): offset, limit = page, page_size if offset >= 1: offset = (offset - 1) * limit else: limit = 0 wheres = [ ['inventory', 'gt', '0'], ] rows = self.dbser.select(wheres, sorts_by, offset, limit).fetchall() return {'code': 0, "list": [self.dbser.row2json(row) for row in rows]} def good_detail(self, id): try: wheres = [['id', 'eq', id]] row = self.dbser.select(wheres).first() if not row: return self.error_tips('商品不存在') else: return {'code': 0, "good": self.dbser.row2json(row)} except Exception as e: logging.error(e) return UNKNOW_ERROR def release_inventory(self, ids: list): """rlease inventory when order exp。""" good_id_str = ','.join([str(good_id) for good_id in ids]) sql = """update %s set inventory = inventory+1 where id in (%s); """ % ( self.dbser.table.name, good_id_str) return self.dbser.sql_transaction_execute(sql=sql) def sub_inventory(self, ids: list) -> dict: """sub inventory when order add. """ good_id_str = ','.join([str(good_id) for good_id in ids]) sql = """update %s set inventory = inventory-1 where id in (%s) and inventory >0 ; """ % ( self.dbser.table.name, good_id_str) conn = self.dbser.connect() with conn.begin() as tran: if len(ids) == conn.execute(sql).rowcount: tran.commit() return {'code': 0} else: tran.rollback() return {'code': 1, 'msg': '库存不足'}
class LoginServer(Server): def __init__(self): self.dbser = CoreDBServer(UserTable) super().__init__() def login(self, username, password): """return token or error msg. """ wheres = [["username", 'eq', username]] row = self.dbser.select(wheres).first() if not row: logging.warning('username:{} password:{} 用户不存在'.format( username, password)) return self.error_tips("不存在该用户") if password == row['password']: return {'code': 0, 'token': get_token(username)} elif password != row['password']: logging.warning('username:{} password:{} 密码错误'.format( username, password)) return self.error_tips('密码错误') else: return self.error_tips('未知错误')
def exp_order(order_no): """过期订单(有效期为15分钟).""" sql = 'update %s set create_time = date_sub(create_time, interval 15 minute) where order_no = %r' % ( OrderTable.name, order_no) CoreDBServer().sql_execute(sql)
def login(): row = CoreDBServer(UserTable).select().first() data = {'username': row['username'], 'password': row['password']} return pe_api('http://localhost:%s/jmeter/login' % PORT, data=data)
def __init__(self): self.dbser = CoreDBServer(GoodTable) super().__init__()
class OrderServer(Server): def __init__(self): self.dbser = CoreDBServer(OrderTable) super().__init__() def add_order(self, username: str, good_ids: list) -> dict: """return order detail or fail reason. """ try: # 减库存 ret = GoodServer().sub_inventory(good_ids) if 1 == ret['code']: return ret # 下单号 日期(精确到分) + 4位随机数,实际上要避免这种有明显规律的单号 order_no = datetime.datetime.utcnow().strftime( '%Y%m%d%H%M')+str(random.randint(0, 9999)).zfill(4) good_id_str = ','.join([str(good_id) for good_id in good_ids]) sql = "select price from %s where id in (%s);" % ( GoodTable.name, good_id_str) rows = self.dbser.sql_execute(sql).fetchall() sum_price = sum([row[0] for row in rows]) values = {"username": username, "order_no": order_no, 'good_ids': good_id_str, "sum_price": sum_price} self.dbser.insert(**values) return {'code': 0, 'order_no': order_no} except Exception as e: logging.error(e) return UNKNOW_ERROR def order_detail(self, username, order_no): wheres = [ ["username", 'eq', username], ["order_no", 'eq', order_no] ] row = self.dbser.select(wheres).first() if row: order = self.dbser.row2json(row) # 15分钟过期 end_time = copy.deepcopy(row['create_time']) end_time += datetime.timedelta(seconds=900) # 过期订单更新状态 if datetime.datetime.now() > end_time and order['status'] not in (1, 3): order['status'] = 3 GoodServer().release_inventory(order['good_ids'].split(',')) print(self.dbser.update(wheres, status=3).rowcount) elif order['status'] in [0, 2]: order['exp_time'] = ( end_time-datetime.datetime.utcnow()).total_seconds() return {"code": 0, "order": order} else: return self.error_tips('订单不存在') def order_list(self, username, page, page_size): offset_num = (page-1) * page_size wheres = [ ['username', 'eq', username] ] sorts_by = [ ['create_time', '1'] ] l = self.dbser.select( wheres, sorts_by, offset=offset_num, limit=page_size).fetchall() l = [self.dbser.row2json(i) for i in l] return {'code': 0, 'list': l}
def setUp(self): self.db = CoreDBServer(UserTable) return super().setUp()