Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 24 additions & 20 deletions tests/others/test_check_copies.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
import re
import shutil
import sys
import tempfile
import unittest

import pytest


git_repo_path = os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
Expand Down Expand Up @@ -45,56 +45,58 @@
"""


class CopyCheckTester(unittest.TestCase):
def setUp(self):
self.diffusers_dir = tempfile.mkdtemp()
os.makedirs(os.path.join(self.diffusers_dir, "schedulers/"))
check_copies.DIFFUSERS_PATH = self.diffusers_dir
class TestCopyCheck:
@pytest.fixture
def diffusers_dir(self, tmp_path, monkeypatch):
"""A stand-in `src/diffusers` holding only `scheduling_ddpm.py`, pointed at by `check_copies`."""
os.makedirs(tmp_path / "schedulers")
shutil.copy(
os.path.join(git_repo_path, "src/diffusers/schedulers/scheduling_ddpm.py"),
os.path.join(self.diffusers_dir, "schedulers/scheduling_ddpm.py"),
tmp_path / "schedulers" / "scheduling_ddpm.py",
)
monkeypatch.setattr(check_copies, "DIFFUSERS_PATH", str(tmp_path))
return tmp_path

def tearDown(self):
check_copies.DIFFUSERS_PATH = "src/diffusers"
shutil.rmtree(self.diffusers_dir)

def check_copy_consistency(self, comment, class_name, class_code, overwrite_result=None):
def check_copy_consistency(self, diffusers_dir, comment, class_name, class_code, overwrite_result=None):
code = comment + f"\nclass {class_name}(nn.Module):\n" + class_code
if overwrite_result is not None:
expected = comment + f"\nclass {class_name}(nn.Module):\n" + overwrite_result
code = check_copies.run_ruff(code)
fname = os.path.join(self.diffusers_dir, "new_code.py")
fname = diffusers_dir / "new_code.py"
with open(fname, "w", newline="\n") as f:
f.write(code)
if overwrite_result is None:
self.assertTrue(len(check_copies.is_copy_consistent(fname)) == 0)
assert len(check_copies.is_copy_consistent(fname)) == 0
else:
check_copies.is_copy_consistent(f.name, overwrite=True)
check_copies.is_copy_consistent(fname, overwrite=True)
with open(fname, "r") as f:
self.assertTrue(f.read(), expected)
assert f.read() == expected

def test_find_code_in_diffusers(self):
def test_find_code_in_diffusers(self, diffusers_dir):
# `diffusers_dir` is requested for its `DIFFUSERS_PATH` patch — the lookup below resolves against it.
code = check_copies.find_code_in_diffusers("schedulers.scheduling_ddpm.DDPMSchedulerOutput")
self.assertEqual(code, REFERENCE_CODE)
assert code == REFERENCE_CODE

def test_is_copy_consistent(self):
def test_is_copy_consistent(self, diffusers_dir):
# Base copy consistency
self.check_copy_consistency(
diffusers_dir,
"# Copied from diffusers.schedulers.scheduling_ddpm.DDPMSchedulerOutput",
"DDPMSchedulerOutput",
REFERENCE_CODE + "\n",
)

# With no empty line at the end
self.check_copy_consistency(
diffusers_dir,
"# Copied from diffusers.schedulers.scheduling_ddpm.DDPMSchedulerOutput",
"DDPMSchedulerOutput",
REFERENCE_CODE,
)

# Copy consistency with rename
self.check_copy_consistency(
diffusers_dir,
"# Copied from diffusers.schedulers.scheduling_ddpm.DDPMSchedulerOutput with DDPM->Test",
"TestSchedulerOutput",
re.sub("DDPM", "Test", REFERENCE_CODE),
Expand All @@ -103,13 +105,15 @@ def test_is_copy_consistent(self):
# Copy consistency with a really long name
long_class_name = "TestClassWithAReallyLongNameBecauseSomePeopleLikeThatForSomeReason"
self.check_copy_consistency(
diffusers_dir,
f"# Copied from diffusers.schedulers.scheduling_ddpm.DDPMSchedulerOutput with DDPM->{long_class_name}",
f"{long_class_name}SchedulerOutput",
re.sub("Bert", long_class_name, REFERENCE_CODE),
)

# Copy consistency with overwrite
self.check_copy_consistency(
diffusers_dir,
"# Copied from diffusers.schedulers.scheduling_ddpm.DDPMSchedulerOutput with DDPM->Test",
"TestSchedulerOutput",
REFERENCE_CODE,
Expand Down
37 changes: 17 additions & 20 deletions tests/others/test_check_dummies.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import os
import sys
import unittest


git_repo_path = os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
Expand All @@ -28,48 +27,46 @@
check_dummies.PATH_TO_DIFFUSERS = os.path.join(git_repo_path, "src", "diffusers")


class CheckDummiesTester(unittest.TestCase):
class TestCheckDummies:
def test_find_backend(self):
simple_backend = find_backend(" if not is_torch_available():")
self.assertEqual(simple_backend, "torch")
assert simple_backend == "torch"

# backend_with_underscore = find_backend(" if not is_tensorflow_text_available():")
# self.assertEqual(backend_with_underscore, "tensorflow_text")
# assert backend_with_underscore == "tensorflow_text"

double_backend = find_backend(" if not (is_torch_available() and is_transformers_available()):")
self.assertEqual(double_backend, "torch_and_transformers")
assert double_backend == "torch_and_transformers"

# double_backend_with_underscore = find_backend(
# " if not (is_sentencepiece_available() and is_tensorflow_text_available()):"
# )
# self.assertEqual(double_backend_with_underscore, "sentencepiece_and_tensorflow_text")
# assert double_backend_with_underscore == "sentencepiece_and_tensorflow_text"

triple_backend = find_backend(
" if not (is_torch_available() and is_transformers_available() and is_onnx_available()):"
)
self.assertEqual(triple_backend, "torch_and_transformers_and_onnx")
assert triple_backend == "torch_and_transformers_and_onnx"

def test_read_init(self):
objects = read_init()
# We don't assert on the exact list of keys to allow for smooth grow of backend-specific objects
self.assertIn("torch", objects)
self.assertIn("torch_and_transformers", objects)
self.assertIn("torch_and_transformers_and_onnx", objects)
assert "torch" in objects
assert "torch_and_transformers" in objects
assert "torch_and_transformers_and_onnx" in objects

# Likewise, we can't assert on the exact content of a key
self.assertIn("UNet2DModel", objects["torch"])
self.assertIn("StableDiffusionPipeline", objects["torch_and_transformers"])
self.assertIn("LMSDiscreteScheduler", objects["torch_and_scipy"])
self.assertIn("OnnxStableDiffusionPipeline", objects["torch_and_transformers_and_onnx"])
assert "UNet2DModel" in objects["torch"]
assert "StableDiffusionPipeline" in objects["torch_and_transformers"]
assert "LMSDiscreteScheduler" in objects["torch_and_scipy"]
assert "OnnxStableDiffusionPipeline" in objects["torch_and_transformers_and_onnx"]

def test_create_dummy_object(self):
dummy_constant = create_dummy_object("CONSTANT", "'torch'")
self.assertEqual(dummy_constant, "\nCONSTANT = None\n")
assert dummy_constant == "\nCONSTANT = None\n"

dummy_function = create_dummy_object("function", "'torch'")
self.assertEqual(
dummy_function, "\ndef function(*args, **kwargs):\n requires_backends(function, 'torch')\n"
)
assert dummy_function == "\ndef function(*args, **kwargs):\n requires_backends(function, 'torch')\n"

expected_dummy_class = """
class FakeClass(metaclass=DummyObject):
Expand All @@ -87,7 +84,7 @@ def from_pretrained(cls, *args, **kwargs):
requires_backends(cls, 'torch')
"""
dummy_class = create_dummy_object("FakeClass", "'torch'")
self.assertEqual(dummy_class, expected_dummy_class)
assert dummy_class == expected_dummy_class

def test_create_dummy_files(self):
expected_dummy_pytorch_file = """# This file is autogenerated by the command `make fix-copies`, do not edit.
Expand Down Expand Up @@ -116,4 +113,4 @@ def from_pretrained(cls, *args, **kwargs):
requires_backends(cls, ["torch"])
"""
dummy_files = create_dummy_files({"torch": ["CONSTANT", "function", "FakeClass"]})
self.assertEqual(dummy_files["torch"], expected_dummy_pytorch_file)
assert dummy_files["torch"] == expected_dummy_pytorch_file
23 changes: 11 additions & 12 deletions tests/others/test_check_support_list.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import sys
import unittest
from unittest.mock import mock_open, patch


Expand All @@ -10,10 +9,8 @@
from check_support_list import check_documentation # noqa: E402


class TestCheckSupportList(unittest.TestCase):
def setUp(self):
# Mock doc and source contents that we can reuse
self.doc_content = """# Documentation
# Mock doc and source contents that we can reuse
DOC_CONTENT = """# Documentation
## FooProcessor

[[autodoc]] module.FooProcessor
Expand All @@ -22,20 +19,22 @@ def setUp(self):

[[autodoc]] module.BarProcessor
"""
self.source_content = """
SOURCE_CONTENT = """
class FooProcessor(nn.Module):
pass

