1313import org .elasticsearch .common .io .stream .BytesStreamOutput ;
1414import org .elasticsearch .common .io .stream .Writeable ;
1515import org .elasticsearch .common .xcontent .XContentHelper ;
16+ import org .elasticsearch .core .Nullable ;
1617import org .elasticsearch .inference .SimilarityMeasure ;
1718import org .elasticsearch .test .AbstractWireSerializingTestCase ;
1819import org .elasticsearch .xcontent .XContentBuilder ;
@@ -41,21 +42,128 @@ public class LlamaEmbeddingsServiceSettingsTests extends AbstractWireSerializing
4142
4243 public void testFromMap_AllFields_Success () {
4344 var serviceSettings = LlamaEmbeddingsServiceSettings .fromMap (
44- new HashMap <>(
45- Map .of (
46- ServiceFields .MODEL_ID ,
45+ buildServiceSettingsMap (
46+ MODEL_ID ,
47+ CORRECT_URL ,
48+ SIMILARITY_MEASURE .toString (),
49+ DIMENSIONS ,
50+ MAX_INPUT_TOKENS ,
51+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
52+ ),
53+ ConfigurationParseContext .PERSISTENT
54+ );
55+
56+ assertThat (
57+ serviceSettings ,
58+ is (
59+ new LlamaEmbeddingsServiceSettings (
4760 MODEL_ID ,
48- ServiceFields .URL ,
4961 CORRECT_URL ,
50- ServiceFields .SIMILARITY ,
62+ DIMENSIONS ,
63+ SIMILARITY_MEASURE ,
64+ MAX_INPUT_TOKENS ,
65+ new RateLimitSettings (RATE_LIMIT )
66+ )
67+ )
68+ );
69+ }
70+
71+ public void testFromMap_NoModelId_Failure () {
72+ var thrownException = expectThrows (
73+ ValidationException .class ,
74+ () -> LlamaEmbeddingsServiceSettings .fromMap (
75+ buildServiceSettingsMap (
76+ null ,
77+ CORRECT_URL ,
5178 SIMILARITY_MEASURE .toString (),
52- ServiceFields .DIMENSIONS ,
5379 DIMENSIONS ,
54- ServiceFields .MAX_INPUT_TOKENS ,
5580 MAX_INPUT_TOKENS ,
56- RateLimitSettings .FIELD_NAME ,
5781 new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
58- )
82+ ),
83+ ConfigurationParseContext .PERSISTENT
84+ )
85+ );
86+ assertThat (
87+ thrownException .getMessage (),
88+ containsString ("Validation Failed: 1: [service_settings] does not contain the required setting [model_id];" )
89+ );
90+ }
91+
92+ public void testFromMap_NoUrl_Failure () {
93+ var thrownException = expectThrows (
94+ ValidationException .class ,
95+ () -> LlamaEmbeddingsServiceSettings .fromMap (
96+ buildServiceSettingsMap (
97+ MODEL_ID ,
98+ null ,
99+ SIMILARITY_MEASURE .toString (),
100+ DIMENSIONS ,
101+ MAX_INPUT_TOKENS ,
102+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
103+ ),
104+ ConfigurationParseContext .PERSISTENT
105+ )
106+ );
107+ assertThat (
108+ thrownException .getMessage (),
109+ containsString ("Validation Failed: 1: [service_settings] does not contain the required setting [url];" )
110+ );
111+ }
112+
113+ public void testFromMap_EmptyUrl_Failure () {
114+ var thrownException = expectThrows (
115+ ValidationException .class ,
116+ () -> LlamaEmbeddingsServiceSettings .fromMap (
117+ buildServiceSettingsMap (
118+ MODEL_ID ,
119+ "" ,
120+ SIMILARITY_MEASURE .toString (),
121+ DIMENSIONS ,
122+ MAX_INPUT_TOKENS ,
123+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
124+ ),
125+ ConfigurationParseContext .PERSISTENT
126+ )
127+ );
128+ assertThat (
129+ thrownException .getMessage (),
130+ containsString ("Validation Failed: 1: [service_settings] Invalid value empty string. [url] must be a non-empty string;" )
131+ );
132+ }
133+
134+ public void testFromMap_InvalidUrl_Failure () {
135+ var thrownException = expectThrows (
136+ ValidationException .class ,
137+ () -> LlamaEmbeddingsServiceSettings .fromMap (
138+ buildServiceSettingsMap (
139+ MODEL_ID ,
140+ "^^^" ,
141+ SIMILARITY_MEASURE .toString (),
142+ DIMENSIONS ,
143+ MAX_INPUT_TOKENS ,
144+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
145+ ),
146+ ConfigurationParseContext .PERSISTENT
147+ )
148+ );
149+ assertThat (
150+ thrownException .getMessage (),
151+ containsString (
152+ "Validation Failed: 1: [service_settings] Invalid url [^^^] received for field [url]. "
153+ + "Error: unable to parse url [^^^]. Reason: Illegal character in path;"
154+ )
155+ );
156+ }
157+
158+ public void testFromMap_NoSimilarity_Success () {
159+ var serviceSettings = LlamaEmbeddingsServiceSettings .fromMap (
160+ buildServiceSettingsMap (
161+ MODEL_ID ,
162+ CORRECT_URL ,
163+ null ,
164+ DIMENSIONS ,
165+ MAX_INPUT_TOKENS ,
166+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
59167 ),
60168 ConfigurationParseContext .PERSISTENT
61169 );
@@ -67,6 +175,58 @@ public void testFromMap_AllFields_Success() {
67175 MODEL_ID ,
68176 CORRECT_URL ,
69177 DIMENSIONS ,
178+ null ,
179+ MAX_INPUT_TOKENS ,
180+ new RateLimitSettings (RATE_LIMIT )
181+ )
182+ )
183+ );
184+ }
185+
186+ public void testFromMap_InvalidSimilarity_Failure () {
187+ var thrownException = expectThrows (
188+ ValidationException .class ,
189+ () -> LlamaEmbeddingsServiceSettings .fromMap (
190+ buildServiceSettingsMap (
191+ MODEL_ID ,
192+ CORRECT_URL ,
193+ "by_size" ,
194+ DIMENSIONS ,
195+ MAX_INPUT_TOKENS ,
196+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
197+ ),
198+ ConfigurationParseContext .PERSISTENT
199+ )
200+ );
201+ assertThat (
202+ thrownException .getMessage (),
203+ containsString (
204+ "Validation Failed: 1: [service_settings] Invalid value [by_size] received. "
205+ + "[similarity] must be one of [cosine, dot_product, l2_norm];"
206+ )
207+ );
208+ }
209+
210+ public void testFromMap_NoDimensions_Success () {
211+ var serviceSettings = LlamaEmbeddingsServiceSettings .fromMap (
212+ buildServiceSettingsMap (
213+ MODEL_ID ,
214+ CORRECT_URL ,
215+ SIMILARITY_MEASURE .toString (),
216+ null ,
217+ MAX_INPUT_TOKENS ,
218+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
219+ ),
220+ ConfigurationParseContext .PERSISTENT
221+ );
222+
223+ assertThat (
224+ serviceSettings ,
225+ is (
226+ new LlamaEmbeddingsServiceSettings (
227+ MODEL_ID ,
228+ CORRECT_URL ,
229+ null ,
70230 SIMILARITY_MEASURE ,
71231 MAX_INPUT_TOKENS ,
72232 new RateLimitSettings (RATE_LIMIT )
@@ -75,30 +235,136 @@ public void testFromMap_AllFields_Success() {
75235 );
76236 }
77237
78- public void testFromMap_NoModelId_Failure () {
238+ public void testFromMap_ZeroDimensions_Failure () {
239+ var thrownException = expectThrows (
240+ ValidationException .class ,
241+ () -> LlamaEmbeddingsServiceSettings .fromMap (
242+ buildServiceSettingsMap (
243+ MODEL_ID ,
244+ CORRECT_URL ,
245+ SIMILARITY_MEASURE .toString (),
246+ 0 ,
247+ MAX_INPUT_TOKENS ,
248+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
249+ ),
250+ ConfigurationParseContext .PERSISTENT
251+ )
252+ );
253+ assertThat (
254+ thrownException .getMessage (),
255+ containsString ("Validation Failed: 1: [service_settings] Invalid value [0]. [dimensions] must be a positive integer;" )
256+ );
257+ }
258+
259+ public void testFromMap_NegativeDimensions_Failure () {
260+ var thrownException = expectThrows (
261+ ValidationException .class ,
262+ () -> LlamaEmbeddingsServiceSettings .fromMap (
263+ buildServiceSettingsMap (
264+ MODEL_ID ,
265+ CORRECT_URL ,
266+ SIMILARITY_MEASURE .toString (),
267+ -10 ,
268+ MAX_INPUT_TOKENS ,
269+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
270+ ),
271+ ConfigurationParseContext .PERSISTENT
272+ )
273+ );
274+ assertThat (
275+ thrownException .getMessage (),
276+ containsString ("Validation Failed: 1: [service_settings] Invalid value [-10]. [dimensions] must be a positive integer;" )
277+ );
278+ }
279+
280+ public void testFromMap_NoInputTokens_Success () {
281+ var serviceSettings = LlamaEmbeddingsServiceSettings .fromMap (
282+ buildServiceSettingsMap (
283+ MODEL_ID ,
284+ CORRECT_URL ,
285+ SIMILARITY_MEASURE .toString (),
286+ DIMENSIONS ,
287+ null ,
288+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
289+ ),
290+ ConfigurationParseContext .PERSISTENT
291+ );
292+
293+ assertThat (
294+ serviceSettings ,
295+ is (
296+ new LlamaEmbeddingsServiceSettings (
297+ MODEL_ID ,
298+ CORRECT_URL ,
299+ DIMENSIONS ,
300+ SIMILARITY_MEASURE ,
301+ null ,
302+ new RateLimitSettings (RATE_LIMIT )
303+ )
304+ )
305+ );
306+ }
307+
308+ public void testFromMap_ZeroInputTokens_Failure () {
309+ var thrownException = expectThrows (
310+ ValidationException .class ,
311+ () -> LlamaEmbeddingsServiceSettings .fromMap (
312+ buildServiceSettingsMap (
313+ MODEL_ID ,
314+ CORRECT_URL ,
315+ SIMILARITY_MEASURE .toString (),
316+ DIMENSIONS ,
317+ 0 ,
318+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
319+ ),
320+ ConfigurationParseContext .PERSISTENT
321+ )
322+ );
323+ assertThat (
324+ thrownException .getMessage (),
325+ containsString ("Validation Failed: 1: [service_settings] Invalid value [0]. [max_input_tokens] must be a positive integer;" )
326+ );
327+ }
328+
329+ public void testFromMap_NegativeInputTokens_Failure () {
79330 var thrownException = expectThrows (
80331 ValidationException .class ,
81332 () -> LlamaEmbeddingsServiceSettings .fromMap (
82- new HashMap <>(
83- Map .of (
84- ServiceFields .URL ,
85- CORRECT_URL ,
86- ServiceFields .SIMILARITY ,
87- SIMILARITY_MEASURE .toString (),
88- ServiceFields .DIMENSIONS ,
89- DIMENSIONS ,
90- ServiceFields .MAX_INPUT_TOKENS ,
91- MAX_INPUT_TOKENS ,
92- RateLimitSettings .FIELD_NAME ,
93- new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
94- )
333+ buildServiceSettingsMap (
334+ MODEL_ID ,
335+ CORRECT_URL ,
336+ SIMILARITY_MEASURE .toString (),
337+ DIMENSIONS ,
338+ -10 ,
339+ new HashMap <>(Map .of (RateLimitSettings .REQUESTS_PER_MINUTE_FIELD , RATE_LIMIT ))
95340 ),
96341 ConfigurationParseContext .PERSISTENT
97342 )
98343 );
99344 assertThat (
100345 thrownException .getMessage (),
101- containsString (Strings .format ("Validation Failed: 1: [service_settings] does not contain the required setting [model_id];" , 2 ))
346+ containsString ("Validation Failed: 1: [service_settings] Invalid value [-10]. [max_input_tokens] must be a positive integer;" )
347+ );
348+ }
349+
350+ public void testFromMap_NoRateLimit_Success () {
351+ var serviceSettings = LlamaEmbeddingsServiceSettings .fromMap (
352+ buildServiceSettingsMap (MODEL_ID , CORRECT_URL , SIMILARITY_MEASURE .toString (), DIMENSIONS , MAX_INPUT_TOKENS , null ),
353+ ConfigurationParseContext .PERSISTENT
354+ );
355+
356+ assertThat (
357+ serviceSettings ,
358+ is (
359+ new LlamaEmbeddingsServiceSettings (
360+ MODEL_ID ,
361+ CORRECT_URL ,
362+ DIMENSIONS ,
363+ SIMILARITY_MEASURE ,
364+ MAX_INPUT_TOKENS ,
365+ new RateLimitSettings (3000 )
366+ )
367+ )
102368 );
103369 }
104370
@@ -180,4 +446,34 @@ private static LlamaEmbeddingsServiceSettings createRandom() {
180446 RateLimitSettingsTests .createRandom ()
181447 );
182448 }
449+
450+ private static HashMap <String , Object > buildServiceSettingsMap (
451+ @ Nullable String modelId ,
452+ @ Nullable String url ,
453+ @ Nullable String similarity ,
454+ @ Nullable Integer dimensions ,
455+ @ Nullable Integer maxInputTokens ,
456+ @ Nullable HashMap <String , Integer > rateLimitSettings
457+ ) {
458+ HashMap <String , Object > result = new HashMap <>();
459+ if (modelId != null ) {
460+ result .put (ServiceFields .MODEL_ID , modelId );
461+ }
462+ if (url != null ) {
463+ result .put (ServiceFields .URL , url );
464+ }
465+ if (similarity != null ) {
466+ result .put (ServiceFields .SIMILARITY , similarity );
467+ }
468+ if (dimensions != null ) {
469+ result .put (ServiceFields .DIMENSIONS , dimensions );
470+ }
471+ if (maxInputTokens != null ) {
472+ result .put (ServiceFields .MAX_INPUT_TOKENS , maxInputTokens );
473+ }
474+ if (rateLimitSettings != null ) {
475+ result .put (RateLimitSettings .FIELD_NAME , rateLimitSettings );
476+ }
477+ return result ;
478+ }
183479}
0 commit comments