Skip to main content
Glama

MCP Toolbox for Databases

by googleapis
Apache 2.0
11,060
  • Linux
clickhouse_test.go7.76 kB
// 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. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package clickhouse import ( "context" "strings" "testing" "github.com/goccy/go-yaml" "github.com/google/go-cmp/cmp" "github.com/googleapis/genai-toolbox/internal/testutils" "go.opentelemetry.io/otel" ) func TestConfigSourceConfigKind(t *testing.T) { config := Config{} if config.SourceConfigKind() != SourceKind { t.Errorf("Expected %s, got %s", SourceKind, config.SourceConfigKind()) } } func TestNewConfig(t *testing.T) { tests := []struct { name string yaml string expected Config }{ { name: "all fields specified", yaml: ` name: test-clickhouse kind: clickhouse host: localhost port: "8443" user: default password: "mypass" database: mydb protocol: https secure: true `, expected: Config{ Name: "test-clickhouse", Kind: "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", Kind: "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", Kind: "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", Kind: "clickhouse", Host: "secure.clickhouse.io", Port: "8443", User: "secureuser", Password: "verysecure", Database: "production", Protocol: "https", Secure: true, }, }, } 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) } 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) } }) } } func TestNewConfigInvalidYAML(t *testing.T) { tests := []struct { name string yaml string expectError bool }{ { name: "invalid yaml syntax", yaml: ` name: test-clickhouse kind: clickhouse host: [invalid `, expectError: true, }, { name: "missing required fields", yaml: ` name: test-clickhouse kind: clickhouse `, expectError: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { decoder := yaml.NewDecoder(strings.NewReader(string(testutils.FormatYaml(tt.yaml)))) _, err := newConfig(context.Background(), "test-clickhouse", decoder) if tt.expectError && err == nil { t.Errorf("Expected error but got none") } if !tt.expectError && err != nil { t.Errorf("Expected no error but got: %v", err) } }) } } func TestSource_SourceKind(t *testing.T) { source := &Source{} if source.SourceKind() != SourceKind { t.Errorf("Expected %s, got %s", SourceKind, source.SourceKind()) } } func TestValidateConfig(t *testing.T) { tests := []struct { name string protocol string expectError bool }{ { name: "valid https protocol", protocol: "https", expectError: false, }, { name: "valid http protocol", protocol: "http", expectError: false, }, { name: "invalid protocol", protocol: "invalid", expectError: true, }, { name: "invalid protocol - native not supported", protocol: "native", expectError: true, }, { name: "empty values use defaults", protocol: "", expectError: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := validateConfig(tt.protocol) if tt.expectError && err == nil { t.Errorf("Expected error but got none") } if !tt.expectError && err != nil { t.Errorf("Expected no error but got: %v", err) } }) } } func TestInitClickHouseConnectionPoolDSNGeneration(t *testing.T) { tracer := otel.Tracer("test") ctx := context.Background() tests := []struct { name string host string port string user string pass string dbname string protocol string secure bool shouldErr bool }{ { name: "http protocol with defaults", host: "localhost", port: "8123", user: "default", pass: "", dbname: "default", protocol: "http", secure: false, shouldErr: true, }, { name: "https protocol with secure", host: "localhost", port: "8443", user: "default", pass: "", dbname: "default", protocol: "https", secure: true, shouldErr: true, }, { name: "special characters in password", host: "localhost", port: "8443", user: "test@user", pass: "pass@word:with/special&chars", dbname: "default", protocol: "https", secure: true, shouldErr: true, }, { name: "invalid protocol should fail", host: "localhost", port: "9000", user: "default", pass: "", dbname: "default", protocol: "invalid", secure: false, shouldErr: true, }, { name: "empty protocol defaults to https", host: "localhost", port: "8443", user: "user", pass: "pass", dbname: "testdb", protocol: "", secure: true, shouldErr: true, }, { name: "http with secure flag should upgrade to https", host: "example.com", port: "8443", user: "user", pass: "pass", dbname: "db", protocol: "http", secure: true, shouldErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pool, err := initClickHouseConnectionPool(ctx, tracer, "test", tt.host, tt.port, tt.user, tt.pass, tt.dbname, tt.protocol, tt.secure) if !tt.shouldErr && err != nil { t.Errorf("Expected no error, got: %v", err) } if pool != nil { pool.Close() } }) } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/googleapis/genai-toolbox'

If you have feedback or need assistance with the MCP directory API, please join our Discord server