1
1
from dataclasses import dataclass
2
2
from typing import Dict , List
3
3
4
+ import pytest
5
+
4
6
from feast import utils
5
7
from feast .protos .feast .types .Value_pb2 import Value
6
8
@@ -17,7 +19,7 @@ class MockFeatureView:
17
19
projection : MockFeatureViewProjection
18
20
19
21
20
- def test_get_unique_entities ():
22
+ def test_get_unique_entities_success ():
21
23
entity_values = {
22
24
"entity_1" : [Value (int64_val = 1 ), Value (int64_val = 2 ), Value (int64_val = 1 )],
23
25
"entity_2" : [
@@ -41,9 +43,87 @@ def test_get_unique_entities():
41
43
join_key_values = entity_values ,
42
44
entity_name_to_join_key_map = entity_name_to_join_key_map ,
43
45
)
44
-
45
- assert unique_entities == (
46
+ expected_entities = (
46
47
{"entity_1" : Value (int64_val = 1 ), "entity_2" : Value (string_val = "1" )},
47
48
{"entity_1" : Value (int64_val = 2 ), "entity_2" : Value (string_val = "2" )},
48
49
)
49
- assert indexes == ([0 , 2 ], [1 ])
50
+ expected_indexes = ([0 , 2 ], [1 ])
51
+
52
+ assert unique_entities == expected_entities
53
+ assert indexes == expected_indexes
54
+
55
+
56
+ def test_get_unique_entities_missing_join_key_success ():
57
+ """
58
+ Tests that _get_unique_entities raises a KeyError when a required join key is missing.
59
+ """
60
+ # Here, we omit the required key for "entity_1"
61
+ entity_values = {
62
+ "entity_2" : [
63
+ Value (string_val = "1" ),
64
+ Value (string_val = "2" ),
65
+ Value (string_val = "1" ),
66
+ ],
67
+ }
68
+
69
+ entity_name_to_join_key_map = {"entity_1" : "entity_1" , "entity_2" : "entity_2" }
70
+
71
+ fv = MockFeatureView (
72
+ name = "fv_1" ,
73
+ entities = ["entity_1" , "entity_2" ],
74
+ projection = MockFeatureViewProjection (join_key_map = {}),
75
+ )
76
+
77
+ unique_entities , indexes = utils ._get_unique_entities (
78
+ table = fv ,
79
+ join_key_values = entity_values ,
80
+ entity_name_to_join_key_map = entity_name_to_join_key_map ,
81
+ )
82
+ expected_entities = (
83
+ {"entity_2" : Value (string_val = "1" )},
84
+ {"entity_2" : Value (string_val = "2" )},
85
+ )
86
+ expected_indexes = ([0 , 2 ], [1 ])
87
+
88
+ assert unique_entities == expected_entities
89
+ assert indexes == expected_indexes
90
+ # We're not say anything about the entity_1 missing from the unique_entities list
91
+ assert "entity_1" not in [entity .keys () for entity in unique_entities ]
92
+
93
+
94
+ def test_get_unique_entities_missing_all_join_keys_error ():
95
+ """
96
+ Tests that _get_unique_entities raises a KeyError when all required join keys are missing.
97
+ """
98
+ entity_values_not_in_feature_view = {
99
+ "entity_3" : [Value (string_val = "3" )],
100
+ }
101
+ entity_name_to_join_key_map = {
102
+ "entity_1" : "entity_1" ,
103
+ "entity_2" : "entity_2" ,
104
+ "entity_3" : "entity_3" ,
105
+ }
106
+
107
+ fv = MockFeatureView (
108
+ name = "fv_1" ,
109
+ entities = ["entity_1" , "entity_2" ],
110
+ projection = MockFeatureViewProjection (join_key_map = {}),
111
+ )
112
+
113
+ with pytest .raises (KeyError ) as excinfo :
114
+ utils ._get_unique_entities (
115
+ table = fv ,
116
+ join_key_values = entity_values_not_in_feature_view ,
117
+ entity_name_to_join_key_map = entity_name_to_join_key_map ,
118
+ )
119
+
120
+ error_message = str (excinfo .value )
121
+ assert (
122
+ "Missing join key values for keys: ['entity_1', 'entity_2', 'entity_3']"
123
+ in error_message
124
+ )
125
+ assert (
126
+ "No values provided for keys: ['entity_1', 'entity_2', 'entity_3']"
127
+ in error_message
128
+ )
129
+ assert "Provided join_key_values: ['entity_3']" in error_message
0 commit comments