class BarProcessor(nn.Module):
pass
"""


class TestCheckSupportList:
def test_check_documentation_all_documented(self):
# In this test, both FooProcessor and BarProcessor are documented
with patch("builtins.open", mock_open(read_data=self.doc_content)) as doc_file:
with patch("builtins.open", mock_open(read_data=DOC_CONTENT)) as doc_file:
doc_file.side_effect = [
mock_open(read_data=self.doc_content).return_value,
mock_open(read_data=self.source_content).return_value,
mock_open(read_data=DOC_CONTENT).return_value,
mock_open(read_data=SOURCE_CONTENT).return_value,
]

undocumented = check_documentation(
Expand All @@ -44,7 +43,7 @@ def test_check_documentation_all_documented(self):
doc_regex=r"\[\[autodoc\]\]\s([^\n]+)",
src_regex=r"class\s+(\w+Processor)\(.*?nn\.Module.*?\):",
)
self.assertEqual(len(undocumented), 0, f"Expected no undocumented classes, got {undocumented}")
assert len(undocumented) == 0, f"Expected no undocumented classes, got {undocumented}"

def test_check_documentation_missing_class(self):
# In this test, only FooProcessor is documented, but BarProcessor is missing from the docs
Expand All @@ -56,7 +55,7 @@ def test_check_documentation_missing_class(self):
with patch("builtins.open", mock_open(read_data=doc_content_missing)) as doc_file:
doc_file.side_effect = [
mock_open(read_data=doc_content_missing).return_value,
mock_open(read_data=self.source_content).return_value,
mock_open(read_data=SOURCE_CONTENT).return_value,
]

undocumented = check_documentation(
Expand All @@ -65,4 +64,4 @@ def test_check_documentation_missing_class(self):
doc_regex=r"\[\[autodoc\]\]\s([^\n]+)",
src_regex=r"class\s+(\w+Processor)\(.*?nn\.Module.*?\):",
)
self.assertIn("BarProcessor", undocumented, f"BarProcessor should be undocumented, got {undocumented}")
assert "BarProcessor" in undocumented, f"BarProcessor should be undocumented, got {undocumented}"
30 changes: 14 additions & 16 deletions tests/others/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
# limitations under the License.

import json
import tempfile
import unittest
from pathlib import Path

import pytest

from diffusers import (
DDIMScheduler,
DDPMScheduler,
Expand Down Expand Up @@ -102,9 +102,9 @@ def __init__(self, test_file_1=Path("foo/bar"), test_file_2=Path("foo bar\\bar")
pass


class ConfigTester(unittest.TestCase):
class TestConfig:
def test_load_not_from_mixin(self):
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
ConfigMixin.load_config("dummy_path")

def test_register_to_config(self):
Expand Down Expand Up @@ -143,7 +143,7 @@ def test_register_to_config(self):
assert config["d"] == "for diffusion"
assert config["e"] == [1, 3]

def test_save_load(self):
def test_save_load(self, tmp_path):
obj = SampleObject()
config = obj.config

Expand All @@ -153,10 +153,9 @@ def test_save_load(self):
assert config["d"] == "for diffusion"
assert config["e"] == [1, 3]

with tempfile.TemporaryDirectory() as tmpdirname:
obj.save_config(tmpdirname)
new_obj = SampleObject.from_config(SampleObject.load_config(tmpdirname))
new_config = new_obj.config
obj.save_config(tmp_path)
new_obj = SampleObject.from_config(SampleObject.load_config(tmp_path))
new_config = new_obj.config

# unfreeze configs
config = dict(config)
Expand Down Expand Up @@ -262,7 +261,7 @@ def test_load_dpmsolver(self):
# no warning should be thrown
assert cap_logger.out == ""

def test_use_default_values(self):
def test_use_default_values(self, tmp_path):
# let's first save a config that should be in the form
# a=2,
# b=5,
Expand All @@ -277,14 +276,13 @@ def test_use_default_values(self):
# make sure that default config has all keys in `_use_default_values`
assert set(config_dict.keys()) == set(config.config._use_default_values)

with tempfile.TemporaryDirectory() as tmpdirname:
config.save_config(tmpdirname)
config.save_config(tmp_path)

# now loading it with SampleObject2 should put f into `_use_default_values`
config = SampleObject2.from_config(SampleObject2.load_config(tmpdirname))
# now loading it with SampleObject2 should put f into `_use_default_values`
config = SampleObject2.from_config(SampleObject2.load_config(tmp_path))

assert "f" in config.config._use_default_values
assert config.config.f == [1, 3]
assert "f" in config.config._use_default_values
assert config.config.f == [1, 3]

# now loading the config, should **NOT** use [1, 3] for `f`, but the default [1, 4] value
# **BECAUSE** it is part of `config.config._use_default_values`
Expand Down
Loading
Loading