| from typing import Any, Dict, List |
| import unittest |
| from PIL import Image |
| import numpy as np |
|
|
| import importlib |
|
|
| utils = importlib.import_module("extensions.sd-webui-controlnet.tests.utils", "utils") |
| utils.setup_test_env() |
|
|
| from scripts import external_code, processor |
| from scripts.controlnet import prepare_mask, Script, set_numpy_seed |
| from modules import processing |
|
|
|
|
| class TestPrepareMask(unittest.TestCase): |
| def test_prepare_mask(self): |
| p = processing.StableDiffusionProcessing() |
| p.inpainting_mask_invert = True |
| p.mask_blur = 5 |
|
|
| mask = Image.new("RGB", (10, 10), color="white") |
|
|
| processed_mask = prepare_mask(mask, p) |
|
|
| |
| self.assertTrue(processed_mask.mode, "L") |
|
|
| |
| self.assertEqual( |
| processed_mask.getpixel((0, 0)), 0 |
| ) |
|
|
| p.inpainting_mask_invert = False |
| processed_mask = prepare_mask(mask, p) |
|
|
| |
| self.assertEqual( |
| processed_mask.getpixel((0, 0)), 255 |
| ) |
|
|
| p.mask_blur = 0 |
| mask = Image.new("RGB", (10, 10), color="black") |
| processed_mask = prepare_mask(mask, p) |
|
|
| |
| self.assertEqual( |
| processed_mask.getpixel((0, 0)), 0 |
| ) |
|
|
|
|
| class TestSetNumpySeed(unittest.TestCase): |
| def test_seed_subseed_minus_one(self): |
| p = processing.StableDiffusionProcessing() |
| p.seed = -1 |
| p.subseed = -1 |
| p.all_seeds = [123, 456] |
| expected_seed = (123 + 123) & 0xFFFFFFFF |
| self.assertEqual(set_numpy_seed(p), expected_seed) |
|
|
| def test_valid_seed_subseed(self): |
| p = processing.StableDiffusionProcessing() |
| p.seed = 50 |
| p.subseed = 100 |
| p.all_seeds = [123, 456] |
| expected_seed = (50 + 100) & 0xFFFFFFFF |
| self.assertEqual(set_numpy_seed(p), expected_seed) |
|
|
| def test_invalid_seed_subseed(self): |
| p = processing.StableDiffusionProcessing() |
| p.seed = "invalid" |
| p.subseed = 2.5 |
| p.all_seeds = [123, 456] |
| self.assertEqual(set_numpy_seed(p), None) |
|
|
| def test_empty_all_seeds(self): |
| p = processing.StableDiffusionProcessing() |
| p.seed = -1 |
| p.subseed = 2 |
| p.all_seeds = [] |
| self.assertEqual(set_numpy_seed(p), None) |
|
|
| def test_random_state_change(self): |
| p = processing.StableDiffusionProcessing() |
| p.seed = 50 |
| p.subseed = 100 |
| p.all_seeds = [123, 456] |
| expected_seed = (50 + 100) & 0xFFFFFFFF |
|
|
| np.random.seed(0) |
| before_random = np.random.randint(0, 1000) |
|
|
| seed = set_numpy_seed(p) |
| self.assertEqual(seed, expected_seed) |
|
|
| after_random = np.random.randint(0, 1000) |
|
|
| self.assertNotEqual(before_random, after_random) |
|
|
|
|
| class MockImg2ImgProcessing(processing.StableDiffusionProcessing): |
| """Mock the Img2Img processing as the WebUI version have dependency on |
| `sd_model`.""" |
|
|
| def __init__(self, init_images, *args, **kwargs): |
| super().__init__(*args, **kwargs) |
| self.init_images = init_images |
|
|
|
|
| class TestScript(unittest.TestCase): |
| sample_base64_image = ( |
| "data:image/png;base64," |
| "iVBORw0KGgoAAAANSUhEUgAAARMAAAC3CAIAAAC+MS2jAAAAqUlEQVR4nO3BAQ" |
| "0AAADCoPdPbQ8HFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" |
| "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" |
| "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" |
| "AAAAAAAAAAAAAAAAAAAAAAAA/wZOlAAB5tU+nAAAAABJRU5ErkJggg==" |
| ) |
|
|
| sample_np_image = np.array( |
| [[100, 200, 50], [150, 75, 225], [30, 120, 180]], dtype=np.uint8 |
| ) |
|
|
| def test_bound_check_params(self): |
| def param_required(module: str, param: str) -> bool: |
| configs = processor.preprocessor_sliders_config[module] |
| config_index = ("processor_res", "threshold_a", "threshold_b").index(param) |
| return config_index < len(configs) and configs[config_index] is not None |
|
|
| for module in processor.preprocessor_sliders_config.keys(): |
| for param in ("processor_res", "threshold_a", "threshold_b"): |
| with self.subTest(param=param, module=module): |
| unit = external_code.ControlNetUnit( |
| module=module, |
| **{param: -100}, |
| ) |
| Script.bound_check_params(unit) |
| if param_required(module, param): |
| self.assertGreaterEqual(getattr(unit, param), 0) |
| else: |
| self.assertEqual(getattr(unit, param), -100) |
|
|
| def test_choose_input_image(self): |
| with self.subTest(name="no image"): |
| with self.assertRaises(ValueError): |
| Script.choose_input_image( |
| p=processing.StableDiffusionProcessing(), |
| unit=external_code.ControlNetUnit(), |
| idx=0, |
| ) |
|
|
| with self.subTest(name="control net input"): |
| _, from_a1111 = Script.choose_input_image( |
| p=MockImg2ImgProcessing(init_images=[TestScript.sample_np_image]), |
| unit=external_code.ControlNetUnit( |
| image=TestScript.sample_base64_image, module="none" |
| ), |
| idx=0, |
| ) |
| self.assertFalse(from_a1111) |
|
|
| with self.subTest(name="A1111 input"): |
| _, from_a1111 = Script.choose_input_image( |
| p=MockImg2ImgProcessing(init_images=[TestScript.sample_np_image]), |
| unit=external_code.ControlNetUnit(module="none"), |
| idx=0, |
| ) |
| self.assertTrue(from_a1111) |
|
|
|
|
| if __name__ == "__main__": |
| unittest.main() |
|
|