update cli tests
This commit is contained in:
parent
52c58ea436
commit
2bee7f6bea
95
cli_test.go
95
cli_test.go
@ -12,20 +12,24 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"decl/tests/tempdir"
|
||||||
|
"archive/tar"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
var TempDir string
|
var TempDir tempdir.Path = "testcli"
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
var err error
|
err := TempDir.Create()
|
||||||
TempDir, err = os.MkdirTemp("", "testcli")
|
|
||||||
if err != nil || TempDir == "" {
|
if err != nil || TempDir == "" {
|
||||||
slog.Error("TestMain()", "error", err)
|
slog.Error("Failed creating temp dir", "error", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc := m.Run()
|
rc := m.Run()
|
||||||
|
|
||||||
os.RemoveAll(TempDir)
|
TempDir.Remove()
|
||||||
os.Exit(rc)
|
os.Exit(rc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +89,7 @@ configurations:
|
|||||||
http_pass: bar
|
http_pass: bar
|
||||||
`
|
`
|
||||||
|
|
||||||
configPath := fmt.Sprintf("%s/testconfig.yaml", TempDir)
|
configPath := fmt.Sprintf("%s/testconfig.jx.yaml", TempDir)
|
||||||
f, err := os.Create(configPath)
|
f, err := os.Create(configPath)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
@ -99,3 +103,78 @@ configurations:
|
|||||||
assert.Nil(t, cliErr)
|
assert.Nil(t, cliErr)
|
||||||
slog.Info("TestConfigSource", "yaml", yaml)
|
slog.Info("TestConfigSource", "yaml", yaml)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCliConfigCommand(t *testing.T) {
|
||||||
|
if _, e := os.Stat("./jx"); errors.Is(e, os.ErrNotExist) {
|
||||||
|
t.Skip("cli not built")
|
||||||
|
}
|
||||||
|
|
||||||
|
yaml, cliErr := exec.Command("./jx", "config", "file://examples/config/file.cfg.jx.yaml").Output()
|
||||||
|
if cliErr != nil {
|
||||||
|
slog.Info("Debug CLI error", "error", cliErr, "stderr", cliErr.(*exec.ExitError).Stderr)
|
||||||
|
}
|
||||||
|
assert.Nil(t, cliErr)
|
||||||
|
slog.Info("TestConfigCommand", "yaml", yaml)
|
||||||
|
assert.NotEqual(t, "", string(yaml))
|
||||||
|
assert.Greater(t, len(yaml), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCliImportPackageCommand(t *testing.T) {
|
||||||
|
if _, e := os.Stat("./jx"); errors.Is(e, os.ErrNotExist) {
|
||||||
|
t.Skip("cli not built")
|
||||||
|
}
|
||||||
|
|
||||||
|
yaml, cliErr := exec.Command("./jx", "import", "package://").Output()
|
||||||
|
if cliErr != nil {
|
||||||
|
slog.Info("Debug CLI error", "error", cliErr, "stderr", cliErr.(*exec.ExitError).Stderr)
|
||||||
|
}
|
||||||
|
assert.Nil(t, cliErr)
|
||||||
|
assert.NotEqual(t, "", string(yaml))
|
||||||
|
assert.Greater(t, len(yaml), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCliExportTar(t *testing.T) {
|
||||||
|
if _, e := os.Stat("./jx"); errors.Is(e, os.ErrNotExist) {
|
||||||
|
t.Skip("cli not built")
|
||||||
|
}
|
||||||
|
assert.Nil(t, TempDir.Mkdir("tar", 0755))
|
||||||
|
assert.Nil(t, TempDir.CreateFile("tar/foo", "data"))
|
||||||
|
assert.Nil(t, TempDir.CreateFile("tar/bar", "data"))
|
||||||
|
|
||||||
|
cmdArgs := []string{"import", "--output", "tar://-", fmt.Sprintf("file://%s/tar", TempDir)}
|
||||||
|
slog.Info("TestCliExportTar()", "cmd", cmdArgs)
|
||||||
|
cmd := exec.Command("./jx", cmdArgs...)
|
||||||
|
slog.Info("TestCliExportTar()", "cmd", cmd)
|
||||||
|
stderr, errerr := cmd.StderrPipe()
|
||||||
|
assert.Nil(t, errerr)
|
||||||
|
stdout, outerr := cmd.StdoutPipe()
|
||||||
|
assert.Nil(t, outerr)
|
||||||
|
|
||||||
|
assert.Nil(t, cmd.Start())
|
||||||
|
|
||||||
|
errOutput, _ := io.ReadAll(stderr)
|
||||||
|
tarData, _ := io.ReadAll(stdout)
|
||||||
|
|
||||||
|
assert.Nil(t, cmd.Wait())
|
||||||
|
|
||||||
|
slog.Info("TestCliExportTar()", "stderr", errOutput)
|
||||||
|
|
||||||
|
assert.Greater(t, len(tarData), 0)
|
||||||
|
|
||||||
|
tr := tar.NewReader(bytes.NewBuffer(tarData))
|
||||||
|
|
||||||
|
files := []string{fmt.Sprintf("%s/tar/foo", TempDir), fmt.Sprintf("%s/tar/bar", TempDir)}
|
||||||
|
for {
|
||||||
|
hdr, err := tr.Next()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
assert.Contains(t, files, hdr.Name)
|
||||||
|
contents, err := io.ReadAll(tr)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, []byte("data"), contents)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -34,15 +34,15 @@ func Load(uri folio.URI) (documents []data.Document, err error) {
|
|||||||
var extractor data.Converter
|
var extractor data.Converter
|
||||||
var sourceResource data.Resource
|
var sourceResource data.Resource
|
||||||
if extractor, err = folio.DocumentRegistry.ConverterTypes.New(string(uri)); err == nil {
|
if extractor, err = folio.DocumentRegistry.ConverterTypes.New(string(uri)); err == nil {
|
||||||
slog.Info("Load() extractor", "error", err)
|
slog.Info("builtin.Load() extractor", "uri", uri, "error", err)
|
||||||
|
|
||||||
targetDeclaration := folio.NewDeclaration()
|
targetDeclaration := folio.NewDeclaration()
|
||||||
if err = targetDeclaration.NewResource((*string)(&uri)); err == nil {
|
if err = targetDeclaration.NewResource((*string)(&uri)); err == nil {
|
||||||
slog.Info("Load() extract many", "resource", sourceResource, "error", err, "uri", uri, "extractor", extractor)
|
slog.Info("builtin.Load() extract many", "resource", sourceResource, "error", err, "uri", uri, "extractor", extractor)
|
||||||
sourceResource = targetDeclaration.Attributes
|
sourceResource = targetDeclaration.Attributes
|
||||||
sourceResource.(data.FileResource).SetFS(documentFiles)
|
sourceResource.(data.FileResource).SetFS(documentFiles)
|
||||||
documents, err = extractor.(data.ManyExtractor).ExtractMany(sourceResource, nil)
|
documents, err = extractor.(data.ManyExtractor).ExtractMany(sourceResource, nil)
|
||||||
slog.Info("Load() extract many", "resource", sourceResource, "error", err)
|
slog.Info("builtin.Load() extract many", "resource", sourceResource, "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -10,11 +10,19 @@ import (
|
|||||||
"embed"
|
"embed"
|
||||||
"net/http"
|
"net/http"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"decl/internal/folio"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed schemas/*.schema.json
|
//go:embed schemas/*.schema.json
|
||||||
var schemaFiles embed.FS
|
var schemaFiles embed.FS
|
||||||
|
|
||||||
|
var schemaFilesUri folio.URI = "file://config/schemas/*.schema.json"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
folio.DocumentRegistry.Schemas[schemaFilesUri] = schemaFiles
|
||||||
|
folio.DocumentRegistry.DefaultSchema = schemaFilesUri
|
||||||
|
}
|
||||||
|
|
||||||
type Schema struct {
|
type Schema struct {
|
||||||
schema gojsonschema.JSONLoader
|
schema gojsonschema.JSONLoader
|
||||||
}
|
}
|
||||||
@ -40,6 +48,7 @@ func (s *Schema) Validate(source string) error {
|
|||||||
for _, err := range result.Errors() {
|
for _, err := range result.Errors() {
|
||||||
schemaErrors.WriteString(err.String() + "\n")
|
schemaErrors.WriteString(err.String() + "\n")
|
||||||
}
|
}
|
||||||
|
schemaErrors.WriteString(source)
|
||||||
return errors.New(schemaErrors.String())
|
return errors.New(schemaErrors.String())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -8,6 +8,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"log/slog"
|
||||||
|
"runtime/debug"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -21,17 +23,18 @@ var (
|
|||||||
ErrInvalidProduct = errors.New("Invalid product")
|
ErrInvalidProduct = errors.New("Invalid product")
|
||||||
)
|
)
|
||||||
|
|
||||||
//type Name[Registry any] string //`json:"type"`
|
|
||||||
|
|
||||||
type Factory[Product comparable] func(*url.URL) Product
|
type Factory[Product comparable] func(*url.URL) Product
|
||||||
type RegistryTypeMap[Product comparable] map[string]Factory[Product]
|
type RegistryTypeMap[Product comparable] map[string]Factory[Product]
|
||||||
|
|
||||||
|
//type Name[Registry any] string //`json:"type"`
|
||||||
|
|
||||||
type Types[Product comparable] struct {
|
type Types[Product comparable] struct {
|
||||||
registry RegistryTypeMap[Product]
|
registry RegistryTypeMap[Product]
|
||||||
|
contentTypes RegistryTypeMap[Product]
|
||||||
}
|
}
|
||||||
|
|
||||||
func New[Product comparable]() *Types[Product] {
|
func New[Product comparable]() *Types[Product] {
|
||||||
return &Types[Product]{registry: make(map[string]Factory[Product])}
|
return &Types[Product]{registry: make(map[string]Factory[Product]), contentTypes: make(map[string]Factory[Product])}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Types[Product]) Register(names []string, factory Factory[Product]) {
|
func (t *Types[Product]) Register(names []string, factory Factory[Product]) {
|
||||||
@ -40,15 +43,24 @@ func (t *Types[Product]) Register(names []string, factory Factory[Product]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Types[Product]) RegisterContentType(contenttypes []string, factory Factory[Product]) {
|
||||||
|
for _,name := range contenttypes {
|
||||||
|
t.contentTypes[name] = factory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Types[Product]) FromExtension(path string) (Factory[Product], error) {
|
func (t *Types[Product]) FromExtension(path string) (Factory[Product], error) {
|
||||||
elements := strings.Split(path, ".")
|
elements := strings.Split(path, ".")
|
||||||
numberOfElements := len(elements)
|
numberOfElements := len(elements)
|
||||||
|
slog.Info("Types[Product].FromExtension()", "path", path, "elements", elements, "types", t.contentTypes, "stacktrace", string(debug.Stack()))
|
||||||
if numberOfElements > 2 {
|
if numberOfElements > 2 {
|
||||||
if src := t.Get(strings.Join(elements[numberOfElements - 2: numberOfElements - 1], ".")); src != nil {
|
ext := strings.Join(elements[numberOfElements - 2: numberOfElements], ".")
|
||||||
|
slog.Info("Types[Product].FromExtension() - Lookup", "ext", ext, "stacktrace", string(debug.Stack()))
|
||||||
|
if src := t.GetContentType(ext); src != nil {
|
||||||
return src, nil
|
return src, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if src := t.Get(elements[numberOfElements - 1]); src != nil {
|
if src := t.GetContentType(elements[numberOfElements - 1]); src != nil {
|
||||||
return src, nil
|
return src, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("%w: %s", ErrUnknownType, path)
|
return nil, fmt.Errorf("%w: %s", ErrUnknownType, path)
|
||||||
@ -57,10 +69,13 @@ func (t *Types[Product]) FromExtension(path string) (Factory[Product], error) {
|
|||||||
func (t *Types[Product]) New(uri string) (result Product, err error) {
|
func (t *Types[Product]) New(uri string) (result Product, err error) {
|
||||||
u, e := url.Parse(uri)
|
u, e := url.Parse(uri)
|
||||||
if u == nil || e != nil {
|
if u == nil || e != nil {
|
||||||
err = fmt.Errorf("%w: %s", ErrUnknownType, e)
|
err = fmt.Errorf("%w: %s %s", ErrUnknownType, e, uri)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
return t.NewFromParsedURI(u)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Types[Product]) NewFromParsedURI(u *url.URL) (result Product, err error) {
|
||||||
if u.Scheme == "" {
|
if u.Scheme == "" {
|
||||||
u.Scheme = "file"
|
u.Scheme = "file"
|
||||||
}
|
}
|
||||||
@ -68,13 +83,15 @@ func (t *Types[Product]) New(uri string) (result Product, err error) {
|
|||||||
path := filepath.Join(u.Hostname(), u.Path)
|
path := filepath.Join(u.Hostname(), u.Path)
|
||||||
if d, lookupErr := t.FromExtension(path); d != nil {
|
if d, lookupErr := t.FromExtension(path); d != nil {
|
||||||
return d(u), lookupErr
|
return d(u), lookupErr
|
||||||
|
} else {
|
||||||
|
slog.Info("Types[Product].NewFromParsedURI() - FromExtension()", "uri", u, "path", path, "error", lookupErr, "stacktrace", string(debug.Stack()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if r, ok := t.registry[u.Scheme]; ok {
|
if r, ok := t.registry[u.Scheme]; ok {
|
||||||
if result = r(u); result != any(nil) {
|
if result = r(u); result != any(nil) {
|
||||||
return result, nil
|
return result, nil
|
||||||
} else {
|
} else {
|
||||||
return result, fmt.Errorf("%w: factory failed creating %s", ErrInvalidProduct, uri)
|
return result, fmt.Errorf("%w: factory failed creating %s", ErrInvalidProduct, u.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = fmt.Errorf("%w: %s", ErrUnknownType, u.Scheme)
|
err = fmt.Errorf("%w: %s", ErrUnknownType, u.Scheme)
|
||||||
@ -88,8 +105,15 @@ func (t *Types[Product]) Has(typename string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Types[Product]) Get(typename string) Factory[Product] {
|
func (t *Types[Product]) HasContentType(contenttype string) bool {
|
||||||
if d, ok := t.registry[typename]; ok {
|
if _, ok := t.contentTypes[contenttype]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Types[Product]) GetContentType(contenttype string) Factory[Product] {
|
||||||
|
if d, ok := t.contentTypes[contenttype]; ok {
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -24,6 +24,7 @@ type MockContainerClient struct {
|
|||||||
InjectContainerStop func(context.Context, string, container.StopOptions) error
|
InjectContainerStop func(context.Context, string, container.StopOptions) error
|
||||||
InjectContainerWait func(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
|
InjectContainerWait func(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
|
||||||
InjectImagePull func(ctx context.Context, refStr string, options image.PullOptions) (io.ReadCloser, error)
|
InjectImagePull func(ctx context.Context, refStr string, options image.PullOptions) (io.ReadCloser, error)
|
||||||
|
InjectImagePush func(ctx context.Context, image string, options image.PushOptions) (io.ReadCloser, error)
|
||||||
InjectImageInspectWithRaw func(ctx context.Context, imageID string) (types.ImageInspect, []byte, error)
|
InjectImageInspectWithRaw func(ctx context.Context, imageID string) (types.ImageInspect, []byte, error)
|
||||||
InjectImageRemove func(ctx context.Context, imageID string, options image.RemoveOptions) ([]image.DeleteResponse, error)
|
InjectImageRemove func(ctx context.Context, imageID string, options image.RemoveOptions) ([]image.DeleteResponse, error)
|
||||||
InjectImageBuild func(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
|
InjectImageBuild func(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)
|
||||||
@ -42,6 +43,10 @@ func (m *MockContainerClient) ImagePull(ctx context.Context, refStr string, opti
|
|||||||
return m.InjectImagePull(ctx, refStr, options)
|
return m.InjectImagePull(ctx, refStr, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MockContainerClient) ImagePush(ctx context.Context, image string, options image.PushOptions) (io.ReadCloser, error) {
|
||||||
|
return m.InjectImagePush(ctx, image, options)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MockContainerClient) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {
|
func (m *MockContainerClient) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {
|
||||||
return m.InjectImageBuild(ctx, buildContext, options)
|
return m.InjectImageBuild(ctx, buildContext, options)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user