mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-13 10:17:58 +02:00
Trois retours d'utilisateurs apres la 0.8.3. Export de la conversation (regression de la 0.8 : conversation.json a disparu dans ajean.db, verrouille et binaire). Bouton dans l'UI + commande 'ajean export [--json] [fichier]', endpoint /api/chat/export. Ecoute reseau du moteur : interrupteur 'joignable depuis le reseau local' dans le panneau Acces OpenAI (HOST + regle de pare-feu Windows), commande 'ajean network [on|off|status]'. HOST devient un reglage de machine preserve au changement de preset. Modeles GGUF decoupes en tranches -00001-of-000NN : une famille = un modele. Telechargement de toutes les tranches depuis n'importe quel lien, sonde d'espace disque sur le total, liste et suppression regroupees, demarrage refuse avec le nom du fichier manquant.
107 lines
3.1 KiB
Go
107 lines
3.1 KiB
Go
package ajean
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestEngineHostDefautEtBascule(t *testing.T) {
|
|
testHome(t)
|
|
// Clé absente : c'est le défaut de backend_serve.go qui s'applique, soit toutes
|
|
// les interfaces. Annoncer « fermé » ici serait un mensonge.
|
|
if h := engineHost(); h != hostAllInterfaces {
|
|
t.Fatalf("HOST absent → %q ; attendu %q", h, hostAllInterfaces)
|
|
}
|
|
if !lanExposed() {
|
|
t.Fatal("HOST absent devrait compter comme exposé")
|
|
}
|
|
if _, err := setLANExposure(false); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if lanExposed() || ReadConfig()["HOST"] != hostLocalOnly {
|
|
t.Fatalf("fermeture sans effet : HOST=%q", ReadConfig()["HOST"])
|
|
}
|
|
if _, err := setLANExposure(true); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !lanExposed() || ReadConfig()["HOST"] != hostAllInterfaces {
|
|
t.Fatalf("ouverture sans effet : HOST=%q", ReadConfig()["HOST"])
|
|
}
|
|
}
|
|
|
|
// « localhost » écrit à la main vaut boucle locale, au même titre que 127.0.0.1.
|
|
func TestLanExposedReconnaitLocalhost(t *testing.T) {
|
|
testHome(t)
|
|
for _, h := range []string{"127.0.0.1", "localhost", "::1", "LOCALHOST"} {
|
|
if err := SetConfigKey("HOST", h); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if lanExposed() {
|
|
t.Errorf("HOST=%q compté comme exposé", h)
|
|
}
|
|
}
|
|
for _, h := range []string{"0.0.0.0", "192.168.1.25", "::"} {
|
|
if err := SetConfigKey("HOST", h); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !lanExposed() {
|
|
t.Errorf("HOST=%q compté comme fermé", h)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Une machine volontairement fermée ne doit pas se rouvrir toute seule parce
|
|
// qu'on bascule sur un preset écrit avant que HOST existe.
|
|
func TestHostSurvitAuChangementDePreset(t *testing.T) {
|
|
testHome(t)
|
|
if _, err := setLANExposure(false); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
p := filepath.Join(t.TempDir(), "vieux.env")
|
|
if err := os.WriteFile(p, []byte("MODEL=\"x.gguf\"\nCTX=4096\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := applyPresetFile(p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ReadConfig()["HOST"] != hostLocalOnly {
|
|
t.Fatalf("HOST perdu à la bascule : %q", ReadConfig()["HOST"])
|
|
}
|
|
// Mais un preset qui revendique HOST garde le dernier mot.
|
|
if err := os.WriteFile(p, []byte("MODEL=\"x.gguf\"\nHOST=\"0.0.0.0\"\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := applyPresetFile(p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ReadConfig()["HOST"] != hostAllInterfaces {
|
|
t.Fatalf("le preset n'a pas pu imposer HOST : %q", ReadConfig()["HOST"])
|
|
}
|
|
}
|
|
|
|
func TestHandleNetwork(t *testing.T) {
|
|
testHome(t)
|
|
rr := httptest.NewRecorder()
|
|
handleNetwork(rr, httptest.NewRequest("POST", "/api/network", strings.NewReader(`{"exposed":false}`)))
|
|
if rr.Code != 200 {
|
|
t.Fatalf("HTTP %d : %s", rr.Code, rr.Body)
|
|
}
|
|
var out struct {
|
|
OK bool `json:"ok"`
|
|
Status netStatus `json:"status"`
|
|
}
|
|
if err := json.Unmarshal(rr.Body.Bytes(), &out); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !out.OK || out.Status.Exposed || out.Status.Host != hostLocalOnly {
|
|
t.Fatalf("état inattendu : %+v", out.Status)
|
|
}
|
|
if out.Status.Port == 0 || !strings.Contains(out.Status.URL, "/v1") {
|
|
t.Fatalf("endpoint mal formé : %+v", out.Status)
|
|
}
|
|
}
|