test: add timeout to all BOM related tests (#34446)

* Revert "chore: remove failing test (#34444)"

This reverts commit b89ecd482d4c8db69765f633bc22c95619f2f3f9.

* test: add timeout to bom tests
This commit is contained in:
Ankush Menat 2023-03-14 18:10:17 +05:30 committed by GitHub
parent b89ecd482d
commit f95ad039e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 2 deletions

View File

@ -6,7 +6,7 @@ from collections import deque
from functools import partial from functools import partial
import frappe import frappe
from frappe.tests.utils import FrappeTestCase from frappe.tests.utils import FrappeTestCase, timeout
from frappe.utils import cstr, flt from frappe.utils import cstr, flt
from erpnext.controllers.tests.test_subcontracting_controller import ( from erpnext.controllers.tests.test_subcontracting_controller import (
@ -27,6 +27,7 @@ test_dependencies = ["Item", "Quality Inspection Template"]
class TestBOM(FrappeTestCase): class TestBOM(FrappeTestCase):
@timeout
def test_get_items(self): def test_get_items(self):
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
@ -37,6 +38,7 @@ class TestBOM(FrappeTestCase):
self.assertTrue(test_records[2]["items"][1]["item_code"] in items_dict) self.assertTrue(test_records[2]["items"][1]["item_code"] in items_dict)
self.assertEqual(len(items_dict.values()), 2) self.assertEqual(len(items_dict.values()), 2)
@timeout
def test_get_items_exploded(self): def test_get_items_exploded(self):
from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict from erpnext.manufacturing.doctype.bom.bom import get_bom_items_as_dict
@ -49,11 +51,13 @@ class TestBOM(FrappeTestCase):
self.assertTrue(test_records[0]["items"][1]["item_code"] in items_dict) self.assertTrue(test_records[0]["items"][1]["item_code"] in items_dict)
self.assertEqual(len(items_dict.values()), 3) self.assertEqual(len(items_dict.values()), 3)
@timeout
def test_get_items_list(self): def test_get_items_list(self):
from erpnext.manufacturing.doctype.bom.bom import get_bom_items from erpnext.manufacturing.doctype.bom.bom import get_bom_items
self.assertEqual(len(get_bom_items(bom=get_default_bom(), company="_Test Company")), 3) self.assertEqual(len(get_bom_items(bom=get_default_bom(), company="_Test Company")), 3)
@timeout
def test_default_bom(self): def test_default_bom(self):
def _get_default_bom_in_item(): def _get_default_bom_in_item():
return cstr(frappe.db.get_value("Item", "_Test FG Item 2", "default_bom")) return cstr(frappe.db.get_value("Item", "_Test FG Item 2", "default_bom"))
@ -71,6 +75,36 @@ class TestBOM(FrappeTestCase):
self.assertTrue(_get_default_bom_in_item(), bom.name) self.assertTrue(_get_default_bom_in_item(), bom.name)
@timeout
def test_update_bom_cost_in_all_boms(self):
# get current rate for '_Test Item 2'
bom_rates = frappe.db.get_values(
"BOM Item",
{
"parent": "BOM-_Test Item Home Desktop Manufactured-001",
"item_code": "_Test Item 2",
"docstatus": 1,
},
fieldname=["rate", "base_rate"],
as_dict=True,
)
rm_base_rate = bom_rates[0].get("base_rate") if bom_rates else 0
# Reset item valuation rate
reset_item_valuation_rate(item_code="_Test Item 2", qty=200, rate=rm_base_rate + 10)
# update cost of all BOMs based on latest valuation rate
update_cost_in_all_boms_in_test()
# check if new valuation rate updated in all BOMs
for d in frappe.db.sql(
"""select base_rate from `tabBOM Item`
where item_code='_Test Item 2' and docstatus=1 and parenttype='BOM'""",
as_dict=1,
):
self.assertEqual(d.base_rate, rm_base_rate + 10)
@timeout
def test_bom_cost(self): def test_bom_cost(self):
bom = frappe.copy_doc(test_records[2]) bom = frappe.copy_doc(test_records[2])
bom.insert() bom.insert()
@ -99,6 +133,7 @@ class TestBOM(FrappeTestCase):
self.assertAlmostEqual(bom.base_raw_material_cost, base_raw_material_cost) self.assertAlmostEqual(bom.base_raw_material_cost, base_raw_material_cost)
self.assertAlmostEqual(bom.base_total_cost, base_raw_material_cost + base_op_cost) self.assertAlmostEqual(bom.base_total_cost, base_raw_material_cost + base_op_cost)
@timeout
def test_bom_cost_with_batch_size(self): def test_bom_cost_with_batch_size(self):
bom = frappe.copy_doc(test_records[2]) bom = frappe.copy_doc(test_records[2])
bom.docstatus = 0 bom.docstatus = 0
@ -117,6 +152,7 @@ class TestBOM(FrappeTestCase):
self.assertAlmostEqual(bom.operating_cost, op_cost / 2) self.assertAlmostEqual(bom.operating_cost, op_cost / 2)
bom.delete() bom.delete()
@timeout
def test_bom_cost_multi_uom_multi_currency_based_on_price_list(self): def test_bom_cost_multi_uom_multi_currency_based_on_price_list(self):
frappe.db.set_value("Price List", "_Test Price List", "price_not_uom_dependent", 1) frappe.db.set_value("Price List", "_Test Price List", "price_not_uom_dependent", 1)
for item_code, rate in (("_Test Item", 3600), ("_Test Item Home Desktop Manufactured", 3000)): for item_code, rate in (("_Test Item", 3600), ("_Test Item Home Desktop Manufactured", 3000)):
@ -153,6 +189,7 @@ class TestBOM(FrappeTestCase):
self.assertEqual(bom.base_raw_material_cost, 27000) self.assertEqual(bom.base_raw_material_cost, 27000)
self.assertEqual(bom.base_total_cost, 33000) self.assertEqual(bom.base_total_cost, 33000)
@timeout
def test_bom_cost_multi_uom_based_on_valuation_rate(self): def test_bom_cost_multi_uom_based_on_valuation_rate(self):
bom = frappe.copy_doc(test_records[2]) bom = frappe.copy_doc(test_records[2])
bom.set_rate_of_sub_assembly_item_based_on_bom = 0 bom.set_rate_of_sub_assembly_item_based_on_bom = 0
@ -174,6 +211,7 @@ class TestBOM(FrappeTestCase):
self.assertEqual(bom.items[0].rate, 20) self.assertEqual(bom.items[0].rate, 20)
@timeout
def test_bom_cost_with_fg_based_operating_cost(self): def test_bom_cost_with_fg_based_operating_cost(self):
bom = frappe.copy_doc(test_records[4]) bom = frappe.copy_doc(test_records[4])
bom.insert() bom.insert()
@ -201,6 +239,7 @@ class TestBOM(FrappeTestCase):
self.assertAlmostEqual(bom.base_raw_material_cost, base_raw_material_cost) self.assertAlmostEqual(bom.base_raw_material_cost, base_raw_material_cost)
self.assertAlmostEqual(bom.base_total_cost, base_raw_material_cost + base_op_cost) self.assertAlmostEqual(bom.base_total_cost, base_raw_material_cost + base_op_cost)
@timeout
def test_subcontractor_sourced_item(self): def test_subcontractor_sourced_item(self):
item_code = "_Test Subcontracted FG Item 1" item_code = "_Test Subcontracted FG Item 1"
set_backflush_based_on("Material Transferred for Subcontract") set_backflush_based_on("Material Transferred for Subcontract")
@ -282,6 +321,7 @@ class TestBOM(FrappeTestCase):
supplied_items = sorted([d.rm_item_code for d in sco.supplied_items]) supplied_items = sorted([d.rm_item_code for d in sco.supplied_items])
self.assertEqual(bom_items, supplied_items) self.assertEqual(bom_items, supplied_items)
@timeout
def test_bom_tree_representation(self): def test_bom_tree_representation(self):
bom_tree = { bom_tree = {
"Assembly": { "Assembly": {
@ -307,6 +347,7 @@ class TestBOM(FrappeTestCase):
for reqd_item, created_item in zip(reqd_order, created_order): for reqd_item, created_item in zip(reqd_order, created_order):
self.assertEqual(reqd_item, created_item.item_code) self.assertEqual(reqd_item, created_item.item_code)
@timeout
def test_generated_variant_bom(self): def test_generated_variant_bom(self):
from erpnext.controllers.item_variant import create_variant from erpnext.controllers.item_variant import create_variant
@ -347,6 +388,7 @@ class TestBOM(FrappeTestCase):
self.assertEqual(reqd_item.qty, created_item.qty) self.assertEqual(reqd_item.qty, created_item.qty)
self.assertEqual(reqd_item.exploded_qty, created_item.exploded_qty) self.assertEqual(reqd_item.exploded_qty, created_item.exploded_qty)
@timeout
def test_bom_recursion_1st_level(self): def test_bom_recursion_1st_level(self):
"""BOM should not allow BOM item again in child""" """BOM should not allow BOM item again in child"""
item_code = make_item(properties={"is_stock_item": 1}).name item_code = make_item(properties={"is_stock_item": 1}).name
@ -359,6 +401,7 @@ class TestBOM(FrappeTestCase):
bom.items[0].bom_no = bom.name bom.items[0].bom_no = bom.name
bom.save() bom.save()
@timeout
def test_bom_recursion_transitive(self): def test_bom_recursion_transitive(self):
item1 = make_item(properties={"is_stock_item": 1}).name item1 = make_item(properties={"is_stock_item": 1}).name
item2 = make_item(properties={"is_stock_item": 1}).name item2 = make_item(properties={"is_stock_item": 1}).name
@ -380,6 +423,7 @@ class TestBOM(FrappeTestCase):
bom1.save() bom1.save()
bom2.save() bom2.save()
@timeout
def test_bom_with_process_loss_item(self): def test_bom_with_process_loss_item(self):
fg_item_non_whole, fg_item_whole, bom_item = create_process_loss_bom_items() fg_item_non_whole, fg_item_whole, bom_item = create_process_loss_bom_items()
@ -393,6 +437,7 @@ class TestBOM(FrappeTestCase):
# Items with whole UOMs can't be PL Items # Items with whole UOMs can't be PL Items
self.assertRaises(frappe.ValidationError, bom_doc.submit) self.assertRaises(frappe.ValidationError, bom_doc.submit)
@timeout
def test_bom_item_query(self): def test_bom_item_query(self):
query = partial( query = partial(
item_query, item_query,
@ -412,6 +457,7 @@ class TestBOM(FrappeTestCase):
) )
self.assertTrue(0 < len(filtered) <= 3, msg="Item filtering showing excessive results") self.assertTrue(0 < len(filtered) <= 3, msg="Item filtering showing excessive results")
@timeout
def test_exclude_exploded_items_from_bom(self): def test_exclude_exploded_items_from_bom(self):
bom_no = get_default_bom() bom_no = get_default_bom()
new_bom = frappe.copy_doc(frappe.get_doc("BOM", bom_no)) new_bom = frappe.copy_doc(frappe.get_doc("BOM", bom_no))
@ -430,6 +476,7 @@ class TestBOM(FrappeTestCase):
new_bom.delete() new_bom.delete()
@timeout
def test_valid_transfer_defaults(self): def test_valid_transfer_defaults(self):
bom_with_op = frappe.db.get_value( bom_with_op = frappe.db.get_value(
"BOM", {"item": "_Test FG Item 2", "with_operations": 1, "is_active": 1} "BOM", {"item": "_Test FG Item 2", "with_operations": 1, "is_active": 1}
@ -461,11 +508,13 @@ class TestBOM(FrappeTestCase):
self.assertEqual(bom.transfer_material_against, "Work Order") self.assertEqual(bom.transfer_material_against, "Work Order")
bom.delete() bom.delete()
@timeout
def test_bom_name_length(self): def test_bom_name_length(self):
"""test >140 char names""" """test >140 char names"""
bom_tree = {"x" * 140: {" ".join(["abc"] * 35): {}}} bom_tree = {"x" * 140: {" ".join(["abc"] * 35): {}}}
create_nested_bom(bom_tree, prefix="") create_nested_bom(bom_tree, prefix="")
@timeout
def test_version_index(self): def test_version_index(self):
bom = frappe.new_doc("BOM") bom = frappe.new_doc("BOM")
@ -487,6 +536,7 @@ class TestBOM(FrappeTestCase):
msg=f"Incorrect index for {existing_boms}", msg=f"Incorrect index for {existing_boms}",
) )
@timeout
def test_bom_versioning(self): def test_bom_versioning(self):
bom_tree = {frappe.generate_hash(length=10): {frappe.generate_hash(length=10): {}}} bom_tree = {frappe.generate_hash(length=10): {frappe.generate_hash(length=10): {}}}
bom = create_nested_bom(bom_tree, prefix="") bom = create_nested_bom(bom_tree, prefix="")
@ -519,6 +569,7 @@ class TestBOM(FrappeTestCase):
self.assertNotEqual(amendment.name, version.name) self.assertNotEqual(amendment.name, version.name)
self.assertEqual(int(version.name.split("-")[-1]), 2) self.assertEqual(int(version.name.split("-")[-1]), 2)
@timeout
def test_clear_inpection_quality(self): def test_clear_inpection_quality(self):
bom = frappe.copy_doc(test_records[2], ignore_no_copy=True) bom = frappe.copy_doc(test_records[2], ignore_no_copy=True)
@ -537,6 +588,7 @@ class TestBOM(FrappeTestCase):
self.assertEqual(bom.quality_inspection_template, None) self.assertEqual(bom.quality_inspection_template, None)
@timeout
def test_bom_pricing_based_on_lpp(self): def test_bom_pricing_based_on_lpp(self):
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
@ -557,6 +609,7 @@ class TestBOM(FrappeTestCase):
bom.submit() bom.submit()
self.assertEqual(bom.items[0].rate, 42) self.assertEqual(bom.items[0].rate, 42)
@timeout
def test_set_default_bom_for_item_having_single_bom(self): def test_set_default_bom_for_item_having_single_bom(self):
from erpnext.stock.doctype.item.test_item import make_item from erpnext.stock.doctype.item.test_item import make_item
@ -593,6 +646,7 @@ class TestBOM(FrappeTestCase):
bom.reload() bom.reload()
self.assertEqual(frappe.get_value("Item", fg_item.item_code, "default_bom"), bom.name) self.assertEqual(frappe.get_value("Item", fg_item.item_code, "default_bom"), bom.name)
@timeout
def test_exploded_items_rate(self): def test_exploded_items_rate(self):
rm_item = make_item( rm_item = make_item(
properties={"is_stock_item": 1, "valuation_rate": 99, "last_purchase_rate": 89} properties={"is_stock_item": 1, "valuation_rate": 99, "last_purchase_rate": 89}
@ -621,6 +675,7 @@ class TestBOM(FrappeTestCase):
bom.submit() bom.submit()
self.assertEqual(bom.exploded_items[0].rate, bom.items[0].base_rate) self.assertEqual(bom.exploded_items[0].rate, bom.items[0].base_rate)
@timeout
def test_bom_cost_update_flag(self): def test_bom_cost_update_flag(self):
rm_item = make_item( rm_item = make_item(
properties={"is_stock_item": 1, "valuation_rate": 99, "last_purchase_rate": 89} properties={"is_stock_item": 1, "valuation_rate": 99, "last_purchase_rate": 89}

View File

@ -2,7 +2,7 @@
# License: GNU General Public License v3. See license.txt # License: GNU General Public License v3. See license.txt
import frappe import frappe
from frappe.tests.utils import FrappeTestCase from frappe.tests.utils import FrappeTestCase, timeout
from erpnext.manufacturing.doctype.bom_update_log.test_bom_update_log import ( from erpnext.manufacturing.doctype.bom_update_log.test_bom_update_log import (
update_cost_in_all_boms_in_test, update_cost_in_all_boms_in_test,
@ -20,6 +20,7 @@ class TestBOMUpdateTool(FrappeTestCase):
def tearDown(self): def tearDown(self):
frappe.db.rollback() frappe.db.rollback()
@timeout
def test_replace_bom(self): def test_replace_bom(self):
current_bom = "BOM-_Test Item Home Desktop Manufactured-001" current_bom = "BOM-_Test Item Home Desktop Manufactured-001"
@ -33,6 +34,7 @@ class TestBOMUpdateTool(FrappeTestCase):
self.assertFalse(frappe.db.exists("BOM Item", {"bom_no": current_bom, "docstatus": 1})) self.assertFalse(frappe.db.exists("BOM Item", {"bom_no": current_bom, "docstatus": 1}))
self.assertTrue(frappe.db.exists("BOM Item", {"bom_no": bom_doc.name, "docstatus": 1})) self.assertTrue(frappe.db.exists("BOM Item", {"bom_no": bom_doc.name, "docstatus": 1}))
@timeout
def test_bom_cost(self): def test_bom_cost(self):
for item in ["BOM Cost Test Item 1", "BOM Cost Test Item 2", "BOM Cost Test Item 3"]: for item in ["BOM Cost Test Item 1", "BOM Cost Test Item 2", "BOM Cost Test Item 3"]:
item_doc = create_item(item, valuation_rate=100) item_doc = create_item(item, valuation_rate=100)