Coverage for tests / unit_tests / test_profile.py: 100%

40 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-24 01:53 +0000

1""" 

2Tests of apio_profile.py 

3""" 

4 

5import json 

6from datetime import datetime, timedelta 

7from tests.conftest import ApioRunner 

8from apio.profile import ( 

9 Profile, 

10 get_datetime_stamp, 

11 days_between_datetime_stamps, 

12) 

13from apio.utils import util 

14from apio.apio_context import ( 

15 ApioContext, 

16 PackagesPolicy, 

17 ProjectPolicy, 

18 RemoteConfigPolicy, 

19) 

20 

21 

22def get_test_data( 

23 apio_ctx: ApioContext, 

24 loaded_by_apio_version: str, 

25 loaded_at_days: int, 

26): 

27 """Returns a fake profile.json content. 'loaded_at_days' is the value of 

28 the remote config "loaded-at" relative to today in days.""" 

29 loaded_at_datetime = datetime.now() + timedelta(days=loaded_at_days) 

30 loaded_at_stamp = get_datetime_stamp(loaded_at_datetime) 

31 assert isinstance(loaded_at_stamp, str) 

32 

33 return { 

34 "preferences": {"theme": "light"}, 

35 "remote-config": { 

36 "metadata": { 

37 "loaded-at": loaded_at_stamp, 

38 "loaded-by": loaded_by_apio_version, 

39 "loaded-from": apio_ctx.profile.remote_config_url, 

40 }, 

41 "packages": { 

42 "drivers": { 

43 "release": { 

44 "package-file": ( 

45 "apio-drivers-${PLATFORM}-${YYYYMMDD}.tgz" 

46 ), 

47 "release-tag": "${YYYY-MM-DD}", 

48 "version": "2025.06.13", 

49 }, 

50 "repository": { 

51 "name": "tools-drivers", 

52 "organization": "fpgawars", 

53 }, 

54 }, 

55 "examples": { 

56 "release": { 

57 "package-file": "apio-examples-${YYYYMMDD}.tgz", 

58 "release-tag": "${YYYY-MM-DD}", 

59 "version": "2025.06.21", 

60 }, 

61 "repository": { 

62 "name": "apio-examples", 

63 "organization": "fpgawars", 

64 }, 

65 }, 

66 }, 

67 }, 

68 } 

69 

70 

71def test_profile_loading_config_ok(apio_runner: ApioRunner): 

72 """Tests the loading and validation of a profile file with no need 

73 to fetch a remote config.""" 

74 

75 with apio_runner.in_sandbox() as sb: 

76 

77 apio_ctx = ApioContext( 

78 project_policy=ProjectPolicy.NO_PROJECT, 

79 remote_config_policy=RemoteConfigPolicy.CACHED_OK, 

80 packages_policy=PackagesPolicy.ENSURE_PACKAGES, 

81 ) 

82 

83 # -- Write a test profile.json file. 

84 path = sb.home_dir / "profile.json" 

85 test_data = get_test_data(apio_ctx, util.get_apio_version_str(), 0) 

86 sb.write_file( 

87 path, 

88 json.dumps( 

89 test_data, 

90 indent=2, 

91 ), 

92 exists_ok=True, 

93 ) 

94 

95 # -- Read back the content. 

96 profile = Profile( 

97 sb.home_dir, 

98 sb.packages_dir, 

99 apio_ctx.profile.remote_config_url, 

100 5, # TTL in days 

101 60, # Remote config retry mins. 

102 RemoteConfigPolicy.CACHED_OK, 

103 ) 

104 

105 # -- Verify 

106 assert profile.preferences == test_data["preferences"] 

107 assert profile.remote_config == test_data["remote-config"] 

108 

109 

110def test_profile_loading_config_stale_version(apio_runner: ApioRunner): 

111 """Tests the loading and validation of a profile file that include 

112 an old config that needs to be refreshed.""" 

113 

114 with apio_runner.in_sandbox() as sb: 

115 

116 apio_ctx = ApioContext( 

117 project_policy=ProjectPolicy.NO_PROJECT, 

118 remote_config_policy=RemoteConfigPolicy.CACHED_OK, 

119 packages_policy=PackagesPolicy.ENSURE_PACKAGES, 

120 ) 

121 

122 # -- Write a test profile.json file. We set an old apio version 

123 # -- to cause the cached remote config to be classified as stale. 

124 path = sb.home_dir / "profile.json" 

125 original_loaded_by = "0.9.6" 

126 assert original_loaded_by != util.get_apio_version_str() 

127 test_data = get_test_data(apio_ctx, original_loaded_by, 0) 

128 

129 sb.write_file( 

130 path, 

131 json.dumps( 

132 test_data, 

133 indent=2, 

134 ), 

135 exists_ok=True, 

136 ) 

137 

138 # -- Read back the content. 

139 profile = Profile( 

140 sb.home_dir, 

141 sb.packages_dir, 

142 apio_ctx.profile.remote_config_url, 

143 5, # TTL in days 

144 60, # Remote config retry mins. 

145 RemoteConfigPolicy.CACHED_OK, 

146 ) 

147 

148 # -- Verify. Remote config should be a fresh one, loaded by this 

149 # -- apio version. 

150 assert profile.preferences == test_data["preferences"] 

151 # assert profile.installed_packages == test_data["installed-packages"] 

152 assert ( 

153 profile.remote_config["metadata"]["loaded-by"] 

154 == util.get_apio_version_str() 

155 ) 

156 

157 

158def test_datetime_stamp_diff_days(): 

159 """Test the datetime timestamp diff.""" 

160 

161 assert ( 

162 get_datetime_stamp( 

163 datetime(year=2025, month=6, day=30, hour=14, minute=45) 

164 ) 

165 == "2025-06-30-14-45" 

166 ) 

167 

168 ts_now = get_datetime_stamp() 

169 assert ( 

170 days_between_datetime_stamps( 

171 ts_now, 

172 ts_now, 

173 default=9999, 

174 ) 

175 == 0 

176 ) 

177 

178 assert ( 

179 days_between_datetime_stamps( 

180 "2025-06-15-07-30", 

181 "2025-06-16-00-01", 

182 default=9999, 

183 ) 

184 == 1 

185 ) 

186 

187 assert ( 

188 days_between_datetime_stamps( 

189 "2025-06-16-00-01", 

190 "2025-06-15-07-30", 

191 default=9999, 

192 ) 

193 == -1 

194 ) 

195 

196 assert ( 

197 days_between_datetime_stamps( 

198 "2025-06-15-00-00", 

199 "2025-06-15-23-59", 

200 default=9999, 

201 ) 

202 == 0 

203 ) 

204 

205 assert ( 

206 days_between_datetime_stamps( 

207 "2025-06-15-00-0x", 

208 "2025-06-15-23-59", 

209 default=9999, 

210 ) 

211 == 9999 

212 ) 

213 

214 assert ( 

215 days_between_datetime_stamps( 

216 "2025-06-15-20-15", 

217 "2025-06-20-00-01", 

218 default=9999, 

219 ) 

220 == 5 

221 )