Coverage for tests/test_wrapper_hunyuanframepack.py: 100%

85 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-09 04:47 +0000

1#!/usr/bin/env python3 

2 

3import sys 

4import pytest 

5 

6from unittest.mock import patch 

7from unittest.mock import MagicMock 

8from tests.torch_mock import TorchMock 

9from tests.diffusers_mock import DiffusersMock 

10 

11from PIL import Image 

12 

13sys.path.append("wrapper") 

14sys.path.append("wrapper/hunyuanframepackf1") 

15sys.path.append("wrapper/hunyuanframepack") 

16 

17mock_torch = TorchMock() 

18mock_diffusers = DiffusersMock() 

19 

20mock_modules = { 

21 'nvidia_smi': MagicMock(), 

22 'imageio': MagicMock(), 

23 'cv2': MagicMock(), 

24 'torch': mock_torch, 

25 'torchvision': MagicMock(), 

26 'torchvision.transforms': MagicMock(), 

27 'torchvision.transforms.functional': MagicMock(), 

28 'xfuser': MagicMock(), 

29 'xfuser.envs': MagicMock(), 

30 'xfuser.config': MagicMock(), 

31 'xfuser.core': MagicMock(), 

32 'xfuser.core.distributed': MagicMock(), 

33 'xfuser.core.cache_manager': MagicMock(), 

34 'xfuser.core.cache_manager.cache_manager': MagicMock(), 

35 'xfuser.core.long_ctx_attention': MagicMock(), 

36 'xfuser.model_executor': MagicMock(), 

37 'xfuser.model_executor.layers': MagicMock(), 

38 'xfuser.model_executor.layers.attention_processor': MagicMock(), 

39 'transformers': MagicMock(), 

40 'einops': MagicMock(), 

41 'flash_attn': MagicMock(), 

42} 

43mock_modules.update({ 

44 'diffusers_helper': MagicMock(), 

45 'diffusers_helper.hunyuan': MagicMock(), 

46 'diffusers_helper.utils': MagicMock(), 

47 'diffusers_helper.clip_vision': MagicMock(), 

48 'diffusers_helper.models': MagicMock(), 

49 'diffusers_helper.models.hunyuan_video_packed': MagicMock(), 

50 'diffusers_helper.pipelines': MagicMock(), 

51 'diffusers_helper.pipelines.k_diffusion_hunyuan': MagicMock(), 

52 'diffusers_helper.k_diffusion': MagicMock(), 

53 'diffusers_helper.k_diffusion.uni_pc_fm': MagicMock(), 

54 'diffusers_helper.k_diffusion.wrapper': MagicMock(), 

55}) 

56mock_modules.update(mock_torch.get_sub_modules()) 

57mock_modules.update(mock_diffusers.get_sub_modules()) 

58 

59with patch.dict(sys.modules, mock_modules): 

60 from image_utils import img_to_base64 

61 from hunyuanframepack.wrapper_hunyuanframepack import HunyuanFramepackGeneration 

62 

63 

64@pytest.mark.asyncio 

65async def test_hunyuan_framepack() -> None: 

66 model = HunyuanFramepackGeneration() 

67 assert model is not None 

68 assert model.model_name == "hunyuanframepack" 

69 assert model.status == "initializing" 

70 

71 model.init() 

72 assert model.status == "ok" 

73 health = model.get_health() 

74 assert health is not None 

75 timestamps = model.get_timestamps() 

76 assert timestamps is not None 

77 

78 with pytest.raises(ValueError): 

79 await model.get_rest_args(None) 

80 with pytest.raises(ValueError): 

81 await model.get_rest_args({}) 

82 img = Image.new("RGB", (40, 30)) 

83 img_base64 = img_to_base64(img) 

84 await model.get_rest_args({ 

85 "img": img_base64, 

86 "prompt": "test prompt", 

87 }) 

88 

89 with pytest.raises(ValueError, match="not enough values to unpack"): 

90 # TODO implement fixtures for diffusers_helper 

91 await model.warmup() 

92 

93 with pytest.raises(ValueError, match="not enough values to unpack"): 

94 # TODO implement fixtures for diffusers_helper 

95 await model.generate( 

96 img=img, 

97 prompt="test prompt", 

98 output_type="video_frames") 

99 # assert video_frames is not None 

100 

101 del model 

102 

103 

104@pytest.mark.asyncio 

105async def test_hunyuan_framepack_get_rest_args_negative_values() -> None: 

106 """get_rest_args raises ValueError for non-positive numeric parameters.""" 

107 model = HunyuanFramepackGeneration() 

108 model.init() 

109 

110 img = Image.new("RGB", (40, 30)) 

111 img_base64 = img_to_base64(img) 

112 base = {"img": img_base64, "prompt": "test prompt"} 

113 

114 with pytest.raises(ValueError, match="num_frames"): 

115 await model.get_rest_args({**base, "num_frames": -3}) 

116 

117 with pytest.raises(ValueError, match="num_frames"): 

118 await model.get_rest_args({**base, "num_frames": 0}) 

119 

120 with pytest.raises(ValueError, match="height"): 

121 await model.get_rest_args({**base, "height": -480}) 

122 

123 with pytest.raises(ValueError, match="height"): 

124 await model.get_rest_args({**base, "height": 0}) 

125 

126 with pytest.raises(ValueError, match="width"): 

127 await model.get_rest_args({**base, "width": -640}) 

128 

129 with pytest.raises(ValueError, match="width"): 

130 await model.get_rest_args({**base, "width": 0}) 

131 

132 with pytest.raises(ValueError, match="sampling_steps"): 

133 await model.get_rest_args({**base, "sampling_steps": -10}) 

134 

135 with pytest.raises(ValueError, match="sampling_steps"): 

136 await model.get_rest_args({**base, "sampling_steps": 0}) 

137 

138 with pytest.raises(ValueError, match="latent_window_size"): 

139 await model.get_rest_args({**base, "latent_window_size": -1}) 

140 

141 with pytest.raises(ValueError, match="latent_window_size"): 

142 await model.get_rest_args({**base, "latent_window_size": 0}) 

143 

144 with pytest.raises(ValueError, match="video_seconds"): 

145 await model.get_rest_args({**base, "video_seconds": -1.0}) 

146 

147 with pytest.raises(ValueError, match="video_seconds"): 

148 await model.get_rest_args({**base, "video_seconds": 0.0}) 

149 

150 del model 

151 

152 

153@pytest.mark.asyncio 

154async def test_hunyuan_framepack_generate_proceeds_past_text_encoding() -> None: 

155 """generate() proceeds past _encode_text when it is patched to return mock values.""" 

156 model = HunyuanFramepackGeneration() 

157 model.init() 

158 

159 img = Image.new("RGB", (768, 512)) 

160 six_mocks = tuple(MagicMock() for _ in range(6)) 

161 

162 with patch.object(model, "_encode_text", return_value=six_mocks): 

163 with pytest.raises(ValueError): 

164 await model.generate( 

165 img=img, 

166 prompt="test prompt", 

167 height=512, 

168 width=768, 

169 ) 

170 

171 del model