package launcher_test import ( "os" "path/filepath" "runtime" "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" launcher "github.com/mudler/LocalAI/cmd/launcher/internal" ) var _ = Describe("ReleaseManager", func() { var ( rm *launcher.ReleaseManager tempDir string ) BeforeEach(func() { var err error tempDir, err = os.MkdirTemp("", "launcher-test-*") Expect(err).ToNot(HaveOccurred()) rm = launcher.NewReleaseManager() // Override binary path for testing rm.BinaryPath = tempDir }) AfterEach(func() { os.RemoveAll(tempDir) }) Describe("NewReleaseManager", func() { It("should create a release manager with correct defaults", func() { newRM := launcher.NewReleaseManager() Expect(newRM.GitHubOwner).To(Equal("mudler")) Expect(newRM.GitHubRepo).To(Equal("LocalAI")) Expect(newRM.BinaryPath).To(ContainSubstring(".localai")) Expect(newRM.HTTPClient).ToNot(BeNil()) Expect(newRM.HTTPClient.Timeout).To(Equal(30 * time.Second)) }) }) Describe("GetBinaryName", func() { It("should return correct binary name for current platform", func() { binaryName := rm.GetBinaryName("v3.4.0") expectedOS := runtime.GOOS expectedArch := runtime.GOARCH expected := "local-ai-v3.4.0-" + expectedOS + "-" + expectedArch Expect(binaryName).To(Equal(expected)) }) It("should handle version with and without 'v' prefix", func() { withV := rm.GetBinaryName("v3.4.0") withoutV := rm.GetBinaryName("3.4.0") // Both should produce the same result Expect(withV).To(Equal(withoutV)) }) }) Describe("GetBinaryPath", func() { It("should return the correct binary path", func() { path := rm.GetBinaryPath() expected := filepath.Join(tempDir, "local-ai") Expect(path).To(Equal(expected)) }) }) Describe("GetInstalledVersion", func() { It("should return empty when no binary exists", func() { version := rm.GetInstalledVersion() Expect(version).To(BeEmpty()) // No binary installed in test }) It("should return empty version when binary exists but no metadata", func() { // Create a fake binary for testing err := os.MkdirAll(rm.BinaryPath, 0755) Expect(err).ToNot(HaveOccurred()) binaryPath := rm.GetBinaryPath() err = os.WriteFile(binaryPath, []byte("fake binary"), 0755) Expect(err).ToNot(HaveOccurred()) version := rm.GetInstalledVersion() Expect(version).To(BeEmpty()) }) }) Context("with mocked responses", func() { // Note: In a real implementation, we'd mock HTTP responses // For now, we'll test the structure and error handling Describe("GetLatestRelease", func() { It("should handle network errors gracefully", func() { // This test would require mocking HTTP client // For demonstration, we're just testing the method exists _, err := rm.GetLatestRelease() // We expect either success or a network error, not a panic // In a real test, we'd mock the HTTP response if err != nil { Expect(err.Error()).To(ContainSubstring("failed to fetch")) } }) }) Describe("DownloadRelease", func() { It("should create binary directory if it doesn't exist", func() { // Remove the temp directory to test creation os.RemoveAll(tempDir) // This will fail due to network, but should create the directory rm.DownloadRelease("v3.4.0", nil) // Check if directory was created _, err := os.Stat(tempDir) Expect(err).ToNot(HaveOccurred()) }) }) }) Describe("VerifyChecksum functionality", func() { var ( testFile string checksumFile string ) BeforeEach(func() { testFile = filepath.Join(tempDir, "test-binary") checksumFile = filepath.Join(tempDir, "checksums.txt") }) It("should verify checksums correctly", func() { // Create a test file with known content testContent := []byte("test content for checksum") err := os.WriteFile(testFile, testContent, 0644) Expect(err).ToNot(HaveOccurred()) // Calculate expected SHA256 // This is a simplified test - in practice we'd use the actual checksum checksumContent := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 test-binary\n" err = os.WriteFile(checksumFile, []byte(checksumContent), 0644) Expect(err).ToNot(HaveOccurred()) // Test checksum verification // Note: This will fail because our content doesn't match the empty string hash // In a real test, we'd calculate the actual hash err = rm.VerifyChecksum(testFile, checksumFile, "test-binary") // We expect this to fail since we're using a dummy checksum Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("checksum mismatch")) }) It("should handle missing checksum file", func() { // Create test file but no checksum file err := os.WriteFile(testFile, []byte("test"), 0644) Expect(err).ToNot(HaveOccurred()) err = rm.VerifyChecksum(testFile, checksumFile, "test-binary") Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("failed to open checksums file")) }) It("should handle missing binary in checksums", func() { // Create files but checksum doesn't contain our binary err := os.WriteFile(testFile, []byte("test"), 0644) Expect(err).ToNot(HaveOccurred()) checksumContent := "hash other-binary\n" err = os.WriteFile(checksumFile, []byte(checksumContent), 0644) Expect(err).ToNot(HaveOccurred()) err = rm.VerifyChecksum(testFile, checksumFile, "test-binary") Expect(err).To(HaveOccurred()) Expect(err.Error()).To(ContainSubstring("checksum not found")) }) }) })