def test_add_food(): _, token = next(token_gen) cart_id = new_cart(token) # success add 3 food for i in range(3): res = json_patch("/carts/%s" % cart_id, token, next(food_gen)) assert res.status_code == 204 assert len(res.content) == 0 # fail if try to add more res = json_patch("/carts/%s" % cart_id, token, next(food_gen)) assert res.status_code == 403 assert res.json() == {"code": "FOOD_OUT_OF_LIMIT", "message": u"篮子中食物数量超过了三个"}
def test_del_food(): _, token = next(token_gen) cart_id = new_cart(token) item = next(food_gen) json_patch("/carts/%s" % cart_id, token, item) # delete existing food item["count"] = -1 res = json_patch("/carts/%s" % cart_id, token, item) assert res.status_code == 204 assert len(res.content) == 0 # delete non-exist food res = json_patch("/carts/%s" % cart_id, token, next(food_gen)) assert res.status_code == 204 assert len(res.content) == 0
def test_food_not_oversold_under_concurrent(): TEST_FOOD_COUNT = 5 TEST_FOOD_STOCK = 10 # random choose foods with more than 10 stock test_food_ids = random.sample( [f for f, s in food_store.items() if s["stock"] >= TEST_FOOD_STOCK], TEST_FOOD_COUNT) for food_id in test_food_ids: buy_to_stock(food_id, TEST_FOOD_STOCK) assert food_store[food_id]["stock"] == TEST_FOOD_STOCK # enumerate all food items total_food_items = [] for food_id in test_food_ids: remain_stock = food_store[food_id]["stock"] items = [{"food_id": food_id, "count": 1}] * remain_stock total_food_items.extend(items) assert len(total_food_items) == TEST_FOOD_COUNT * TEST_FOOD_STOCK # try to buy as much as twice of the stock test_food_items = total_food_items * 2 random.shuffle(test_food_items) # prepare carts & tokens, each carts contains 2 foods cart_ids, tokens, items_list = [], [], [] for food_items in zip(test_food_items[::2], test_food_items[1::2]): _, token = next(token_gen) cart_id = new_cart(token) for item in food_items: res = json_patch("/carts/%s" % cart_id, token, item) assert res.status_code == 204 cart_ids.append(cart_id) tokens.append(token) items_list.append(food_items) def _make(cart_id, token, food_items): res = json_post("/orders", token, {"cart_id": cart_id}) if res.status_code == 200: for food_item in food_items: food_store[food_item["food_id"]]["stock"] -= 1 return res # make order with prepared carts, using 3 concurrent threads # allow sell slower (remain stock > 0) # best sell all and correct (remain stock == 0) # disallow oversold (remain stock < 0) with ThreadPoolExecutor(max_workers=3) as executor: future_results = [ executor.submit(_make, ct, tk, fs) for ct, tk, fs in zip(cart_ids, tokens, items_list)] concurrent.futures.wait(future_results, timeout=30) # test not oversold for food_id in test_food_ids: print("stock %s -> %s" % (food_id, food_store[food_id]["stock"])) assert food_store[food_id]["stock"] >= 0
def test_food_not_oversold_under_concurrent(): TEST_FOOD_COUNT = 5 TEST_FOOD_STOCK = 10 # random choose foods with more than 10 stock test_food_ids = random.sample( [f for f, s in food_store.items() if s["stock"] >= TEST_FOOD_STOCK], TEST_FOOD_COUNT) for food_id in test_food_ids: buy_to_stock(food_id, TEST_FOOD_STOCK) assert food_store[food_id]["stock"] == TEST_FOOD_STOCK # enumerate all food items total_food_items = [] for food_id in test_food_ids: remain_stock = food_store[food_id]["stock"] items = [{"food_id": food_id, "count": 1}] * remain_stock total_food_items.extend(items) assert len(total_food_items) == TEST_FOOD_COUNT * TEST_FOOD_STOCK # try to buy as much as twice of the stock test_food_items = total_food_items * 2 random.shuffle(test_food_items) # prepare carts & tokens, each carts contains 2 foods cart_ids, tokens, items_list = [], [], [] for food_items in zip(test_food_items[::2], test_food_items[1::2]): _, token = next(token_gen) cart_id = new_cart(token) for item in food_items: res = json_patch("/carts/%s" % cart_id, token, item) assert res.status_code == 204 cart_ids.append(cart_id) tokens.append(token) items_list.append(food_items) def _make(cart_id, token, food_items): res = json_post("/orders", token, {"cart_id": cart_id}) if res.status_code == 200: for food_item in food_items: food_store[food_item["food_id"]]["stock"] -= 1 return res # make order with prepared carts, using 3 concurrent threads # allow sell slower (remain stock > 0) # best sell all and correct (remain stock == 0) # disallow oversold (remain stock < 0) with ThreadPoolExecutor(max_workers=3) as executor: future_results = [ executor.submit(_make, ct, tk, fs) for ct, tk, fs in zip(cart_ids, tokens, items_list)] concurrent.futures.wait(future_results, timeout=30) # test not oversold for food_id in test_food_ids: # print("stock %s -> %s" % (food_id, food_store[food_id]["stock"])) assert food_store[food_id]["stock"] >= 0
def test_cart_not_owned_error(): _, token1 = next(token_gen) _, token2 = next(token_gen) cart_id2 = new_cart(token2) res = json_patch("/carts/%s" % cart_id2, token1, next(food_gen)) assert res.status_code == 401 assert res.json() == {"code": "NOT_AUTHORIZED_TO_ACCESS_CART", "message": u"无权限访问指定的篮子"}
def test_food_not_found_error(): _, token = next(token_gen) cart_id = new_cart(token) item = {"food_id": -1, "count": 2} res = json_patch("/carts/%s" % cart_id, token, item) assert res.status_code == 404 assert res.json() == {"code": "FOOD_NOT_FOUND", "message": u"食物不存在"}
def test_cart_not_found_error(): _, token = next(token_gen) res = json_patch("/carts/-1", token, next(food_gen)) assert res.status_code == 404 assert res.json() == {"code": "CART_NOT_FOUND", "message": u"篮子不存在"}