280 lines
7.4 KiB
Go
280 lines
7.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
|
|
"spore-registry/internal/database"
|
|
"spore-registry/internal/handlers"
|
|
"spore-registry/internal/models"
|
|
"spore-registry/internal/repository"
|
|
"spore-registry/internal/service"
|
|
"spore-registry/internal/storage"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
// setupTestDB creates a temporary database for testing
|
|
func setupTestDB(t *testing.T) (*database.DB, *storage.FileStorage, *handlers.FirmwareHandler) {
|
|
// Create temporary directory for test registry
|
|
tmpDir, err := os.MkdirTemp("", "registry_test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir: %v", err)
|
|
}
|
|
|
|
// Clean up temporary directory after test
|
|
defer func() {
|
|
os.RemoveAll(tmpDir)
|
|
}()
|
|
|
|
// Create test database
|
|
db, err := database.NewDB(":memory:")
|
|
if err != nil {
|
|
t.Fatalf("Failed to open test database: %v", err)
|
|
}
|
|
|
|
// Create repository
|
|
repo := repository.NewFirmwareRepository(db.GetConnection())
|
|
|
|
// Create storage
|
|
fileStorage := storage.NewFileStorage(tmpDir)
|
|
|
|
// Create service
|
|
firmwareService := service.NewFirmwareService(repo, fileStorage)
|
|
|
|
// Create handler
|
|
handler := handlers.NewFirmwareHandler(firmwareService)
|
|
|
|
return db, fileStorage, handler
|
|
}
|
|
|
|
func TestStoreFirmwareMetadata(t *testing.T) {
|
|
db, _, _ := setupTestDB(t)
|
|
defer db.Close()
|
|
|
|
metadata := models.FirmwareMetadata{
|
|
Name: "test-firmware",
|
|
Version: "1.0.0",
|
|
Labels: map[string]string{
|
|
"app": "test",
|
|
},
|
|
}
|
|
|
|
// Create a test service to test the repository directly
|
|
repo := repository.NewFirmwareRepository(db.GetConnection())
|
|
fileStorage := storage.NewFileStorage("/tmp")
|
|
service := service.NewFirmwareService(repo, fileStorage)
|
|
|
|
_, err := service.UploadFirmware(metadata, bytes.NewReader([]byte("test data")))
|
|
if err != nil {
|
|
t.Fatalf("Failed to upload firmware: %v", err)
|
|
}
|
|
|
|
// Verify the record was stored by listing firmware
|
|
grouped, err := service.ListFirmware("", "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to retrieve firmware records: %v", err)
|
|
}
|
|
|
|
if len(grouped) != 1 {
|
|
t.Fatalf("Expected 1 group, got %d", len(grouped))
|
|
}
|
|
|
|
if len(grouped[0].Firmware) != 1 {
|
|
t.Fatalf("Expected 1 firmware record, got %d", len(grouped[0].Firmware))
|
|
}
|
|
|
|
record := grouped[0].Firmware[0]
|
|
if record.Name != metadata.Name {
|
|
t.Errorf("Expected name %s, got %s", metadata.Name, record.Name)
|
|
}
|
|
if record.Version != metadata.Version {
|
|
t.Errorf("Expected version %s, got %s", metadata.Version, record.Version)
|
|
}
|
|
if record.Labels["app"] != "test" {
|
|
t.Errorf("Expected label app=test, got %s", record.Labels["app"])
|
|
}
|
|
}
|
|
|
|
func TestGetFirmwareRecordsWithFilters(t *testing.T) {
|
|
db, _, _ := setupTestDB(t)
|
|
defer db.Close()
|
|
|
|
// Create a test service to test the repository directly
|
|
repo := repository.NewFirmwareRepository(db.GetConnection())
|
|
fileStorage := storage.NewFileStorage("/tmp")
|
|
service := service.NewFirmwareService(repo, fileStorage)
|
|
|
|
// Insert test data
|
|
testRecords := []models.FirmwareMetadata{
|
|
{Name: "firmware1", Version: "1.0.0", Labels: map[string]string{"type": "app"}},
|
|
{Name: "firmware1", Version: "1.1.0", Labels: map[string]string{"type": "app"}},
|
|
{Name: "firmware2", Version: "1.0.0", Labels: map[string]string{"type": "sensor"}},
|
|
}
|
|
|
|
for _, record := range testRecords {
|
|
_, err := service.UploadFirmware(record, bytes.NewReader([]byte("test data")))
|
|
if err != nil {
|
|
t.Fatalf("Failed to store test data: %v", err)
|
|
}
|
|
}
|
|
|
|
// Test filtering by name
|
|
grouped, err := service.ListFirmware("firmware1", "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to get records by name: %v", err)
|
|
}
|
|
if len(grouped) != 1 || len(grouped[0].Firmware) != 2 {
|
|
t.Errorf("Expected 1 group with 2 records for firmware1, got %d groups", len(grouped))
|
|
}
|
|
|
|
// Test filtering by version
|
|
grouped, err = service.ListFirmware("", "1.0.0")
|
|
if err != nil {
|
|
t.Fatalf("Failed to get records by version: %v", err)
|
|
}
|
|
if len(grouped) != 2 {
|
|
t.Errorf("Expected 2 groups for version 1.0.0, got %d", len(grouped))
|
|
}
|
|
|
|
// Test filtering by both name and version
|
|
grouped, err = service.ListFirmware("firmware1", "1.0.0")
|
|
if err != nil {
|
|
t.Fatalf("Failed to get records by name and version: %v", err)
|
|
}
|
|
if len(grouped) != 1 || len(grouped[0].Firmware) != 1 {
|
|
t.Errorf("Expected 1 group with 1 record for firmware1/1.0.0, got %d groups", len(grouped))
|
|
}
|
|
}
|
|
|
|
func TestStoreFirmwareBinary(t *testing.T) {
|
|
db, fileStorage, _ := setupTestDB(t)
|
|
defer db.Close()
|
|
|
|
testData := []byte("test firmware binary data")
|
|
reader := bytes.NewReader(testData)
|
|
|
|
filePath, size, err := fileStorage.StoreFirmwareBinary("test", "1.0.0", reader)
|
|
if err != nil {
|
|
t.Fatalf("Failed to store firmware binary: %v", err)
|
|
}
|
|
|
|
if size != int64(len(testData)) {
|
|
t.Errorf("Expected size %d, got %d", len(testData), size)
|
|
}
|
|
|
|
// Verify file was created
|
|
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
|
t.Errorf("Firmware file was not created at %s", filePath)
|
|
}
|
|
|
|
// Verify file contents
|
|
storedData, err := os.ReadFile(filePath)
|
|
if err != nil {
|
|
t.Fatalf("Failed to read stored file: %v", err)
|
|
}
|
|
|
|
if !bytes.Equal(testData, storedData) {
|
|
t.Error("Stored file contents don't match original data")
|
|
}
|
|
}
|
|
|
|
func TestListFirmwareAPI(t *testing.T) {
|
|
db, _, handler := setupTestDB(t)
|
|
defer db.Close()
|
|
|
|
// Create a test service to test the repository directly
|
|
repo := repository.NewFirmwareRepository(db.GetConnection())
|
|
fileStorage := storage.NewFileStorage("/tmp")
|
|
service := service.NewFirmwareService(repo, fileStorage)
|
|
|
|
// Insert test data
|
|
metadata := models.FirmwareMetadata{
|
|
Name: "test-firmware",
|
|
Version: "1.0.0",
|
|
Labels: map[string]string{"app": "test"},
|
|
}
|
|
_, err := service.UploadFirmware(metadata, bytes.NewReader([]byte("test data")))
|
|
if err != nil {
|
|
t.Fatalf("Failed to store test data: %v", err)
|
|
}
|
|
|
|
// Test GET /firmware
|
|
req := httptest.NewRequest("GET", "/firmware", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
handler.ListFirmware(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("Expected status 200, got %d", w.Code)
|
|
}
|
|
|
|
var grouped []models.GroupedFirmware
|
|
err = json.Unmarshal(w.Body.Bytes(), &grouped)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
if len(grouped) != 1 {
|
|
t.Errorf("Expected 1 group, got %d", len(grouped))
|
|
}
|
|
}
|
|
|
|
func TestHealthCheckAPI(t *testing.T) {
|
|
db, _, handler := setupTestDB(t)
|
|
defer db.Close()
|
|
|
|
req := httptest.NewRequest("GET", "/health", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
handler.HealthCheck(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("Expected status 200, got %d", w.Code)
|
|
}
|
|
|
|
var response models.HealthResponse
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
if response.Status != "healthy" {
|
|
t.Errorf("Expected status 'healthy', got '%s'", response.Status)
|
|
}
|
|
}
|
|
|
|
func TestInvalidFirmwarePath(t *testing.T) {
|
|
db, _, handler := setupTestDB(t)
|
|
defer db.Close()
|
|
|
|
// Test invalid path (too many parts)
|
|
req := httptest.NewRequest("GET", "/firmware/invalid/path/extra", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
handler.DownloadFirmware(w, req)
|
|
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Errorf("Expected status 400, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestFirmwareNotFound(t *testing.T) {
|
|
db, _, handler := setupTestDB(t)
|
|
defer db.Close()
|
|
|
|
// Test firmware not found
|
|
req := httptest.NewRequest("GET", "/firmware/nonexistent/1.0.0", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
handler.DownloadFirmware(w, req)
|
|
|
|
if w.Code != http.StatusNotFound {
|
|
t.Errorf("Expected status 404, got %d", w.Code)
|
|
}
|
|
}
|