summaryrefslogtreecommitdiff
path: root/vendor/github.com/varlink/go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/varlink/go')
-rw-r--r--vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/generator_test.go90
-rw-r--r--vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go354
-rw-r--r--vendor/github.com/varlink/go/cmd/varlink-go-type-generator/main.go172
-rw-r--r--vendor/github.com/varlink/go/golang-github-varlink-go.spec44
-rw-r--r--vendor/github.com/varlink/go/varlink/external_test.go181
-rw-r--r--vendor/github.com/varlink/go/varlink/idl/idl_test.go150
-rw-r--r--vendor/github.com/varlink/go/varlink/varlink_test.go232
7 files changed, 1223 insertions, 0 deletions
diff --git a/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/generator_test.go b/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/generator_test.go
new file mode 100644
index 000000000..8e749f411
--- /dev/null
+++ b/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/generator_test.go
@@ -0,0 +1,90 @@
+package main
+
+import (
+ "strings"
+ "testing"
+)
+
+func expect(t *testing.T, expected string, returned string) {
+ if strings.Compare(returned, expected) != 0 {
+ t.Fatalf("Expected(%d): `%s`\nGot(%d): `%s`\n",
+ len(expected), expected,
+ len(returned), returned)
+ }
+}
+
+func TestIDLParser(t *testing.T) {
+ pkgname, b, err := generateTemplate(`
+# Interface to jump a spacecraft to another point in space. The
+# FTL Drive is the propulsion system to achieve faster-than-light
+# travel through space. A ship making a properly calculated
+# jump can arrive safely in planetary orbit, or alongside other
+# ships or spaceborne objects.
+interface org.example.ftl
+
+# The current state of the FTL drive and the amount of fuel
+# available to jump.
+type DriveCondition (
+ state: (idle, spooling, busy),
+ booster: bool,
+ active_engines: [](id: int, state: bool),
+ tylium_level: int
+)
+
+# Speed, trajectory and jump duration is calculated prior to
+# activating the FTL drive.
+type DriveConfiguration (
+ speed: int,
+ trajectory: int,
+ duration: int
+)
+
+# The galactic coordinates use the Sun as the origin. Galactic
+# longitude is measured with primary direction from the Sun to
+# the center of the galaxy in the galactic plane, while the
+# galactic latitude measures the angle of the object above the
+# galactic plane.
+type Coordinate (
+ longitude: float,
+ latitude: float,
+ distance: int
+)
+
+# Monitor the drive. The method will reply with an update whenever
+# the drive's state changes
+method Monitor() -> (condition: DriveCondition)
+
+# Calculate the drive's jump parameters from the current
+# position to the target position in the galaxy
+method CalculateConfiguration(
+ current: Coordinate,
+ target: Coordinate
+) -> (configuration: DriveConfiguration)
+
+# Jump to the calculated point in space
+method Jump(configuration: DriveConfiguration) -> ()
+
+# There is not enough tylium to jump with the given parameters
+error NotEnoughEnergy ()
+
+# The supplied parameters are outside the supported range
+error ParameterOutOfRange (field: string)
+
+# some more coverage
+method Foo(interface: string) -> (ret: (go: string, switch: bool, more: (t:bool, f:bool)))
+
+# some more coverage
+method TestMap(map: [string]string) -> (map: [string](i: int, val: string))
+method TestSet(set: [string]()) -> (set: [string]())
+method TestObject(object: object) -> (object: object)
+ `)
+
+ if err != nil {
+ t.Fatalf("Error parsing %v", err)
+ }
+ expect(t, "orgexampleftl", pkgname)
+ if len(b) <= 0 {
+ t.Fatal("No generated go source")
+ }
+ // FIXME: compare b.String() against expected output
+}
diff --git a/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go b/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go
new file mode 100644
index 000000000..2db4e5cfd
--- /dev/null
+++ b/vendor/github.com/varlink/go/cmd/varlink-go-interface-generator/main.go
@@ -0,0 +1,354 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "go/format"
+ "io/ioutil"
+ "os"
+ "path"
+ "strings"
+
+ "github.com/varlink/go/varlink/idl"
+)
+
+func writeType(b *bytes.Buffer, t *idl.Type, json bool, ident int) {
+ switch t.Kind {
+ case idl.TypeBool:
+ b.WriteString("bool")
+
+ case idl.TypeInt:
+ b.WriteString("int64")
+
+ case idl.TypeFloat:
+ b.WriteString("float64")
+
+ case idl.TypeString, idl.TypeEnum:
+ b.WriteString("string")
+
+ case idl.TypeObject:
+ b.WriteString("json.RawMessage")
+
+ case idl.TypeArray:
+ b.WriteString("[]")
+ writeType(b, t.ElementType, json, ident)
+
+ case idl.TypeMap:
+ b.WriteString("map[string]")
+ writeType(b, t.ElementType, json, ident)
+
+ case idl.TypeMaybe:
+ b.WriteString("*")
+ writeType(b, t.ElementType, json, ident)
+
+ case idl.TypeAlias:
+ b.WriteString(t.Alias)
+
+ case idl.TypeStruct:
+ if len(t.Fields) == 0 {
+ b.WriteString("struct{}")
+ } else {
+ b.WriteString("struct {\n")
+ for _, field := range t.Fields {
+ for i := 0; i < ident+1; i++ {
+ b.WriteString("\t")
+ }
+
+ b.WriteString(strings.Title(field.Name) + " ")
+ writeType(b, field.Type, json, ident+1)
+ if json {
+ b.WriteString(" `json:\"" + field.Name)
+ if field.Type.Kind == idl.TypeMaybe {
+ b.WriteString(",omitempty")
+ }
+ b.WriteString("\"`")
+ }
+ b.WriteString("\n")
+ }
+ for i := 0; i < ident; i++ {
+ b.WriteString("\t")
+ }
+ b.WriteString("}")
+ }
+ }
+}
+
+func generateTemplate(description string) (string, []byte, error) {
+ description = strings.TrimRight(description, "\n")
+
+ midl, err := idl.New(description)
+ if err != nil {
+ return "", nil, err
+ }
+
+ pkgname := strings.Replace(midl.Name, ".", "", -1)
+
+ var b bytes.Buffer
+ b.WriteString("// Generated with github.com/varlink/go/cmd/varlink-go-interface-generator\n")
+ b.WriteString("package " + pkgname + "\n\n")
+ b.WriteString("@IMPORTS@\n\n")
+
+ b.WriteString("// Type declarations\n")
+ for _, a := range midl.Aliases {
+ b.WriteString("type " + a.Name + " ")
+ writeType(&b, a.Type, true, 0)
+ b.WriteString("\n\n")
+ }
+
+ b.WriteString("// Client method calls and reply readers\n")
+ for _, m := range midl.Methods {
+ b.WriteString("func " + m.Name + "(c__ *varlink.Connection, more__ bool, oneway__ bool")
+ for _, field := range m.In.Fields {
+ b.WriteString(", " + field.Name + "_ ")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") error {\n")
+ if len(m.In.Fields) > 0 {
+ b.WriteString("\tvar in ")
+ writeType(&b, m.In, true, 1)
+ b.WriteString("\n")
+ for _, field := range m.In.Fields {
+ switch field.Type.Kind {
+ case idl.TypeStruct, idl.TypeArray, idl.TypeMap:
+ b.WriteString("\tin." + strings.Title(field.Name) + " = ")
+ writeType(&b, field.Type, true, 1)
+ b.WriteString("(" + field.Name + "_)\n")
+
+ default:
+ b.WriteString("\tin." + strings.Title(field.Name) + " = " + field.Name + "_\n")
+ }
+ }
+ b.WriteString("\treturn c__.Send(\"" + midl.Name + "." + m.Name + "\", in, more__, oneway__)\n" +
+ "}\n\n")
+ } else {
+ b.WriteString("\treturn c__.Send(\"" + midl.Name + "." + m.Name + "\", nil, more__, oneway__)\n" +
+ "}\n\n")
+ }
+
+ b.WriteString("func Read" + m.Name + "_(c__ *varlink.Connection")
+ for _, field := range m.Out.Fields {
+ b.WriteString(", " + field.Name + "_ *")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") (bool, error) {\n")
+ if len(m.Out.Fields) > 0 {
+ b.WriteString("\tvar out ")
+ writeType(&b, m.Out, true, 1)
+ b.WriteString("\n")
+ b.WriteString("\tcontinues_, err := c__.Receive(&out)\n")
+ } else {
+ b.WriteString("\tcontinues_, err := c__.Receive(nil)\n")
+ }
+ b.WriteString("\tif err != nil {\n" +
+ "\t\treturn false, err\n" +
+ "\t}\n")
+ for _, field := range m.Out.Fields {
+ b.WriteString("\tif " + field.Name + "_ != nil {\n")
+ switch field.Type.Kind {
+ case idl.TypeStruct, idl.TypeArray, idl.TypeMap:
+ b.WriteString("\t\t*" + field.Name + "_ = ")
+ writeType(&b, field.Type, false, 2)
+ b.WriteString(" (out." + strings.Title(field.Name) + ")\n")
+
+ default:
+ b.WriteString("\t\t*" + field.Name + "_ = out." + strings.Title(field.Name) + "\n")
+ }
+ b.WriteString("\t}\n")
+ }
+
+ b.WriteString("\treturn continues_, nil\n" +
+ "}\n\n")
+ }
+
+ b.WriteString("// Service interface with all methods\n")
+ b.WriteString("type " + pkgname + "Interface interface {\n")
+ for _, m := range midl.Methods {
+ b.WriteString("\t" + m.Name + "(c__ VarlinkCall")
+ for _, field := range m.In.Fields {
+ b.WriteString(", " + field.Name + "_ ")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") error\n")
+ }
+ b.WriteString("}\n\n")
+
+ b.WriteString("// Service object with all methods\n")
+ b.WriteString("type VarlinkCall struct{ varlink.Call }\n\n")
+
+ b.WriteString("// Reply methods for all varlink errors\n")
+ for _, e := range midl.Errors {
+ b.WriteString("func (c__ *VarlinkCall) Reply" + e.Name + "(")
+ for i, field := range e.Type.Fields {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ b.WriteString(field.Name + "_ ")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") error {\n")
+ if len(e.Type.Fields) > 0 {
+ b.WriteString("\tvar out ")
+ writeType(&b, e.Type, true, 1)
+ b.WriteString("\n")
+ for _, field := range e.Type.Fields {
+ switch field.Type.Kind {
+ case idl.TypeStruct, idl.TypeArray, idl.TypeMap:
+ b.WriteString("\tout." + strings.Title(field.Name) + " = ")
+ writeType(&b, field.Type, true, 1)
+ b.WriteString("(" + field.Name + "_)\n")
+
+ default:
+ b.WriteString("\tout." + strings.Title(field.Name) + " = " + field.Name + "_\n")
+ }
+ }
+ b.WriteString("\treturn c__.ReplyError(\"" + midl.Name + "." + e.Name + "\", &out)\n")
+ } else {
+ b.WriteString("\treturn c__.ReplyError(\"" + midl.Name + "." + e.Name + "\", nil)\n")
+ }
+ b.WriteString("}\n\n")
+ }
+
+ b.WriteString("// Reply methods for all varlink methods\n")
+ for _, m := range midl.Methods {
+ b.WriteString("func (c__ *VarlinkCall) Reply" + m.Name + "(")
+ for i, field := range m.Out.Fields {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ b.WriteString(field.Name + "_ ")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") error {\n")
+ if len(m.Out.Fields) > 0 {
+ b.WriteString("\tvar out ")
+ writeType(&b, m.Out, true, 1)
+ b.WriteString("\n")
+ for _, field := range m.Out.Fields {
+ switch field.Type.Kind {
+ case idl.TypeStruct, idl.TypeArray, idl.TypeMap:
+ b.WriteString("\tout." + strings.Title(field.Name) + " = ")
+ writeType(&b, field.Type, true, 1)
+ b.WriteString("(" + field.Name + "_)\n")
+
+ default:
+ b.WriteString("\tout." + strings.Title(field.Name) + " = " + field.Name + "_\n")
+ }
+ }
+ b.WriteString("\treturn c__.Reply(&out)\n")
+ } else {
+ b.WriteString("\treturn c__.Reply(nil)\n")
+ }
+ b.WriteString("}\n\n")
+ }
+
+ b.WriteString("// Dummy methods for all varlink methods\n")
+ for _, m := range midl.Methods {
+ b.WriteString("func (s__ *VarlinkInterface) " + m.Name + "(c__ VarlinkCall")
+ for _, field := range m.In.Fields {
+ b.WriteString(", " + field.Name + "_ ")
+ writeType(&b, field.Type, false, 1)
+ }
+ b.WriteString(") error {\n" +
+ "\treturn c__.ReplyMethodNotImplemented(\"" + m.Name + "\")\n" +
+ "}\n\n")
+ }
+
+ b.WriteString("// Method call dispatcher\n")
+ b.WriteString("func (s__ *VarlinkInterface) VarlinkDispatch(call varlink.Call, methodname string) error {\n" +
+ "\tswitch methodname {\n")
+ for _, m := range midl.Methods {
+ b.WriteString("\tcase \"" + m.Name + "\":\n")
+ if len(m.In.Fields) > 0 {
+ b.WriteString("\t\tvar in ")
+ writeType(&b, m.In, true, 2)
+ b.WriteString("\n")
+ b.WriteString("\t\terr := call.GetParameters(&in)\n" +
+ "\t\tif err != nil {\n" +
+ "\t\t\treturn call.ReplyInvalidParameter(\"parameters\")\n" +
+ "\t\t}\n")
+ b.WriteString("\t\treturn s__." + pkgname + "Interface." + m.Name + "(VarlinkCall{call}")
+ if len(m.In.Fields) > 0 {
+ for _, field := range m.In.Fields {
+ switch field.Type.Kind {
+ case idl.TypeStruct, idl.TypeArray, idl.TypeMap:
+ b.WriteString(", ")
+ writeType(&b, field.Type, false, 2)
+ b.WriteString("(in." + strings.Title(field.Name) + ")")
+
+ default:
+ b.WriteString(", in." + strings.Title(field.Name))
+ }
+ }
+ }
+ b.WriteString(")\n")
+ } else {
+ b.WriteString("\t\treturn s__." + pkgname + "Interface." + m.Name + "(VarlinkCall{call})\n")
+ }
+ b.WriteString("\n")
+ }
+ b.WriteString("\tdefault:\n" +
+ "\t\treturn call.ReplyMethodNotFound(methodname)\n" +
+ "\t}\n" +
+ "}\n\n")
+
+ b.WriteString("// Varlink interface name\n")
+ b.WriteString("func (s__ *VarlinkInterface) VarlinkGetName() string {\n" +
+ "\treturn `" + midl.Name + "`\n" + "}\n\n")
+
+ b.WriteString("// Varlink interface description\n")
+ b.WriteString("func (s__ *VarlinkInterface) VarlinkGetDescription() string {\n" +
+ "\treturn `" + midl.Description + "\n`\n}\n\n")
+
+ b.WriteString("// Service interface\n")
+ b.WriteString("type VarlinkInterface struct {\n" +
+ "\t" + pkgname + "Interface\n" +
+ "}\n\n")
+
+ b.WriteString("func VarlinkNew(m " + pkgname + "Interface) *VarlinkInterface {\n" +
+ "\treturn &VarlinkInterface{m}\n" +
+ "}\n")
+
+ ret_string := b.String()
+
+ if strings.Contains(ret_string, "json.RawMessage") {
+ ret_string = strings.Replace(ret_string, "@IMPORTS@", "import (\n\t\"github.com/varlink/go/varlink\"\n\t\"encoding/json\"\n)", 1)
+ } else {
+ ret_string = strings.Replace(ret_string, "@IMPORTS@", `import "github.com/varlink/go/varlink"`, 1)
+ }
+
+ pretty, err := format.Source([]byte(ret_string))
+ if err != nil {
+ return "", nil, err
+ }
+
+ return pkgname, pretty, nil
+}
+
+func generateFile(varlinkFile string) {
+ file, err := ioutil.ReadFile(varlinkFile)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error reading file '%s': %s\n", varlinkFile, err)
+ os.Exit(1)
+ }
+
+ pkgname, b, err := generateTemplate(string(file))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error parsing file '%s': %s\n", varlinkFile, err)
+ os.Exit(1)
+ }
+
+ filename := path.Dir(varlinkFile) + "/" + pkgname + ".go"
+ err = ioutil.WriteFile(filename, b, 0660)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error writing file '%s': %s\n", filename, err)
+ os.Exit(1)
+ }
+}
+
+func main() {
+ if len(os.Args) != 2 {
+ fmt.Printf("Usage: %s <file>\n", os.Args[0])
+ os.Exit(1)
+ }
+ generateFile(os.Args[1])
+}
diff --git a/vendor/github.com/varlink/go/cmd/varlink-go-type-generator/main.go b/vendor/github.com/varlink/go/cmd/varlink-go-type-generator/main.go
new file mode 100644
index 000000000..46414b7bf
--- /dev/null
+++ b/vendor/github.com/varlink/go/cmd/varlink-go-type-generator/main.go
@@ -0,0 +1,172 @@
+package main
+
+import (
+ "fmt"
+ "go/ast"
+ "go/importer"
+ "go/parser"
+ "go/token"
+ "go/types"
+ "log"
+ "os"
+)
+
+func IsBasicGoType(t types.Type, flag types.BasicInfo) bool {
+ switch u := t.(type) {
+ case *types.Basic:
+ if u.Info()&flag != 0 {
+ return true
+ }
+ return false
+ case *types.Named:
+ return IsBasicGoType(u.Underlying(), flag)
+ }
+ return false
+}
+
+func GoToVarlinkType(t types.Type) string {
+ if IsBasicGoType(t, types.IsBoolean) {
+ return "bool"
+ }
+
+ if IsBasicGoType(t, types.IsInteger) {
+ return "int"
+ }
+
+ if IsBasicGoType(t, types.IsFloat) {
+ return "float"
+ }
+
+ if IsBasicGoType(t, types.IsString) {
+ return "string"
+ }
+
+ switch u := t.(type) {
+ case *types.Basic:
+ return fmt.Sprintf("<<<%s>>>", t.String())
+
+ case *types.Named:
+ return u.Obj().Name()
+
+ case *types.Map:
+ if IsBasicGoType(u.Key(), types.IsString) {
+ return fmt.Sprintf("[string]%s", GoToVarlinkType(u.Elem()))
+ } else {
+ return fmt.Sprintf("<<<%s>>>", u.String())
+ }
+
+ case *types.Interface:
+ if u.Empty() {
+ return "()"
+ }
+ return fmt.Sprintf("<<<%s>>>", u.String())
+
+ case *types.Pointer:
+ return fmt.Sprintf("?%s", GoToVarlinkType(u.Elem()))
+
+ case *types.Array:
+ return fmt.Sprintf("[]%s", GoToVarlinkType(u.Elem()))
+
+ case *types.Slice:
+ return fmt.Sprintf("[]%s", GoToVarlinkType(u.Elem()))
+
+ case *types.Struct:
+ if u.NumFields() > 0 {
+ s := ""
+ for i := 0; i < u.NumFields(); i++ {
+ if i > 0 {
+ s += ",\n"
+ }
+ s += fmt.Sprintf("\t%s: %s",
+ u.Field(i).Name(), GoToVarlinkType(u.Field(i).Type()))
+ }
+
+ return fmt.Sprintf("(\n%s\n)", s)
+ }
+ return "()"
+
+ default:
+ return fmt.Sprintf("<<<%T %s>>>", t, u)
+ }
+}
+
+func PrintDefsUses(name string, fset *token.FileSet, files []*ast.File) error {
+ conf := types.Config{
+ Importer: importer.Default(),
+ FakeImportC: true,
+ }
+
+ info := &types.Info{
+ Defs: make(map[*ast.Ident]types.Object),
+ }
+
+ _, err := conf.Check(name, fset, files, info)
+ if err != nil {
+ return err // type error
+ }
+
+ seen := map[string]interface{}{}
+
+ for id, obj := range info.Defs {
+ if obj == nil {
+ continue
+ }
+
+ if _, ok := seen[id.Name]; ok {
+ continue
+ }
+
+ /*
+ if !obj.Exported() || obj.Pkg().Name() != name {
+ continue
+ }
+ */
+ switch f := obj.Type().Underlying().(type) {
+ case *types.Struct:
+ if f.NumFields() > 0 {
+ fmt.Printf("type %s %s\n\n", id.Name, GoToVarlinkType(f))
+ }
+ }
+ seen[id.Name] = nil
+ }
+
+ return nil
+}
+
+func main() {
+
+ path := os.Args[1]
+ fs := token.NewFileSet()
+
+ if stat, err := os.Stat(path); err == nil && stat.IsDir() {
+ pkgs, err := parser.ParseDir(fs, path, nil, 0)
+ if err != nil {
+ fmt.Printf("parsing dir '%s': %s", path, err)
+ }
+ for name, pkg := range pkgs {
+ log.Println("Found package:", name)
+
+ fset := make([]*ast.File, len(pkg.Files), len(pkg.Files))
+ idx := 0
+ for _, value := range pkg.Files {
+ fset[idx] = value
+ idx++
+ }
+
+ if err := PrintDefsUses(name, fs, fset); err != nil {
+ log.Print(err) // type error
+ }
+ }
+ } else {
+
+ fset, err := parser.ParseFile(fs, path, nil, 0)
+
+ if err != nil {
+ fmt.Printf("parsing file '%s': %s", path, err)
+ }
+ name := fset.Name.String()
+ if err := PrintDefsUses(name, fs, []*ast.File{fset}); err != nil {
+ log.Print(err) // type error
+ }
+ }
+}
diff --git a/vendor/github.com/varlink/go/golang-github-varlink-go.spec b/vendor/github.com/varlink/go/golang-github-varlink-go.spec
new file mode 100644
index 000000000..85f5d1788
--- /dev/null
+++ b/vendor/github.com/varlink/go/golang-github-varlink-go.spec
@@ -0,0 +1,44 @@
+%global goipath github.com/varlink/go
+Version: 0
+%gometa
+
+Name: %{goname}
+Release: 1%{?dist}
+Summary: Go bindings for varlink
+License: ASL 2.0
+URL: %{gourl}
+Source0: %{gosource}
+
+%description
+Native Go bindings for the varlink protocol.
+
+%package devel
+Summary: %{summary}
+BuildArch: noarch
+
+%description devel
+%{summary}
+
+This package contains library source intended for
+building other packages which use import path with
+%{gobaseipath} prefix.
+
+%prep
+%forgesetup
+
+%build
+%gobuildroot
+
+%install
+gofiles=$(find . %{gofindfilter} -print)
+%goinstall $gofiles
+
+%check
+
+%files devel -f devel.file-list
+%license LICENSE
+%doc README.md
+
+%changelog
+* Tue Mar 20 2018 <info@varlink.org> 0-1
+- Version 0
diff --git a/vendor/github.com/varlink/go/varlink/external_test.go b/vendor/github.com/varlink/go/varlink/external_test.go
new file mode 100644
index 000000000..daed4ba2d
--- /dev/null
+++ b/vendor/github.com/varlink/go/varlink/external_test.go
@@ -0,0 +1,181 @@
+package varlink_test
+
+// test with no internal access
+
+import (
+ "github.com/varlink/go/varlink"
+ "os"
+ "runtime"
+ "testing"
+ "time"
+)
+
+type VarlinkInterface struct{}
+
+func (s *VarlinkInterface) VarlinkDispatch(call varlink.Call, methodname string) error {
+ return call.ReplyMethodNotImplemented(methodname)
+}
+func (s *VarlinkInterface) VarlinkGetName() string {
+ return `org.example.test`
+}
+
+func (s *VarlinkInterface) VarlinkGetDescription() string {
+ return "#"
+}
+
+type VarlinkInterface2 struct{}
+
+func (s *VarlinkInterface2) VarlinkDispatch(call varlink.Call, methodname string) error {
+ return call.ReplyMethodNotImplemented(methodname)
+}
+func (s *VarlinkInterface2) VarlinkGetName() string {
+ return `org.example.test2`
+}
+
+func (s *VarlinkInterface2) VarlinkGetDescription() string {
+ return "#"
+}
+
+func TestRegisterService(t *testing.T) {
+ newTestInterface := new(VarlinkInterface)
+ service, err := varlink.NewService(
+ "Varlink",
+ "Varlink Test",
+ "1",
+ "https://github.com/varlink/go/varlink",
+ )
+ if err != nil {
+ t.Fatalf("NewService(): %v", err)
+ }
+
+ if err := service.RegisterInterface(newTestInterface); err != nil {
+ t.Fatalf("Couldn't register service: %v", err)
+ }
+
+ if err := service.RegisterInterface(newTestInterface); err == nil {
+ t.Fatal("Could register service twice")
+ }
+
+ defer func() { service.Shutdown() }()
+
+ servererror := make(chan error)
+
+ go func() {
+ servererror <- service.Listen("unix:varlinkexternal_TestRegisterService", 0)
+ }()
+
+ time.Sleep(time.Second / 5)
+
+ n := new(VarlinkInterface2)
+
+ if err := service.RegisterInterface(n); err == nil {
+ t.Fatal("Could register service while running")
+ }
+ time.Sleep(time.Second / 5)
+ service.Shutdown()
+
+ if err := <-servererror; err != nil {
+ t.Fatalf("service.Listen(): %v", err)
+ }
+}
+
+func TestUnix(t *testing.T) {
+ newTestInterface := new(VarlinkInterface)
+ service, err := varlink.NewService(
+ "Varlink",
+ "Varlink Test",
+ "1",
+ "https://github.com/varlink/go/varlink",
+ )
+
+ if err != nil {
+ t.Fatalf("NewService(): %v", err)
+ }
+
+ if err := service.RegisterInterface(newTestInterface); err != nil {
+ t.Fatalf("RegisterInterface(): %v", err)
+ }
+
+ servererror := make(chan error)
+
+ go func() {
+ servererror <- service.Listen("unix:varlinkexternal_TestUnix", 0)
+ }()
+
+ time.Sleep(time.Second / 5)
+ service.Shutdown()
+
+ if err := <-servererror; err != nil {
+ t.Fatalf("service.Listen(): %v", err)
+ }
+}
+
+func TestAnonUnix(t *testing.T) {
+ if runtime.GOOS != "linux" {
+ return
+ }
+
+ newTestInterface := new(VarlinkInterface)
+ service, err := varlink.NewService(
+ "Varlink",
+ "Varlink Test",
+ "1",
+ "https://github.com/varlink/go/varlink",
+ )
+
+ if err != nil {
+ t.Fatalf("NewService(): %v", err)
+ }
+
+ if err := service.RegisterInterface(newTestInterface); err != nil {
+ t.Fatalf("RegisterInterface(): %v", err)
+ }
+
+ servererror := make(chan error)
+
+ go func() {
+ servererror <- service.Listen("unix:@varlinkexternal_TestAnonUnix", 0)
+ }()
+
+ time.Sleep(time.Second / 5)
+ service.Shutdown()
+
+ if err := <-servererror; err != nil {
+ t.Fatalf("service.Listen(): %v", err)
+ }
+}
+
+func TestListenFDSNotInt(t *testing.T) {
+ newTestInterface := new(VarlinkInterface)
+ service, err := varlink.NewService(
+ "Varlink",
+ "Varlink Test",
+ "1",
+ "https://github.com/varlink/go/varlink",
+ )
+
+ if err != nil {
+ t.Fatalf("NewService(): %v", err)
+ }
+
+ if err := service.RegisterInterface(newTestInterface); err != nil {
+ t.Fatalf("Couldn't register service: %v", err)
+ }
+ os.Setenv("LISTEN_FDS", "foo")
+ os.Setenv("LISTEN_PID", string(os.Getpid()))
+
+ servererror := make(chan error)
+
+ go func() {
+ servererror <- service.Listen("unix:varlinkexternal_TestListenFDSNotInt", 0)
+ }()
+
+ time.Sleep(time.Second / 5)
+ service.Shutdown()
+
+ err = <-servererror
+
+ if err != nil {
+ t.Fatalf("service.Run(): %v", err)
+ }
+}
diff --git a/vendor/github.com/varlink/go/varlink/idl/idl_test.go b/vendor/github.com/varlink/go/varlink/idl/idl_test.go
new file mode 100644
index 000000000..a3377bec0
--- /dev/null
+++ b/vendor/github.com/varlink/go/varlink/idl/idl_test.go
@@ -0,0 +1,150 @@
+package idl
+
+import (
+ "fmt"
+ "runtime"
+ "testing"
+)
+
+/*
+func expect(t *testing.T, expected string, returned string) {
+ if strings.Compare(returned, expected) != 0 {
+ t.Fatalf("Expected(%d): `%s`\nGot(%d): `%s`\n",
+ len(expected), expected,
+ len(returned), returned)
+ }
+}
+*/
+
+func testParse(t *testing.T, pass bool, description string) {
+ _, _, line, _ := runtime.Caller(1)
+
+ t.Run(fmt.Sprintf("Line-%d", line), func(t *testing.T) {
+ midl, err := New(description)
+ if pass {
+ if err != nil {
+ t.Fatalf("generateTemplate(`%s`): %v", description, err)
+ }
+ if len(midl.Name) <= 0 {
+ t.Fatalf("generateTemplate(`%s`): returned no pkgname", description)
+ }
+ }
+ if !pass && (err == nil) {
+ t.Fatalf("generateTemplate(`%s`): did not fail", description)
+ }
+ })
+}
+
+func TestOneMethod(t *testing.T) {
+ testParse(t, true, "interface foo.bar\nmethod Foo()->()")
+}
+
+func TestOneMethodNoType(t *testing.T) {
+ testParse(t, false, "interface foo.bar\nmethod Foo()->(b:)")
+}
+
+func TestDomainNames(t *testing.T) {
+ testParse(t, true, "interface org.varlink.service\nmethod F()->()")
+ testParse(t, true, "interface com.example.0example\nmethod F()->()")
+ testParse(t, true, "interface com.example.example-dash\nmethod F()->()")
+ testParse(t, true, "interface xn--lgbbat1ad8j.example.algeria\nmethod F()->()")
+ testParse(t, false, "interface com.-example.leadinghyphen\nmethod F()->()")
+ testParse(t, false, "interface com.example-.danglinghyphen-\nmethod F()->()")
+ testParse(t, false, "interface Com.example.uppercase-toplevel\nmethod F()->()")
+ testParse(t, false, "interface Co9.example.number-toplevel\nmethod F()->()")
+ testParse(t, false, "interface 1om.example.number-toplevel\nmethod F()->()")
+ testParse(t, false, "interface com.Example\nmethod F()->()")
+ var name string
+ for i := 0; i < 255; i++ {
+ name += "a"
+ }
+ testParse(t, false, "interface com.example.toolong"+name+"\nmethod F()->()")
+ testParse(t, false, "interface xn--example.toolong"+name+"\nmethod F()->()")
+}
+
+func TestNoMethod(t *testing.T) {
+ testParse(t, false, `
+interface org.varlink.service
+ type Interface (name: string, types: []Type, methods: []Method)
+ type Property (key: string, value: string)
+`)
+}
+
+func TestTypeNoArgs(t *testing.T) {
+ testParse(t, true, "interface foo.bar\n type I ()\nmethod F()->()")
+}
+
+func TestTypeOneArg(t *testing.T) {
+ testParse(t, true, "interface foo.bar\n type I (b:bool)\nmethod F()->()")
+}
+
+func TestBasicTypes(t *testing.T) {
+ testParse(t, true, "interface foo.bar\n type I (b:bool)\nmethod F()->()")
+ testParse(t, true, "interface foo.bar\n type I (b:string)\nmethod F()->()")
+ testParse(t, true, "interface foo.bar\n type I (b:float)\nmethod F()->()")
+ testParse(t, true, "interface foo.bar\n type I (b:int)\nmethod F()->()")
+ testParse(t, true, "interface foo.bar\n type I (b:object)\nmethod F()->()")
+}
+
+func TestTypeOneArray(t *testing.T) {
+ testParse(t, true, "interface foo.bar\n type I (b:[]bool)\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\n type I (b:bool[ ])\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\n type I (b:bool[1])\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\n type I (b:bool[ 1 ])\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\n type I (b:bool[ 1 1 ])\nmethod F()->()")
+}
+
+func TestFieldnames(t *testing.T) {
+ testParse(t, false, "interface foo.bar\n type I (Test:[]bool)\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\n type I (_test:[]bool)\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\n type I (Ă„est:[]bool)\nmethod F()->()")
+}
+
+func TestNestedStructs(t *testing.T) {
+ testParse(t, true, "interface foo.bar\n type I ( b: [](foo: bool, bar: bool, baz: int) )\nmethod F()->()")
+}
+
+func TestEnum(t *testing.T) {
+ testParse(t, true, "interface foo.bar\n type I (b:(foo, bar, baz))\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\n type I (foo, bar, baz : bool)\nmethod F()->()")
+}
+
+func TestMap(t *testing.T) {
+ testParse(t, true, "interface foo.bar\n type I (m: [string]string)\nmethod F()->()")
+ testParse(t, true, "interface foo.bar\n type I (m: [string]int)\nmethod F()->()")
+ testParse(t, true, "interface foo.bar\n type I (m: [string]())\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\n type I (m: [int]string)\nmethod F()->()")
+}
+
+func TestMaybe(t *testing.T) {
+ testParse(t, true, "interface foo.bar\n type I (m: ?string)\nmethod F()->()")
+ testParse(t, true, "interface foo.bar\n type I (m: ?[string]?int)\nmethod F()->()")
+ testParse(t, true, "interface foo.bar\n type I (m: ?[]?int)\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\n type I (m: ??int)\nmethod F()->()")
+}
+
+func TestIncomplete(t *testing.T) {
+ testParse(t, false, "interfacef foo.bar\nmethod F()->()")
+ testParse(t, false, "interface foo.bar\nmethod F()->()\ntype I (b: bool")
+ testParse(t, false, "interface foo.bar\nmethod F()->(")
+ testParse(t, false, "interface foo.bar\nmethod F(")
+ testParse(t, false, "interface foo.bar\nmethod ()->()")
+ testParse(t, false, "interface foo.bar\nmethod F->()\n")
+ testParse(t, false, "interface foo.bar\nmethod F()->\n")
+ testParse(t, false, "interface foo.bar\nmethod F()>()\n")
+ testParse(t, false, "interface foo.bar\nmethod F()->()\ntype (b: bool)")
+ testParse(t, false, "interface foo.bar\nmethod F()->()\nerror (b: bool)")
+ testParse(t, false, "interface foo.bar\nmethod F()->()\n dfghdrg")
+}
+
+func TestDuplicate(t *testing.T) {
+ testParse(t, false, `
+interface foo.example
+ type Device()
+ type Device()
+ type T()
+ type T()
+ method F() -> ()
+ method F() -> ()
+`)
+}
diff --git a/vendor/github.com/varlink/go/varlink/varlink_test.go b/vendor/github.com/varlink/go/varlink/varlink_test.go
new file mode 100644
index 000000000..e19e768a2
--- /dev/null
+++ b/vendor/github.com/varlink/go/varlink/varlink_test.go
@@ -0,0 +1,232 @@
+package varlink
+
+// tests with access to internals
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "strings"
+ "testing"
+)
+
+func expect(t *testing.T, expected string, returned string) {
+ if strings.Compare(returned, expected) != 0 {
+ t.Fatalf("Expected(%d): `%s`\nGot(%d): `%s`\n",
+ len(expected), expected,
+ len(returned), strings.Replace(returned, "\000", "`+\"\\000\"+`", -1))
+ }
+}
+
+func TestService(t *testing.T) {
+ service, _ := NewService(
+ "Varlink",
+ "Varlink Test",
+ "1",
+ "https://github.com/varlink/go/varlink",
+ )
+
+ t.Run("ZeroMessage", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ if err := service.handleMessage(w, []byte{0}); err == nil {
+ t.Fatal("HandleMessage returned non-error")
+ }
+ })
+
+ t.Run("InvalidJson", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"foo.GetInterfaceDescription" fdgdfg}`)
+ if err := service.handleMessage(w, msg); err == nil {
+ t.Fatal("HandleMessage returned no error on invalid json")
+ }
+ })
+
+ t.Run("WrongInterface", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"foo.GetInterfaceDescription"}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatal("HandleMessage returned error on wrong interface")
+ }
+ expect(t, `{"parameters":{"interface":"foo"},"error":"org.varlink.service.InterfaceNotFound"}`+"\000",
+ b.String())
+ })
+
+ t.Run("InvalidMethod", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"InvalidMethod"}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatal("HandleMessage returned error on invalid method")
+ }
+ expect(t, `{"parameters":{"parameter":"method"},"error":"org.varlink.service.InvalidParameter"}`+"\000",
+ b.String())
+ })
+
+ t.Run("WrongMethod", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"org.varlink.service.WrongMethod"}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatal("HandleMessage returned error on wrong method")
+ }
+ expect(t, `{"parameters":{"method":"WrongMethod"},"error":"org.varlink.service.MethodNotFound"}`+"\000",
+ b.String())
+ })
+
+ t.Run("GetInterfaceDescriptionNullParameters", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"org.varlink.service.GetInterfaceDescription","parameters": null}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatalf("HandleMessage returned error: %v", err)
+ }
+ expect(t, `{"parameters":{"parameter":"parameters"},"error":"org.varlink.service.InvalidParameter"}`+"\000",
+ b.String())
+ })
+
+ t.Run("GetInterfaceDescriptionNoInterface", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"org.varlink.service.GetInterfaceDescription","parameters":{}}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatalf("HandleMessage returned error: %v", err)
+ }
+ expect(t, `{"parameters":{"parameter":"interface"},"error":"org.varlink.service.InvalidParameter"}`+"\000",
+ b.String())
+ })
+
+ t.Run("GetInterfaceDescriptionWrongInterface", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"org.varlink.service.GetInterfaceDescription","parameters":{"interface":"foo"}}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatalf("HandleMessage returned error: %v", err)
+ }
+ expect(t, `{"parameters":{"parameter":"interface"},"error":"org.varlink.service.InvalidParameter"}`+"\000",
+ b.String())
+ })
+
+ t.Run("GetInterfaceDescription", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"org.varlink.service.GetInterfaceDescription","parameters":{"interface":"org.varlink.service"}}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatalf("HandleMessage returned error: %v", err)
+ }
+ expect(t, `{"parameters":{"description":"# The Varlink Service Interface is provided by every varlink service. It\n# describes the service and the interfaces it implements.\ninterface org.varlink.service\n\n# Get a list of all the interfaces a service provides and information\n# about the implementation.\nmethod GetInfo() -\u003e (\n vendor: string,\n product: string,\n version: string,\n url: string,\n interfaces: []string\n)\n\n# Get the description of an interface that is implemented by this service.\nmethod GetInterfaceDescription(interface: string) -\u003e (description: string)\n\n# The requested interface was not found.\nerror InterfaceNotFound (interface: string)\n\n# The requested method was not found\nerror MethodNotFound (method: string)\n\n# The interface defines the requested method, but the service does not\n# implement it.\nerror MethodNotImplemented (method: string)\n\n# One of the passed parameters is invalid.\nerror InvalidParameter (parameter: string)"}}`+"\000",
+ b.String())
+ })
+
+ t.Run("GetInfo", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"org.varlink.service.GetInfo"}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatalf("HandleMessage returned error: %v", err)
+ }
+ expect(t, `{"parameters":{"vendor":"Varlink","product":"Varlink Test","version":"1","url":"https://github.com/varlink/go/varlink","interfaces":["org.varlink.service"]}}`+"\000",
+ b.String())
+ })
+}
+
+type VarlinkInterface struct{}
+
+func (s *VarlinkInterface) VarlinkDispatch(call Call, methodname string) error {
+ switch methodname {
+ case "Ping":
+ if !call.WantsMore() {
+ return fmt.Errorf("More flag not passed")
+ }
+ if call.IsOneShot() {
+ return fmt.Errorf("OneShot flag set")
+ }
+ call.Continues = true
+ if err := call.Reply(nil); err != nil {
+ return err
+ }
+ if err := call.Reply(nil); err != nil {
+ return err
+ }
+ call.Continues = false
+ if err := call.Reply(nil); err != nil {
+ return err
+ }
+ return nil
+
+ case "PingError":
+ return call.ReplyError("org.example.test.PingError", nil)
+ }
+
+ call.Continues = true
+ if err := call.Reply(nil); err == nil {
+ return fmt.Errorf("call.Reply did not fail for Continues/More mismatch")
+ }
+ call.Continues = false
+
+ if err := call.ReplyError("WrongName", nil); err == nil {
+ return fmt.Errorf("call.ReplyError accepted invalid error name")
+ }
+
+ if err := call.ReplyError("org.varlink.service.MethodNotImplemented", nil); err == nil {
+ return fmt.Errorf("call.ReplyError accepted org.varlink.service error")
+ }
+
+ return call.ReplyMethodNotImplemented(methodname)
+}
+func (s *VarlinkInterface) VarlinkGetName() string {
+ return `org.example.test`
+}
+
+func (s *VarlinkInterface) VarlinkGetDescription() string {
+ return "#"
+}
+
+func TestMoreService(t *testing.T) {
+ newTestInterface := new(VarlinkInterface)
+
+ service, _ := NewService(
+ "Varlink",
+ "Varlink Test",
+ "1",
+ "https://github.com/varlink/go/varlink",
+ )
+
+ if err := service.RegisterInterface(newTestInterface); err != nil {
+ t.Fatalf("Couldn't register service: %v", err)
+ }
+
+ t.Run("MethodNotImplemented", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"org.example.test.Pingf"}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatalf("HandleMessage returned error: %v", err)
+ }
+ expect(t, `{"parameters":{"method":"Pingf"},"error":"org.varlink.service.MethodNotImplemented"}`+"\000",
+ b.String())
+ })
+
+ t.Run("PingError", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"org.example.test.PingError", "more" : true}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatalf("HandleMessage returned error: %v", err)
+ }
+ expect(t, `{"error":"org.example.test.PingError"}`+"\000",
+ b.String())
+ })
+ t.Run("MoreTest", func(t *testing.T) {
+ var b bytes.Buffer
+ w := bufio.NewWriter(&b)
+ msg := []byte(`{"method":"org.example.test.Ping", "more" : true}`)
+ if err := service.handleMessage(w, msg); err != nil {
+ t.Fatalf("HandleMessage returned error: %v", err)
+ }
+ expect(t, `{"continues":true}`+"\000"+`{"continues":true}`+"\000"+`{}`+"\000",
+ b.String())
+ })
+}