Files
rasahq--rasa/tests/engine/storage/test_local_model_storage.py
wehub-resource-sync dc6079821b
Docs Tests / Check for file changes (push) Has been cancelled
Docs Tests / Test Documentation (push) Has been cancelled
Docs Tests / Documentation Linting Checks (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.9) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.9) (push) Has been cancelled
Continuous Integration / Check for file changes (push) Has been cancelled
Continuous Integration / Wait for docs tests (push) Has been cancelled
Continuous Integration / Code Quality (push) Has been cancelled
Continuous Integration / Check for changelog (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Upload coverage reports to codeclimate (push) Has been cancelled
Continuous Integration / Run Non-Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Run Broker Integration Tests (push) Has been cancelled
Continuous Integration / Run Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Build Docker base images and setup environment (push) Has been cancelled
Continuous Integration / Build Docker (default) (push) Has been cancelled
Continuous Integration / Build Docker (full) (push) Has been cancelled
Continuous Integration / Build Docker (mitie-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-de) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-it) (push) Has been cancelled
Continuous Integration / Deploy to PyPI (push) Has been cancelled
Continuous Integration / Notify Slack & Publish Release Notes (push) Has been cancelled
Publish Documentation / Evaluate release tag (push) Has been cancelled
Publish Documentation / Prebuild Docs (push) Has been cancelled
Publish Documentation / Preview Docs (push) Has been cancelled
Publish Documentation / Check for file changes (push) Has been cancelled
Publish Documentation / Publish Docs (push) Has been cancelled
Automatic PR Merger / mergepal (push) Has been cancelled
CI Github Actions / Run Tests (push) Has been cancelled
Semgrep / Semgrep Workflow Security Scan (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:24:47 +08:00

369 lines
12 KiB
Python

import sys
import uuid
from datetime import datetime
from pathlib import Path
import freezegun
import pytest
from _pytest.monkeypatch import MonkeyPatch
from _pytest.tmpdir import TempPathFactory
from tarsafe import TarSafe
import rasa.shared.utils.io
from rasa.engine.graph import GraphModelConfiguration, GraphSchema, SchemaNode
from rasa.engine.storage.local_model_storage import (
MODEL_ARCHIVE_METADATA_FILE,
LocalModelStorage,
)
from rasa.engine.storage.resource import Resource
from rasa.engine.storage.storage import ModelMetadata, ModelStorage
from rasa.exceptions import UnsupportedModelVersionError
from rasa.shared.core.domain import Domain
from rasa.shared.data import TrainingType
from tests.engine.graph_components_test_classes import PersistableTestComponent
def test_write_to_and_read(default_model_storage: ModelStorage):
test_filename = "file.txt"
test_file_content = "hi"
test_sub_filename = "sub_file"
test_sub_dir_name = "sub_directory"
test_sub_file_content = "sub file"
resource = Resource("some_node123")
# Fill model storage for resource
with default_model_storage.write_to(resource) as resource_directory:
file = resource_directory / test_filename
file.write_text(test_file_content)
sub_directory = resource_directory / test_sub_dir_name
sub_directory.mkdir()
file_in_sub_directory = sub_directory / test_sub_filename
file_in_sub_directory.write_text(test_sub_file_content)
# Read written resource data from model storage to see whether all expected
# content is there
with default_model_storage.read_from(resource) as resource_directory:
assert (resource_directory / test_filename).read_text() == test_file_content
assert (
resource_directory / test_sub_dir_name / test_sub_filename
).read_text() == test_sub_file_content
def test_read_from_not_existing_resource(default_model_storage: ModelStorage):
with default_model_storage.write_to(Resource("resource1")) as temporary_directory:
file = temporary_directory / "file.txt"
file.write_text("test")
with pytest.raises(ValueError):
with default_model_storage.read_from(Resource("a different resource")) as _:
pass
def test_read_from_rasa2_resource(tmp_path_factory: TempPathFactory):
# we only search for the fingerprint file - nlu and core folder do not even need
# to exist
model_dir = tmp_path_factory.mktemp("model_dir")
version = "2.8.5"
rasa.shared.utils.io.dump_obj_as_json_to_file(
model_dir / "fingerprint.json",
{"version": version, "irrelevant-other-key": "bla"},
)
model_zips = tmp_path_factory.mktemp("model_zips")
resource_name = "model"
with TarSafe.open(model_zips / resource_name, "w:gz") as tar:
tar.add(model_dir, arcname="")
storage_dir = tmp_path_factory.mktemp("storage_dir")
storage = LocalModelStorage(storage_path=storage_dir)
with pytest.raises(UnsupportedModelVersionError, match=f".*{version}.*"):
storage.from_model_archive(
storage_path=storage_dir, model_archive_path=model_zips / resource_name
)
with pytest.raises(UnsupportedModelVersionError, match=f".*{version}.*"):
storage.metadata_from_archive(model_archive_path=model_zips / resource_name)
@pytest.mark.skipif(
sys.platform != "win32",
reason="no need to run this test on other platform than Windows",
)
def test_read_long_resource_names_windows(
tmp_path_factory: TempPathFactory,
domain: Domain,
):
model_dir = tmp_path_factory.mktemp("model_dir")
version = "3.6.21"
# full path length > 260 chars
# but each component of the path needs to be below 255 chars
# https://bugs.python.org/issue542314#msg10256
long_file_path = model_dir / f"{'custom_file' * 22}.json"
rasa.shared.utils.io.dump_obj_as_json_to_file(
Path(f"\\\\?\\{long_file_path}"),
{"irrelevant-key": "bla"},
)
train_schema = GraphSchema(
{
"train": SchemaNode(
needs={},
uses=PersistableTestComponent,
fn="train",
constructor_name="create",
config={"some_config": 123455, "some more config": [{"nested": "hi"}]},
),
"load": SchemaNode(
needs={"resource": "train"},
uses=PersistableTestComponent,
fn="run_inference",
constructor_name="load",
config={},
is_target=True,
),
}
)
predict_schema = GraphSchema(
{
"run": SchemaNode(
needs={},
uses=PersistableTestComponent,
fn="run",
constructor_name="load",
config={"some_config": 123455, "some more config": [{"nested": "hi"}]},
)
}
)
rasa.shared.utils.io.dump_obj_as_json_to_file(
model_dir / MODEL_ARCHIVE_METADATA_FILE,
ModelMetadata(
trained_at=datetime.utcnow(),
rasa_open_source_version=version,
model_id="xxxxxxx",
assistant_id="test_assistant",
domain=domain,
train_schema=train_schema,
predict_schema=predict_schema,
project_fingerprint="xxxxxxx",
core_target="",
nlu_target="",
language="en",
training_type=TrainingType.BOTH,
).as_dict(),
)
model_zips = tmp_path_factory.mktemp("model_zips")
resource_name = "model"
with TarSafe.open(model_zips / resource_name, "w:gz") as tar:
tar.add(Path(f"\\\\?\\{model_dir}"), arcname="")
storage_dir = tmp_path_factory.mktemp("storage_dir")
storage = LocalModelStorage(storage_path=storage_dir)
storage.metadata_from_archive(model_archive_path=model_zips / resource_name)
def test_create_model_package(tmp_path_factory: TempPathFactory, domain: Domain):
train_model_storage = LocalModelStorage(
tmp_path_factory.mktemp("train model storage")
)
train_schema = GraphSchema(
{
"train": SchemaNode(
needs={},
uses=PersistableTestComponent,
fn="train",
constructor_name="create",
config={"some_config": 123455, "some more config": [{"nested": "hi"}]},
),
"load": SchemaNode(
needs={"resource": "train"},
uses=PersistableTestComponent,
fn="run_inference",
constructor_name="load",
config={},
is_target=True,
),
}
)
predict_schema = GraphSchema(
{
"run": SchemaNode(
needs={},
uses=PersistableTestComponent,
fn="run",
constructor_name="load",
config={"some_config": 123455, "some more config": [{"nested": "hi"}]},
)
}
)
# Fill model Storage
with train_model_storage.write_to(Resource("resource1")) as directory:
file = directory / "file.txt"
file.write_text("test")
# Package model
persisted_model_dir = tmp_path_factory.mktemp("persisted models")
archive_path = persisted_model_dir / "my-model.tar.gz"
trained_at = datetime.utcnow()
with freezegun.freeze_time(trained_at):
train_model_storage.create_model_package(
archive_path,
GraphModelConfiguration(
train_schema,
predict_schema,
TrainingType.BOTH,
"test_assistant",
None,
None,
"nlu",
),
domain,
)
# Unpack and inspect packaged model
load_model_storage_dir = tmp_path_factory.mktemp("load model storage")
just_packaged_metadata = LocalModelStorage.metadata_from_archive(archive_path)
(load_model_storage, packaged_metadata) = LocalModelStorage.from_model_archive(
load_model_storage_dir, archive_path
)
assert just_packaged_metadata.trained_at == packaged_metadata.trained_at
assert packaged_metadata.train_schema == train_schema
assert packaged_metadata.predict_schema == predict_schema
assert packaged_metadata.domain.as_dict() == domain.as_dict()
assert packaged_metadata.rasa_open_source_version == rasa.__version__
assert packaged_metadata.trained_at == trained_at
assert packaged_metadata.model_id
assert packaged_metadata.assistant_id == "test_assistant"
assert packaged_metadata.project_fingerprint
persisted_resources = load_model_storage_dir.glob("*")
assert list(persisted_resources) == [Path(load_model_storage_dir, "resource1")]
def test_read_unsupported_model(
monkeypatch: MonkeyPatch, tmp_path_factory: TempPathFactory, domain: Domain
):
train_model_storage = LocalModelStorage(
tmp_path_factory.mktemp("train model storage")
)
graph_schema = GraphSchema(nodes={})
persisted_model_dir = tmp_path_factory.mktemp("persisted models")
archive_path = persisted_model_dir / "my-model.tar.gz"
# Create outdated model meta data
trained_at = datetime.utcnow()
model_configuration = GraphModelConfiguration(
graph_schema,
graph_schema,
TrainingType.BOTH,
"test_assistant",
None,
None,
"nlu",
)
outdated_model_meta_data = ModelMetadata(
trained_at=trained_at,
rasa_open_source_version=rasa.__version__, # overwrite later to avoid error
model_id=uuid.uuid4().hex,
assistant_id=model_configuration.assistant_id,
domain=domain,
train_schema=model_configuration.train_schema,
predict_schema=model_configuration.predict_schema,
training_type=model_configuration.training_type,
project_fingerprint=rasa.model.project_fingerprint(),
language=model_configuration.language,
core_target=model_configuration.core_target,
nlu_target=model_configuration.nlu_target,
)
old_version = "0.0.1"
outdated_model_meta_data.rasa_open_source_version = old_version
# Package model - and inject the outdated model meta data
monkeypatch.setattr(
LocalModelStorage,
"_create_model_metadata",
lambda *args, **kwargs: outdated_model_meta_data,
)
train_model_storage.create_model_package(
model_archive_path=archive_path,
model_configuration=model_configuration,
domain=domain,
)
# Unpack and inspect packaged model
load_model_storage_dir = tmp_path_factory.mktemp("load model storage")
expected_message = (
f"The model version is trained using Rasa Open Source "
f"{old_version} and is not compatible with your current "
f"installation .*"
)
with pytest.raises(UnsupportedModelVersionError, match=expected_message):
LocalModelStorage.metadata_from_archive(archive_path)
with pytest.raises(UnsupportedModelVersionError, match=expected_message):
LocalModelStorage.from_model_archive(load_model_storage_dir, archive_path)
def test_create_package_with_non_existing_parent(tmp_path: Path):
storage = LocalModelStorage.create(tmp_path)
model_file = tmp_path / "new" / "sub" / "dir" / "file.tar.gz"
storage.create_model_package(
model_file,
GraphModelConfiguration(
GraphSchema({}),
GraphSchema({}),
TrainingType.BOTH,
"test_assistant",
None,
None,
"nlu",
),
Domain.empty(),
)
assert model_file.is_file()
def test_create_model_package_with_non_empty_model_storage(tmp_path: Path):
# Put something in the future model storage directory
(tmp_path / "somefile.json").touch()
with pytest.raises(ValueError):
# Unpacking into an already filled `ModelStorage` raises an exception.
_ = LocalModelStorage.from_model_archive(tmp_path, Path("does not matter"))
def test_create_model_package_with_non_existing_dir(
tmp_path: Path, default_model_storage: ModelStorage
):
path = tmp_path / "some_dir" / "another" / "model.tar.gz"
default_model_storage.create_model_package(
path,
GraphModelConfiguration(
GraphSchema({}),
GraphSchema({}),
TrainingType.BOTH,
"test_assistant",
None,
None,
"nlu",
),
Domain.empty(),
)
assert path.exists()