2024-09-24 19:26:40 +00:00
|
|
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
|
|
|
|
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"os"
|
|
|
|
"os/user"
|
|
|
|
"os/exec"
|
|
|
|
"testing"
|
|
|
|
"decl/internal/tempdir"
|
|
|
|
"log"
|
|
|
|
"decl/internal/folio"
|
|
|
|
_ "decl/internal/fan"
|
|
|
|
"decl/internal/codec"
|
|
|
|
"decl/internal/data"
|
2024-10-04 00:30:49 +00:00
|
|
|
"decl/internal/ext"
|
2024-09-24 19:26:40 +00:00
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"log/slog"
|
2024-10-04 00:30:49 +00:00
|
|
|
"archive/tar"
|
|
|
|
"compress/gzip"
|
|
|
|
"bytes"
|
|
|
|
"io"
|
2024-09-24 19:26:40 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var programLevel = new(slog.LevelVar)
|
|
|
|
|
|
|
|
var TempDir tempdir.Path = "jx_client"
|
|
|
|
|
|
|
|
var ProcessTestUserName string
|
|
|
|
var ProcessTestGroupName string
|
|
|
|
|
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
LoggerConfig()
|
2024-09-25 04:41:26 +00:00
|
|
|
err := TempDir.Create()
|
2024-09-24 19:26:40 +00:00
|
|
|
if err != nil || TempDir == "" {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ProcessTestUserName, ProcessTestGroupName = ProcessUserName()
|
|
|
|
rc := m.Run()
|
|
|
|
|
|
|
|
TempDir.Remove()
|
|
|
|
os.Exit(rc)
|
|
|
|
}
|
|
|
|
|
|
|
|
func LoggerConfig() {
|
|
|
|
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel}))
|
|
|
|
slog.SetDefault(logger)
|
|
|
|
programLevel.Set(slog.LevelDebug)
|
|
|
|
}
|
|
|
|
|
|
|
|
func ProcessUserName() (string, string) {
|
|
|
|
processUser, userErr := user.Current()
|
|
|
|
if userErr != nil {
|
|
|
|
panic(userErr)
|
|
|
|
}
|
|
|
|
processGroup, groupErr := user.LookupGroupId(processUser.Gid)
|
|
|
|
if groupErr != nil {
|
|
|
|
panic(groupErr)
|
|
|
|
}
|
|
|
|
return processUser.Username, processGroup.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
func ExitError(e error) string {
|
|
|
|
if e != nil {
|
|
|
|
switch v := e.(type) {
|
|
|
|
case *exec.ExitError:
|
|
|
|
return string(v.Stderr)
|
|
|
|
default:
|
|
|
|
return e.Error()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// jx import <docuri>...
|
|
|
|
func TestClientImport(t *testing.T) {
|
|
|
|
c := NewClient()
|
|
|
|
assert.NotNil(t, c)
|
|
|
|
|
|
|
|
importDocuments := []string{
|
|
|
|
"file://../../examples/file.jx.yaml",
|
|
|
|
"file://../../examples/user.jx.yaml",
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Nil(t, c.Import(importDocuments))
|
|
|
|
|
|
|
|
for index, uri := range importDocuments {
|
|
|
|
u := folio.URI(uri)
|
|
|
|
r, readerErr := u.ContentReaderStream()
|
|
|
|
assert.Nil(t, readerErr)
|
|
|
|
assert.NotNil(t, r)
|
|
|
|
|
|
|
|
doc := folio.DocumentRegistry.NewDocument(folio.URI(uri))
|
|
|
|
assert.Nil(t, doc.LoadReader(r, codec.FormatYaml))
|
|
|
|
|
|
|
|
imported := c.Documents[index]
|
|
|
|
assert.NotNil(t, imported)
|
|
|
|
assert.Equal(t, uri, imported.GetURI())
|
|
|
|
assert.Equal(t, doc.Len(), imported.Len())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// jx import --resource <resource>
|
|
|
|
func TestClientImportResource(t *testing.T) {
|
|
|
|
ctx := context.Background()
|
|
|
|
c := NewClient()
|
|
|
|
assert.NotNil(t, c)
|
|
|
|
|
|
|
|
importResources := []string{
|
|
|
|
"file://../../COPYRIGHT",
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, uri := range importResources {
|
|
|
|
assert.Nil(t, c.ImportResource(ctx, uri))
|
|
|
|
}
|
|
|
|
|
|
|
|
imported := c.Documents[0]
|
|
|
|
assert.NotNil(t, imported)
|
|
|
|
for _, uri := range importResources {
|
|
|
|
assert.NotNil(t, imported.(*folio.Document).GetResource(uri))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClientEmit(t *testing.T) {
|
|
|
|
//ctx := context.Background()
|
|
|
|
c := NewClient()
|
|
|
|
assert.NotNil(t, c)
|
|
|
|
|
|
|
|
importDocuments := []string{
|
|
|
|
"file://../../examples/file.jx.yaml",
|
|
|
|
"file://../../examples/user.jx.yaml",
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Nil(t, c.Import(importDocuments))
|
|
|
|
targetFile := TempDir.FilePath("jx_emit_output.jx.yaml")
|
|
|
|
targetFileURI := fmt.Sprintf("file://%s", targetFile)
|
|
|
|
assert.Nil(t, c.SetOutput(targetFile))
|
|
|
|
assert.Nil(t, c.Emit())
|
|
|
|
|
|
|
|
assert.FileExists(t, targetFile)
|
|
|
|
|
|
|
|
|
|
|
|
u := folio.URI(targetFileURI)
|
|
|
|
r, readerErr := u.ContentReaderStream()
|
|
|
|
assert.Nil(t, readerErr)
|
|
|
|
assert.NotNil(t, r)
|
|
|
|
|
|
|
|
extractor, err := folio.DocumentRegistry.ConverterTypes.New(targetFileURI)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.NotNil(t, extractor)
|
|
|
|
|
|
|
|
targetResource, resErr := u.NewResource(nil)
|
|
|
|
assert.Nil(t, resErr)
|
|
|
|
docs, exErr := extractor.(data.ManyExtractor).ExtractMany(targetResource, nil)
|
|
|
|
assert.Nil(t, exErr)
|
|
|
|
|
|
|
|
assert.Equal(t, 2, len(docs))
|
|
|
|
|
|
|
|
assert.Equal(t, 1, docs[1].Len())
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkClientSystemConfigurations(b *testing.B) {
|
|
|
|
assert.Nil(b, TempDir.Mkdir("benchconfig", 0700))
|
|
|
|
ConfDir := tempdir.Path(TempDir.FilePath("benchconfig"))
|
2024-09-25 04:41:26 +00:00
|
|
|
assert.Nil(b, ConfDir.CreateFile("cfg.jx.yaml", `
|
2024-09-24 19:26:40 +00:00
|
|
|
configurations:
|
|
|
|
- name: files
|
|
|
|
values:
|
|
|
|
prefix: /usr
|
2024-09-25 04:41:26 +00:00
|
|
|
`))
|
2024-09-24 19:26:40 +00:00
|
|
|
|
|
|
|
configDirURI := fmt.Sprintf("file://%s", ConfDir)
|
|
|
|
|
|
|
|
programLevel.Set(slog.LevelError)
|
|
|
|
b.Run("systemconfiguration", func(b *testing.B) {
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
|
|
c := NewClient()
|
2024-09-25 04:41:26 +00:00
|
|
|
_ = c.SystemConfiguration(configDirURI)
|
2024-09-24 19:26:40 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
programLevel.Set(slog.LevelDebug)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClientSystemConfiguration(t *testing.T) {
|
|
|
|
c := NewClient()
|
|
|
|
assert.NotNil(t, c)
|
|
|
|
|
|
|
|
assert.Nil(t, TempDir.Mkdir("config", 0700))
|
|
|
|
|
|
|
|
ConfDir := tempdir.Path(TempDir.FilePath("config"))
|
2024-09-25 04:41:26 +00:00
|
|
|
assert.Nil(t, ConfDir.CreateFile("cfg.jx.yaml", `
|
2024-09-24 19:26:40 +00:00
|
|
|
configurations:
|
|
|
|
- name: files
|
|
|
|
values:
|
|
|
|
prefix: /usr
|
2024-09-25 04:41:26 +00:00
|
|
|
`))
|
2024-09-24 19:26:40 +00:00
|
|
|
|
|
|
|
//configDirURI := fmt.Sprintf("file://%s", ConfDir)
|
|
|
|
configErr := c.SystemConfiguration(string(ConfDir))
|
|
|
|
assert.Nil(t, configErr)
|
|
|
|
|
|
|
|
assert.NotNil(t, c.Config)
|
|
|
|
|
|
|
|
slog.Info("TestClientSystemConfiguration", "config", c.Config)
|
|
|
|
cfg := c.Config.GetConfig("files")
|
|
|
|
assert.NotNil(t, cfg)
|
|
|
|
|
|
|
|
value, valueErr := cfg.GetValue("prefix")
|
|
|
|
assert.Nil(t, valueErr)
|
|
|
|
assert.Equal(t, "/usr", value.(string))
|
2024-09-25 04:41:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestClientApply(t *testing.T) {
|
|
|
|
ctx := context.Background()
|
|
|
|
c := NewClient()
|
|
|
|
assert.NotNil(t, c)
|
|
|
|
|
|
|
|
assert.Nil(t, TempDir.Mkdir("apply", 0700))
|
|
|
|
ApplyDir := tempdir.Path(TempDir.FilePath("apply"))
|
|
|
|
|
|
|
|
DocSource := ApplyDir.FilePath("res.jx.yaml")
|
|
|
|
TestFile := ApplyDir.FilePath("testfile.txt")
|
|
|
|
assert.Nil(t, ApplyDir.CreateFile("res.jx.yaml", fmt.Sprintf(`
|
|
|
|
resources:
|
|
|
|
- type: file
|
|
|
|
transition: create
|
|
|
|
attributes:
|
|
|
|
path: %s
|
|
|
|
content: |
|
|
|
|
a test string
|
|
|
|
owner: %s
|
|
|
|
group: %s
|
|
|
|
mode: 0644
|
|
|
|
`, TestFile, ProcessTestUserName, ProcessTestGroupName)))
|
|
|
|
|
|
|
|
|
|
|
|
assert.Nil(t, c.Import([]string{DocSource}))
|
|
|
|
assert.Nil(t, c.LoadDocumentImports())
|
|
|
|
|
|
|
|
assert.Nil(t, c.Apply(ctx, false))
|
|
|
|
|
|
|
|
assert.FileExists(t, TestFile)
|
|
|
|
|
|
|
|
assert.Nil(t, c.Apply(ctx, true))
|
|
|
|
|
|
|
|
assert.NoFileExists(t, TestFile)
|
2024-09-24 19:26:40 +00:00
|
|
|
}
|
2024-10-04 00:30:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var tarArchiveBuffer bytes.Buffer
|
|
|
|
|
|
|
|
func TarArchive(compress bool) (err error) {
|
|
|
|
var fileWriter io.WriteCloser
|
|
|
|
|
|
|
|
if compress {
|
|
|
|
gz := gzip.NewWriter(&tarArchiveBuffer)
|
|
|
|
defer gz.Close()
|
|
|
|
fileWriter = gz
|
|
|
|
} else {
|
|
|
|
fileWriter = ext.WriteNopCloser(&tarArchiveBuffer)
|
|
|
|
}
|
|
|
|
|
|
|
|
tw := tar.NewWriter(fileWriter)
|
|
|
|
|
|
|
|
fileContent := "test file content"
|
|
|
|
|
|
|
|
if err = tw.WriteHeader(&tar.Header{
|
|
|
|
Name: "testfile",
|
|
|
|
Mode: 0600,
|
|
|
|
Size: int64(len(fileContent)),
|
|
|
|
}); err == nil {
|
|
|
|
_, err = tw.Write([]byte(fileContent))
|
|
|
|
}
|
|
|
|
tw.Close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClientConverters(t *testing.T) {
|
|
|
|
for _, v := range []struct { Expected data.TypeName; URI string } {
|
|
|
|
{ Expected: data.TypeName("dir"), URI: "file:///tmp" },
|
|
|
|
{ Expected: data.TypeName("http"), URI: "https://localhost/test" },
|
|
|
|
{ Expected: data.TypeName("iptable"), URI: "iptable://filter/INPUT" },
|
|
|
|
{ Expected: data.TypeName("jx"), URI: "file:///tmp/test.jx.yaml" },
|
|
|
|
{ Expected: data.TypeName("package"), URI: "package://" },
|
|
|
|
{ Expected: data.TypeName("container"), URI: "container://" },
|
|
|
|
{ Expected: data.TypeName("user"), URI: "user://" },
|
|
|
|
{ Expected: data.TypeName("group"), URI: "group://" },
|
|
|
|
{ Expected: data.TypeName("tar"), URI: "tar://" },
|
|
|
|
{ Expected: data.TypeName("tar"), URI: "file:///tmp/foo.tar" },
|
|
|
|
{ Expected: data.TypeName("tar"), URI: "file:///tmp/foo.tar.gz" },
|
|
|
|
{ Expected: data.TypeName("tar"), URI: "file:///tmp/foo.tgz" },
|
|
|
|
} {
|
|
|
|
c, e := folio.DocumentRegistry.ConverterTypes.New(v.URI)
|
|
|
|
assert.Nil(t, e)
|
|
|
|
assert.NotNil(t, c)
|
|
|
|
assert.Equal(t, v.Expected, c.Type())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClientImportTar(t *testing.T) {
|
|
|
|
c := NewClient()
|
|
|
|
assert.NotNil(t, c)
|
|
|
|
|
|
|
|
e := TarArchive(true)
|
|
|
|
assert.Nil(t, e)
|
|
|
|
assert.Greater(t, tarArchiveBuffer.Len(), 0)
|
|
|
|
|
|
|
|
path, err := TempDir.CreateFileFromReader("test.tar.gz", &tarArchiveBuffer)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
uri := fmt.Sprintf("file://%s", path)
|
|
|
|
|
|
|
|
d := folio.NewDeclaration()
|
|
|
|
assert.Nil(t, d.NewResource(&uri))
|
|
|
|
|
|
|
|
docs, importErr := c.ImportSource(uri)
|
|
|
|
|
|
|
|
assert.Nil(t, importErr)
|
|
|
|
assert.Greater(t, len(docs), 0)
|
|
|
|
}
|