mirror of
https://github.com/davidallendj/configurator.git
synced 2025-12-20 03:27:02 -07:00
Added initial general unit tests
This commit is contained in:
parent
1d862ebd8c
commit
6359f8eaba
1 changed files with 257 additions and 0 deletions
257
tests/generate.go
Normal file
257
tests/generate.go
Normal file
|
|
@ -0,0 +1,257 @@
|
||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"command-line-arguments/Users/allend/Desktop/projects/ochami/configurator/internal/server/server.go"
|
||||||
|
|
||||||
|
configurator "github.com/OpenCHAMI/configurator/internal"
|
||||||
|
"github.com/OpenCHAMI/configurator/internal/generator"
|
||||||
|
"github.com/OpenCHAMI/configurator/internal/util"
|
||||||
|
"github.com/docker/docker/api/server"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A valid test generator that implements the `Generator` interface.
|
||||||
|
type TestGenerator struct{}
|
||||||
|
|
||||||
|
func (g *TestGenerator) GetName() string { return "test" }
|
||||||
|
func (g *TestGenerator) GetVersion() string { return "v1.0.0" }
|
||||||
|
func (g *TestGenerator) GetDescription() string {
|
||||||
|
return "This is a plugin creating for running tests."
|
||||||
|
}
|
||||||
|
func (g *TestGenerator) Generate(config *configurator.Config, opts ...util.Option) (generator.FileMap, error) {
|
||||||
|
// Jinja 2 template file
|
||||||
|
files := [][]byte{
|
||||||
|
[]byte(`
|
||||||
|
Name: {{plugin_name}}
|
||||||
|
Version: {{plugin_version}}
|
||||||
|
Description: {{plugin_description}}
|
||||||
|
|
||||||
|
This is the first test template file.
|
||||||
|
`),
|
||||||
|
[]byte(`
|
||||||
|
This is another testing Jinja 2 template file using {{plugin_name}}.
|
||||||
|
`),
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply Jinja templates to file
|
||||||
|
fileList, err := generator.ApplyTemplates(generator.Mappings{
|
||||||
|
"plugin_name": g.GetName(),
|
||||||
|
"plugin_version": g.GetVersion(),
|
||||||
|
"plugin_description": g.GetDescription(),
|
||||||
|
}, files...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to apply templates: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure we're able to receive certain arguments when passed
|
||||||
|
params := generator.GetParams(opts...)
|
||||||
|
if len(params) <= 0 {
|
||||||
|
return nil, fmt.Errorf("expect at least one params, but found none")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make sure we can get the target
|
||||||
|
|
||||||
|
// make sure we're able to get the client as well
|
||||||
|
client := generator.GetClient(params)
|
||||||
|
if client == nil {
|
||||||
|
return nil, fmt.Errorf("invalid client (client is nil)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure we have the same number of files in file list
|
||||||
|
if len(files) != len(fileList) {
|
||||||
|
return nil, fmt.Errorf("file list output count is not the same as the input")
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert file list to file map
|
||||||
|
fileMap := make(generator.FileMap, len(fileList))
|
||||||
|
for i, contents := range fileList {
|
||||||
|
fileMap[fmt.Sprintf("t-%d.txt", i)] = contents
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileMap, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// An invalid generator that does not or partially implements
|
||||||
|
// the `Generator` interface.
|
||||||
|
type InvalidGenerator struct{}
|
||||||
|
|
||||||
|
// Test building and loading plugins
|
||||||
|
func TestPlugin(t *testing.T) {
|
||||||
|
var (
|
||||||
|
tempDir = t.TempDir()
|
||||||
|
testPlugin = []byte(`
|
||||||
|
package main
|
||||||
|
|
||||||
|
type TestGenerator struct{}
|
||||||
|
|
||||||
|
func (g *TestGenerator) GetName() string { return "test" }
|
||||||
|
func (g *TestGenerator) GetVersion() string { return "v1.0.0" }
|
||||||
|
func (g *TestGenerator) GetDescription() string { return "This is a plugin creating for running tests." }
|
||||||
|
func (g *TestGenerator) Generate(config *configurator.Config, opts ...util.Option) (generator.FileMap, error) {
|
||||||
|
return generator.FileMap{"test": []byte("test")}, nil
|
||||||
|
}
|
||||||
|
var Generator TestGenerator
|
||||||
|
`)
|
||||||
|
testPluginPath = fmt.Sprintf("%s/testplugin.go")
|
||||||
|
)
|
||||||
|
|
||||||
|
// build a test plugin
|
||||||
|
t.Run("build", func(t *testing.T) {
|
||||||
|
// dump the plugin source code to a file
|
||||||
|
err := os.WriteFile(testPluginPath, testPlugin, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to write test plugin file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute command to build the plugin
|
||||||
|
cmd := exec.Command("go", "build", "-buildmode=plugin", fmt.Sprintf("-o=%s/test.so", tempDir))
|
||||||
|
if cmd.Err != nil {
|
||||||
|
t.Fatalf("failed to build plugin: %v", cmd.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// stat the file to confirm that it was built
|
||||||
|
fileInfo, err := os.Stat(testPluginPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to stat plugin file: %v", err)
|
||||||
|
}
|
||||||
|
if fileInfo.IsDir() {
|
||||||
|
t.Fatalf("directory file but a file was expected")
|
||||||
|
}
|
||||||
|
if fileInfo.Size() <= 0 {
|
||||||
|
t.Fatal("found an empty file or file with size of 0 bytes")
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
// test loading plugins both individually and in a dir
|
||||||
|
t.Run("load", func(t *testing.T) {
|
||||||
|
gen, err := generator.LoadPlugin(testPluginPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to load the test plugin: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that we have all expected methods with type assertions
|
||||||
|
if _, ok := gen.(interface {
|
||||||
|
GetName() string
|
||||||
|
GetVersion() string
|
||||||
|
GetDescription() string
|
||||||
|
Generate(*configurator.Config, ...util.Option) (generator.FileMap, error)
|
||||||
|
}); !ok {
|
||||||
|
t.Error("plugin does not implement all of the generator interface")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test loading plugins from a directory (should just load a single one)
|
||||||
|
gens, err := generator.LoadPlugins(tempDir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to load plugins in '%s': %v", tempDir, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test all of the plugins loaded from a directory (should expect same result as above)
|
||||||
|
for _, gen := range gens {
|
||||||
|
if _, ok := gen.(interface {
|
||||||
|
GetName() string
|
||||||
|
GetVersion() string
|
||||||
|
GetDescription() string
|
||||||
|
Generate(*configurator.Config, ...util.Option) (generator.FileMap, error)
|
||||||
|
}); !ok {
|
||||||
|
t.Error("plugin does not implement all of the generator interface")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that expects to successfully "generate" a file using the built-in
|
||||||
|
// example plugin with no fetching.
|
||||||
|
//
|
||||||
|
// NOTE: Normally we would dynamically load a generator from a plugin, but
|
||||||
|
// we're not doing it here since that's not what is being tested.
|
||||||
|
func TestGenerateExample(t *testing.T) {
|
||||||
|
var (
|
||||||
|
config = configurator.NewConfig()
|
||||||
|
client = configurator.NewSmdClient()
|
||||||
|
gen = TestGenerator{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// make sure our generator returns expected strings
|
||||||
|
t.Run("properties", func(t *testing.T) {
|
||||||
|
if gen.GetName() != "test" {
|
||||||
|
t.Error("test generator return unexpected name")
|
||||||
|
}
|
||||||
|
if gen.GetVersion() != "v1.0.0" {
|
||||||
|
t.Error("test generator return unexpected version")
|
||||||
|
}
|
||||||
|
if gen.GetDescription() != "test" {
|
||||||
|
t.Error("test generator return unexpected description")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// try to generate a file with templating applied
|
||||||
|
fileMap, err := gen.Generate(
|
||||||
|
&config,
|
||||||
|
generator.WithTarget("test"),
|
||||||
|
generator.WithClient(client),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("failed to generate file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test for 2 expected files to be generated in the output (hint: check the
|
||||||
|
// TestGenerator.Generate implementation)
|
||||||
|
if len(fileMap) != 2 {
|
||||||
|
t.Error("expected 2 files in generated output")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that expects to successfully "generate" a file using the built-in
|
||||||
|
// example plugin but by making a HTTP request to a service instance instead.
|
||||||
|
//
|
||||||
|
// NOTE: This test uses the default server settings to run.
|
||||||
|
func TestGenerateExampleWithServer(t *testing.T) {
|
||||||
|
var (
|
||||||
|
config = configurator.NewConfig()
|
||||||
|
gen = TestGenerator{}
|
||||||
|
headers = make(map[string]string, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
// add a test target to config
|
||||||
|
config.Targets["test"] = configurator.Target{}
|
||||||
|
|
||||||
|
// start up a new server in background
|
||||||
|
server := server.New(config)
|
||||||
|
go server.Server()
|
||||||
|
|
||||||
|
// make request to server to generate a file
|
||||||
|
res, b, err := util.MakeRequest("http://127.0.0.1:3334/generate?target=test", http.MethodGet, nil, headers)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to make request: %v", err)
|
||||||
|
}
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
t.Fatalf("expect status code 200 from response but received %d instead", res.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// test for specific output from request
|
||||||
|
fileMap, err := gen.Generate(&config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to generate file: %v", err)
|
||||||
|
}
|
||||||
|
if string(fileMap["test"]) != string(b) {
|
||||||
|
t.Fatal("response does not match expected output")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that expects to fail with a specific error: "failed to loook up
|
||||||
|
// symbol at path"
|
||||||
|
func TestGenerateWithNoSymbol(t *testing.T) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that expects to fail with a specific error: "failed to load the
|
||||||
|
// correct symbol type at path"
|
||||||
|
func TestGenerateWithInvalidGenerator() {
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue