Skip to content

Commit fb186b7

Browse files
woopachals
authored andcommitted
Add integration test
Signed-off-by: Felix Wang <wangfelix98@gmail.com> Signed-off-by: Achal Shah <achals@gmail.com>
1 parent 90a5fb2 commit fb186b7

1 file changed

Lines changed: 216 additions & 0 deletions

File tree

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
//go:build integration
2+
// +build integration
3+
4+
package feast
5+
6+
import (
7+
"fmt"
8+
"github.com/feast-dev/feast/go/protos/feast/serving"
9+
"github.com/feast-dev/feast/go/protos/feast/types"
10+
"github.com/stretchr/testify/assert"
11+
"io/ioutil"
12+
"log"
13+
"os"
14+
"os/exec"
15+
"path/filepath"
16+
"testing"
17+
"time"
18+
)
19+
20+
func setupFeastRepo(tb testing.TB, featureStoreYaml string) (func(testing.TB), string) {
21+
// Use time as unique identifier for test
22+
t := time.Now()
23+
project := "test_" + t.Format("20060102150405")
24+
25+
// create temp dir for the feature store repo and data
26+
dir, err := ioutil.TempDir("", project)
27+
if err != nil {
28+
log.Fatal(err)
29+
}
30+
31+
// TODO: Use testcontainers to start Redis
32+
33+
// Init feast repo
34+
// TODO (woop): Use Feast from repo
35+
cmd := exec.Command("sh", "-c", "feast init repo")
36+
cmd.Dir = dir
37+
out, err := cmd.CombinedOutput()
38+
fmt.Printf("%s\n", out)
39+
if err != nil {
40+
tb.Errorf("%v", err)
41+
}
42+
dir = filepath.Join(dir, "/repo")
43+
44+
// Configure feature_store.yaml
45+
ioutil.WriteFile(dir+"/feature_store.yaml", []byte(featureStoreYaml), 0644)
46+
47+
// run apply
48+
cmd = exec.Command("sh", "-c", "feast apply")
49+
cmd.Dir = dir
50+
out, err = cmd.CombinedOutput()
51+
fmt.Printf("%s\n", out)
52+
if err != nil {
53+
tb.Errorf("%v", err)
54+
}
55+
56+
// run materialize
57+
cmd = exec.Command("sh", "-c", "feast materialize-incremental $(date -u +\"%Y-%m-%dT%H:%M:%S\")")
58+
cmd.Dir = dir
59+
out, err = cmd.CombinedOutput()
60+
fmt.Printf("%s\n", out)
61+
if err != nil {
62+
tb.Errorf("%v", err)
63+
}
64+
65+
return func(tb testing.TB) {
66+
os.RemoveAll(dir)
67+
}, dir
68+
}
69+
70+
func TestFeatureStore(t *testing.T) {
71+
72+
defaultFeatureStoreYaml := `project: test_repo
73+
registry: data/registry.db
74+
provider: local
75+
online_store:
76+
type: redis
77+
connection_string: "localhost:6379"`
78+
79+
tests := []struct {
80+
name string
81+
featureStoreYaml string
82+
useDefaultRepo bool
83+
repoContents string
84+
request serving.GetOnlineFeaturesRequest
85+
expected serving.GetOnlineFeaturesResponse
86+
wantError bool
87+
want string
88+
}{
89+
{
90+
"multiple_features_single_entity_multiple_entity_values",
91+
defaultFeatureStoreYaml,
92+
true,
93+
"",
94+
serving.GetOnlineFeaturesRequest{Kind: &serving.GetOnlineFeaturesRequest_Features{
95+
Features: &serving.FeatureList{Val: []string{
96+
"driver_hourly_stats:conv_rate",
97+
"driver_hourly_stats:acc_rate",
98+
"driver_hourly_stats:avg_daily_trips"}}},
99+
Entities: map[string]*types.RepeatedValue{"driver_id": {Val: []*types.Value{
100+
{Val: &types.Value_Int64Val{Int64Val: 1001}},
101+
{Val: &types.Value_Int64Val{Int64Val: 1002}},
102+
{Val: &types.Value_Int64Val{Int64Val: 1003}}}}},
103+
FullFeatureNames: true},
104+
serving.GetOnlineFeaturesResponse{
105+
Metadata: nil,
106+
Results: nil,
107+
},
108+
false,
109+
"",
110+
},
111+
{
112+
"multiple_features_multiple_entities_multiple_entity_values",
113+
defaultFeatureStoreYaml,
114+
true,
115+
"",
116+
serving.GetOnlineFeaturesRequest{Kind: &serving.GetOnlineFeaturesRequest_Features{
117+
Features: &serving.FeatureList{Val: []string{
118+
"driver_hourly_stats:conv_rate",
119+
"driver_hourly_stats:acc_rate",
120+
"driver_hourly_stats:avg_daily_trips"}}},
121+
Entities: map[string]*types.RepeatedValue{"driver_id": {Val: []*types.Value{
122+
{Val: &types.Value_Int64Val{Int64Val: 1001}},
123+
{Val: &types.Value_Int64Val{Int64Val: 1002}},
124+
{Val: &types.Value_Int64Val{Int64Val: 1003}}}},
125+
"customer_id": {Val: []*types.Value{
126+
{Val: &types.Value_Int64Val{Int64Val: 2001}},
127+
{Val: &types.Value_Int64Val{Int64Val: 2002}},
128+
{Val: &types.Value_Int64Val{Int64Val: 2003}}}}},
129+
FullFeatureNames: true},
130+
serving.GetOnlineFeaturesResponse{
131+
Metadata: nil,
132+
Results: nil,
133+
},
134+
false,
135+
"",
136+
},
137+
{
138+
"no_feature_references",
139+
defaultFeatureStoreYaml,
140+
true,
141+
"",
142+
serving.GetOnlineFeaturesRequest{Kind: &serving.GetOnlineFeaturesRequest_Features{
143+
Features: &serving.FeatureList{Val: []string{}}},
144+
Entities: map[string]*types.RepeatedValue{"driver_id": {Val: []*types.Value{
145+
{Val: &types.Value_Int64Val{Int64Val: 1001}},
146+
{Val: &types.Value_Int64Val{Int64Val: 1002}},
147+
{Val: &types.Value_Int64Val{Int64Val: 1003}}}}},
148+
FullFeatureNames: true},
149+
serving.GetOnlineFeaturesResponse{
150+
Metadata: nil,
151+
Results: nil,
152+
},
153+
true,
154+
"No feature references provided",
155+
},
156+
{
157+
"no_entity_keys",
158+
defaultFeatureStoreYaml,
159+
true,
160+
"",
161+
serving.GetOnlineFeaturesRequest{Kind: &serving.GetOnlineFeaturesRequest_Features{
162+
Features: &serving.FeatureList{Val: []string{}}},
163+
Entities: map[string]*types.RepeatedValue{"driver_id": {Val: []*types.Value{
164+
{Val: &types.Value_Int64Val{Int64Val: 1001}},
165+
{Val: &types.Value_Int64Val{Int64Val: 1002}},
166+
{Val: &types.Value_Int64Val{Int64Val: 1003}}}}},
167+
FullFeatureNames: true},
168+
serving.GetOnlineFeaturesResponse{
169+
Metadata: nil,
170+
Results: nil,
171+
},
172+
true,
173+
"No entity keys provided",
174+
},
175+
}
176+
177+
for _, tc := range tests {
178+
t.Run(tc.name, func(t *testing.T) {
179+
teardown, dir := setupFeastRepo(t, tc.featureStoreYaml)
180+
defer teardown(t)
181+
182+
conf, err := NewRepoConfig(dir)
183+
if err != nil {
184+
t.Errorf("%v", err)
185+
}
186+
187+
fs, err := NewFeatureStore(conf)
188+
if err != nil {
189+
t.Errorf("%v", err)
190+
}
191+
192+
actual, err := fs.GetOnlineFeatures(&tc.request)
193+
194+
if err != nil && !tc.wantError {
195+
t.Errorf("%v", err)
196+
}
197+
198+
//if tc.wantError {
199+
// if err == nil {
200+
// t.Errorf("Expected error with message %s, but no error returned", tc.want)
201+
// }
202+
//
203+
// if err.Error() != tc.want {
204+
// t.Errorf("hello() = %v, want %v", err, tc.want)
205+
// }
206+
//
207+
//}
208+
209+
if !assert.Equal(t, actual, tc.expected) {
210+
//t.Errorf("expected %v, got %v", tc.expected, actual)
211+
// TODO: Enable these tests when GetOnlineFeaturesWorks
212+
println("These tests are being skipped for now!!")
213+
}
214+
})
215+
}
216+
}

0 commit comments

Comments
 (0)