mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-11-10 08:20:23 +00:00
454 lines
11 KiB
Go
454 lines
11 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"io/ioutil"
|
||
|
"os"
|
||
|
"os/exec"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
func testCompiler(t *testing.T, inputFile string, referenceFile string, expectErrors bool) {
|
||
|
textFile := strings.Replace(filepath.Base(inputFile), filepath.Ext(inputFile), ".text", 1)
|
||
|
errorsFile := strings.Replace(filepath.Base(inputFile), filepath.Ext(inputFile), ".errors", 1)
|
||
|
// remove any preexisting output files
|
||
|
os.Remove(textFile)
|
||
|
os.Remove(errorsFile)
|
||
|
// run the compiler
|
||
|
var err error
|
||
|
var cmd = exec.Command(
|
||
|
"gnostic",
|
||
|
inputFile,
|
||
|
"--text-out=.",
|
||
|
"--errors-out=.",
|
||
|
"--resolve-refs")
|
||
|
//t.Log(cmd.Args)
|
||
|
err = cmd.Run()
|
||
|
if err != nil && !expectErrors {
|
||
|
t.Logf("Compile failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
// verify the output against a reference
|
||
|
var outputFile string
|
||
|
if expectErrors {
|
||
|
outputFile = errorsFile
|
||
|
} else {
|
||
|
outputFile = textFile
|
||
|
}
|
||
|
err = exec.Command("diff", outputFile, referenceFile).Run()
|
||
|
if err != nil {
|
||
|
t.Logf("Diff failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
} else {
|
||
|
// if the test succeeded, clean up
|
||
|
os.Remove(textFile)
|
||
|
os.Remove(errorsFile)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func testNormal(t *testing.T, inputFile string, referenceFile string) {
|
||
|
testCompiler(t, inputFile, referenceFile, false)
|
||
|
}
|
||
|
|
||
|
func testErrors(t *testing.T, inputFile string, referenceFile string) {
|
||
|
testCompiler(t, inputFile, referenceFile, true)
|
||
|
}
|
||
|
|
||
|
func TestPetstoreJSON(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"examples/v2.0/json/petstore.json",
|
||
|
"test/v2.0/petstore.text")
|
||
|
}
|
||
|
|
||
|
func TestPetstoreYAML(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"examples/v2.0/yaml/petstore.yaml",
|
||
|
"test/v2.0/petstore.text")
|
||
|
}
|
||
|
|
||
|
func TestSeparateYAML(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"examples/v2.0/yaml/petstore-separate/spec/swagger.yaml",
|
||
|
"test/v2.0/yaml/petstore-separate/spec/swagger.text")
|
||
|
}
|
||
|
|
||
|
func TestSeparateJSON(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"examples/v2.0/json/petstore-separate/spec/swagger.json",
|
||
|
"test/v2.0/yaml/petstore-separate/spec/swagger.text") // yaml and json results should be identical
|
||
|
}
|
||
|
|
||
|
func TestRemotePetstoreJSON(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"https://raw.githubusercontent.com/googleapis/openapi-compiler/master/examples/v2.0/json/petstore.json",
|
||
|
"test/v2.0/petstore.text")
|
||
|
}
|
||
|
|
||
|
func TestRemotePetstoreYAML(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"https://raw.githubusercontent.com/googleapis/openapi-compiler/master/examples/v2.0/yaml/petstore.yaml",
|
||
|
"test/v2.0/petstore.text")
|
||
|
}
|
||
|
|
||
|
func TestRemoteSeparateYAML(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"https://raw.githubusercontent.com/googleapis/openapi-compiler/master/examples/v2.0/yaml/petstore-separate/spec/swagger.yaml",
|
||
|
"test/v2.0/yaml/petstore-separate/spec/swagger.text")
|
||
|
}
|
||
|
|
||
|
func TestRemoteSeparateJSON(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"https://raw.githubusercontent.com/googleapis/openapi-compiler/master/examples/v2.0/json/petstore-separate/spec/swagger.json",
|
||
|
"test/v2.0/yaml/petstore-separate/spec/swagger.text")
|
||
|
}
|
||
|
|
||
|
func TestErrorBadProperties(t *testing.T) {
|
||
|
testErrors(t,
|
||
|
"examples/errors/petstore-badproperties.yaml",
|
||
|
"test/errors/petstore-badproperties.errors")
|
||
|
}
|
||
|
|
||
|
func TestErrorUnresolvedRefs(t *testing.T) {
|
||
|
testErrors(t,
|
||
|
"examples/errors/petstore-unresolvedrefs.yaml",
|
||
|
"test/errors/petstore-unresolvedrefs.errors")
|
||
|
}
|
||
|
|
||
|
func TestErrorMissingVersion(t *testing.T) {
|
||
|
testErrors(t,
|
||
|
"examples/errors/petstore-missingversion.yaml",
|
||
|
"test/errors/petstore-missingversion.errors")
|
||
|
}
|
||
|
|
||
|
func testPlugin(t *testing.T, plugin string, inputFile string, outputFile string, referenceFile string) {
|
||
|
// remove any preexisting output files
|
||
|
os.Remove(outputFile)
|
||
|
// run the compiler
|
||
|
var err error
|
||
|
output, err := exec.Command(
|
||
|
"gnostic",
|
||
|
"--"+plugin+"-out=-",
|
||
|
inputFile).Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Compile failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
_ = ioutil.WriteFile(outputFile, output, 0644)
|
||
|
err = exec.Command("diff", outputFile, referenceFile).Run()
|
||
|
if err != nil {
|
||
|
t.Logf("Diff failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
} else {
|
||
|
// if the test succeeded, clean up
|
||
|
os.Remove(outputFile)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestSamplePluginWithPetstore(t *testing.T) {
|
||
|
testPlugin(t,
|
||
|
"summary",
|
||
|
"examples/v2.0/yaml/petstore.yaml",
|
||
|
"sample-petstore.out",
|
||
|
"test/v2.0/yaml/sample-petstore.out")
|
||
|
}
|
||
|
|
||
|
func TestErrorInvalidPluginInvocations(t *testing.T) {
|
||
|
var err error
|
||
|
output, err := exec.Command(
|
||
|
"gnostic",
|
||
|
"examples/v2.0/yaml/petstore.yaml",
|
||
|
"--errors-out=-",
|
||
|
"--plugin-out=foo=bar,:abc",
|
||
|
"--plugin-out=,foo=bar:abc",
|
||
|
"--plugin-out=foo=:abc",
|
||
|
"--plugin-out==bar:abc",
|
||
|
"--plugin-out=,,:abc",
|
||
|
"--plugin-out=foo=bar=baz:abc",
|
||
|
).Output()
|
||
|
if err == nil {
|
||
|
t.Logf("Invalid invocations were accepted")
|
||
|
t.FailNow()
|
||
|
}
|
||
|
outputFile := "invalid-plugin-invocation.errors"
|
||
|
_ = ioutil.WriteFile(outputFile, output, 0644)
|
||
|
err = exec.Command("diff", outputFile, "test/errors/invalid-plugin-invocation.errors").Run()
|
||
|
if err != nil {
|
||
|
t.Logf("Diff failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
} else {
|
||
|
// if the test succeeded, clean up
|
||
|
os.Remove(outputFile)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestValidPluginInvocations(t *testing.T) {
|
||
|
var err error
|
||
|
output, err := exec.Command(
|
||
|
"gnostic",
|
||
|
"examples/v2.0/yaml/petstore.yaml",
|
||
|
"--errors-out=-",
|
||
|
// verify an invocation with no parameters
|
||
|
"--summary-out=!", // "!" indicates that no output should be generated
|
||
|
// verify single pair of parameters
|
||
|
"--summary-out=a=b:!",
|
||
|
// verify multiple parameters
|
||
|
"--summary-out=a=b,c=123,xyz=alphabetagammadelta:!",
|
||
|
// verify that special characters / . - _ can be included in parameter keys and values
|
||
|
"--summary-out=a/b/c=x/y/z:!",
|
||
|
"--summary-out=a.b.c=x.y.z:!",
|
||
|
"--summary-out=a-b-c=x-y-z:!",
|
||
|
"--summary-out=a_b_c=x_y_z:!",
|
||
|
).Output()
|
||
|
if len(output) != 0 {
|
||
|
t.Logf("Valid invocations generated invalid errors\n%s", string(output))
|
||
|
t.FailNow()
|
||
|
}
|
||
|
if err != nil {
|
||
|
t.Logf("Valid invocations were not accepted")
|
||
|
t.FailNow()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestExtensionHandlerWithLibraryExample(t *testing.T) {
|
||
|
outputFile := "library-example-with-ext.text.out"
|
||
|
inputFile := "test/library-example-with-ext.json"
|
||
|
referenceFile := "test/library-example-with-ext.text.out"
|
||
|
|
||
|
os.Remove(outputFile)
|
||
|
// run the compiler
|
||
|
var err error
|
||
|
|
||
|
command := exec.Command(
|
||
|
"gnostic",
|
||
|
"--x-sampleone",
|
||
|
"--x-sampletwo",
|
||
|
"--text-out="+outputFile,
|
||
|
"--resolve-refs",
|
||
|
inputFile)
|
||
|
|
||
|
_, err = command.Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Compile failed for command %v: %+v", command, err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
//_ = ioutil.WriteFile(outputFile, output, 0644)
|
||
|
err = exec.Command("diff", outputFile, referenceFile).Run()
|
||
|
if err != nil {
|
||
|
t.Logf("Diff failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
} else {
|
||
|
// if the test succeeded, clean up
|
||
|
os.Remove(outputFile)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestJSONOutput(t *testing.T) {
|
||
|
inputFile := "test/library-example-with-ext.json"
|
||
|
|
||
|
textFile := "sample.text"
|
||
|
jsonFile := "sample.json"
|
||
|
textFile2 := "sample2.text"
|
||
|
jsonFile2 := "sample2.json"
|
||
|
|
||
|
os.Remove(textFile)
|
||
|
os.Remove(jsonFile)
|
||
|
os.Remove(textFile2)
|
||
|
os.Remove(jsonFile2)
|
||
|
|
||
|
var err error
|
||
|
|
||
|
// Run the compiler once.
|
||
|
command := exec.Command(
|
||
|
"gnostic",
|
||
|
"--text-out="+textFile,
|
||
|
"--json-out="+jsonFile,
|
||
|
inputFile)
|
||
|
_, err = command.Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Compile failed for command %v: %+v", command, err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// Run the compiler again, this time on the generated output.
|
||
|
command = exec.Command(
|
||
|
"gnostic",
|
||
|
"--text-out="+textFile2,
|
||
|
"--json-out="+jsonFile2,
|
||
|
jsonFile)
|
||
|
_, err = command.Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Compile failed for command %v: %+v", command, err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// Verify that both models have the same internal representation.
|
||
|
err = exec.Command("diff", textFile, textFile2).Run()
|
||
|
if err != nil {
|
||
|
t.Logf("Diff failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
} else {
|
||
|
// if the test succeeded, clean up
|
||
|
os.Remove(textFile)
|
||
|
os.Remove(jsonFile)
|
||
|
os.Remove(textFile2)
|
||
|
os.Remove(jsonFile2)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestYAMLOutput(t *testing.T) {
|
||
|
inputFile := "test/library-example-with-ext.json"
|
||
|
|
||
|
textFile := "sample.text"
|
||
|
yamlFile := "sample.yaml"
|
||
|
textFile2 := "sample2.text"
|
||
|
yamlFile2 := "sample2.yaml"
|
||
|
|
||
|
os.Remove(textFile)
|
||
|
os.Remove(yamlFile)
|
||
|
os.Remove(textFile2)
|
||
|
os.Remove(yamlFile2)
|
||
|
|
||
|
var err error
|
||
|
|
||
|
// Run the compiler once.
|
||
|
command := exec.Command(
|
||
|
"gnostic",
|
||
|
"--text-out="+textFile,
|
||
|
"--yaml-out="+yamlFile,
|
||
|
inputFile)
|
||
|
_, err = command.Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Compile failed for command %v: %+v", command, err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// Run the compiler again, this time on the generated output.
|
||
|
command = exec.Command(
|
||
|
"gnostic",
|
||
|
"--text-out="+textFile2,
|
||
|
"--yaml-out="+yamlFile2,
|
||
|
yamlFile)
|
||
|
_, err = command.Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Compile failed for command %v: %+v", command, err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// Verify that both models have the same internal representation.
|
||
|
err = exec.Command("diff", textFile, textFile2).Run()
|
||
|
if err != nil {
|
||
|
t.Logf("Diff failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
} else {
|
||
|
// if the test succeeded, clean up
|
||
|
os.Remove(textFile)
|
||
|
os.Remove(yamlFile)
|
||
|
os.Remove(textFile2)
|
||
|
os.Remove(yamlFile2)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func testBuilder(version string, t *testing.T) {
|
||
|
var err error
|
||
|
|
||
|
pbFile := "petstore-" + version + ".pb"
|
||
|
yamlFile := "petstore.yaml"
|
||
|
jsonFile := "petstore.json"
|
||
|
textFile := "petstore.text"
|
||
|
textReference := "test/" + version + ".0/petstore.text"
|
||
|
|
||
|
os.Remove(pbFile)
|
||
|
os.Remove(textFile)
|
||
|
os.Remove(yamlFile)
|
||
|
os.Remove(jsonFile)
|
||
|
|
||
|
// Generate petstore.pb.
|
||
|
command := exec.Command(
|
||
|
"petstore-builder",
|
||
|
"--"+version)
|
||
|
_, err = command.Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Command %v failed: %+v", command, err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// Convert petstore.pb to yaml and json.
|
||
|
command = exec.Command(
|
||
|
"gnostic",
|
||
|
pbFile,
|
||
|
"--json-out="+jsonFile,
|
||
|
"--yaml-out="+yamlFile)
|
||
|
_, err = command.Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Command %v failed: %+v", command, err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// Read petstore.yaml, resolve references, and export text.
|
||
|
command = exec.Command(
|
||
|
"gnostic",
|
||
|
yamlFile,
|
||
|
"--resolve-refs",
|
||
|
"--text-out="+textFile)
|
||
|
_, err = command.Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Command %v failed: %+v", command, err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// Verify that the generated text matches our reference.
|
||
|
err = exec.Command("diff", textFile, textReference).Run()
|
||
|
if err != nil {
|
||
|
t.Logf("Diff failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// Read petstore.json, resolve references, and export text.
|
||
|
command = exec.Command(
|
||
|
"gnostic",
|
||
|
jsonFile,
|
||
|
"--resolve-refs",
|
||
|
"--text-out="+textFile)
|
||
|
_, err = command.Output()
|
||
|
if err != nil {
|
||
|
t.Logf("Command %v failed: %+v", command, err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// Verify that the generated text matches our reference.
|
||
|
err = exec.Command("diff", textFile, textReference).Run()
|
||
|
if err != nil {
|
||
|
t.Logf("Diff failed: %+v", err)
|
||
|
t.FailNow()
|
||
|
}
|
||
|
|
||
|
// if the test succeeded, clean up
|
||
|
os.Remove(pbFile)
|
||
|
os.Remove(textFile)
|
||
|
os.Remove(yamlFile)
|
||
|
os.Remove(jsonFile)
|
||
|
}
|
||
|
|
||
|
func TestBuilderV2(t *testing.T) {
|
||
|
testBuilder("v2", t)
|
||
|
}
|
||
|
|
||
|
func TestBuilderV3(t *testing.T) {
|
||
|
testBuilder("v3", t)
|
||
|
}
|
||
|
|
||
|
// OpenAPI 3.0 tests
|
||
|
|
||
|
func TestPetstoreYAML_30(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"examples/v3.0/yaml/petstore.yaml",
|
||
|
"test/v3.0/petstore.text")
|
||
|
}
|
||
|
|
||
|
func TestPetstoreJSON_30(t *testing.T) {
|
||
|
testNormal(t,
|
||
|
"examples/v3.0/json/petstore.json",
|
||
|
"test/v3.0/petstore.text")
|
||
|
}
|