<!-- Provide a brief summary of your changes --> ## Motivation and Context <!-- Why is this change needed? What problem does it solve? --> The follow PR removes the in-memory database option from the registry. We had a chat about this with @domdomegg and although it is supposed to be convenient, it isn't that useful in reality. We want to test and develop the registry in a setup that is closer to the environment it is supposed to be run. One of the main reasons are: * We don't use it anywhere else besides unit testing and potentially local development. Instead we should use postgresql for reliable results (in-memory was actually giving false positive results) * We have to keep maintaining it and make sure it mimics the behaviour we have for postgresql which is not yielding a lot of value ## How Has This Been Tested? <!-- Have you tested this in a real application? Which scenarios were tested? --> Yes, I've updated the test unit make target to run in the postgresql environment and now we can see the race condition issue happening. ## Breaking Changes <!-- Will users need to update their code or configurations? --> No ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [ ] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [ ] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed ## Additional context <!-- Add any other context, implementation notes, or design decisions --> --------- Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
197 lines
5.3 KiB
Go
197 lines
5.3 KiB
Go
package importer_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/modelcontextprotocol/registry/internal/database"
|
|
"github.com/modelcontextprotocol/registry/internal/importer"
|
|
apiv0 "github.com/modelcontextprotocol/registry/pkg/api/v0"
|
|
"github.com/modelcontextprotocol/registry/pkg/model"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestImportService_LocalFile(t *testing.T) {
|
|
// Create a temporary seed file
|
|
tempFile := "/tmp/test_import_seed.json"
|
|
seedData := []apiv0.ServerJSON{
|
|
{
|
|
Name: "io.github.test/test-server-1",
|
|
Description: "Test server 1",
|
|
Repository: model.Repository{
|
|
URL: "https://github.com/test/repo1",
|
|
Source: "github",
|
|
ID: "123",
|
|
},
|
|
Version: "1.0.0",
|
|
Meta: &apiv0.ServerMeta{
|
|
Official: &apiv0.RegistryExtensions{
|
|
ServerID: "server-id-1",
|
|
VersionID: "test-id-1",
|
|
PublishedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
IsLatest: true,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
jsonData, err := json.Marshal(seedData)
|
|
require.NoError(t, err)
|
|
|
|
err = os.WriteFile(tempFile, jsonData, 0600)
|
|
require.NoError(t, err)
|
|
defer os.Remove(tempFile)
|
|
|
|
testDB := database.NewTestDB(t)
|
|
|
|
// Create importer service and test import
|
|
service := importer.NewService(testDB)
|
|
err = service.ImportFromPath(context.Background(), tempFile)
|
|
require.NoError(t, err)
|
|
|
|
// Verify the server was imported
|
|
servers, _, err := testDB.List(context.Background(), nil, "", 10)
|
|
require.NoError(t, err)
|
|
assert.Len(t, servers, 1)
|
|
assert.Equal(t, "io.github.test/test-server-1", servers[0].Name)
|
|
}
|
|
|
|
func TestImportService_HTTPFile(t *testing.T) {
|
|
// Create a test HTTP server
|
|
seedData := []apiv0.ServerJSON{
|
|
{
|
|
Name: "io.github.test/http-test-server",
|
|
Description: "HTTP test server",
|
|
Repository: model.Repository{
|
|
URL: "https://github.com/test/repo1",
|
|
Source: "github",
|
|
ID: "123",
|
|
},
|
|
Version: "2.0.0",
|
|
Meta: &apiv0.ServerMeta{
|
|
Official: &apiv0.RegistryExtensions{
|
|
ServerID: "server-id-test",
|
|
VersionID: "test-id-2",
|
|
PublishedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
IsLatest: true,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_ = json.NewEncoder(w).Encode(seedData)
|
|
}))
|
|
defer server.Close()
|
|
|
|
testDB := database.NewTestDB(t)
|
|
|
|
// Create importer service and test import
|
|
service := importer.NewService(testDB)
|
|
err := service.ImportFromPath(context.Background(), server.URL+"/seed.json")
|
|
require.NoError(t, err)
|
|
|
|
// Verify the server was imported
|
|
servers, _, err := testDB.List(context.Background(), nil, "", 10)
|
|
require.NoError(t, err)
|
|
assert.Len(t, servers, 1)
|
|
assert.Equal(t, "io.github.test/http-test-server", servers[0].Name)
|
|
}
|
|
|
|
func TestImportService_RegistryAPI(t *testing.T) {
|
|
// Create test data
|
|
testServers := []apiv0.ServerJSON{
|
|
{
|
|
Name: "io.github.test/api-server-1",
|
|
Description: "API server 1",
|
|
Repository: model.Repository{
|
|
URL: "https://github.com/test/repo1",
|
|
Source: "github",
|
|
ID: "123",
|
|
},
|
|
Version: "1.0.0",
|
|
Meta: &apiv0.ServerMeta{
|
|
Official: &apiv0.RegistryExtensions{
|
|
ServerID: "server-id-test-1",
|
|
VersionID: "api-test-id-1",
|
|
PublishedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
IsLatest: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "io.github.test/api-server-2",
|
|
Description: "API server 2",
|
|
Repository: model.Repository{
|
|
URL: "https://github.com/test/repo2",
|
|
Source: "github",
|
|
ID: "456",
|
|
},
|
|
Version: "2.0.0",
|
|
Meta: &apiv0.ServerMeta{
|
|
Official: &apiv0.RegistryExtensions{
|
|
ServerID: "server-id-test-2",
|
|
VersionID: "api-test-id-2",
|
|
PublishedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
IsLatest: true,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
// Create test server that responds with paginated results
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
cursor := r.URL.Query().Get("cursor")
|
|
|
|
var response struct {
|
|
Servers []apiv0.ServerJSON `json:"servers"`
|
|
Metadata *struct {
|
|
NextCursor string `json:"next_cursor,omitempty"`
|
|
} `json:"metadata,omitempty"`
|
|
}
|
|
|
|
switch cursor {
|
|
case "":
|
|
// First page
|
|
response.Servers = []apiv0.ServerJSON{testServers[0]}
|
|
response.Metadata = &struct {
|
|
NextCursor string `json:"next_cursor,omitempty"`
|
|
}{NextCursor: "page2"}
|
|
case "page2":
|
|
// Second page
|
|
response.Servers = []apiv0.ServerJSON{testServers[1]}
|
|
// No next cursor means end of results
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_ = json.NewEncoder(w).Encode(response)
|
|
}))
|
|
defer server.Close()
|
|
|
|
testDB := database.NewTestDB(t)
|
|
|
|
// Create importer service and test import
|
|
service := importer.NewService(testDB)
|
|
err := service.ImportFromPath(context.Background(), server.URL+"/v0/servers")
|
|
require.NoError(t, err)
|
|
|
|
// Verify both servers were imported
|
|
servers, _, err := testDB.List(context.Background(), nil, "", 10)
|
|
require.NoError(t, err)
|
|
assert.Len(t, servers, 2)
|
|
|
|
names := []string{servers[0].Name, servers[1].Name}
|
|
assert.Contains(t, names, "io.github.test/api-server-1")
|
|
assert.Contains(t, names, "io.github.test/api-server-2")
|
|
}
|