mirror of
https://github.com/googleapis/genai-toolbox.git
synced 2026-01-22 22:08:04 -05:00
Compare commits
3 Commits
config-unm
...
config-yam
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87c5953b75 | ||
|
|
7f0c49a4df | ||
|
|
ad8df40791 |
@@ -31,7 +31,7 @@ var _ auth.AuthServiceConfig = Config{}
|
||||
// Auth service configuration
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
ClientID string `yaml:"clientId" validate:"required"`
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ var _ embeddingmodels.EmbeddingModelConfig = Config{}
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Model string `yaml:"model" validate:"required"`
|
||||
ApiKey string `yaml:"apiKey"`
|
||||
Dimension int32 `yaml:"dimension"`
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package gemini_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/embeddingmodels"
|
||||
"github.com/googleapis/genai-toolbox/internal/embeddingmodels/gemini"
|
||||
@@ -34,10 +34,10 @@ func TestParseFromYamlGemini(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
embeddingModels:
|
||||
my-gemini-model:
|
||||
kind: gemini
|
||||
model: text-embedding-004
|
||||
kind: embeddingModels
|
||||
name: my-gemini-model
|
||||
type: gemini
|
||||
model: text-embedding-004
|
||||
`,
|
||||
want: map[string]embeddingmodels.EmbeddingModelConfig{
|
||||
"my-gemini-model": gemini.Config{
|
||||
@@ -50,12 +50,12 @@ func TestParseFromYamlGemini(t *testing.T) {
|
||||
{
|
||||
desc: "full example with optional fields",
|
||||
in: `
|
||||
embeddingModels:
|
||||
complex-gemini:
|
||||
kind: gemini
|
||||
model: text-embedding-004
|
||||
apiKey: "test-api-key"
|
||||
dimension: 768
|
||||
kind: embeddingModels
|
||||
name: complex-gemini
|
||||
type: gemini
|
||||
model: text-embedding-004
|
||||
apiKey: "test-api-key"
|
||||
dimension: 768
|
||||
`,
|
||||
want: map[string]embeddingmodels.EmbeddingModelConfig{
|
||||
"complex-gemini": gemini.Config{
|
||||
@@ -70,16 +70,13 @@ func TestParseFromYamlGemini(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Models server.EmbeddingModelConfigs `yaml:"embeddingModels"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, got, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Models) {
|
||||
t.Fatalf("incorrect parse: %v", cmp.Diff(tc.want, got.Models))
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: %v", cmp.Diff(tc.want, got))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -93,32 +90,29 @@ func TestFailParseFromYamlGemini(t *testing.T) {
|
||||
{
|
||||
desc: "missing required model field",
|
||||
in: `
|
||||
embeddingModels:
|
||||
bad-model:
|
||||
kind: gemini
|
||||
kind: embeddingModels
|
||||
name: bad-model
|
||||
type: gemini
|
||||
`,
|
||||
// Removed the specific model name from the prefix to match your output
|
||||
err: "unable to parse as \"gemini\": Key: 'Config.Model' Error:Field validation for 'Model' failed on the 'required' tag",
|
||||
err: "error unmarshaling embeddingModels: unable to parse as \"bad-model\": Key: 'Config.Model' Error:Field validation for 'Model' failed on the 'required' tag",
|
||||
},
|
||||
{
|
||||
desc: "unknown field",
|
||||
in: `
|
||||
embeddingModels:
|
||||
bad-field:
|
||||
kind: gemini
|
||||
model: text-embedding-004
|
||||
invalid_param: true
|
||||
kind: embeddingModels
|
||||
name: bad-field
|
||||
type: gemini
|
||||
model: text-embedding-004
|
||||
invalid_param: true
|
||||
`,
|
||||
// Updated to match the specific line-starting format of your error output
|
||||
err: "unable to parse as \"gemini\": [1:1] unknown field \"invalid_param\"\n> 1 | invalid_param: true\n ^\n 2 | kind: gemini\n 3 | model: text-embedding-004",
|
||||
err: "error unmarshaling embeddingModels: unable to parse as \"bad-field\": [1:1] unknown field \"invalid_param\"\n> 1 | invalid_param: true\n ^\n 2 | model: text-embedding-004\n 3 | name: bad-field\n 4 | type: gemini",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Models server.EmbeddingModelConfigs `yaml:"embeddingModels"`
|
||||
}{}
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ import (
|
||||
|
||||
type Message = prompts.Message
|
||||
|
||||
const kind = "custom"
|
||||
const resourceType = "custom"
|
||||
|
||||
// init registers this prompt type with the prompt framework.
|
||||
func init() {
|
||||
if !prompts.Register(kind, newConfig) {
|
||||
panic(fmt.Sprintf("prompt type %q already registered", kind))
|
||||
if !prompts.Register(resourceType, newConfig) {
|
||||
panic(fmt.Sprintf("prompt type %q already registered", resourceType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ var _ prompts.PromptConfig = Config{}
|
||||
var _ prompts.Prompt = Prompt{}
|
||||
|
||||
func (c Config) PromptConfigType() string {
|
||||
return kind
|
||||
return resourceType
|
||||
}
|
||||
|
||||
func (c Config) Initialize() (prompts.Prompt, error) {
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestConfig(t *testing.T) {
|
||||
Arguments: testArgs,
|
||||
}
|
||||
|
||||
// initialize and check kind
|
||||
// initialize and check type
|
||||
p, err := cfg.Initialize()
|
||||
if err != nil {
|
||||
t.Fatalf("Initialize() failed: %v", err)
|
||||
|
||||
@@ -30,34 +30,34 @@ var promptRegistry = make(map[string]PromptConfigFactory)
|
||||
|
||||
// Register allows individual prompt packages to register their configuration
|
||||
// factory function. This is typically called from an init() function in the
|
||||
// prompt's package. It associates a 'kind' string with a function that can
|
||||
// prompt's package. It associates a 'type' string with a function that can
|
||||
// produce the specific PromptConfig type. It returns true if the registration was
|
||||
// successful, and false if a prompt with the same kind was already registered.
|
||||
func Register(kind string, factory PromptConfigFactory) bool {
|
||||
if _, exists := promptRegistry[kind]; exists {
|
||||
// Prompt with this kind already exists, do not overwrite.
|
||||
// successful, and false if a prompt with the same type was already registered.
|
||||
func Register(resourceType string, factory PromptConfigFactory) bool {
|
||||
if _, exists := promptRegistry[resourceType]; exists {
|
||||
// Prompt with this type already exists, do not overwrite.
|
||||
return false
|
||||
}
|
||||
promptRegistry[kind] = factory
|
||||
promptRegistry[resourceType] = factory
|
||||
return true
|
||||
}
|
||||
|
||||
// DecodeConfig looks up the registered factory for the given kind and uses it
|
||||
// DecodeConfig looks up the registered factory for the given type and uses it
|
||||
// to decode the prompt configuration.
|
||||
func DecodeConfig(ctx context.Context, kind, name string, decoder *yaml.Decoder) (PromptConfig, error) {
|
||||
factory, found := promptRegistry[kind]
|
||||
if !found && kind == "" {
|
||||
kind = "custom"
|
||||
factory, found = promptRegistry[kind]
|
||||
func DecodeConfig(ctx context.Context, resourceType, name string, decoder *yaml.Decoder) (PromptConfig, error) {
|
||||
factory, found := promptRegistry[resourceType]
|
||||
if !found && resourceType == "" {
|
||||
resourceType = "custom"
|
||||
factory, found = promptRegistry[resourceType]
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, fmt.Errorf("unknown prompt type: %q", kind)
|
||||
return nil, fmt.Errorf("unknown prompt type: %q", resourceType)
|
||||
}
|
||||
|
||||
promptConfig, err := factory(ctx, name, decoder)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse prompt %q as kind %q: %w", name, kind, err)
|
||||
return nil, fmt.Errorf("unable to parse prompt %q as resourceType %q: %w", name, resourceType, err)
|
||||
}
|
||||
return promptConfig, nil
|
||||
}
|
||||
|
||||
@@ -50,17 +50,17 @@ func TestRegistry(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
t.Run("RegisterAndDecodeSuccess", func(t *testing.T) {
|
||||
kind := "testTypeSuccess"
|
||||
if !prompts.Register(kind, mockFactory) {
|
||||
resourceType := "testTypeSuccess"
|
||||
if !prompts.Register(resourceType, mockFactory) {
|
||||
t.Fatal("expected registration to succeed")
|
||||
}
|
||||
// This should fail because we are registering a duplicate
|
||||
if prompts.Register(kind, mockFactory) {
|
||||
if prompts.Register(resourceType, mockFactory) {
|
||||
t.Fatal("expected duplicate registration to fail")
|
||||
}
|
||||
|
||||
decoder := yaml.NewDecoder(strings.NewReader(""))
|
||||
config, err := prompts.DecodeConfig(ctx, kind, "testPrompt", decoder)
|
||||
config, err := prompts.DecodeConfig(ctx, resourceType, "testPrompt", decoder)
|
||||
if err != nil {
|
||||
t.Fatalf("expected DecodeConfig to succeed, but got error: %v", err)
|
||||
}
|
||||
@@ -73,7 +73,7 @@ func TestRegistry(t *testing.T) {
|
||||
decoder := yaml.NewDecoder(strings.NewReader(""))
|
||||
_, err := prompts.DecodeConfig(ctx, "unregisteredType", "testPrompt", decoder)
|
||||
if err == nil {
|
||||
t.Fatal("expected an error for unknown kind, but got nil")
|
||||
t.Fatal("expected an error for unknown type, but got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "unknown prompt type") {
|
||||
t.Errorf("expected error to contain 'unknown prompt type', but got: %v", err)
|
||||
@@ -81,13 +81,13 @@ func TestRegistry(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("FactoryReturnsError", func(t *testing.T) {
|
||||
kind := "testTypeError"
|
||||
if !prompts.Register(kind, mockErrorFactory) {
|
||||
resourceType := "testTypeError"
|
||||
if !prompts.Register(resourceType, mockErrorFactory) {
|
||||
t.Fatal("expected registration to succeed")
|
||||
}
|
||||
|
||||
decoder := yaml.NewDecoder(strings.NewReader(""))
|
||||
_, err := prompts.DecodeConfig(ctx, kind, "testPrompt", decoder)
|
||||
_, err := prompts.DecodeConfig(ctx, resourceType, "testPrompt", decoder)
|
||||
if err == nil {
|
||||
t.Fatal("expected an error from the factory, but got nil")
|
||||
}
|
||||
@@ -100,13 +100,13 @@ func TestRegistry(t *testing.T) {
|
||||
decoder := yaml.NewDecoder(strings.NewReader("description: A test prompt"))
|
||||
config, err := prompts.DecodeConfig(ctx, "", "testDefaultPrompt", decoder)
|
||||
if err != nil {
|
||||
t.Fatalf("expected DecodeConfig with empty kind to succeed, but got error: %v", err)
|
||||
t.Fatalf("expected DecodeConfig with empty type to succeed, but got error: %v", err)
|
||||
}
|
||||
if config == nil {
|
||||
t.Fatal("expected a non-nil config for default kind")
|
||||
t.Fatal("expected a non-nil config for default type")
|
||||
}
|
||||
if config.PromptConfigType() != "custom" {
|
||||
t.Errorf("expected default kind to be 'custom', but got %q", config.PromptConfigType())
|
||||
t.Errorf("expected default type to be 'custom', but got %q", config.PromptConfigType())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -126,25 +126,12 @@ func (s *StringLevel) Type() string {
|
||||
return "stringLevel"
|
||||
}
|
||||
|
||||
// SourceConfigs is a type used to allow unmarshal of the data source config map
|
||||
type SourceConfigs map[string]sources.SourceConfig
|
||||
|
||||
// AuthServiceConfigs is a type used to allow unmarshal of the data authService config map
|
||||
type AuthServiceConfigs map[string]auth.AuthServiceConfig
|
||||
|
||||
// EmbeddingModelConfigs is a type used to allow unmarshal of the embedding model config map
|
||||
type EmbeddingModelConfigs map[string]embeddingmodels.EmbeddingModelConfig
|
||||
|
||||
// ToolConfigs is a type used to allow unmarshal of the tool configs
|
||||
type ToolConfigs map[string]tools.ToolConfig
|
||||
|
||||
// ToolsetConfigs is a type used to allow unmarshal of the toolset configs
|
||||
type ToolsetConfigs map[string]tools.ToolsetConfig
|
||||
|
||||
// PromptConfigs is a type used to allow unmarshal of the prompt configs
|
||||
type PromptConfigs map[string]prompts.PromptConfig
|
||||
|
||||
// PromptConfigs is a type used to allow unmarshal of the prompt configs
|
||||
type PromptsetConfigs map[string]prompts.PromptsetConfig
|
||||
|
||||
func UnmarshalResourceConfig(ctx context.Context, raw []byte) (SourceConfigs, AuthServiceConfigs, EmbeddingModelConfigs, ToolConfigs, ToolsetConfigs, PromptConfigs, error) {
|
||||
@@ -223,7 +210,7 @@ func UnmarshalResourceConfig(ctx context.Context, raw []byte) (SourceConfigs, Au
|
||||
}
|
||||
|
||||
func UnmarshalYAMLSourceConfig(ctx context.Context, name string, r map[string]any) (sources.SourceConfig, error) {
|
||||
typeStr, ok := r["type"].(string)
|
||||
resourceType, ok := r["type"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("missing 'type' field or it is not a string")
|
||||
}
|
||||
@@ -231,7 +218,7 @@ func UnmarshalYAMLSourceConfig(ctx context.Context, name string, r map[string]an
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating decoder: %w", err)
|
||||
}
|
||||
sourceConfig, err := sources.DecodeConfig(ctx, typeStr, name, dec)
|
||||
sourceConfig, err := sources.DecodeConfig(ctx, resourceType, name, dec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -239,12 +226,12 @@ func UnmarshalYAMLSourceConfig(ctx context.Context, name string, r map[string]an
|
||||
}
|
||||
|
||||
func UnmarshalYAMLAuthServiceConfig(ctx context.Context, name string, r map[string]any) (auth.AuthServiceConfig, error) {
|
||||
typeStr, ok := r["type"].(string)
|
||||
resourceType, ok := r["type"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("missing 'type' field or it is not a string")
|
||||
}
|
||||
if typeStr != google.AuthServiceType {
|
||||
return nil, fmt.Errorf("%s is not a valid type of auth service", typeStr)
|
||||
if resourceType != google.AuthServiceType {
|
||||
return nil, fmt.Errorf("%s is not a valid type of auth service", resourceType)
|
||||
}
|
||||
dec, err := util.NewStrictDecoder(r)
|
||||
if err != nil {
|
||||
@@ -258,12 +245,12 @@ func UnmarshalYAMLAuthServiceConfig(ctx context.Context, name string, r map[stri
|
||||
}
|
||||
|
||||
func UnmarshalYAMLEmbeddingModelConfig(ctx context.Context, name string, r map[string]any) (embeddingmodels.EmbeddingModelConfig, error) {
|
||||
typeStr, ok := r["type"].(string)
|
||||
resourceType, ok := r["type"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("missing 'type' field or it is not a string")
|
||||
}
|
||||
if typeStr != gemini.EmbeddingModelType {
|
||||
return nil, fmt.Errorf("%s is not a valid type of embedding model", typeStr)
|
||||
if resourceType != gemini.EmbeddingModelType {
|
||||
return nil, fmt.Errorf("%s is not a valid type of embedding model", resourceType)
|
||||
}
|
||||
dec, err := util.NewStrictDecoder(r)
|
||||
if err != nil {
|
||||
@@ -277,7 +264,7 @@ func UnmarshalYAMLEmbeddingModelConfig(ctx context.Context, name string, r map[s
|
||||
}
|
||||
|
||||
func UnmarshalYAMLToolConfig(ctx context.Context, name string, r map[string]any) (tools.ToolConfig, error) {
|
||||
typeStr, ok := r["type"].(string)
|
||||
resourceType, ok := r["type"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("missing 'type' field or it is not a string")
|
||||
}
|
||||
@@ -293,7 +280,7 @@ func UnmarshalYAMLToolConfig(ctx context.Context, name string, r map[string]any)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating decoder: %s", err)
|
||||
}
|
||||
toolCfg, err := tools.DecodeConfig(ctx, typeStr, name, dec)
|
||||
toolCfg, err := tools.DecodeConfig(ctx, resourceType, name, dec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -315,12 +302,12 @@ func UnmarshalYAMLToolsetConfig(ctx context.Context, name string, r map[string]a
|
||||
}
|
||||
|
||||
func UnmarshalYAMLPromptConfig(ctx context.Context, name string, r map[string]any) (prompts.PromptConfig, error) {
|
||||
// Look for the 'kind' field. If it's not present, kindStr will be an
|
||||
// Look for the 'type' field. If it's not present, typeStr will be an
|
||||
// empty string, which prompts.DecodeConfig will correctly default to "custom".
|
||||
var typeStr string
|
||||
var resourceType string
|
||||
if typeVal, ok := r["type"]; ok {
|
||||
var isString bool
|
||||
typeStr, isString = typeVal.(string)
|
||||
resourceType, isString = typeVal.(string)
|
||||
if !isString {
|
||||
return nil, fmt.Errorf("invalid 'type' field for prompt %q (must be a string)", name)
|
||||
}
|
||||
@@ -330,8 +317,8 @@ func UnmarshalYAMLPromptConfig(ctx context.Context, name string, r map[string]an
|
||||
return nil, fmt.Errorf("error creating decoder: %s", err)
|
||||
}
|
||||
|
||||
// Use the central registry to decode the prompt based on its kind.
|
||||
promptCfg, err := prompts.DecodeConfig(ctx, typeStr, name, dec)
|
||||
// Use the central registry to decode the prompt based on its type.
|
||||
promptCfg, err := prompts.DecodeConfig(ctx, resourceType, name, dec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
DefaultProject string `yaml:"defaultProject"`
|
||||
UseClientOAuth bool `yaml:"useClientOAuth"`
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package alloydbadmin_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -34,9 +34,9 @@ func TestParseFromYamlAlloyDBAdmin(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-alloydb-admin-instance:
|
||||
kind: alloydb-admin
|
||||
kind: sources
|
||||
name: my-alloydb-admin-instance
|
||||
type: alloydb-admin
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-alloydb-admin-instance": alloydbadmin.Config{
|
||||
@@ -49,10 +49,10 @@ func TestParseFromYamlAlloyDBAdmin(t *testing.T) {
|
||||
{
|
||||
desc: "use client auth example",
|
||||
in: `
|
||||
sources:
|
||||
my-alloydb-admin-instance:
|
||||
kind: alloydb-admin
|
||||
useClientOAuth: true
|
||||
kind: sources
|
||||
name: my-alloydb-admin-instance
|
||||
type: alloydb-admin
|
||||
useClientOAuth: true
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-alloydb-admin-instance": alloydbadmin.Config{
|
||||
@@ -65,16 +65,13 @@ func TestParseFromYamlAlloyDBAdmin(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -89,30 +86,27 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-alloydb-admin-instance:
|
||||
kind: alloydb-admin
|
||||
project: test-project
|
||||
kind: sources
|
||||
name: my-alloydb-admin-instance
|
||||
type: alloydb-admin
|
||||
project: test-project
|
||||
`,
|
||||
err: "unable to parse source \"my-alloydb-admin-instance\" as \"alloydb-admin\": [2:1] unknown field \"project\"\n 1 | kind: alloydb-admin\n> 2 | project: test-project\n ^\n",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-alloydb-admin-instance\" as \"alloydb-admin\": [2:1] unknown field \"project\"\n 1 | name: my-alloydb-admin-instance\n> 2 | project: test-project\n ^\n 3 | type: alloydb-admin",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-alloydb-admin-instance:
|
||||
useClientOAuth: true
|
||||
kind: sources
|
||||
name: my-alloydb-admin-instance
|
||||
useClientOAuth: true
|
||||
`,
|
||||
err: "missing 'kind' field for source \"my-alloydb-admin-instance\"",
|
||||
err: "error unmarshaling sources: missing 'type' field or it is not a string",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Region string `yaml:"region" validate:"required"`
|
||||
Cluster string `yaml:"cluster" validate:"required"`
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package alloydbpg_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -34,16 +34,16 @@ func TestParseFromYamlAlloyDBPg(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-pg-instance": alloydbpg.Config{
|
||||
@@ -63,17 +63,17 @@ func TestParseFromYamlAlloyDBPg(t *testing.T) {
|
||||
{
|
||||
desc: "public ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
ipType: Public
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
ipType: Public
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-pg-instance": alloydbpg.Config{
|
||||
@@ -93,17 +93,17 @@ func TestParseFromYamlAlloyDBPg(t *testing.T) {
|
||||
{
|
||||
desc: "private ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
ipType: private
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
ipType: private
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-pg-instance": alloydbpg.Config{
|
||||
@@ -123,16 +123,13 @@ func TestParseFromYamlAlloyDBPg(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -147,60 +144,56 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "invalid ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
ipType: fail
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
ipType: fail
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"",
|
||||
},
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: alloydb-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": [3:1] unknown field \"foo\"\n 1 | cluster: my-cluster\n 2 | database: my_db\n> 3 | foo: bar\n ^\n 4 | instance: my-instance\n 5 | kind: alloydb-postgres\n 6 | password: my_pass\n 7 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": [3:1] unknown field \"foo\"\n 1 | cluster: my-cluster\n 2 | database: my_db\n> 3 | foo: bar\n ^\n 4 | instance: my-instance\n 5 | name: my-pg-instance\n 6 | password: my_pass\n 7 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: alloydb-postgres
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: alloydb-postgres
|
||||
region: my-region
|
||||
cluster: my-cluster
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"alloydb-postgres\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
type Config struct {
|
||||
// BigQuery configs
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Location string `yaml:"location"`
|
||||
WriteMode string `yaml:"writeMode"`
|
||||
@@ -120,7 +120,7 @@ func (s *StringOrStringSlice) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
}
|
||||
|
||||
func (r Config) SourceConfigType() string {
|
||||
// Returns BigQuery source kind
|
||||
// Returns BigQuery source type
|
||||
return SourceType
|
||||
}
|
||||
func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
|
||||
@@ -303,7 +303,7 @@ type Session struct {
|
||||
}
|
||||
|
||||
func (s *Source) SourceType() string {
|
||||
// Returns BigQuery Google SQL source kind
|
||||
// Returns BigQuery Google SQL source type
|
||||
return SourceType
|
||||
}
|
||||
|
||||
|
||||
@@ -15,18 +15,18 @@
|
||||
package bigquery_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/bigquery"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
"github.com/googleapis/genai-toolbox/internal/util"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
)
|
||||
|
||||
func TestParseFromYamlBigQuery(t *testing.T) {
|
||||
@@ -38,12 +38,12 @@ func TestParseFromYamlBigQuery(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: bigquery
|
||||
project: my-project
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: bigquery
|
||||
project: my-project
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": bigquery.Config{
|
||||
Name: "my-instance",
|
||||
Type: bigquery.SourceType,
|
||||
@@ -56,14 +56,14 @@ func TestParseFromYamlBigQuery(t *testing.T) {
|
||||
{
|
||||
desc: "all fields specified",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: bigquery
|
||||
project: my-project
|
||||
location: asia
|
||||
writeMode: blocked
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: bigquery
|
||||
project: my-project
|
||||
location: asia
|
||||
writeMode: blocked
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": bigquery.Config{
|
||||
Name: "my-instance",
|
||||
Type: bigquery.SourceType,
|
||||
@@ -77,14 +77,14 @@ func TestParseFromYamlBigQuery(t *testing.T) {
|
||||
{
|
||||
desc: "use client auth example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
useClientOAuth: true
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
useClientOAuth: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": bigquery.Config{
|
||||
Name: "my-instance",
|
||||
Type: bigquery.SourceType,
|
||||
@@ -97,15 +97,15 @@ func TestParseFromYamlBigQuery(t *testing.T) {
|
||||
{
|
||||
desc: "with allowed datasets example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
allowedDatasets:
|
||||
- my_dataset
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
allowedDatasets:
|
||||
- my_dataset
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": bigquery.Config{
|
||||
Name: "my-instance",
|
||||
Type: bigquery.SourceType,
|
||||
@@ -118,14 +118,14 @@ func TestParseFromYamlBigQuery(t *testing.T) {
|
||||
{
|
||||
desc: "with service account impersonation example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
impersonateServiceAccount: service-account@my-project.iam.gserviceaccount.com
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
impersonateServiceAccount: service-account@my-project.iam.gserviceaccount.com
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": bigquery.Config{
|
||||
Name: "my-instance",
|
||||
Type: bigquery.SourceType,
|
||||
@@ -138,16 +138,16 @@ func TestParseFromYamlBigQuery(t *testing.T) {
|
||||
{
|
||||
desc: "with custom scopes example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
scopes:
|
||||
- https://www.googleapis.com/auth/bigquery
|
||||
- https://www.googleapis.com/auth/cloud-platform
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
scopes:
|
||||
- https://www.googleapis.com/auth/bigquery
|
||||
- https://www.googleapis.com/auth/cloud-platform
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": bigquery.Config{
|
||||
Name: "my-instance",
|
||||
Type: bigquery.SourceType,
|
||||
@@ -160,14 +160,14 @@ func TestParseFromYamlBigQuery(t *testing.T) {
|
||||
{
|
||||
desc: "with max query result rows example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
maxQueryResultRows: 10
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
maxQueryResultRows: 10
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": bigquery.Config{
|
||||
Name: "my-instance",
|
||||
Type: bigquery.SourceType,
|
||||
@@ -180,20 +180,15 @@ func TestParseFromYamlBigQuery(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Fatalf("incorrect parse (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestFailParseFromYaml(t *testing.T) {
|
||||
@@ -205,33 +200,29 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: bigquery
|
||||
project: my-project
|
||||
location: us
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"bigquery\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: bigquery\n 3 | location: us\n 4 | project: my-project",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"bigquery\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | location: us\n 3 | name: my-instance\n 4 | project: my-project\n 5 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: bigquery
|
||||
location: us
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: bigquery
|
||||
location: us
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"bigquery\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"bigquery\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Instance string `yaml:"instance" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package bigtable_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -34,11 +34,11 @@ func TestParseFromYamlBigtableDb(t *testing.T) {
|
||||
{
|
||||
desc: "can configure with a bigtable table",
|
||||
in: `
|
||||
sources:
|
||||
my-bigtable-instance:
|
||||
kind: bigtable
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
kind: sources
|
||||
name: my-bigtable-instance
|
||||
type: bigtable
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-bigtable-instance": bigtable.Config{
|
||||
@@ -52,16 +52,12 @@ func TestParseFromYamlBigtableDb(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -77,33 +73,29 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-bigtable-instance:
|
||||
kind: bigtable
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-bigtable-instance
|
||||
type: bigtable
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-bigtable-instance\" as \"bigtable\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | instance: my-instance\n 3 | kind: bigtable\n 4 | project: my-project",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-bigtable-instance\" as \"bigtable\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | instance: my-instance\n 3 | name: my-bigtable-instance\n 4 | project: my-project\n 5 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-bigtable-instance:
|
||||
kind: bigtable
|
||||
project: my-project
|
||||
kind: sources
|
||||
name: my-bigtable-instance
|
||||
type: bigtable
|
||||
project: my-project
|
||||
`,
|
||||
err: "unable to parse source \"my-bigtable-instance\" as \"bigtable\": Key: 'Config.Instance' Error:Field validation for 'Instance' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-bigtable-instance\" as \"bigtable\": Key: 'Config.Instance' Error:Field validation for 'Instance' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Hosts []string `yaml:"hosts" validate:"required"`
|
||||
Keyspace string `yaml:"keyspace"`
|
||||
ProtoVersion int `yaml:"protoVersion"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package cassandra_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/cassandra"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,14 +34,14 @@ func TestParseFromYamlCassandra(t *testing.T) {
|
||||
{
|
||||
desc: "basic example (without optional fields)",
|
||||
in: `
|
||||
sources:
|
||||
my-cassandra-instance:
|
||||
kind: cassandra
|
||||
hosts:
|
||||
- "my-host1"
|
||||
- "my-host2"
|
||||
kind: sources
|
||||
name: my-cassandra-instance
|
||||
type: cassandra
|
||||
hosts:
|
||||
- "my-host1"
|
||||
- "my-host2"
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-cassandra-instance": cassandra.Config{
|
||||
Name: "my-cassandra-instance",
|
||||
Type: cassandra.SourceType,
|
||||
@@ -59,22 +60,22 @@ func TestParseFromYamlCassandra(t *testing.T) {
|
||||
{
|
||||
desc: "with optional fields",
|
||||
in: `
|
||||
sources:
|
||||
my-cassandra-instance:
|
||||
kind: cassandra
|
||||
hosts:
|
||||
- "my-host1"
|
||||
- "my-host2"
|
||||
username: "user"
|
||||
password: "pass"
|
||||
keyspace: "example_keyspace"
|
||||
protoVersion: 4
|
||||
caPath: "path/to/ca.crt"
|
||||
certPath: "path/to/cert"
|
||||
keyPath: "path/to/key"
|
||||
enableHostVerification: true
|
||||
kind: sources
|
||||
name: my-cassandra-instance
|
||||
type: cassandra
|
||||
hosts:
|
||||
- "my-host1"
|
||||
- "my-host2"
|
||||
username: "user"
|
||||
password: "pass"
|
||||
keyspace: "example_keyspace"
|
||||
protoVersion: 4
|
||||
caPath: "path/to/ca.crt"
|
||||
certPath: "path/to/cert"
|
||||
keyPath: "path/to/key"
|
||||
enableHostVerification: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-cassandra-instance": cassandra.Config{
|
||||
Name: "my-cassandra-instance",
|
||||
Type: cassandra.SourceType,
|
||||
@@ -93,16 +94,12 @@ func TestParseFromYamlCassandra(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -118,33 +115,29 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-cassandra-instance:
|
||||
kind: cassandra
|
||||
hosts:
|
||||
- "my-host"
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-cassandra-instance
|
||||
type: cassandra
|
||||
hosts:
|
||||
- "my-host"
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-cassandra-instance\" as \"cassandra\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | hosts:\n 3 | - my-host\n 4 | kind: cassandra",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-cassandra-instance\" as \"cassandra\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | hosts:\n 3 | - my-host\n 4 | name: my-cassandra-instance\n 5 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-cassandra-instance:
|
||||
kind: cassandra
|
||||
kind: sources
|
||||
name: my-cassandra-instance
|
||||
type: cassandra
|
||||
`,
|
||||
err: "unable to parse source \"my-cassandra-instance\" as \"cassandra\": Key: 'Config.Hosts' Error:Field validation for 'Hosts' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-cassandra-instance\" as \"cassandra\": Key: 'Config.Hosts' Error:Field validation for 'Hosts' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
Database string `yaml:"database" validate:"required"`
|
||||
|
||||
@@ -21,137 +21,113 @@ import (
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
"go.opentelemetry.io/otel"
|
||||
)
|
||||
|
||||
func TestConfigSourceConfigType(t *testing.T) {
|
||||
config := Config{}
|
||||
if config.SourceConfigType() != SourceType {
|
||||
t.Errorf("Expected %s, got %s", SourceType, config.SourceConfigType())
|
||||
func TestParseFromYamlClickhouse(t *testing.T) {
|
||||
tcs := []struct {
|
||||
desc string
|
||||
in string
|
||||
want server.SourceConfigs
|
||||
}{
|
||||
{
|
||||
desc: "all fields specified",
|
||||
in: `
|
||||
kind: sources
|
||||
name: test-clickhouse
|
||||
type: clickhouse
|
||||
host: localhost
|
||||
port: "8443"
|
||||
user: default
|
||||
password: "mypass"
|
||||
database: mydb
|
||||
protocol: https
|
||||
secure: true
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"test-clickhouse": Config{
|
||||
Name: "test-clickhouse",
|
||||
Type: "clickhouse",
|
||||
Host: "localhost",
|
||||
Port: "8443",
|
||||
User: "default",
|
||||
Password: "mypass",
|
||||
Database: "mydb",
|
||||
Protocol: "https",
|
||||
Secure: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "minimal configuration with defaults",
|
||||
in: `
|
||||
kind: sources
|
||||
name: minimal-clickhouse
|
||||
type: clickhouse
|
||||
host: 127.0.0.1
|
||||
port: "8123"
|
||||
user: testuser
|
||||
database: testdb
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"minimal-clickhouse": Config{
|
||||
Name: "minimal-clickhouse",
|
||||
Type: "clickhouse",
|
||||
Host: "127.0.0.1",
|
||||
Port: "8123",
|
||||
User: "testuser",
|
||||
Password: "",
|
||||
Database: "testdb",
|
||||
Protocol: "",
|
||||
Secure: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
yaml string
|
||||
expected Config
|
||||
func TestFailParseFromYaml(t *testing.T) {
|
||||
tcs := []struct {
|
||||
desc string
|
||||
in string
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "all fields specified",
|
||||
yaml: `
|
||||
name: test-clickhouse
|
||||
kind: clickhouse
|
||||
host: localhost
|
||||
port: "8443"
|
||||
user: default
|
||||
password: "mypass"
|
||||
database: mydb
|
||||
protocol: https
|
||||
secure: true
|
||||
desc: "extra field",
|
||||
in: `
|
||||
kind: sources
|
||||
name: test-clickhouse
|
||||
type: clickhouse
|
||||
host: localhost
|
||||
foo: bar
|
||||
`,
|
||||
expected: Config{
|
||||
Name: "test-clickhouse",
|
||||
Type: "clickhouse",
|
||||
Host: "localhost",
|
||||
Port: "8443",
|
||||
User: "default",
|
||||
Password: "mypass",
|
||||
Database: "mydb",
|
||||
Protocol: "https",
|
||||
Secure: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "minimal configuration with defaults",
|
||||
yaml: `
|
||||
name: minimal-clickhouse
|
||||
kind: clickhouse
|
||||
host: 127.0.0.1
|
||||
port: "8123"
|
||||
user: testuser
|
||||
database: testdb
|
||||
`,
|
||||
expected: Config{
|
||||
Name: "minimal-clickhouse",
|
||||
Type: "clickhouse",
|
||||
Host: "127.0.0.1",
|
||||
Port: "8123",
|
||||
User: "testuser",
|
||||
Password: "",
|
||||
Database: "testdb",
|
||||
Protocol: "",
|
||||
Secure: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "http protocol",
|
||||
yaml: `
|
||||
name: http-clickhouse
|
||||
kind: clickhouse
|
||||
host: clickhouse.example.com
|
||||
port: "8123"
|
||||
user: analytics
|
||||
password: "securepass"
|
||||
database: analytics_db
|
||||
protocol: http
|
||||
secure: false
|
||||
`,
|
||||
expected: Config{
|
||||
Name: "http-clickhouse",
|
||||
Type: "clickhouse",
|
||||
Host: "clickhouse.example.com",
|
||||
Port: "8123",
|
||||
User: "analytics",
|
||||
Password: "securepass",
|
||||
Database: "analytics_db",
|
||||
Protocol: "http",
|
||||
Secure: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "https with secure connection",
|
||||
yaml: `
|
||||
name: secure-clickhouse
|
||||
kind: clickhouse
|
||||
host: secure.clickhouse.io
|
||||
port: "8443"
|
||||
user: secureuser
|
||||
password: "verysecure"
|
||||
database: production
|
||||
protocol: https
|
||||
secure: true
|
||||
`,
|
||||
expected: Config{
|
||||
Name: "secure-clickhouse",
|
||||
Type: "clickhouse",
|
||||
Host: "secure.clickhouse.io",
|
||||
Port: "8443",
|
||||
User: "secureuser",
|
||||
Password: "verysecure",
|
||||
Database: "production",
|
||||
Protocol: "https",
|
||||
Secure: true,
|
||||
},
|
||||
err: "error unmarshaling sources: unable to parse source \"test-clickhouse\" as \"clickhouse\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | host: localhost\n 3 | name: test-clickhouse\n 4 | type: clickhouse",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
decoder := yaml.NewDecoder(strings.NewReader(string(testutils.FormatYaml(tt.yaml))))
|
||||
config, err := newConfig(context.Background(), tt.expected.Name, decoder)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create config: %v", err)
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
clickhouseConfig, ok := config.(Config)
|
||||
if !ok {
|
||||
t.Fatalf("Expected Config type, got %T", config)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(tt.expected, clickhouseConfig); diff != "" {
|
||||
t.Errorf("Config mismatch (-want +got):\n%s", diff)
|
||||
errStr := err.Error()
|
||||
if errStr != tc.err {
|
||||
t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -167,19 +143,11 @@ func TestNewConfigInvalidYAML(t *testing.T) {
|
||||
name: "invalid yaml syntax",
|
||||
yaml: `
|
||||
name: test-clickhouse
|
||||
kind: clickhouse
|
||||
type: clickhouse
|
||||
host: [invalid
|
||||
`,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
name: "missing required fields",
|
||||
yaml: `
|
||||
name: test-clickhouse
|
||||
kind: clickhouse
|
||||
`,
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
ProjectID string `yaml:"projectId" validate:"required"`
|
||||
UseClientOAuth bool `yaml:"useClientOAuth"`
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -39,11 +38,11 @@ func TestParseFromYamlCloudGDA(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-gda-instance:
|
||||
kind: cloud-gemini-data-analytics
|
||||
projectId: test-project-id
|
||||
`,
|
||||
kind: sources
|
||||
name: my-gda-instance
|
||||
type: cloud-gemini-data-analytics
|
||||
projectId: test-project-id
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-gda-instance": cloudgda.Config{
|
||||
Name: "my-gda-instance",
|
||||
@@ -56,11 +55,11 @@ func TestParseFromYamlCloudGDA(t *testing.T) {
|
||||
{
|
||||
desc: "use client auth example",
|
||||
in: `
|
||||
sources:
|
||||
my-gda-instance:
|
||||
kind: cloud-gemini-data-analytics
|
||||
projectId: another-project
|
||||
useClientOAuth: true
|
||||
kind: sources
|
||||
name: my-gda-instance
|
||||
type: cloud-gemini-data-analytics
|
||||
projectId: another-project
|
||||
useClientOAuth: true
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-gda-instance": cloudgda.Config{
|
||||
@@ -76,16 +75,12 @@ func TestParseFromYamlCloudGDA(t *testing.T) {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -101,22 +96,18 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "missing projectId",
|
||||
in: `
|
||||
sources:
|
||||
my-gda-instance:
|
||||
kind: cloud-gemini-data-analytics
|
||||
kind: sources
|
||||
name: my-gda-instance
|
||||
type: cloud-gemini-data-analytics
|
||||
`,
|
||||
err: "unable to parse source \"my-gda-instance\" as \"cloud-gemini-data-analytics\": Key: 'Config.ProjectID' Error:Field validation for 'ProjectID' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-gda-instance\" as \"cloud-gemini-data-analytics\": Key: 'Config.ProjectID' Error:Field validation for 'ProjectID' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
type Config struct {
|
||||
// Healthcare configs
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Region string `yaml:"region" validate:"required"`
|
||||
Dataset string `yaml:"dataset" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package cloudhealthcare_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/cloudhealthcare"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,14 +34,14 @@ func TestParseFromYamlCloudHealthcare(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-healthcare
|
||||
project: my-project
|
||||
region: us-central1
|
||||
dataset: my-dataset
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-healthcare
|
||||
project: my-project
|
||||
region: us-central1
|
||||
dataset: my-dataset
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": cloudhealthcare.Config{
|
||||
Name: "my-instance",
|
||||
Type: cloudhealthcare.SourceType,
|
||||
@@ -54,15 +55,15 @@ func TestParseFromYamlCloudHealthcare(t *testing.T) {
|
||||
{
|
||||
desc: "use client auth example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-healthcare
|
||||
project: my-project
|
||||
region: us
|
||||
dataset: my-dataset
|
||||
useClientOAuth: true
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-healthcare
|
||||
project: my-project
|
||||
region: us
|
||||
dataset: my-dataset
|
||||
useClientOAuth: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": cloudhealthcare.Config{
|
||||
Name: "my-instance",
|
||||
Type: cloudhealthcare.SourceType,
|
||||
@@ -76,19 +77,19 @@ func TestParseFromYamlCloudHealthcare(t *testing.T) {
|
||||
{
|
||||
desc: "with allowed stores example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-healthcare
|
||||
project: my-project
|
||||
region: us
|
||||
dataset: my-dataset
|
||||
allowedFhirStores:
|
||||
- my-fhir-store
|
||||
allowedDicomStores:
|
||||
- my-dicom-store1
|
||||
- my-dicom-store2
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-healthcare
|
||||
project: my-project
|
||||
region: us
|
||||
dataset: my-dataset
|
||||
allowedFhirStores:
|
||||
- my-fhir-store
|
||||
allowedDicomStores:
|
||||
- my-dicom-store1
|
||||
- my-dicom-store2
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": cloudhealthcare.Config{
|
||||
Name: "my-instance",
|
||||
Type: cloudhealthcare.SourceType,
|
||||
@@ -103,16 +104,12 @@ func TestParseFromYamlCloudHealthcare(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -127,35 +124,31 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-healthcare
|
||||
project: my-project
|
||||
region: us-central1
|
||||
dataset: my-dataset
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-healthcare
|
||||
project: my-project
|
||||
region: us-central1
|
||||
dataset: my-dataset
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"cloud-healthcare\": [2:1] unknown field \"foo\"\n 1 | dataset: my-dataset\n> 2 | foo: bar\n ^\n 3 | kind: cloud-healthcare\n 4 | project: my-project\n 5 | region: us-central1",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-healthcare\": [2:1] unknown field \"foo\"\n 1 | dataset: my-dataset\n> 2 | foo: bar\n ^\n 3 | name: my-instance\n 4 | project: my-project\n 5 | region: us-central1\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-healthcare
|
||||
project: my-project
|
||||
region: us-central1
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-healthcare
|
||||
project: my-project
|
||||
region: us-central1
|
||||
`,
|
||||
err: `unable to parse source "my-instance" as "cloud-healthcare": Key: 'Config.Dataset' Error:Field validation for 'Dataset' failed on the 'required' tag`,
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-healthcare\": Key: 'Config.Dataset' Error:Field validation for 'Dataset' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
UseClientOAuth bool `yaml:"useClientOAuth"`
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package cloudmonitoring_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -35,9 +35,9 @@ func TestParseFromYamlCloudMonitoring(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-cloud-monitoring-instance:
|
||||
kind: cloud-monitoring
|
||||
kind: sources
|
||||
name: my-cloud-monitoring-instance
|
||||
type: cloud-monitoring
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-cloud-monitoring-instance": cloudmonitoring.Config{
|
||||
@@ -50,10 +50,10 @@ func TestParseFromYamlCloudMonitoring(t *testing.T) {
|
||||
{
|
||||
desc: "use client auth example",
|
||||
in: `
|
||||
sources:
|
||||
my-cloud-monitoring-instance:
|
||||
kind: cloud-monitoring
|
||||
useClientOAuth: true
|
||||
kind: sources
|
||||
name: my-cloud-monitoring-instance
|
||||
type: cloud-monitoring
|
||||
useClientOAuth: true
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-cloud-monitoring-instance": cloudmonitoring.Config{
|
||||
@@ -68,16 +68,12 @@ func TestParseFromYamlCloudMonitoring(t *testing.T) {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -93,36 +89,28 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-cloud-monitoring-instance:
|
||||
kind: cloud-monitoring
|
||||
project: test-project
|
||||
kind: sources
|
||||
name: my-cloud-monitoring-instance
|
||||
type: cloud-monitoring
|
||||
project: test-project
|
||||
`,
|
||||
err: `unable to parse source "my-cloud-monitoring-instance" as "cloud-monitoring": [2:1] unknown field "project"
|
||||
1 | kind: cloud-monitoring
|
||||
> 2 | project: test-project
|
||||
^
|
||||
`,
|
||||
err: "error unmarshaling sources: unable to parse source \"my-cloud-monitoring-instance\" as \"cloud-monitoring\": [2:1] unknown field \"project\"\n 1 | name: my-cloud-monitoring-instance\n> 2 | project: test-project\n ^\n 3 | type: cloud-monitoring",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-cloud-monitoring-instance:
|
||||
useClientOAuth: true
|
||||
kind: sources
|
||||
name: my-cloud-monitoring-instance
|
||||
useClientOAuth: true
|
||||
`,
|
||||
err: "missing 'kind' field for source \"my-cloud-monitoring-instance\"",
|
||||
err: "error unmarshaling sources: missing 'type' field or it is not a string",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
DefaultProject string `yaml:"defaultProject"`
|
||||
UseClientOAuth bool `yaml:"useClientOAuth"`
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package cloudsqladmin_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -35,9 +35,9 @@ func TestParseFromYamlCloudSQLAdmin(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-cloud-sql-admin-instance:
|
||||
kind: cloud-sql-admin
|
||||
kind: sources
|
||||
name: my-cloud-sql-admin-instance
|
||||
type: cloud-sql-admin
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-cloud-sql-admin-instance": cloudsqladmin.Config{
|
||||
@@ -50,10 +50,10 @@ func TestParseFromYamlCloudSQLAdmin(t *testing.T) {
|
||||
{
|
||||
desc: "use client auth example",
|
||||
in: `
|
||||
sources:
|
||||
my-cloud-sql-admin-instance:
|
||||
kind: cloud-sql-admin
|
||||
useClientOAuth: true
|
||||
kind: sources
|
||||
name: my-cloud-sql-admin-instance
|
||||
type: cloud-sql-admin
|
||||
useClientOAuth: true
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-cloud-sql-admin-instance": cloudsqladmin.Config{
|
||||
@@ -68,16 +68,12 @@ func TestParseFromYamlCloudSQLAdmin(t *testing.T) {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -93,36 +89,28 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-cloud-sql-admin-instance:
|
||||
kind: cloud-sql-admin
|
||||
project: test-project
|
||||
kind: sources
|
||||
name: my-cloud-sql-admin-instance
|
||||
type: cloud-sql-admin
|
||||
project: test-project
|
||||
`,
|
||||
err: `unable to parse source "my-cloud-sql-admin-instance" as "cloud-sql-admin": [2:1] unknown field "project"
|
||||
1 | kind: cloud-sql-admin
|
||||
> 2 | project: test-project
|
||||
^
|
||||
`,
|
||||
err: "error unmarshaling sources: unable to parse source \"my-cloud-sql-admin-instance\" as \"cloud-sql-admin\": [2:1] unknown field \"project\"\n 1 | name: my-cloud-sql-admin-instance\n> 2 | project: test-project\n ^\n 3 | type: cloud-sql-admin",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-cloud-sql-admin-instance:
|
||||
useClientOAuth: true
|
||||
kind: sources
|
||||
name: my-cloud-sql-admin-instance
|
||||
useClientOAuth: true
|
||||
`,
|
||||
err: "missing 'kind' field for source \"my-cloud-sql-admin-instance\"",
|
||||
err: "error unmarshaling sources: missing 'type' field or it is not a string",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
tc := tc
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
type Config struct {
|
||||
// Cloud SQL MSSQL configs
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Region string `yaml:"region" validate:"required"`
|
||||
Instance string `yaml:"instance" validate:"required"`
|
||||
@@ -63,7 +63,7 @@ type Config struct {
|
||||
}
|
||||
|
||||
func (r Config) SourceConfigType() string {
|
||||
// Returns Cloud SQL MSSQL source kind
|
||||
// Returns Cloud SQL MSSQL source type
|
||||
return SourceType
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ type Source struct {
|
||||
}
|
||||
|
||||
func (s *Source) SourceType() string {
|
||||
// Returns Cloud SQL MSSQL source kind
|
||||
// Returns Cloud SQL MSSQL source type
|
||||
return SourceType
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package cloudsqlmssql_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmssql"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,17 +34,17 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": cloudsqlmssql.Config{
|
||||
Name: "my-instance",
|
||||
Type: cloudsqlmssql.SourceType,
|
||||
@@ -60,18 +61,18 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) {
|
||||
{
|
||||
desc: "psc ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
ipType: psc
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
ipType: psc
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": cloudsqlmssql.Config{
|
||||
Name: "my-instance",
|
||||
Type: cloudsqlmssql.SourceType,
|
||||
@@ -88,18 +89,18 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) {
|
||||
{
|
||||
desc: "with deprecated ipAddress",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipAddress: random
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipAddress: random
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": cloudsqlmssql.Config{
|
||||
Name: "my-instance",
|
||||
Type: cloudsqlmssql.SourceType,
|
||||
@@ -117,16 +118,12 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect psarse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect psarse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -142,57 +139,53 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "invalid ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: fail
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: fail
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"cloud-sql-mssql\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-sql-mssql\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"",
|
||||
},
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-sql-mssql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"cloud-sql-mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | kind: cloud-sql-mssql\n 5 | password: my_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-sql-mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | name: my-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: cloud-sql-mssql
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: cloud-sql-mssql
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"cloud-sql-mssql\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"cloud-sql-mssql\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Region string `yaml:"region" validate:"required"`
|
||||
Instance string `yaml:"instance" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package cloudsqlmysql_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/cloudsqlmysql"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,17 +34,17 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mysql-instance": cloudsqlmysql.Config{
|
||||
Name: "my-mysql-instance",
|
||||
Type: cloudsqlmysql.SourceType,
|
||||
@@ -60,18 +61,18 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) {
|
||||
{
|
||||
desc: "public ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: Public
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: Public
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mysql-instance": cloudsqlmysql.Config{
|
||||
Name: "my-mysql-instance",
|
||||
Type: cloudsqlmysql.SourceType,
|
||||
@@ -88,18 +89,18 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) {
|
||||
{
|
||||
desc: "private ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: private
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: private
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mysql-instance": cloudsqlmysql.Config{
|
||||
Name: "my-mysql-instance",
|
||||
Type: cloudsqlmysql.SourceType,
|
||||
@@ -116,18 +117,18 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) {
|
||||
{
|
||||
desc: "psc ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: psc
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: psc
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mysql-instance": cloudsqlmysql.Config{
|
||||
Name: "my-mysql-instance",
|
||||
Type: cloudsqlmysql.SourceType,
|
||||
@@ -144,16 +145,12 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -169,57 +166,53 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "invalid ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: fail
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: fail
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"",
|
||||
},
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: cloud-sql-mysql
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | kind: cloud-sql-mysql\n 5 | password: my_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | name: my-mysql-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: cloud-sql-mysql
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: cloud-sql-mysql
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"cloud-sql-mysql\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Region string `yaml:"region" validate:"required"`
|
||||
Instance string `yaml:"instance" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package cloudsqlpg_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/cloudsqlpg"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,17 +34,17 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-pg-instance": cloudsqlpg.Config{
|
||||
Name: "my-pg-instance",
|
||||
Type: cloudsqlpg.SourceType,
|
||||
@@ -60,18 +61,18 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) {
|
||||
{
|
||||
desc: "public ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: Public
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: Public
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-pg-instance": cloudsqlpg.Config{
|
||||
Name: "my-pg-instance",
|
||||
Type: cloudsqlpg.SourceType,
|
||||
@@ -88,18 +89,18 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) {
|
||||
{
|
||||
desc: "private ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: private
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: private
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-pg-instance": cloudsqlpg.Config{
|
||||
Name: "my-pg-instance",
|
||||
Type: cloudsqlpg.SourceType,
|
||||
@@ -116,18 +117,18 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) {
|
||||
{
|
||||
desc: "psc ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: psc
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: psc
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-pg-instance": cloudsqlpg.Config{
|
||||
Name: "my-pg-instance",
|
||||
Type: cloudsqlpg.SourceType,
|
||||
@@ -144,16 +145,12 @@ func TestParseFromYamlCloudSQLPg(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -169,57 +166,53 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "invalid ipType",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: fail
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
ipType: fail
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": ipType invalid: must be one of \"public\", \"private\", or \"psc\"",
|
||||
},
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: cloud-sql-postgres
|
||||
project: my-project
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | kind: cloud-sql-postgres\n 5 | password: my_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | name: my-pg-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: cloud-sql-postgres
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: cloud-sql-postgres
|
||||
region: my-region
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"cloud-sql-postgres\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
ConnectionString string `yaml:"connectionString" validate:"required"`
|
||||
Bucket string `yaml:"bucket" validate:"required"`
|
||||
Scope string `yaml:"scope" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package couchbase_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/couchbase"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,16 +34,16 @@ func TestParseFromYamlCouchbase(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-couchbase-instance:
|
||||
kind: couchbase
|
||||
connectionString: localhost
|
||||
username: Administrator
|
||||
password: password
|
||||
bucket: travel-sample
|
||||
scope: inventory
|
||||
kind: sources
|
||||
name: my-couchbase-instance
|
||||
type: couchbase
|
||||
connectionString: localhost
|
||||
username: Administrator
|
||||
password: password
|
||||
bucket: travel-sample
|
||||
scope: inventory
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-couchbase-instance": couchbase.Config{
|
||||
Name: "my-couchbase-instance",
|
||||
Type: couchbase.SourceType,
|
||||
@@ -57,21 +58,21 @@ func TestParseFromYamlCouchbase(t *testing.T) {
|
||||
{
|
||||
desc: "with TLS configuration",
|
||||
in: `
|
||||
sources:
|
||||
my-couchbase-instance:
|
||||
kind: couchbase
|
||||
connectionString: couchbases://localhost
|
||||
bucket: travel-sample
|
||||
scope: inventory
|
||||
clientCert: /path/to/cert.pem
|
||||
clientKey: /path/to/key.pem
|
||||
clientCertPassword: password
|
||||
clientKeyPassword: password
|
||||
caCert: /path/to/ca.pem
|
||||
noSslVerify: false
|
||||
queryScanConsistency: 2
|
||||
kind: sources
|
||||
name: my-couchbase-instance
|
||||
type: couchbase
|
||||
connectionString: couchbases://localhost
|
||||
bucket: travel-sample
|
||||
scope: inventory
|
||||
clientCert: /path/to/cert.pem
|
||||
clientKey: /path/to/key.pem
|
||||
clientCertPassword: password
|
||||
clientKeyPassword: password
|
||||
caCert: /path/to/ca.pem
|
||||
noSslVerify: false
|
||||
queryScanConsistency: 2
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-couchbase-instance": couchbase.Config{
|
||||
Name: "my-couchbase-instance",
|
||||
Type: couchbase.SourceType,
|
||||
@@ -91,16 +92,12 @@ func TestParseFromYamlCouchbase(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -115,39 +112,35 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-couchbase-instance:
|
||||
kind: couchbase
|
||||
connectionString: localhost
|
||||
username: Administrator
|
||||
password: password
|
||||
bucket: travel-sample
|
||||
scope: inventory
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-couchbase-instance
|
||||
type: couchbase
|
||||
connectionString: localhost
|
||||
username: Administrator
|
||||
password: password
|
||||
bucket: travel-sample
|
||||
scope: inventory
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-couchbase-instance\" as \"couchbase\": [3:1] unknown field \"foo\"\n 1 | bucket: travel-sample\n 2 | connectionString: localhost\n> 3 | foo: bar\n ^\n 4 | kind: couchbase\n 5 | password: password\n 6 | scope: inventory\n 7 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-couchbase-instance\" as \"couchbase\": [3:1] unknown field \"foo\"\n 1 | bucket: travel-sample\n 2 | connectionString: localhost\n> 3 | foo: bar\n ^\n 4 | name: my-couchbase-instance\n 5 | password: password\n 6 | scope: inventory\n 7 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-couchbase-instance:
|
||||
kind: couchbase
|
||||
username: Administrator
|
||||
password: password
|
||||
bucket: travel-sample
|
||||
scope: inventory
|
||||
kind: sources
|
||||
name: my-couchbase-instance
|
||||
type: couchbase
|
||||
username: Administrator
|
||||
password: password
|
||||
bucket: travel-sample
|
||||
scope: inventory
|
||||
`,
|
||||
err: "unable to parse source \"my-couchbase-instance\" as \"couchbase\": Key: 'Config.ConnectionString' Error:Field validation for 'ConnectionString' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-couchbase-instance\" as \"couchbase\": Key: 'Config.ConnectionString' Error:Field validation for 'ConnectionString' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -51,12 +51,12 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
type Config struct {
|
||||
// Dataplex configs
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
}
|
||||
|
||||
func (r Config) SourceConfigType() string {
|
||||
// Returns Dataplex source kind
|
||||
// Returns Dataplex source type
|
||||
return SourceType
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ type Source struct {
|
||||
}
|
||||
|
||||
func (s *Source) SourceType() string {
|
||||
// Returns Dataplex source kind
|
||||
// Returns Dataplex source type
|
||||
return SourceType
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package dataplex_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/dataplex"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,12 +34,12 @@ func TestParseFromYamlDataplex(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: dataplex
|
||||
project: my-project
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: dataplex
|
||||
project: my-project
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": dataplex.Config{
|
||||
Name: "my-instance",
|
||||
Type: dataplex.SourceType,
|
||||
@@ -49,16 +50,12 @@ func TestParseFromYamlDataplex(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -74,31 +71,27 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: dataplex
|
||||
project: my-project
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: dataplex
|
||||
project: my-project
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"dataplex\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: dataplex\n 3 | project: my-project",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"dataplex\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | name: my-instance\n 3 | project: my-project\n 4 | type: dataplex",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: dataplex
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: dataplex
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"dataplex\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"dataplex\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ type DgraphClient struct {
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
DgraphUrl string `yaml:"dgraphUrl" validate:"required"`
|
||||
User string `yaml:"user"`
|
||||
Password string `yaml:"password"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package dgraph_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/dgraph"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,16 +34,16 @@ func TestParseFromYamlDgraph(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-dgraph-instance:
|
||||
kind: dgraph
|
||||
dgraphUrl: https://localhost:8080
|
||||
apiKey: abc123
|
||||
password: pass@123
|
||||
namespace: 0
|
||||
user: user123
|
||||
kind: sources
|
||||
name: my-dgraph-instance
|
||||
type: dgraph
|
||||
dgraphUrl: https://localhost:8080
|
||||
apiKey: abc123
|
||||
password: pass@123
|
||||
namespace: 0
|
||||
user: user123
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-dgraph-instance": dgraph.Config{
|
||||
Name: "my-dgraph-instance",
|
||||
Type: dgraph.SourceType,
|
||||
@@ -57,12 +58,12 @@ func TestParseFromYamlDgraph(t *testing.T) {
|
||||
{
|
||||
desc: "basic example minimal field",
|
||||
in: `
|
||||
sources:
|
||||
my-dgraph-instance:
|
||||
kind: dgraph
|
||||
dgraphUrl: https://localhost:8080
|
||||
kind: sources
|
||||
name: my-dgraph-instance
|
||||
type: dgraph
|
||||
dgraphUrl: https://localhost:8080
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-dgraph-instance": dgraph.Config{
|
||||
Name: "my-dgraph-instance",
|
||||
Type: dgraph.SourceType,
|
||||
@@ -74,16 +75,12 @@ func TestParseFromYamlDgraph(t *testing.T) {
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(tc.want, got.Sources); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Fatalf("incorrect parse: diff %v", diff)
|
||||
}
|
||||
})
|
||||
@@ -100,31 +97,27 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-dgraph-instance:
|
||||
kind: dgraph
|
||||
dgraphUrl: https://localhost:8080
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-dgraph-instance
|
||||
type: dgraph
|
||||
dgraphUrl: https://localhost:8080
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-dgraph-instance\" as \"dgraph\": [2:1] unknown field \"foo\"\n 1 | dgraphUrl: https://localhost:8080\n> 2 | foo: bar\n ^\n 3 | kind: dgraph",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-dgraph-instance\" as \"dgraph\": [2:1] unknown field \"foo\"\n 1 | dgraphUrl: https://localhost:8080\n> 2 | foo: bar\n ^\n 3 | name: my-dgraph-instance\n 4 | type: dgraph",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-dgraph-instance:
|
||||
kind: dgraph
|
||||
kind: sources
|
||||
name: my-dgraph-instance
|
||||
type: dgraph
|
||||
`,
|
||||
err: "unable to parse source \"my-dgraph-instance\" as \"dgraph\": Key: 'Config.DgraphUrl' Error:Field validation for 'DgraphUrl' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-dgraph-instance\" as \"dgraph\": Key: 'Config.DgraphUrl' Error:Field validation for 'DgraphUrl' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Addresses []string `yaml:"addresses" validate:"required"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
@@ -139,7 +139,7 @@ func (c Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.So
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// SourceType returns the kind string for this source.
|
||||
// SourceType returns the resourceType string for this source.
|
||||
func (s *Source) SourceType() string {
|
||||
return SourceType
|
||||
}
|
||||
|
||||
@@ -15,13 +15,15 @@
|
||||
package elasticsearch_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/elasticsearch"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
|
||||
func TestParseFromYamlElasticsearch(t *testing.T) {
|
||||
@@ -33,14 +35,14 @@ func TestParseFromYamlElasticsearch(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-es-instance:
|
||||
kind: elasticsearch
|
||||
addresses:
|
||||
- http://localhost:9200
|
||||
apikey: somekey
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
kind: sources
|
||||
name: my-es-instance
|
||||
type: elasticsearch
|
||||
addresses:
|
||||
- http://localhost:9200
|
||||
apikey: somekey
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-es-instance": elasticsearch.Config{
|
||||
Name: "my-es-instance",
|
||||
Type: elasticsearch.SourceType,
|
||||
@@ -52,20 +54,50 @@ func TestParseFromYamlElasticsearch(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
err := yaml.Unmarshal([]byte(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse yaml: %v", err)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got.Sources); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Errorf("unexpected config diff (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailParseFromYaml(t *testing.T) {
|
||||
tcs := []struct {
|
||||
desc string
|
||||
in string
|
||||
err string
|
||||
}{
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
kind: sources
|
||||
name: my-es-instance
|
||||
type: elasticsearch
|
||||
addresses:
|
||||
- http://localhost:9200
|
||||
foo: bar
|
||||
`,
|
||||
err: "error unmarshaling sources: unable to parse source \"my-es-instance\" as \"elasticsearch\": [3:1] unknown field \"foo\"\n 1 | addresses:\n 2 | - http://localhost:9200\n> 3 | foo: bar\n ^\n 4 | name: my-es-instance\n 5 | type: elasticsearch",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
errStr := err.Error()
|
||||
if errStr != tc.err {
|
||||
t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTool_esqlToMap(t1 *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@@ -47,7 +47,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package firebird_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/firebird"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,16 +34,16 @@ func TestParseFromYamlFirebird(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-fdb-instance:
|
||||
kind: firebird
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-fdb-instance
|
||||
type: firebird
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-fdb-instance": firebird.Config{
|
||||
Name: "my-fdb-instance",
|
||||
Type: firebird.SourceType,
|
||||
@@ -57,16 +58,12 @@ func TestParseFromYamlFirebird(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -82,39 +79,35 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-fdb-instance:
|
||||
kind: firebird
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-fdb-instance
|
||||
type: firebird
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-fdb-instance\" as \"firebird\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: my-host\n 4 | kind: firebird\n 5 | password: my_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-fdb-instance\" as \"firebird\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: my-host\n 4 | name: my-fdb-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-fdb-instance:
|
||||
kind: firebird
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
kind: sources
|
||||
name: my-fdb-instance
|
||||
type: firebird
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
`,
|
||||
err: "unable to parse source \"my-fdb-instance\" as \"firebird\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-fdb-instance\" as \"firebird\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -53,13 +53,13 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
type Config struct {
|
||||
// Firestore configs
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Database string `yaml:"database"` // Optional, defaults to "(default)"
|
||||
}
|
||||
|
||||
func (r Config) SourceConfigType() string {
|
||||
// Returns Firestore source kind
|
||||
// Returns Firestore source type
|
||||
return SourceType
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ type Source struct {
|
||||
}
|
||||
|
||||
func (s *Source) SourceType() string {
|
||||
// Returns Firestore source kind
|
||||
// Returns Firestore source type
|
||||
return SourceType
|
||||
}
|
||||
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
package firestore_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/firestore"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -34,12 +35,12 @@ func TestParseFromYamlFirestore(t *testing.T) {
|
||||
{
|
||||
desc: "basic example with default database",
|
||||
in: `
|
||||
sources:
|
||||
my-firestore:
|
||||
kind: firestore
|
||||
project: my-project
|
||||
kind: sources
|
||||
name: my-firestore
|
||||
type: firestore
|
||||
project: my-project
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-firestore": firestore.Config{
|
||||
Name: "my-firestore",
|
||||
Type: firestore.SourceType,
|
||||
@@ -51,13 +52,13 @@ func TestParseFromYamlFirestore(t *testing.T) {
|
||||
{
|
||||
desc: "with custom database",
|
||||
in: `
|
||||
sources:
|
||||
my-firestore:
|
||||
kind: firestore
|
||||
project: my-project
|
||||
database: my-database
|
||||
kind: sources
|
||||
name: my-firestore
|
||||
type: firestore
|
||||
project: my-project
|
||||
database: my-database
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-firestore": firestore.Config{
|
||||
Name: "my-firestore",
|
||||
Type: firestore.SourceType,
|
||||
@@ -69,22 +70,18 @@ func TestParseFromYamlFirestore(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailParseFromYamlFirestore(t *testing.T) {
|
||||
func TestFailParseFromYaml(t *testing.T) {
|
||||
tcs := []struct {
|
||||
desc string
|
||||
in string
|
||||
@@ -93,32 +90,27 @@ func TestFailParseFromYamlFirestore(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-firestore:
|
||||
kind: firestore
|
||||
project: my-project
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-firestore
|
||||
type: firestore
|
||||
project: my-project
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-firestore\" as \"firestore\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: firestore\n 3 | project: my-project",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-firestore\" as \"firestore\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | name: my-firestore\n 3 | project: my-project\n 4 | type: firestore",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-firestore:
|
||||
kind: firestore
|
||||
database: my-database
|
||||
kind: sources
|
||||
name: my-firestore
|
||||
type: firestore
|
||||
`,
|
||||
err: "unable to parse source \"my-firestore\" as \"firestore\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-firestore\" as \"firestore\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
BaseURL string `yaml:"baseUrl"`
|
||||
Timeout string `yaml:"timeout"`
|
||||
DefaultHeaders map[string]string `yaml:"headers"`
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package http_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -34,10 +34,10 @@ func TestParseFromYamlHttp(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-http-instance:
|
||||
kind: http
|
||||
baseUrl: http://test_server/
|
||||
kind: sources
|
||||
name: my-http-instance
|
||||
type: http
|
||||
baseUrl: http://test_server/
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-http-instance": http.Config{
|
||||
@@ -52,18 +52,18 @@ func TestParseFromYamlHttp(t *testing.T) {
|
||||
{
|
||||
desc: "advanced example",
|
||||
in: `
|
||||
sources:
|
||||
my-http-instance:
|
||||
kind: http
|
||||
baseUrl: http://test_server/
|
||||
timeout: 10s
|
||||
headers:
|
||||
Authorization: test_header
|
||||
Custom-Header: custom
|
||||
queryParams:
|
||||
api-key: test_api_key
|
||||
param: param-value
|
||||
disableSslVerification: true
|
||||
kind: sources
|
||||
name: my-http-instance
|
||||
type: http
|
||||
baseUrl: http://test_server/
|
||||
timeout: 10s
|
||||
headers:
|
||||
Authorization: test_header
|
||||
Custom-Header: custom
|
||||
queryParams:
|
||||
api-key: test_api_key
|
||||
param: param-value
|
||||
disableSslVerification: true
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-http-instance": http.Config{
|
||||
@@ -80,16 +80,12 @@ func TestParseFromYamlHttp(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -104,36 +100,32 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-http-instance:
|
||||
kind: http
|
||||
baseUrl: http://test_server/
|
||||
timeout: 10s
|
||||
headers:
|
||||
Authorization: test_header
|
||||
queryParams:
|
||||
api-key: test_api_key
|
||||
project: test-project
|
||||
kind: sources
|
||||
name: my-http-instance
|
||||
type: http
|
||||
baseUrl: http://test_server/
|
||||
timeout: 10s
|
||||
headers:
|
||||
Authorization: test_header
|
||||
queryParams:
|
||||
api-key: test_api_key
|
||||
project: test-project
|
||||
`,
|
||||
err: "unable to parse source \"my-http-instance\" as \"http\": [5:1] unknown field \"project\"\n 2 | headers:\n 3 | Authorization: test_header\n 4 | kind: http\n> 5 | project: test-project\n ^\n 6 | queryParams:\n 7 | api-key: test_api_key\n 8 | timeout: 10s",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-http-instance\" as \"http\": [5:1] unknown field \"project\"\n 2 | headers:\n 3 | Authorization: test_header\n 4 | name: my-http-instance\n> 5 | project: test-project\n ^\n 6 | queryParams:\n 7 | api-key: test_api_key\n 8 | timeout: 10s\n 9 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-http-instance:
|
||||
baseUrl: http://test_server/
|
||||
kind: sources
|
||||
name: my-http-instance
|
||||
baseUrl: http://test_server/
|
||||
`,
|
||||
err: "missing 'kind' field for source \"my-http-instance\"",
|
||||
err: "error unmarshaling sources: missing 'type' field or it is not a string",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
BaseURL string `yaml:"base_url" validate:"required"`
|
||||
ClientId string `yaml:"client_id"`
|
||||
ClientSecret string `yaml:"client_secret"`
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package looker_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -34,12 +34,12 @@ func TestParseFromYamlLooker(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-looker-instance:
|
||||
kind: looker
|
||||
base_url: http://example.looker.com/
|
||||
client_id: jasdl;k;tjl
|
||||
client_secret: sdakl;jgflkasdfkfg
|
||||
kind: sources
|
||||
name: my-looker-instance
|
||||
type: looker
|
||||
base_url: http://example.looker.com/
|
||||
client_id: jasdl;k;tjl
|
||||
client_secret: sdakl;jgflkasdfkfg
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-looker-instance": looker.Config{
|
||||
@@ -62,22 +62,18 @@ func TestParseFromYamlLooker(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailParseFromYamlLooker(t *testing.T) {
|
||||
func TestFailParseFromYaml(t *testing.T) {
|
||||
tcs := []struct {
|
||||
desc string
|
||||
in string
|
||||
@@ -86,34 +82,30 @@ func TestFailParseFromYamlLooker(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-looker-instance:
|
||||
kind: looker
|
||||
base_url: http://example.looker.com/
|
||||
client_id: jasdl;k;tjl
|
||||
client_secret: sdakl;jgflkasdfkfg
|
||||
schema: test-schema
|
||||
kind: sources
|
||||
name: my-looker-instance
|
||||
type: looker
|
||||
base_url: http://example.looker.com/
|
||||
client_id: jasdl;k;tjl
|
||||
client_secret: sdakl;jgflkasdfkfg
|
||||
schema: test-schema
|
||||
`,
|
||||
err: "unable to parse source \"my-looker-instance\" as \"looker\": [5:1] unknown field \"schema\"\n 2 | client_id: jasdl;k;tjl\n 3 | client_secret: sdakl;jgflkasdfkfg\n 4 | kind: looker\n> 5 | schema: test-schema\n ^\n",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-looker-instance\" as \"looker\": [5:1] unknown field \"schema\"\n 2 | client_id: jasdl;k;tjl\n 3 | client_secret: sdakl;jgflkasdfkfg\n 4 | name: my-looker-instance\n> 5 | schema: test-schema\n ^\n 6 | type: looker",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-looker-instance:
|
||||
kind: looker
|
||||
client_id: jasdl;k;tjl
|
||||
kind: sources
|
||||
name: my-looker-instance
|
||||
type: looker
|
||||
client_id: jasdl;k;tjl
|
||||
`,
|
||||
err: "unable to parse source \"my-looker-instance\" as \"looker\": Key: 'Config.BaseURL' Error:Field validation for 'BaseURL' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-looker-instance\" as \"looker\": Key: 'Config.BaseURL' Error:Field validation for 'BaseURL' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package mindsdb_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/mindsdb"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,16 +34,16 @@ func TestParseFromYamlMindsDB(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-mindsdb-instance:
|
||||
kind: mindsdb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mindsdb-instance
|
||||
type: mindsdb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mindsdb-instance": mindsdb.Config{
|
||||
Name: "my-mindsdb-instance",
|
||||
Type: mindsdb.SourceType,
|
||||
@@ -57,17 +58,17 @@ func TestParseFromYamlMindsDB(t *testing.T) {
|
||||
{
|
||||
desc: "with query timeout",
|
||||
in: `
|
||||
sources:
|
||||
my-mindsdb-instance:
|
||||
kind: mindsdb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryTimeout: 45s
|
||||
kind: sources
|
||||
name: my-mindsdb-instance
|
||||
type: mindsdb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryTimeout: 45s
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mindsdb-instance": mindsdb.Config{
|
||||
Name: "my-mindsdb-instance",
|
||||
Type: mindsdb.SourceType,
|
||||
@@ -83,16 +84,12 @@ func TestParseFromYamlMindsDB(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -108,39 +105,35 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-mindsdb-instance:
|
||||
kind: mindsdb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-mindsdb-instance
|
||||
type: mindsdb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-mindsdb-instance\" as \"mindsdb\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: mindsdb\n 5 | password: my_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mindsdb-instance\" as \"mindsdb\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-mindsdb-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-mindsdb-instance:
|
||||
kind: mindsdb
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mindsdb-instance
|
||||
type: mindsdb
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-mindsdb-instance\" as \"mindsdb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mindsdb-instance\" as \"mindsdb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Uri string `yaml:"uri" validate:"required"` // MongoDB Atlas connection URI
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package mongodb_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/mongodb"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,12 +34,12 @@ func TestParseFromYamlMongoDB(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
mongo-db:
|
||||
kind: "mongodb"
|
||||
uri: "mongodb+srv://username:password@host/dbname"
|
||||
kind: sources
|
||||
name: mongo-db
|
||||
type: "mongodb"
|
||||
uri: "mongodb+srv://username:password@host/dbname"
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"mongo-db": mongodb.Config{
|
||||
Name: "mongo-db",
|
||||
Type: mongodb.SourceType,
|
||||
@@ -49,16 +50,12 @@ func TestParseFromYamlMongoDB(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -74,31 +71,27 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
mongo-db:
|
||||
kind: mongodb
|
||||
uri: "mongodb+srv://username:password@host/dbname"
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: mongo-db
|
||||
type: mongodb
|
||||
uri: "mongodb+srv://username:password@host/dbname"
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"mongo-db\" as \"mongodb\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: mongodb\n 3 | uri: mongodb+srv://username:password@host/dbname",
|
||||
err: "error unmarshaling sources: unable to parse source \"mongo-db\" as \"mongodb\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | name: mongo-db\n 3 | type: mongodb\n 4 | uri: mongodb+srv://username:password@host/dbname",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
mongo-db:
|
||||
kind: mongodb
|
||||
kind: sources
|
||||
name: mongo-db
|
||||
type: mongodb
|
||||
`,
|
||||
err: "unable to parse source \"mongo-db\" as \"mongodb\": Key: 'Config.Uri' Error:Field validation for 'Uri' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"mongo-db\" as \"mongodb\": Key: 'Config.Uri' Error:Field validation for 'Uri' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
type Config struct {
|
||||
// Cloud SQL MSSQL configs
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
@@ -60,7 +60,7 @@ type Config struct {
|
||||
}
|
||||
|
||||
func (r Config) SourceConfigType() string {
|
||||
// Returns Cloud SQL MSSQL source kind
|
||||
// Returns Cloud SQL MSSQL source type
|
||||
return SourceType
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ type Source struct {
|
||||
}
|
||||
|
||||
func (s *Source) SourceType() string {
|
||||
// Returns Cloud SQL MSSQL source kind
|
||||
// Returns Cloud SQL MSSQL source type
|
||||
return SourceType
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package mssql_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/mssql"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,16 +34,16 @@ func TestParseFromYamlMssql(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-mssql-instance:
|
||||
kind: mssql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mssql-instance
|
||||
type: mssql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mssql-instance": mssql.Config{
|
||||
Name: "my-mssql-instance",
|
||||
Type: mssql.SourceType,
|
||||
@@ -57,17 +58,17 @@ func TestParseFromYamlMssql(t *testing.T) {
|
||||
{
|
||||
desc: "with encrypt field",
|
||||
in: `
|
||||
sources:
|
||||
my-mssql-instance:
|
||||
kind: mssql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
encrypt: strict
|
||||
kind: sources
|
||||
name: my-mssql-instance
|
||||
type: mssql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
encrypt: strict
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mssql-instance": mssql.Config{
|
||||
Name: "my-mssql-instance",
|
||||
Type: mssql.SourceType,
|
||||
@@ -83,16 +84,12 @@ func TestParseFromYamlMssql(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect psarse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect psarse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -107,39 +104,35 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-mssql-instance:
|
||||
kind: mssql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-mssql-instance
|
||||
type: mssql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-mssql-instance\" as \"mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: mssql\n 5 | password: my_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mssql-instance\" as \"mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-mssql-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-mssql-instance:
|
||||
kind: mssql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
kind: sources
|
||||
name: my-mssql-instance
|
||||
type: mssql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
`,
|
||||
err: "unable to parse source \"my-mssql-instance\" as \"mssql\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mssql-instance\" as \"mssql\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
|
||||
@@ -19,12 +19,12 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/mysql"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -38,16 +38,16 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: mysql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: mysql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mysql-instance": mysql.Config{
|
||||
Name: "my-mysql-instance",
|
||||
Type: mysql.SourceType,
|
||||
@@ -62,17 +62,17 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) {
|
||||
{
|
||||
desc: "with query timeout",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: mysql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryTimeout: 45s
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: mysql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryTimeout: 45s
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mysql-instance": mysql.Config{
|
||||
Name: "my-mysql-instance",
|
||||
Type: mysql.SourceType,
|
||||
@@ -88,19 +88,19 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) {
|
||||
{
|
||||
desc: "with query params",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: mysql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryParams:
|
||||
tls: preferred
|
||||
charset: utf8mb4
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: mysql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryParams:
|
||||
tls: preferred
|
||||
charset: utf8mb4
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-mysql-instance": mysql.Config{
|
||||
Name: "my-mysql-instance",
|
||||
Type: mysql.SourceType,
|
||||
@@ -120,15 +120,11 @@ func TestParseFromYamlCloudSQLMySQL(t *testing.T) {
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got.Sources, cmpopts.EquateEmpty()); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, got, cmpopts.EquateEmpty()); diff != "" {
|
||||
t.Fatalf("mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
@@ -145,55 +141,51 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: mysql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: mysql
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unknown field \"foo\"",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"mysql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-mysql-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: mysql
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: mysql
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "Field validation for 'Host' failed",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"mysql\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
},
|
||||
{
|
||||
desc: "invalid query params type",
|
||||
in: `
|
||||
sources:
|
||||
my-mysql-instance:
|
||||
kind: mysql
|
||||
host: 0.0.0.0
|
||||
port: 3306
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryParams: not-a-map
|
||||
kind: sources
|
||||
name: my-mysql-instance
|
||||
type: mysql
|
||||
host: 0.0.0.0
|
||||
port: 3306
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryParams: not-a-map
|
||||
`,
|
||||
err: "string was used where mapping is expected",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-mysql-instance\" as \"mysql\": [6:14] string was used where mapping is expected\n 3 | name: my-mysql-instance\n 4 | password: my_pass\n 5 | port: 3306\n> 6 | queryParams: not-a-map\n ^\n 7 | type: mysql\n 8 | user: my_user",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Uri string `yaml:"uri" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
Password string `yaml:"password" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package neo4j_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/neo4j"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,15 +34,15 @@ func TestParseFromYamlNeo4j(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-neo4j-instance:
|
||||
kind: neo4j
|
||||
uri: neo4j+s://my-host:7687
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-neo4j-instance
|
||||
type: neo4j
|
||||
uri: neo4j+s://my-host:7687
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-neo4j-instance": neo4j.Config{
|
||||
Name: "my-neo4j-instance",
|
||||
Type: neo4j.SourceType,
|
||||
@@ -55,16 +56,12 @@ func TestParseFromYamlNeo4j(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -80,37 +77,33 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-neo4j-instance:
|
||||
kind: neo4j
|
||||
uri: neo4j+s://my-host:7687
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-neo4j-instance
|
||||
type: neo4j
|
||||
uri: neo4j+s://my-host:7687
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-neo4j-instance\" as \"neo4j\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | kind: neo4j\n 4 | password: my_pass\n 5 | uri: neo4j+s://my-host:7687\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-neo4j-instance\" as \"neo4j\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | name: my-neo4j-instance\n 4 | password: my_pass\n 5 | type: neo4j\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-neo4j-instance:
|
||||
kind: neo4j
|
||||
uri: neo4j+s://my-host:7687
|
||||
database: my_db
|
||||
user: my_user
|
||||
kind: sources
|
||||
name: my-neo4j-instance
|
||||
type: neo4j
|
||||
uri: neo4j+s://my-host:7687
|
||||
database: my_db
|
||||
user: my_user
|
||||
`,
|
||||
err: "unable to parse source \"my-neo4j-instance\" as \"neo4j\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-neo4j-instance\" as \"neo4j\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package oceanbase_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/oceanbase"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -34,16 +35,16 @@ func TestParseFromYamlOceanBase(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-oceanbase-instance:
|
||||
kind: oceanbase
|
||||
host: 0.0.0.0
|
||||
port: 2881
|
||||
database: ob_db
|
||||
user: ob_user
|
||||
password: ob_pass
|
||||
kind: sources
|
||||
name: my-oceanbase-instance
|
||||
type: oceanbase
|
||||
host: 0.0.0.0
|
||||
port: 2881
|
||||
database: ob_db
|
||||
user: ob_user
|
||||
password: ob_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-oceanbase-instance": oceanbase.Config{
|
||||
Name: "my-oceanbase-instance",
|
||||
Type: oceanbase.SourceType,
|
||||
@@ -58,17 +59,17 @@ func TestParseFromYamlOceanBase(t *testing.T) {
|
||||
{
|
||||
desc: "with query timeout",
|
||||
in: `
|
||||
sources:
|
||||
my-oceanbase-instance:
|
||||
kind: oceanbase
|
||||
host: 0.0.0.0
|
||||
port: 2881
|
||||
database: ob_db
|
||||
user: ob_user
|
||||
password: ob_pass
|
||||
queryTimeout: 30s
|
||||
kind: sources
|
||||
name: my-oceanbase-instance
|
||||
type: oceanbase
|
||||
host: 0.0.0.0
|
||||
port: 2881
|
||||
database: ob_db
|
||||
user: ob_user
|
||||
password: ob_pass
|
||||
queryTimeout: 30s
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-oceanbase-instance": oceanbase.Config{
|
||||
Name: "my-oceanbase-instance",
|
||||
Type: oceanbase.SourceType,
|
||||
@@ -84,16 +85,12 @@ func TestParseFromYamlOceanBase(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -109,39 +106,35 @@ func TestFailParseFromYamlOceanBase(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-oceanbase-instance:
|
||||
kind: oceanbase
|
||||
host: 0.0.0.0
|
||||
port: 2881
|
||||
database: ob_db
|
||||
user: ob_user
|
||||
password: ob_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-oceanbase-instance
|
||||
type: oceanbase
|
||||
host: 0.0.0.0
|
||||
port: 2881
|
||||
database: ob_db
|
||||
user: ob_user
|
||||
password: ob_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-oceanbase-instance\" as \"oceanbase\": [2:1] unknown field \"foo\"\n 1 | database: ob_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: oceanbase\n 5 | password: ob_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-oceanbase-instance\" as \"oceanbase\": [2:1] unknown field \"foo\"\n 1 | database: ob_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-oceanbase-instance\n 5 | password: ob_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-oceanbase-instance:
|
||||
kind: oceanbase
|
||||
port: 2881
|
||||
database: ob_db
|
||||
user: ob_user
|
||||
password: ob_pass
|
||||
kind: sources
|
||||
name: my-oceanbase-instance
|
||||
type: oceanbase
|
||||
port: 2881
|
||||
database: ob_db
|
||||
user: ob_user
|
||||
password: ob_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-oceanbase-instance\" as \"oceanbase\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-oceanbase-instance\" as \"oceanbase\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
ConnectionString string `yaml:"connectionString,omitempty"`
|
||||
TnsAlias string `yaml:"tnsAlias,omitempty"`
|
||||
TnsAdmin string `yaml:"tnsAdmin,omitempty"`
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
package oracle_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/oracle"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -22,15 +23,15 @@ func TestParseFromYamlOracle(t *testing.T) {
|
||||
{
|
||||
desc: "connection string and useOCI=true",
|
||||
in: `
|
||||
sources:
|
||||
my-oracle-cs:
|
||||
kind: oracle
|
||||
connectionString: "my-host:1521/XEPDB1"
|
||||
user: my_user
|
||||
password: my_pass
|
||||
useOCI: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
kind: sources
|
||||
name: my-oracle-cs
|
||||
type: oracle
|
||||
connectionString: "my-host:1521/XEPDB1"
|
||||
user: my_user
|
||||
password: my_pass
|
||||
useOCI: true
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-oracle-cs": oracle.Config{
|
||||
Name: "my-oracle-cs",
|
||||
Type: oracle.SourceType,
|
||||
@@ -44,16 +45,16 @@ func TestParseFromYamlOracle(t *testing.T) {
|
||||
{
|
||||
desc: "host/port/serviceName and default useOCI=false",
|
||||
in: `
|
||||
sources:
|
||||
my-oracle-host:
|
||||
kind: oracle
|
||||
host: my-host
|
||||
port: 1521
|
||||
serviceName: ORCLPDB
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
kind: sources
|
||||
name: my-oracle-host
|
||||
type: oracle
|
||||
host: my-host
|
||||
port: 1521
|
||||
serviceName: ORCLPDB
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-oracle-host": oracle.Config{
|
||||
Name: "my-oracle-host",
|
||||
Type: oracle.SourceType,
|
||||
@@ -69,16 +70,16 @@ func TestParseFromYamlOracle(t *testing.T) {
|
||||
{
|
||||
desc: "tnsAlias and TnsAdmin specified with explicit useOCI=true",
|
||||
in: `
|
||||
sources:
|
||||
my-oracle-tns-oci:
|
||||
kind: oracle
|
||||
tnsAlias: FINANCE_DB
|
||||
tnsAdmin: /opt/oracle/network/admin
|
||||
user: my_user
|
||||
password: my_pass
|
||||
useOCI: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
kind: sources
|
||||
name: my-oracle-tns-oci
|
||||
type: oracle
|
||||
tnsAlias: FINANCE_DB
|
||||
tnsAdmin: /opt/oracle/network/admin
|
||||
user: my_user
|
||||
password: my_pass
|
||||
useOCI: true
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-oracle-tns-oci": oracle.Config{
|
||||
Name: "my-oracle-tns-oci",
|
||||
Type: oracle.SourceType,
|
||||
@@ -93,22 +94,18 @@ func TestParseFromYamlOracle(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse:\nwant: %v\ngot: %v\ndiff: %s", tc.want, got.Sources, cmp.Diff(tc.want, got.Sources))
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse:\nwant: %v\ngot: %v\ndiff: %s", tc.want, got, cmp.Diff(tc.want, got))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailParseFromYamlOracle(t *testing.T) {
|
||||
func TestFailParseFromYaml(t *testing.T) {
|
||||
tcs := []struct {
|
||||
desc string
|
||||
in string
|
||||
@@ -117,76 +114,72 @@ func TestFailParseFromYamlOracle(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-oracle-instance:
|
||||
kind: oracle
|
||||
host: my-host
|
||||
serviceName: ORCL
|
||||
user: my_user
|
||||
password: my_pass
|
||||
extraField: value
|
||||
kind: sources
|
||||
name: my-oracle-instance
|
||||
type: oracle
|
||||
host: my-host
|
||||
serviceName: ORCL
|
||||
user: my_user
|
||||
password: my_pass
|
||||
extraField: value
|
||||
`,
|
||||
err: "unable to parse source \"my-oracle-instance\" as \"oracle\": [1:1] unknown field \"extraField\"\n> 1 | extraField: value\n ^\n 2 | host: my-host\n 3 | kind: oracle\n 4 | password: my_pass\n 5 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-oracle-instance\" as \"oracle\": [1:1] unknown field \"extraField\"\n> 1 | extraField: value\n ^\n 2 | host: my-host\n 3 | name: my-oracle-instance\n 4 | password: my_pass\n 5 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required password field",
|
||||
in: `
|
||||
sources:
|
||||
my-oracle-instance:
|
||||
kind: oracle
|
||||
host: my-host
|
||||
serviceName: ORCL
|
||||
user: my_user
|
||||
`,
|
||||
err: "unable to parse source \"my-oracle-instance\" as \"oracle\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
kind: sources
|
||||
name: my-oracle-instance
|
||||
type: oracle
|
||||
host: my-host
|
||||
serviceName: ORCL
|
||||
user: my_user
|
||||
`,
|
||||
err: "error unmarshaling sources: unable to parse source \"my-oracle-instance\" as \"oracle\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
},
|
||||
{
|
||||
desc: "missing connection method fields (validate fails)",
|
||||
in: `
|
||||
sources:
|
||||
my-oracle-instance:
|
||||
kind: oracle
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-oracle-instance\" as \"oracle\": invalid Oracle configuration: must provide one of: 'tns_alias', 'connection_string', or both 'host' and 'service_name'",
|
||||
kind: sources
|
||||
name: my-oracle-instance
|
||||
type: oracle
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "error unmarshaling sources: unable to parse source \"my-oracle-instance\" as \"oracle\": invalid Oracle configuration: must provide one of: 'tns_alias', 'connection_string', or both 'host' and 'service_name'",
|
||||
},
|
||||
{
|
||||
desc: "multiple connection methods provided (validate fails)",
|
||||
in: `
|
||||
sources:
|
||||
my-oracle-instance:
|
||||
kind: oracle
|
||||
host: my-host
|
||||
serviceName: ORCL
|
||||
connectionString: "my-host:1521/XEPDB1"
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-oracle-instance\" as \"oracle\": invalid Oracle configuration: provide only one connection method: 'tns_alias', 'connection_string', or 'host'+'service_name'",
|
||||
kind: sources
|
||||
name: my-oracle-instance
|
||||
type: oracle
|
||||
host: my-host
|
||||
serviceName: ORCL
|
||||
connectionString: "my-host:1521/XEPDB1"
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "error unmarshaling sources: unable to parse source \"my-oracle-instance\" as \"oracle\": invalid Oracle configuration: provide only one connection method: 'tns_alias', 'connection_string', or 'host'+'service_name'",
|
||||
},
|
||||
{
|
||||
desc: "fail on tnsAdmin with useOCI=false",
|
||||
in: `
|
||||
sources:
|
||||
my-oracle-fail:
|
||||
kind: oracle
|
||||
tnsAlias: FINANCE_DB
|
||||
tnsAdmin: /opt/oracle/network/admin
|
||||
user: my_user
|
||||
password: my_pass
|
||||
useOCI: false
|
||||
kind: sources
|
||||
name: my-oracle-fail
|
||||
type: oracle
|
||||
tnsAlias: FINANCE_DB
|
||||
tnsAdmin: /opt/oracle/network/admin
|
||||
user: my_user
|
||||
password: my_pass
|
||||
useOCI: false
|
||||
`,
|
||||
err: "unable to parse source \"my-oracle-fail\" as \"oracle\": invalid Oracle configuration: `tnsAdmin` can only be used when `UseOCI` is true, or use `walletLocation` instead",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-oracle-fail\" as \"oracle\": invalid Oracle configuration: `tnsAdmin` can only be used when `UseOCI` is true, or use `walletLocation` instead",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2024 Google LLC
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -15,13 +15,14 @@
|
||||
package postgres_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/postgres"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -35,16 +36,16 @@ func TestParseFromYamlPostgres(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: postgres
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: postgres
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-pg-instance": postgres.Config{
|
||||
Name: "my-pg-instance",
|
||||
Type: postgres.SourceType,
|
||||
@@ -59,19 +60,19 @@ func TestParseFromYamlPostgres(t *testing.T) {
|
||||
{
|
||||
desc: "example with query params",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: postgres
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryParams:
|
||||
sslmode: verify-full
|
||||
sslrootcert: /tmp/ca.crt
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: postgres
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryParams:
|
||||
sslmode: verify-full
|
||||
sslrootcert: /tmp/ca.crt
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-pg-instance": postgres.Config{
|
||||
Name: "my-pg-instance",
|
||||
Type: postgres.SourceType,
|
||||
@@ -90,16 +91,12 @@ func TestParseFromYamlPostgres(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -115,39 +112,35 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: postgres
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: postgres
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-pg-instance\" as \"postgres\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: my-host\n 4 | kind: postgres\n 5 | password: my_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"postgres\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: my-host\n 4 | name: my-pg-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-pg-instance:
|
||||
kind: postgres
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
kind: sources
|
||||
name: my-pg-instance
|
||||
type: postgres
|
||||
host: my-host
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
`,
|
||||
err: "unable to parse source \"my-pg-instance\" as \"postgres\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-pg-instance\" as \"postgres\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Address []string `yaml:"address" validate:"required"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
package redis_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/redis"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -34,13 +35,13 @@ func TestParseFromYamlRedis(t *testing.T) {
|
||||
{
|
||||
desc: "default setting",
|
||||
in: `
|
||||
sources:
|
||||
my-redis-instance:
|
||||
kind: redis
|
||||
address:
|
||||
- 127.0.0.1
|
||||
kind: sources
|
||||
name: my-redis-instance
|
||||
type: redis
|
||||
address:
|
||||
- 127.0.0.1
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-redis-instance": redis.Config{
|
||||
Name: "my-redis-instance",
|
||||
Type: redis.SourceType,
|
||||
@@ -53,17 +54,17 @@ func TestParseFromYamlRedis(t *testing.T) {
|
||||
{
|
||||
desc: "advanced example",
|
||||
in: `
|
||||
sources:
|
||||
my-redis-instance:
|
||||
kind: redis
|
||||
address:
|
||||
- 127.0.0.1
|
||||
password: my-pass
|
||||
database: 1
|
||||
useGCPIAM: true
|
||||
clusterEnabled: true
|
||||
kind: sources
|
||||
name: my-redis-instance
|
||||
type: redis
|
||||
address:
|
||||
- 127.0.0.1
|
||||
password: my-pass
|
||||
database: 1
|
||||
useGCPIAM: true
|
||||
clusterEnabled: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-redis-instance": redis.Config{
|
||||
Name: "my-redis-instance",
|
||||
Type: redis.SourceType,
|
||||
@@ -78,16 +79,12 @@ func TestParseFromYamlRedis(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -103,48 +100,43 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "invalid database",
|
||||
in: `
|
||||
sources:
|
||||
my-redis-instance:
|
||||
kind: redis
|
||||
project: my-project
|
||||
address:
|
||||
- 127.0.0.1
|
||||
password: my-pass
|
||||
database: data
|
||||
kind: sources
|
||||
name: my-redis-instance
|
||||
type: redis
|
||||
address:
|
||||
- 127.0.0.1
|
||||
password: my-pass
|
||||
database: data
|
||||
`,
|
||||
err: "cannot unmarshal string into Go struct field .Sources of type int",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-redis-instance\" as \"redis\": [3:11] cannot unmarshal string into Go struct field Config.Database of type int\n 1 | address:\n 2 | - 127.0.0.1\n> 3 | database: data\n ^\n 4 | name: my-redis-instance\n 5 | password: my-pass\n 6 | type: redis",
|
||||
},
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-redis-instance:
|
||||
kind: redis
|
||||
project: my-project
|
||||
address:
|
||||
- 127.0.0.1
|
||||
password: my-pass
|
||||
database: 1
|
||||
kind: sources
|
||||
name: my-redis-instance
|
||||
type: redis
|
||||
project: my-project
|
||||
address:
|
||||
- 127.0.0.1
|
||||
password: my-pass
|
||||
database: 1
|
||||
`,
|
||||
err: "unable to parse source \"my-redis-instance\" as \"redis\": [6:1] unknown field \"project\"",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-redis-instance\" as \"redis\": [6:1] unknown field \"project\"\n 3 | database: 1\n 4 | name: my-redis-instance\n 5 | password: my-pass\n> 6 | project: my-project\n ^\n 7 | type: redis",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-redis-instance:
|
||||
kind: redis
|
||||
kind: sources
|
||||
name: my-redis-instance
|
||||
type: redis
|
||||
`,
|
||||
err: "unable to parse source \"my-redis-instance\" as \"redis\": Key: 'Config.Address' Error:Field validation for 'Address' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-redis-instance\" as \"redis\": Key: 'Config.Address' Error:Field validation for 'Address' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Location string `yaml:"location" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package serverlessspark_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/serverlessspark"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,13 +34,13 @@ func TestParseFromYamlServerlessSpark(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: serverless-spark
|
||||
project: my-project
|
||||
location: my-location
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: serverless-spark
|
||||
project: my-project
|
||||
location: my-location
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-instance": serverlessspark.Config{
|
||||
Name: "my-instance",
|
||||
Type: serverlessspark.SourceType,
|
||||
@@ -51,16 +52,12 @@ func TestParseFromYamlServerlessSpark(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -76,43 +73,39 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: serverless-spark
|
||||
project: my-project
|
||||
location: my-location
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: serverless-spark
|
||||
project: my-project
|
||||
location: my-location
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"serverless-spark\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | kind: serverless-spark\n 3 | location: my-location\n 4 | project: my-project",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"serverless-spark\": [1:1] unknown field \"foo\"\n> 1 | foo: bar\n ^\n 2 | location: my-location\n 3 | name: my-instance\n 4 | project: my-project\n 5 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field project",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: serverless-spark
|
||||
location: my-location
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: serverless-spark
|
||||
location: my-location
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"serverless-spark\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"serverless-spark\": Key: 'Config.Project' Error:Field validation for 'Project' failed on the 'required' tag",
|
||||
},
|
||||
{
|
||||
desc: "missing required field location",
|
||||
in: `
|
||||
sources:
|
||||
my-instance:
|
||||
kind: serverless-spark
|
||||
project: my-project
|
||||
kind: sources
|
||||
name: my-instance
|
||||
type: serverless-spark
|
||||
project: my-project
|
||||
`,
|
||||
err: "unable to parse source \"my-instance\" as \"serverless-spark\": Key: 'Config.Location' Error:Field validation for 'Location' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-instance\" as \"serverless-spark\": Key: 'Config.Location' Error:Field validation for 'Location' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
// Config holds the configuration parameters for connecting to a SingleStore database.
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
@@ -61,7 +61,7 @@ type Config struct {
|
||||
QueryTimeout string `yaml:"queryTimeout"`
|
||||
}
|
||||
|
||||
// SourceConfigType returns the kind of the source configuration.
|
||||
// SourceConfigType returns the type of the source configuration.
|
||||
func (r Config) SourceConfigType() string {
|
||||
return SourceType
|
||||
}
|
||||
@@ -93,7 +93,7 @@ type Source struct {
|
||||
Pool *sql.DB
|
||||
}
|
||||
|
||||
// SourceType returns the kind of the source configuration.
|
||||
// SourceType returns the type of the source configuration.
|
||||
func (s *Source) SourceType() string {
|
||||
return SourceType
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
package singlestore_test
|
||||
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -14,12 +12,15 @@ package singlestore_test
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package singlestore_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/singlestore"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,16 +34,16 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-s2-instance:
|
||||
kind: singlestore
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-s2-instance
|
||||
type: singlestore
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-s2-instance": singlestore.Config{
|
||||
Name: "my-s2-instance",
|
||||
Type: singlestore.SourceType,
|
||||
@@ -57,17 +58,17 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "with query timeout",
|
||||
in: `
|
||||
sources:
|
||||
my-s2-instance:
|
||||
kind: singlestore
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryTimeout: 45s
|
||||
kind: sources
|
||||
name: my-s2-instance
|
||||
type: singlestore
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
queryTimeout: 45s
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-s2-instance": singlestore.Config{
|
||||
Name: "my-s2-instance",
|
||||
Type: singlestore.SourceType,
|
||||
@@ -83,16 +84,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -108,39 +105,35 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-s2-instance:
|
||||
kind: singlestore
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-s2-instance
|
||||
type: singlestore
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-s2-instance\" as \"singlestore\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: singlestore\n 5 | password: my_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-s2-instance\" as \"singlestore\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-s2-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-s2-instance:
|
||||
kind: singlestore
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-s2-instance
|
||||
type: singlestore
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-s2-instance\" as \"singlestore\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-s2-instance\" as \"singlestore\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Account string `yaml:"account" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
Password string `yaml:"password" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package snowflake_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/snowflake"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,16 +34,16 @@ func TestParseFromYamlSnowflake(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-snowflake-instance:
|
||||
kind: snowflake
|
||||
account: my-account
|
||||
user: my_user
|
||||
password: my_pass
|
||||
database: my_db
|
||||
schema: my_schema
|
||||
kind: sources
|
||||
name: my-snowflake-instance
|
||||
type: snowflake
|
||||
account: my-account
|
||||
user: my_user
|
||||
password: my_pass
|
||||
database: my_db
|
||||
schema: my_schema
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-snowflake-instance": snowflake.Config{
|
||||
Name: "my-snowflake-instance",
|
||||
Type: snowflake.SourceType,
|
||||
@@ -59,16 +60,12 @@ func TestParseFromYamlSnowflake(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -84,39 +81,35 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-snowflake-instance:
|
||||
kind: snowflake
|
||||
account: my-account
|
||||
user: my_user
|
||||
password: my_pass
|
||||
database: my_db
|
||||
schema: my_schema
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-snowflake-instance
|
||||
type: snowflake
|
||||
account: my-account
|
||||
user: my_user
|
||||
password: my_pass
|
||||
database: my_db
|
||||
schema: my_schema
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-snowflake-instance\" as \"snowflake\": [3:1] unknown field \"foo\"\n 1 | account: my-account\n 2 | database: my_db\n> 3 | foo: bar\n ^\n 4 | kind: snowflake\n 5 | password: my_pass\n 6 | schema: my_schema\n 7 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-snowflake-instance\" as \"snowflake\": [3:1] unknown field \"foo\"\n 1 | account: my-account\n 2 | database: my_db\n> 3 | foo: bar\n ^\n 4 | name: my-snowflake-instance\n 5 | password: my_pass\n 6 | schema: my_schema\n 7 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-snowflake-instance:
|
||||
kind: snowflake
|
||||
account: my-account
|
||||
user: my_user
|
||||
password: my_pass
|
||||
database: my_db
|
||||
kind: sources
|
||||
name: my-snowflake-instance
|
||||
type: snowflake
|
||||
account: my-account
|
||||
user: my_user
|
||||
password: my_pass
|
||||
database: my_db
|
||||
`,
|
||||
err: "unable to parse source \"my-snowflake-instance\" as \"snowflake\": Key: 'Config.Schema' Error:Field validation for 'Schema' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-snowflake-instance\" as \"snowflake\": Key: 'Config.Schema' Error:Field validation for 'Schema' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -29,22 +29,22 @@ type SourceConfigFactory func(ctx context.Context, name string, decoder *yaml.De
|
||||
|
||||
var sourceRegistry = make(map[string]SourceConfigFactory)
|
||||
|
||||
// Register registers a new source kind with its factory.
|
||||
// It returns false if the kind is already registered.
|
||||
// Register registers a new source type with its factory.
|
||||
// It returns false if the type is already registered.
|
||||
func Register(sourceType string, factory SourceConfigFactory) bool {
|
||||
if _, exists := sourceRegistry[sourceType]; exists {
|
||||
// Source with this kind already exists, do not overwrite.
|
||||
// Source with this type already exists, do not overwrite.
|
||||
return false
|
||||
}
|
||||
sourceRegistry[sourceType] = factory
|
||||
return true
|
||||
}
|
||||
|
||||
// DecodeConfig decodes a source configuration using the registered factory for the given kind.
|
||||
// DecodeConfig decodes a source configuration using the registered factory for the given type.
|
||||
func DecodeConfig(ctx context.Context, sourceType string, name string, decoder *yaml.Decoder) (SourceConfig, error) {
|
||||
factory, found := sourceRegistry[sourceType]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("unknown source kind: %q", sourceType)
|
||||
return nil, fmt.Errorf("unknown source type: %q", sourceType)
|
||||
}
|
||||
sourceConfig, err := factory(ctx, name, decoder)
|
||||
if err != nil {
|
||||
|
||||
@@ -49,7 +49,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Project string `yaml:"project" validate:"required"`
|
||||
Instance string `yaml:"instance" validate:"required"`
|
||||
Dialect sources.Dialect `yaml:"dialect" validate:"required"`
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package spanner_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -34,12 +34,12 @@ func TestParseFromYamlSpannerDb(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-spanner-instance:
|
||||
kind: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
kind: sources
|
||||
name: my-spanner-instance
|
||||
type: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-spanner-instance": spanner.Config{
|
||||
@@ -55,13 +55,13 @@ func TestParseFromYamlSpannerDb(t *testing.T) {
|
||||
{
|
||||
desc: "gsql dialect",
|
||||
in: `
|
||||
sources:
|
||||
my-spanner-instance:
|
||||
kind: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
dialect: Googlesql
|
||||
database: my_db
|
||||
kind: sources
|
||||
name: my-spanner-instance
|
||||
type: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
dialect: Googlesql
|
||||
database: my_db
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-spanner-instance": spanner.Config{
|
||||
@@ -77,13 +77,13 @@ func TestParseFromYamlSpannerDb(t *testing.T) {
|
||||
{
|
||||
desc: "postgresql dialect",
|
||||
in: `
|
||||
sources:
|
||||
my-spanner-instance:
|
||||
kind: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
dialect: postgresql
|
||||
database: my_db
|
||||
kind: sources
|
||||
name: my-spanner-instance
|
||||
type: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
dialect: postgresql
|
||||
database: my_db
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-spanner-instance": spanner.Config{
|
||||
@@ -99,16 +99,12 @@ func TestParseFromYamlSpannerDb(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -124,48 +120,44 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "invalid dialect",
|
||||
in: `
|
||||
sources:
|
||||
my-spanner-instance:
|
||||
kind: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
dialect: fail
|
||||
database: my_db
|
||||
kind: sources
|
||||
name: my-spanner-instance
|
||||
type: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
dialect: fail
|
||||
database: my_db
|
||||
`,
|
||||
err: "unable to parse source \"my-spanner-instance\" as \"spanner\": dialect invalid: must be one of \"googlesql\", or \"postgresql\"",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-spanner-instance\" as \"spanner\": dialect invalid: must be one of \"googlesql\", or \"postgresql\"",
|
||||
},
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-spanner-instance:
|
||||
kind: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-spanner-instance
|
||||
type: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
database: my_db
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-spanner-instance\" as \"spanner\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | kind: spanner\n 5 | project: my-project",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-spanner-instance\" as \"spanner\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | name: my-spanner-instance\n 5 | project: my-project\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-spanner-instance:
|
||||
kind: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
kind: sources
|
||||
name: my-spanner-instance
|
||||
type: spanner
|
||||
project: my-project
|
||||
instance: my-instance
|
||||
`,
|
||||
err: "unable to parse source \"my-spanner-instance\" as \"spanner\": Key: 'Config.Database' Error:Field validation for 'Database' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-spanner-instance\" as \"spanner\": Key: 'Config.Database' Error:Field validation for 'Database' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Database string `yaml:"database" validate:"required"` // Path to SQLite database file
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
package sqlite_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -34,10 +34,10 @@ func TestParseFromYamlSQLite(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-sqlite-db:
|
||||
kind: sqlite
|
||||
database: /path/to/database.db
|
||||
kind: sources
|
||||
name: my-sqlite-db
|
||||
type: sqlite
|
||||
database: /path/to/database.db
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-sqlite-db": sqlite.Config{
|
||||
@@ -50,16 +50,53 @@ func TestParseFromYamlSQLite(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailParseFromYaml(t *testing.T) {
|
||||
tcs := []struct {
|
||||
desc string
|
||||
in string
|
||||
err string
|
||||
}{
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
kind: sources
|
||||
name: my-sqlite-db
|
||||
type: sqlite
|
||||
database: /path/to/database.db
|
||||
foo: bar
|
||||
`,
|
||||
err: "error unmarshaling sources: unable to parse source \"my-sqlite-db\" as \"sqlite\": [2:1] unknown field \"foo\"\n 1 | database: /path/to/database.db\n> 2 | foo: bar\n ^\n 3 | name: my-sqlite-db\n 4 | type: sqlite",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
kind: sources
|
||||
name: my-sqlite-db
|
||||
type: sqlite
|
||||
`,
|
||||
err: "error unmarshaling sources: unable to parse source \"my-sqlite-db\" as \"sqlite\": Key: 'Config.Database' Error:Field validation for 'Database' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
errStr := err.Error()
|
||||
if errStr != tc.err {
|
||||
t.Fatalf("unexpected error: got %q, want %q", errStr, tc.err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package tidb_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/tidb"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -33,16 +34,16 @@ func TestParseFromYamlTiDB(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-tidb-instance:
|
||||
kind: tidb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
kind: sources
|
||||
name: my-tidb-instance
|
||||
type: tidb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-tidb-instance": tidb.Config{
|
||||
Name: "my-tidb-instance",
|
||||
Type: tidb.SourceType,
|
||||
@@ -58,17 +59,17 @@ func TestParseFromYamlTiDB(t *testing.T) {
|
||||
{
|
||||
desc: "with SSL enabled",
|
||||
in: `
|
||||
sources:
|
||||
my-tidb-cloud:
|
||||
kind: tidb
|
||||
host: gateway01.us-west-2.prod.aws.tidbcloud.com
|
||||
port: 4000
|
||||
database: test_db
|
||||
user: cloud_user
|
||||
password: cloud_pass
|
||||
ssl: true
|
||||
kind: sources
|
||||
name: my-tidb-cloud
|
||||
type: tidb
|
||||
host: gateway01.us-west-2.prod.aws.tidbcloud.com
|
||||
port: 4000
|
||||
database: test_db
|
||||
user: cloud_user
|
||||
password: cloud_pass
|
||||
ssl: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-tidb-cloud": tidb.Config{
|
||||
Name: "my-tidb-cloud",
|
||||
Type: tidb.SourceType,
|
||||
@@ -84,16 +85,16 @@ func TestParseFromYamlTiDB(t *testing.T) {
|
||||
{
|
||||
desc: "Change SSL enabled due to TiDB Cloud host",
|
||||
in: `
|
||||
sources:
|
||||
my-tidb-cloud:
|
||||
kind: tidb
|
||||
host: gateway01.us-west-2.prod.aws.tidbcloud.com
|
||||
port: 4000
|
||||
database: test_db
|
||||
user: cloud_user
|
||||
password: cloud_pass
|
||||
kind: sources
|
||||
name: my-tidb-cloud
|
||||
type: tidb
|
||||
host: gateway01.us-west-2.prod.aws.tidbcloud.com
|
||||
port: 4000
|
||||
database: test_db
|
||||
user: cloud_user
|
||||
password: cloud_pass
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-tidb-cloud": tidb.Config{
|
||||
Name: "my-tidb-cloud",
|
||||
Type: tidb.SourceType,
|
||||
@@ -109,16 +110,12 @@ func TestParseFromYamlTiDB(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -134,41 +131,37 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-tidb-instance:
|
||||
kind: tidb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
ssl: false
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-tidb-instance
|
||||
type: tidb
|
||||
host: 0.0.0.0
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
ssl: false
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-tidb-instance\" as \"tidb\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | kind: tidb\n 5 | password: my_pass\n 6 | ",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-tidb-instance\" as \"tidb\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | host: 0.0.0.0\n 4 | name: my-tidb-instance\n 5 | password: my_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-tidb-instance:
|
||||
kind: tidb
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
ssl: false
|
||||
kind: sources
|
||||
name: my-tidb-instance
|
||||
type: tidb
|
||||
port: my-port
|
||||
database: my_db
|
||||
user: my_user
|
||||
password: my_pass
|
||||
ssl: false
|
||||
`,
|
||||
err: "unable to parse source \"my-tidb-instance\" as \"tidb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-tidb-instance\" as \"tidb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user"`
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
package trino
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
|
||||
@@ -153,16 +154,16 @@ func TestParseFromYamlTrino(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
sources:
|
||||
my-trino-instance:
|
||||
kind: trino
|
||||
host: localhost
|
||||
port: "8080"
|
||||
user: testuser
|
||||
catalog: hive
|
||||
schema: default
|
||||
kind: sources
|
||||
name: my-trino-instance
|
||||
type: trino
|
||||
host: localhost
|
||||
port: "8080"
|
||||
user: testuser
|
||||
catalog: hive
|
||||
schema: default
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-trino-instance": Config{
|
||||
Name: "my-trino-instance",
|
||||
Type: SourceType,
|
||||
@@ -177,21 +178,21 @@ func TestParseFromYamlTrino(t *testing.T) {
|
||||
{
|
||||
desc: "example with optional fields",
|
||||
in: `
|
||||
sources:
|
||||
my-trino-instance:
|
||||
kind: trino
|
||||
host: localhost
|
||||
port: "8443"
|
||||
user: testuser
|
||||
password: testpass
|
||||
catalog: hive
|
||||
schema: default
|
||||
queryTimeout: "30m"
|
||||
accessToken: "jwt-token-here"
|
||||
kerberosEnabled: true
|
||||
sslEnabled: true
|
||||
kind: sources
|
||||
name: my-trino-instance
|
||||
type: trino
|
||||
host: localhost
|
||||
port: "8443"
|
||||
user: testuser
|
||||
password: testpass
|
||||
catalog: hive
|
||||
schema: default
|
||||
queryTimeout: "30m"
|
||||
accessToken: "jwt-token-here"
|
||||
kerberosEnabled: true
|
||||
sslEnabled: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-trino-instance": Config{
|
||||
Name: "my-trino-instance",
|
||||
Type: SourceType,
|
||||
@@ -211,15 +212,15 @@ func TestParseFromYamlTrino(t *testing.T) {
|
||||
{
|
||||
desc: "anonymous access without user",
|
||||
in: `
|
||||
sources:
|
||||
my-trino-anonymous:
|
||||
kind: trino
|
||||
host: localhost
|
||||
port: "8080"
|
||||
catalog: hive
|
||||
schema: default
|
||||
kind: sources
|
||||
name: my-trino-anonymous
|
||||
type: trino
|
||||
host: localhost
|
||||
port: "8080"
|
||||
catalog: hive
|
||||
schema: default
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-trino-anonymous": Config{
|
||||
Name: "my-trino-anonymous",
|
||||
Type: SourceType,
|
||||
@@ -233,23 +234,23 @@ func TestParseFromYamlTrino(t *testing.T) {
|
||||
{
|
||||
desc: "example with SSL cert path and cert",
|
||||
in: `
|
||||
sources:
|
||||
my-trino-ssl-cert:
|
||||
kind: trino
|
||||
host: localhost
|
||||
port: "8443"
|
||||
user: testuser
|
||||
catalog: hive
|
||||
schema: default
|
||||
sslEnabled: true
|
||||
sslCertPath: /path/to/cert.pem
|
||||
sslCert: |-
|
||||
kind: sources
|
||||
name: my-trino-ssl-cert
|
||||
type: trino
|
||||
host: localhost
|
||||
port: "8443"
|
||||
user: testuser
|
||||
catalog: hive
|
||||
schema: default
|
||||
sslEnabled: true
|
||||
sslCertPath: /path/to/cert.pem
|
||||
sslCert: |-
|
||||
-----BEGIN CERTIFICATE-----
|
||||
...
|
||||
-----END CERTIFICATE-----
|
||||
disableSslVerification: true
|
||||
disableSslVerification: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-trino-ssl-cert": Config{
|
||||
Name: "my-trino-ssl-cert",
|
||||
Type: SourceType,
|
||||
@@ -268,16 +269,12 @@ func TestParseFromYamlTrino(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Address []string `yaml:"address" validate:"required"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
package valkey_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
@@ -35,11 +35,11 @@ func TestParseFromYamlValkey(t *testing.T) {
|
||||
{
|
||||
desc: "default setting",
|
||||
in: `
|
||||
sources:
|
||||
my-valkey-instance:
|
||||
kind: valkey
|
||||
address:
|
||||
- 127.0.0.1
|
||||
kind: sources
|
||||
name: my-valkey-instance
|
||||
type: valkey
|
||||
address:
|
||||
- 127.0.0.1
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-valkey-instance": valkey.Config{
|
||||
@@ -57,16 +57,16 @@ func TestParseFromYamlValkey(t *testing.T) {
|
||||
{
|
||||
desc: "advanced example",
|
||||
in: `
|
||||
sources:
|
||||
my-valkey-instance:
|
||||
kind: valkey
|
||||
address:
|
||||
- 127.0.0.1
|
||||
database: 1
|
||||
username: user
|
||||
password: pass
|
||||
useGCPIAM: true
|
||||
disableCache: true
|
||||
kind: sources
|
||||
name: my-valkey-instance
|
||||
type: valkey
|
||||
address:
|
||||
- 127.0.0.1
|
||||
database: 1
|
||||
username: user
|
||||
password: pass
|
||||
useGCPIAM: true
|
||||
disableCache: true
|
||||
`,
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-valkey-instance": valkey.Config{
|
||||
@@ -84,16 +84,12 @@ func TestParseFromYamlValkey(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got.Sources)
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse: want %v, got %v", tc.want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -109,47 +105,42 @@ func TestFailParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "invalid database",
|
||||
in: `
|
||||
sources:
|
||||
my-valkey-instance:
|
||||
kind: valkey
|
||||
project: my-project
|
||||
address:
|
||||
- 127.0.0.1
|
||||
database: my-db
|
||||
useGCPIAM: false
|
||||
kind: sources
|
||||
name: my-valkey-instance
|
||||
type: valkey
|
||||
address:
|
||||
- 127.0.0.1
|
||||
database: my-db
|
||||
useGCPIAM: false
|
||||
`,
|
||||
err: "cannot unmarshal string into Go struct field .Sources of type int",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-valkey-instance\" as \"valkey\": [3:11] cannot unmarshal string into Go struct field Config.Database of type int\n 1 | address:\n 2 | - 127.0.0.1\n> 3 | database: my-db\n ^\n 4 | name: my-valkey-instance\n 5 | type: valkey\n 6 | useGCPIAM: false",
|
||||
},
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-valkey-instance:
|
||||
kind: valkey
|
||||
address:
|
||||
- 127.0.0.1
|
||||
project: proj
|
||||
database: 1
|
||||
kind: sources
|
||||
name: my-valkey-instance
|
||||
type: valkey
|
||||
address:
|
||||
- 127.0.0.1
|
||||
project: proj
|
||||
database: 1
|
||||
`,
|
||||
err: "unable to parse source \"my-valkey-instance\" as \"valkey\": [5:1] unknown field \"project\"",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-valkey-instance\" as \"valkey\": [5:1] unknown field \"project\"\n 2 | - 127.0.0.1\n 3 | database: 1\n 4 | name: my-valkey-instance\n> 5 | project: proj\n ^\n 6 | type: valkey",
|
||||
},
|
||||
{
|
||||
desc: "missing required field",
|
||||
in: `
|
||||
sources:
|
||||
my-valkey-instance:
|
||||
kind: valkey
|
||||
kind: sources
|
||||
name: my-valkey-instance
|
||||
type: valkey
|
||||
`,
|
||||
err: "unable to parse source \"my-valkey-instance\" as \"valkey\": Key: 'Config.Address' Error:Field validation for 'Address' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-valkey-instance\" as \"valkey\": Key: 'Config.Address' Error:Field validation for 'Address' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expect parsing to fail")
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func newConfig(ctx context.Context, name string, decoder *yaml.Decoder) (sources
|
||||
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Host string `yaml:"host" validate:"required"`
|
||||
Port string `yaml:"port" validate:"required"`
|
||||
User string `yaml:"user" validate:"required"`
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
package yugabytedb_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"strings"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources"
|
||||
"github.com/googleapis/genai-toolbox/internal/sources/yugabytedb"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
)
|
||||
@@ -36,17 +37,16 @@ func TestParseFromYamlYugabyteDB(t *testing.T) {
|
||||
{
|
||||
desc: "only required fields",
|
||||
in: `
|
||||
sources:
|
||||
my-yb-instance:
|
||||
kind: yugabytedb
|
||||
name: my-yb-instance
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
kind: sources
|
||||
name: my-yb-instance
|
||||
type: yugabytedb
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-yb-instance": yugabytedb.Config{
|
||||
Name: "my-yb-instance",
|
||||
Type: "yugabytedb",
|
||||
@@ -61,18 +61,17 @@ func TestParseFromYamlYugabyteDB(t *testing.T) {
|
||||
{
|
||||
desc: "with loadBalance only",
|
||||
in: `
|
||||
sources:
|
||||
my-yb-instance:
|
||||
kind: yugabytedb
|
||||
name: my-yb-instance
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
kind: sources
|
||||
name: my-yb-instance
|
||||
type: yugabytedb
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-yb-instance": yugabytedb.Config{
|
||||
Name: "my-yb-instance",
|
||||
Type: "yugabytedb",
|
||||
@@ -88,19 +87,18 @@ func TestParseFromYamlYugabyteDB(t *testing.T) {
|
||||
{
|
||||
desc: "loadBalance with topologyKeys",
|
||||
in: `
|
||||
sources:
|
||||
my-yb-instance:
|
||||
kind: yugabytedb
|
||||
name: my-yb-instance
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
topologyKeys: zone1,zone2
|
||||
kind: sources
|
||||
name: my-yb-instance
|
||||
type: yugabytedb
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
topologyKeys: zone1,zone2
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-yb-instance": yugabytedb.Config{
|
||||
Name: "my-yb-instance",
|
||||
Type: "yugabytedb",
|
||||
@@ -117,20 +115,19 @@ func TestParseFromYamlYugabyteDB(t *testing.T) {
|
||||
{
|
||||
desc: "with fallback only",
|
||||
in: `
|
||||
sources:
|
||||
my-yb-instance:
|
||||
kind: yugabytedb
|
||||
name: my-yb-instance
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
topologyKeys: zone1
|
||||
fallbackToTopologyKeysOnly: true
|
||||
kind: sources
|
||||
name: my-yb-instance
|
||||
type: yugabytedb
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
topologyKeys: zone1
|
||||
fallbackToTopologyKeysOnly: true
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-yb-instance": yugabytedb.Config{
|
||||
Name: "my-yb-instance",
|
||||
Type: "yugabytedb",
|
||||
@@ -148,20 +145,19 @@ func TestParseFromYamlYugabyteDB(t *testing.T) {
|
||||
{
|
||||
desc: "with refresh interval and reconnect delay",
|
||||
in: `
|
||||
sources:
|
||||
my-yb-instance:
|
||||
kind: yugabytedb
|
||||
name: my-yb-instance
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
ybServersRefreshInterval: 20
|
||||
failedHostReconnectDelaySecs: 5
|
||||
kind: sources
|
||||
name: my-yb-instance
|
||||
type: yugabytedb
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
ybServersRefreshInterval: 20
|
||||
failedHostReconnectDelaySecs: 5
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-yb-instance": yugabytedb.Config{
|
||||
Name: "my-yb-instance",
|
||||
Type: "yugabytedb",
|
||||
@@ -179,22 +175,21 @@ func TestParseFromYamlYugabyteDB(t *testing.T) {
|
||||
{
|
||||
desc: "all fields set",
|
||||
in: `
|
||||
sources:
|
||||
my-yb-instance:
|
||||
kind: yugabytedb
|
||||
name: my-yb-instance
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
topologyKeys: zone1,zone2
|
||||
fallbackToTopologyKeysOnly: true
|
||||
ybServersRefreshInterval: 30
|
||||
failedHostReconnectDelaySecs: 10
|
||||
kind: sources
|
||||
name: my-yb-instance
|
||||
type: yugabytedb
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
database: yb_db
|
||||
loadBalance: true
|
||||
topologyKeys: zone1,zone2
|
||||
fallbackToTopologyKeysOnly: true
|
||||
ybServersRefreshInterval: 30
|
||||
failedHostReconnectDelaySecs: 10
|
||||
`,
|
||||
want: server.SourceConfigs{
|
||||
want: map[string]sources.SourceConfig{
|
||||
"my-yb-instance": yugabytedb.Config{
|
||||
Name: "my-yb-instance",
|
||||
Type: "yugabytedb",
|
||||
@@ -215,16 +210,12 @@ func TestParseFromYamlYugabyteDB(t *testing.T) {
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
got, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if !cmp.Equal(tc.want, got.Sources) {
|
||||
t.Fatalf("incorrect parse (-want +got):\n%s", cmp.Diff(tc.want, got.Sources))
|
||||
if !cmp.Equal(tc.want, got) {
|
||||
t.Fatalf("incorrect parse (-want +got):\n%s", cmp.Diff(tc.want, got))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -239,54 +230,48 @@ func TestFailParseFromYamlYugabyteDB(t *testing.T) {
|
||||
{
|
||||
desc: "extra field",
|
||||
in: `
|
||||
sources:
|
||||
my-yb-source:
|
||||
kind: yugabytedb
|
||||
name: my-yb-source
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
database: yb_db
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
foo: bar
|
||||
kind: sources
|
||||
name: my-yb-source
|
||||
type: yugabytedb
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
database: yb_db
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
foo: bar
|
||||
`,
|
||||
err: "unable to parse source \"my-yb-source\" as \"yugabytedb\": [2:1] unknown field \"foo\"",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-yb-source\" as \"yugabytedb\": [2:1] unknown field \"foo\"\n 1 | database: yb_db\n> 2 | foo: bar\n ^\n 3 | host: yb-host\n 4 | name: my-yb-source\n 5 | password: yb_pass\n 6 | ",
|
||||
},
|
||||
{
|
||||
desc: "missing required field (password)",
|
||||
in: `
|
||||
sources:
|
||||
my-yb-source:
|
||||
kind: yugabytedb
|
||||
name: my-yb-source
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
database: yb_db
|
||||
user: yb_user
|
||||
kind: sources
|
||||
name: my-yb-source
|
||||
type: yugabytedb
|
||||
host: yb-host
|
||||
port: yb-port
|
||||
database: yb_db
|
||||
user: yb_user
|
||||
`,
|
||||
err: "unable to parse source \"my-yb-source\" as \"yugabytedb\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-yb-source\" as \"yugabytedb\": Key: 'Config.Password' Error:Field validation for 'Password' failed on the 'required' tag",
|
||||
},
|
||||
{
|
||||
desc: "missing required field (host)",
|
||||
in: `
|
||||
sources:
|
||||
my-yb-source:
|
||||
kind: yugabytedb
|
||||
name: my-yb-source
|
||||
port: yb-port
|
||||
database: yb_db
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
kind: sources
|
||||
name: my-yb-source
|
||||
type: yugabytedb
|
||||
port: yb-port
|
||||
database: yb_db
|
||||
user: yb_user
|
||||
password: yb_pass
|
||||
`,
|
||||
err: "unable to parse source \"my-yb-source\" as \"yugabytedb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
err: "error unmarshaling sources: unable to parse source \"my-yb-source\" as \"yugabytedb\": Key: 'Config.Host' Error:Field validation for 'Host' failed on the 'required' tag",
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Sources server.SourceConfigs `yaml:"sources"`
|
||||
}{}
|
||||
err := yaml.Unmarshal(testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, _, _, _, err := server.UnmarshalResourceConfig(context.Background(), testutils.FormatYaml(tc.in))
|
||||
if err == nil {
|
||||
t.Fatalf("expected parsing to fail")
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ import (
|
||||
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||
)
|
||||
|
||||
const kind string = "alloydb-create-cluster"
|
||||
const resourceType string = "alloydb-create-cluster"
|
||||
|
||||
func init() {
|
||||
if !tools.Register(kind, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", kind))
|
||||
if !tools.Register(resourceType, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", resourceType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ type compatibleSource interface {
|
||||
// Configuration for the create-cluster tool.
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Source string `yaml:"source" validate:"required"`
|
||||
Description string `yaml:"description"`
|
||||
AuthRequired []string `yaml:"authRequired"`
|
||||
@@ -59,9 +59,9 @@ type Config struct {
|
||||
// validate interface
|
||||
var _ tools.ToolConfig = Config{}
|
||||
|
||||
// ToolConfigType returns the kind of the tool.
|
||||
// ToolConfigType returns the type of the tool.
|
||||
func (cfg Config) ToolConfigType() string {
|
||||
return kind
|
||||
return resourceType
|
||||
}
|
||||
|
||||
// Initialize initializes the tool from the configuration.
|
||||
@@ -73,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
|
||||
|
||||
s, ok := rawS.(compatibleSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source)
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source)
|
||||
}
|
||||
|
||||
project := s.GetDefaultProject()
|
||||
|
||||
@@ -17,7 +17,6 @@ package alloydbcreatecluster_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
@@ -37,11 +36,11 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
tools:
|
||||
create-my-cluster:
|
||||
kind: alloydb-create-cluster
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
kind: tools
|
||||
name: create-my-cluster
|
||||
type: alloydb-create-cluster
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"create-my-cluster": alloydbcreatecluster.Config{
|
||||
@@ -56,14 +55,14 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "with auth required",
|
||||
in: `
|
||||
tools:
|
||||
create-my-cluster-auth:
|
||||
kind: alloydb-create-cluster
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
kind: tools
|
||||
name: create-my-cluster-auth
|
||||
type: alloydb-create-cluster
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"create-my-cluster-auth": alloydbcreatecluster.Config{
|
||||
@@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Tools server.ToolConfigs `yaml:"tools"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Fatalf("incorrect parse: diff %v", diff)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -25,11 +25,11 @@ import (
|
||||
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||
)
|
||||
|
||||
const kind string = "alloydb-create-instance"
|
||||
const resourceType string = "alloydb-create-instance"
|
||||
|
||||
func init() {
|
||||
if !tools.Register(kind, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", kind))
|
||||
if !tools.Register(resourceType, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", resourceType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ type compatibleSource interface {
|
||||
// Configuration for the create-instance tool.
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Source string `yaml:"source" validate:"required"`
|
||||
Description string `yaml:"description"`
|
||||
AuthRequired []string `yaml:"authRequired"`
|
||||
@@ -59,9 +59,9 @@ type Config struct {
|
||||
// validate interface
|
||||
var _ tools.ToolConfig = Config{}
|
||||
|
||||
// ToolConfigType returns the kind of the tool.
|
||||
// ToolConfigType returns the type of the tool.
|
||||
func (cfg Config) ToolConfigType() string {
|
||||
return kind
|
||||
return resourceType
|
||||
}
|
||||
|
||||
// Initialize initializes the tool from the configuration.
|
||||
@@ -73,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
|
||||
|
||||
s, ok := rawS.(compatibleSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source)
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source)
|
||||
}
|
||||
|
||||
project := s.GetDefaultProject()
|
||||
|
||||
@@ -17,7 +17,6 @@ package alloydbcreateinstance_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
@@ -37,11 +36,11 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
tools:
|
||||
create-my-instance:
|
||||
kind: alloydb-create-instance
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
kind: tools
|
||||
name: create-my-instance
|
||||
type: alloydb-create-instance
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"create-my-instance": alloydbcreateinstance.Config{
|
||||
@@ -56,14 +55,14 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "with auth required",
|
||||
in: `
|
||||
tools:
|
||||
create-my-instance-auth:
|
||||
kind: alloydb-create-instance
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
kind: tools
|
||||
name: create-my-instance-auth
|
||||
type: alloydb-create-instance
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"create-my-instance-auth": alloydbcreateinstance.Config{
|
||||
@@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Tools server.ToolConfigs `yaml:"tools"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Fatalf("incorrect parse: diff %v", diff)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -25,11 +25,11 @@ import (
|
||||
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||
)
|
||||
|
||||
const kind string = "alloydb-create-user"
|
||||
const resourceType string = "alloydb-create-user"
|
||||
|
||||
func init() {
|
||||
if !tools.Register(kind, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", kind))
|
||||
if !tools.Register(resourceType, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", resourceType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ type compatibleSource interface {
|
||||
// Configuration for the create-user tool.
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Source string `yaml:"source" validate:"required"`
|
||||
Description string `yaml:"description"`
|
||||
AuthRequired []string `yaml:"authRequired"`
|
||||
@@ -59,9 +59,9 @@ type Config struct {
|
||||
// validate interface
|
||||
var _ tools.ToolConfig = Config{}
|
||||
|
||||
// ToolConfigType returns the kind of the tool.
|
||||
// ToolConfigType returns the type of the tool.
|
||||
func (cfg Config) ToolConfigType() string {
|
||||
return kind
|
||||
return resourceType
|
||||
}
|
||||
|
||||
// Initialize initializes the tool from the configuration.
|
||||
@@ -73,7 +73,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
|
||||
|
||||
s, ok := rawS.(compatibleSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source)
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source)
|
||||
}
|
||||
|
||||
project := s.GetDefaultProject()
|
||||
|
||||
@@ -17,7 +17,6 @@ package alloydbcreateuser_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
@@ -37,11 +36,11 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
tools:
|
||||
create-my-user:
|
||||
kind: alloydb-create-user
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
kind: tools
|
||||
name: create-my-user
|
||||
type: alloydb-create-user
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"create-my-user": alloydbcreateuser.Config{
|
||||
@@ -56,14 +55,14 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "with auth required",
|
||||
in: `
|
||||
tools:
|
||||
create-my-user-auth:
|
||||
kind: alloydb-create-user
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
kind: tools
|
||||
name: create-my-user-auth
|
||||
type: alloydb-create-user
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"create-my-user-auth": alloydbcreateuser.Config{
|
||||
@@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Tools server.ToolConfigs `yaml:"tools"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Fatalf("incorrect parse: diff %v", diff)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -25,11 +25,11 @@ import (
|
||||
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||
)
|
||||
|
||||
const kind string = "alloydb-get-cluster"
|
||||
const resourceType string = "alloydb-get-cluster"
|
||||
|
||||
func init() {
|
||||
if !tools.Register(kind, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", kind))
|
||||
if !tools.Register(resourceType, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", resourceType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ type compatibleSource interface {
|
||||
// Configuration for the get-cluster tool.
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Source string `yaml:"source" validate:"required"`
|
||||
Description string `yaml:"description"`
|
||||
AuthRequired []string `yaml:"authRequired"`
|
||||
@@ -60,9 +60,9 @@ type Config struct {
|
||||
// validate interface
|
||||
var _ tools.ToolConfig = Config{}
|
||||
|
||||
// ToolConfigType returns the kind of the tool.
|
||||
// ToolConfigType returns the type of the tool.
|
||||
func (cfg Config) ToolConfigType() string {
|
||||
return kind
|
||||
return resourceType
|
||||
}
|
||||
|
||||
// Initialize initializes the tool from the configuration.
|
||||
@@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
|
||||
|
||||
s, ok := rawS.(compatibleSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source)
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source)
|
||||
}
|
||||
|
||||
project := s.GetDefaultProject()
|
||||
|
||||
@@ -17,7 +17,6 @@ package alloydbgetcluster_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
@@ -37,12 +36,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
tools:
|
||||
get-my-cluster:
|
||||
kind: alloydb-get-cluster
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
`,
|
||||
kind: tools
|
||||
name: get-my-cluster
|
||||
type: alloydb-get-cluster
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"get-my-cluster": alloydbgetcluster.Config{
|
||||
Name: "get-my-cluster",
|
||||
@@ -56,15 +55,15 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "with auth required",
|
||||
in: `
|
||||
tools:
|
||||
get-my-cluster-auth:
|
||||
kind: alloydb-get-cluster
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
`,
|
||||
kind: tools
|
||||
name: get-my-cluster-auth
|
||||
type: alloydb-get-cluster
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"get-my-cluster-auth": alloydbgetcluster.Config{
|
||||
Name: "get-my-cluster-auth",
|
||||
@@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Tools server.ToolConfigs `yaml:"tools"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Fatalf("incorrect parse: diff %v", diff)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -25,11 +25,11 @@ import (
|
||||
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||
)
|
||||
|
||||
const kind string = "alloydb-get-instance"
|
||||
const resourceType string = "alloydb-get-instance"
|
||||
|
||||
func init() {
|
||||
if !tools.Register(kind, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", kind))
|
||||
if !tools.Register(resourceType, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", resourceType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ type compatibleSource interface {
|
||||
// Configuration for the get-instance tool.
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Source string `yaml:"source" validate:"required"`
|
||||
Description string `yaml:"description"`
|
||||
AuthRequired []string `yaml:"authRequired"`
|
||||
@@ -60,9 +60,9 @@ type Config struct {
|
||||
// validate interface
|
||||
var _ tools.ToolConfig = Config{}
|
||||
|
||||
// ToolConfigType returns the kind of the tool.
|
||||
// ToolConfigType returns the type of the tool.
|
||||
func (cfg Config) ToolConfigType() string {
|
||||
return kind
|
||||
return resourceType
|
||||
}
|
||||
|
||||
// Initialize initializes the tool from the configuration.
|
||||
@@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
|
||||
|
||||
s, ok := rawS.(compatibleSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source)
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source)
|
||||
}
|
||||
|
||||
project := s.GetDefaultProject()
|
||||
|
||||
@@ -17,7 +17,6 @@ package alloydbgetinstance_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
@@ -37,12 +36,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
tools:
|
||||
get-my-instance:
|
||||
kind: alloydb-get-instance
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
`,
|
||||
kind: tools
|
||||
name: get-my-instance
|
||||
type: alloydb-get-instance
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"get-my-instance": alloydbgetinstance.Config{
|
||||
Name: "get-my-instance",
|
||||
@@ -56,15 +55,15 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "with auth required",
|
||||
in: `
|
||||
tools:
|
||||
get-my-instance-auth:
|
||||
kind: alloydb-get-instance
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
`,
|
||||
kind: tools
|
||||
name: get-my-instance-auth
|
||||
type: alloydb-get-instance
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"get-my-instance-auth": alloydbgetinstance.Config{
|
||||
Name: "get-my-instance-auth",
|
||||
@@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Tools server.ToolConfigs `yaml:"tools"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Fatalf("incorrect parse: diff %v", diff)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -25,11 +25,11 @@ import (
|
||||
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||
)
|
||||
|
||||
const kind string = "alloydb-get-user"
|
||||
const resourceType string = "alloydb-get-user"
|
||||
|
||||
func init() {
|
||||
if !tools.Register(kind, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", kind))
|
||||
if !tools.Register(resourceType, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", resourceType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ type compatibleSource interface {
|
||||
// Configuration for the get-user tool.
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Source string `yaml:"source" validate:"required"`
|
||||
Description string `yaml:"description"`
|
||||
AuthRequired []string `yaml:"authRequired"`
|
||||
@@ -60,9 +60,9 @@ type Config struct {
|
||||
// validate interface
|
||||
var _ tools.ToolConfig = Config{}
|
||||
|
||||
// ToolConfigType returns the kind of the tool.
|
||||
// ToolConfigType returns the type of the tool.
|
||||
func (cfg Config) ToolConfigType() string {
|
||||
return kind
|
||||
return resourceType
|
||||
}
|
||||
|
||||
// Initialize initializes the tool from the configuration.
|
||||
@@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
|
||||
|
||||
s, ok := rawS.(compatibleSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source)
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source)
|
||||
}
|
||||
|
||||
project := s.GetDefaultProject()
|
||||
|
||||
@@ -17,7 +17,6 @@ package alloydbgetuser_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/googleapis/genai-toolbox/internal/server"
|
||||
"github.com/googleapis/genai-toolbox/internal/testutils"
|
||||
@@ -37,12 +36,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "basic example",
|
||||
in: `
|
||||
tools:
|
||||
get-my-user:
|
||||
kind: alloydb-get-user
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
`,
|
||||
kind: tools
|
||||
name: get-my-user
|
||||
type: alloydb-get-user
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"get-my-user": alloydbgetuser.Config{
|
||||
Name: "get-my-user",
|
||||
@@ -56,15 +55,15 @@ func TestParseFromYaml(t *testing.T) {
|
||||
{
|
||||
desc: "with auth required",
|
||||
in: `
|
||||
tools:
|
||||
get-my-user-auth:
|
||||
kind: alloydb-get-user
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
`,
|
||||
kind: tools
|
||||
name: get-my-user-auth
|
||||
type: alloydb-get-user
|
||||
source: my-alloydb-admin-source
|
||||
description: some description
|
||||
authRequired:
|
||||
- my-google-auth-service
|
||||
- other-auth-service
|
||||
`,
|
||||
want: server.ToolConfigs{
|
||||
"get-my-user-auth": alloydbgetuser.Config{
|
||||
Name: "get-my-user-auth",
|
||||
@@ -78,15 +77,12 @@ func TestParseFromYaml(t *testing.T) {
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
got := struct {
|
||||
Tools server.ToolConfigs `yaml:"tools"`
|
||||
}{}
|
||||
// Parse contents
|
||||
err := yaml.UnmarshalContext(ctx, testutils.FormatYaml(tc.in), &got)
|
||||
_, _, _, got, _, _, err := server.UnmarshalResourceConfig(ctx, testutils.FormatYaml(tc.in))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to unmarshal: %s", err)
|
||||
}
|
||||
if diff := cmp.Diff(tc.want, got.Tools); diff != "" {
|
||||
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||
t.Fatalf("incorrect parse: diff %v", diff)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -25,11 +25,11 @@ import (
|
||||
"github.com/googleapis/genai-toolbox/internal/util/parameters"
|
||||
)
|
||||
|
||||
const kind string = "alloydb-list-clusters"
|
||||
const resourceType string = "alloydb-list-clusters"
|
||||
|
||||
func init() {
|
||||
if !tools.Register(kind, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", kind))
|
||||
if !tools.Register(resourceType, newConfig) {
|
||||
panic(fmt.Sprintf("tool type %q already registered", resourceType))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ type compatibleSource interface {
|
||||
// Configuration for the list-clusters tool.
|
||||
type Config struct {
|
||||
Name string `yaml:"name" validate:"required"`
|
||||
Type string `yaml:"kind" validate:"required"`
|
||||
Type string `yaml:"type" validate:"required"`
|
||||
Source string `yaml:"source" validate:"required"`
|
||||
Description string `yaml:"description"`
|
||||
AuthRequired []string `yaml:"authRequired"`
|
||||
@@ -60,9 +60,9 @@ type Config struct {
|
||||
// validate interface
|
||||
var _ tools.ToolConfig = Config{}
|
||||
|
||||
// ToolConfigType returns the kind of the tool.
|
||||
// ToolConfigType returns the type of the tool.
|
||||
func (cfg Config) ToolConfigType() string {
|
||||
return kind
|
||||
return resourceType
|
||||
}
|
||||
|
||||
// Initialize initializes the tool from the configuration.
|
||||
@@ -74,7 +74,7 @@ func (cfg Config) Initialize(srcs map[string]sources.Source) (tools.Tool, error)
|
||||
|
||||
s, ok := rawS.(compatibleSource)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", kind, cfg.Source)
|
||||
return nil, fmt.Errorf("invalid source for %q tool: source %q not compatible", resourceType, cfg.Source)
|
||||
}
|
||||
|
||||
project := s.GetDefaultProject()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user