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
369 lines
12 KiB
Python
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()
|