mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-08-23 06:37:10 +00:00
Test fixes
This commit is contained in:
@@ -66,7 +66,7 @@ echo "-------------------- Running rest of tests in parallel -------------------
|
||||
# REMOVE_REQUESTS_OLD_SCREENSHOTS disabled so that we can write a screenshot and send it in test_notifications.py without a real browser
|
||||
REMOVE_REQUESTS_OLD_SCREENSHOTS=false \
|
||||
pytest tests/test_*.py \
|
||||
-n 30 \
|
||||
-n 16 \
|
||||
--dist=load \
|
||||
-vvv \
|
||||
-s \
|
||||
|
||||
@@ -166,6 +166,9 @@ class ChangeDetectionStore(DatastoreUpdatesMixin, FileSavingDataStore):
|
||||
"""
|
||||
logger.info(f"Datastore path is '{datastore_path}'")
|
||||
|
||||
# CRITICAL: Update datastore_path (was using old path from __init__)
|
||||
self.datastore_path = datastore_path
|
||||
|
||||
# Initialize data structure
|
||||
self.__data = App.model()
|
||||
self.json_store_path = os.path.join(self.datastore_path, "changedetection.json")
|
||||
|
||||
@@ -175,31 +175,55 @@ def prepare_test_function(live_server, datastore_path):
|
||||
# CRITICAL: Get datastore and stop it from writing stale data
|
||||
datastore = live_server.app.config.get('DATASTORE')
|
||||
|
||||
# Clear the queue before starting the test to prevent state leakage
|
||||
from changedetectionio.flask_app import update_q
|
||||
# CRITICAL: Clear ALL global state that persists between tests
|
||||
from changedetectionio.flask_app import update_q, notification_q, notification_debug_log
|
||||
|
||||
# Clear update queue
|
||||
while not update_q.empty():
|
||||
try:
|
||||
update_q.get_nowait()
|
||||
except:
|
||||
break
|
||||
|
||||
# Clear notification queue (was missing!)
|
||||
while not notification_q.empty():
|
||||
try:
|
||||
notification_q.get_nowait()
|
||||
except:
|
||||
break
|
||||
|
||||
# Clear notification debug log (accumulates across tests!)
|
||||
notification_debug_log.clear()
|
||||
|
||||
# Clear SALTED_PASS env var if set by previous test
|
||||
if 'SALTED_PASS' in os.environ:
|
||||
del os.environ['SALTED_PASS']
|
||||
|
||||
# Stop background thread with longer timeout
|
||||
datastore.stop_thread = True
|
||||
if hasattr(datastore, 'save_data_thread') and datastore.save_data_thread:
|
||||
datastore.save_data_thread.join(timeout=2.0)
|
||||
|
||||
# Prevent background thread from writing during cleanup/reload
|
||||
datastore.needs_write = False
|
||||
datastore.needs_write_urgent = False
|
||||
|
||||
# Reset dirty tracking
|
||||
datastore._dirty_watches = set()
|
||||
datastore._dirty_settings = False
|
||||
datastore._watch_hashes = {}
|
||||
|
||||
# CRITICAL: Clean up any files from previous tests
|
||||
# This ensures a completely clean directory
|
||||
cleanup(datastore_path)
|
||||
|
||||
# CRITICAL: Reload the EXISTING datastore instead of creating a new one
|
||||
# This keeps blueprint references valid (they capture datastore at construction)
|
||||
# reload_state() completely resets the datastore to a clean state
|
||||
# Reset stop_thread so reload_state can start new thread
|
||||
datastore.stop_thread = False
|
||||
|
||||
# Reload state with clean data (no default watches)
|
||||
datastore.reload_state(
|
||||
datastore_path=datastore_path,
|
||||
include_default_watches=False,
|
||||
version_tag=datastore.data.get('version_tag', '0.0.0')
|
||||
version_tag='0.0.0'
|
||||
)
|
||||
live_server.app.secret_key = init_app_secret(datastore_path)
|
||||
logger.debug(f"prepare_test_function: Reloaded datastore at {hex(id(datastore))}")
|
||||
|
||||
@@ -142,7 +142,7 @@ def test_tag_import_singular(client, live_server, measure_memory_usage, datastor
|
||||
)
|
||||
# Should be only 1 tag because they both had the same
|
||||
assert len(live_server.app.config['DATASTORE'].data['settings']['application'].get('tags')) ==1
|
||||
|
||||
wait_for_all_checks()
|
||||
delete_all_watches(client)
|
||||
|
||||
def test_tag_add_in_ui(client, live_server, measure_memory_usage, datastore_path):
|
||||
|
||||
@@ -213,6 +213,7 @@ def test_method_in_request(client, live_server, measure_memory_usage, datastore_
|
||||
follow_redirects=True
|
||||
)
|
||||
assert b"Updated watch." in res.data
|
||||
res = client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||
|
||||
# Give the thread time to pick up the first version
|
||||
wait_for_all_checks(client)
|
||||
|
||||
@@ -236,22 +236,17 @@ def test_restock_itemprop_with_tag(client, live_server, measure_memory_usage, da
|
||||
|
||||
def test_itemprop_percent_threshold(client, live_server, measure_memory_usage, datastore_path):
|
||||
|
||||
delete_all_watches(client)
|
||||
|
||||
test_url = url_for('test_endpoint', _external=True)
|
||||
|
||||
set_original_response(props_markup=instock_props[0], price="950.95", datastore_path=datastore_path)
|
||||
client.post(
|
||||
url_for("ui.ui_views.form_quick_watch_add"),
|
||||
data={"url": test_url, "tags": 'restock tests', 'processor': 'restock_diff'},
|
||||
follow_redirects=True
|
||||
)
|
||||
uuid = client.application.config.get('DATASTORE').add_watch(url=test_url, tag="restock tests", extras={'processor':"restock_diff"})
|
||||
res = client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||
|
||||
# A change in price, should trigger a change by default
|
||||
wait_for_all_checks(client)
|
||||
|
||||
res = client.post(
|
||||
url_for("ui.ui_edit.edit_page", uuid="first"),
|
||||
url_for("ui.ui_edit.edit_page", uuid=uuid),
|
||||
data={"restock_settings-follow_price_changes": "y",
|
||||
"restock_settings-price_change_threshold_percent": 5.0,
|
||||
"url": test_url,
|
||||
@@ -295,7 +290,6 @@ def test_itemprop_percent_threshold(client, live_server, measure_memory_usage, d
|
||||
|
||||
# Re #2600 - Switch the mode to normal type and back, and see if the values stick..
|
||||
###################################################################################
|
||||
uuid = next(iter(live_server.app.config['DATASTORE'].data['watching']))
|
||||
|
||||
res = client.post(
|
||||
url_for("ui.ui_edit.edit_page", uuid=uuid),
|
||||
@@ -314,9 +308,6 @@ def test_itemprop_percent_threshold(client, live_server, measure_memory_usage, d
|
||||
res = client.get(url_for("ui.ui_edit.edit_page", uuid=uuid))
|
||||
assert b'type="text" value="5.05"' in res.data
|
||||
|
||||
delete_all_watches(client)
|
||||
|
||||
|
||||
|
||||
def test_change_with_notification_values(client, live_server, measure_memory_usage, datastore_path):
|
||||
|
||||
@@ -390,16 +381,11 @@ def test_change_with_notification_values(client, live_server, measure_memory_usa
|
||||
def test_data_sanity(client, live_server, measure_memory_usage, datastore_path):
|
||||
|
||||
|
||||
delete_all_watches(client)
|
||||
|
||||
test_url = url_for('test_endpoint', _external=True)
|
||||
test_url2 = url_for('test_endpoint2', _external=True)
|
||||
set_original_response(props_markup=instock_props[0], price="950.95", datastore_path=datastore_path)
|
||||
client.post(
|
||||
url_for("ui.ui_views.form_quick_watch_add"),
|
||||
data={"url": test_url, "tags": 'restock tests', 'processor': 'restock_diff'},
|
||||
follow_redirects=True
|
||||
)
|
||||
uuid = client.application.config.get('DATASTORE').add_watch(url=test_url, tag="restock tests", extras={'processor':"restock_diff"})
|
||||
res = client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||
|
||||
|
||||
wait_for_all_checks(client)
|
||||
@@ -418,16 +404,12 @@ def test_data_sanity(client, live_server, measure_memory_usage, datastore_path):
|
||||
|
||||
## different test, check the edit page works on an empty request result
|
||||
delete_all_watches(client)
|
||||
|
||||
client.post(
|
||||
url_for("ui.ui_views.form_quick_watch_add"),
|
||||
data={"url": test_url2, "tags": 'restock tests', 'processor': 'restock_diff'},
|
||||
follow_redirects=True
|
||||
)
|
||||
uuid = client.application.config.get('DATASTORE').add_watch(url=test_url2, tag="restock tests", extras={'processor':"restock_diff"})
|
||||
res = client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||
wait_for_all_checks(client)
|
||||
|
||||
res = client.get(
|
||||
url_for("ui.ui_edit.edit_page", uuid="first"))
|
||||
url_for("ui.ui_edit.edit_page", uuid=uuid))
|
||||
assert test_url2.encode('utf-8') in res.data
|
||||
|
||||
delete_all_watches(client)
|
||||
|
||||
@@ -144,7 +144,7 @@ def wait_for_all_checks(client=None):
|
||||
"""
|
||||
from changedetectionio.flask_app import update_q as global_update_q
|
||||
from changedetectionio import worker_pool
|
||||
time.sleep(0.05)
|
||||
time.sleep(0.15)
|
||||
# Use the shared wait logic from worker_handler
|
||||
return worker_pool.wait_for_all_checks(global_update_q, timeout=150)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user