-
Notifications
You must be signed in to change notification settings - Fork 117
/
testruntime.go
144 lines (124 loc) · 4.02 KB
/
testruntime.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package testruntime
import (
"context"
"fmt"
"path/filepath"
goruntime "runtime"
"strings"
"github.com/c2h5oh/datasize"
runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1"
"github.com/rilldata/rill/runtime"
"github.com/rilldata/rill/runtime/drivers"
"github.com/rilldata/rill/runtime/pkg/activity"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
// Load database drivers for testing.
_ "github.com/rilldata/rill/runtime/drivers/duckdb"
_ "github.com/rilldata/rill/runtime/drivers/file"
_ "github.com/rilldata/rill/runtime/drivers/sqlite"
)
// TestingT satisfies both *testing.T and *testing.B.
type TestingT interface {
Name() string
TempDir() string
FailNow()
Errorf(format string, args ...interface{})
Cleanup(f func())
}
// New returns a runtime configured for use in tests.
func New(t TestingT) *runtime.Runtime {
systemConnectors := []*runtimev1.Connector{
{
Type: "sqlite",
Name: "metastore",
// Setting a test-specific name ensures a unique connection when "cache=shared" is enabled.
// "cache=shared" is needed to prevent threading problems.
Config: map[string]string{"dsn": fmt.Sprintf("file:%s?mode=memory&cache=shared", t.Name())},
},
}
opts := &runtime.Options{
ConnectionCacheSize: 100,
MetastoreConnector: "metastore",
QueryCacheSizeBytes: int64(datasize.MB * 100),
AllowHostAccess: true,
SystemConnectors: systemConnectors,
SecurityEngineCacheSize: 100,
}
rt, err := runtime.New(opts, zap.NewNop(), activity.NewNoopClient())
require.NoError(t, err)
t.Cleanup(func() {
rt.Close()
})
return rt
}
// NewInstance creates a runtime and an instance for use in tests.
// The instance's repo is a temp directory that will be cleared when the tests finish.
func NewInstance(t TestingT) (*runtime.Runtime, string) {
rt := New(t)
inst := &drivers.Instance{
OLAPConnector: "duckdb",
RepoConnector: "repo",
EmbedCatalog: true,
Connectors: []*runtimev1.Connector{
{
Type: "file",
Name: "repo",
Config: map[string]string{"dsn": t.TempDir()},
},
{
Type: "duckdb",
Name: "duckdb",
Config: map[string]string{"dsn": ""},
},
},
}
err := rt.CreateInstance(context.Background(), inst)
require.NoError(t, err)
require.NotEmpty(t, inst.ID)
err = rt.PutFile(context.Background(), inst.ID, "rill.yaml", strings.NewReader(""), true, false)
require.NoError(t, err)
return rt, inst.ID
}
// NewInstanceWithModel creates a runtime and an instance for use in tests.
// The passed model name and SQL SELECT statement will be loaded into the instance.
func NewInstanceWithModel(t TestingT, name, sql string) (*runtime.Runtime, string) {
rt, instanceID := NewInstance(t)
path := filepath.Join("models", name+".sql")
err := rt.PutFile(context.Background(), instanceID, path, strings.NewReader(sql), true, false)
require.NoError(t, err)
res, err := rt.Reconcile(context.Background(), instanceID, nil, nil, false, false)
require.NoError(t, err)
require.Empty(t, res.Errors)
return rt, instanceID
}
// NewInstanceForProject creates a runtime and an instance for use in tests.
// The passed name should match a test project in the testdata folder.
// You should not do mutable repo operations on the returned instance.
func NewInstanceForProject(t TestingT, name string) (*runtime.Runtime, string) {
rt := New(t)
_, currentFile, _, _ := goruntime.Caller(0)
inst := &drivers.Instance{
OLAPConnector: "duckdb",
RepoConnector: "repo",
EmbedCatalog: true,
Connectors: []*runtimev1.Connector{
{
Type: "file",
Name: "repo",
Config: map[string]string{"dsn": filepath.Join(currentFile, "..", "testdata", name)},
},
{
Type: "duckdb",
Name: "duckdb",
Config: map[string]string{"dsn": "?access_mode=read_write"},
},
},
}
err := rt.CreateInstance(context.Background(), inst)
require.NoError(t, err)
require.NotEmpty(t, inst.ID)
res, err := rt.Reconcile(context.Background(), inst.ID, nil, nil, false, false)
require.NoError(t, err)
require.Empty(t, res.Errors)
return rt, inst.ID
}