rpc: ResourceProvider over RPC

This commit is contained in:
Mitchell Hashimoto 2014-05-28 15:07:47 -07:00
parent 1b5dfa043b
commit f8dc3286d9
5 changed files with 137 additions and 1 deletions

41
rpc/resource_provider.go Normal file
View File

@ -0,0 +1,41 @@
package rpc
import (
"net/rpc"
"github.com/hashicorp/terraform/terraform"
)
type ResourceProvider struct {
Client *rpc.Client
}
func (p *ResourceProvider) Configure(c map[string]interface{}) ([]string, error) {
var resp ResourceProviderConfigureResponse
err := p.Client.Call("ResourceProvider.Configure", c, &resp)
if err != nil {
return nil, err
}
return resp.Warnings, resp.Error
}
type ResourceProviderServer struct {
Provider terraform.ResourceProvider
}
type ResourceProviderConfigureResponse struct {
Warnings []string
Error error
}
func (s *ResourceProviderServer) Configure(
config map[string]interface{},
reply *ResourceProviderConfigureResponse) error {
warnings, err := s.Provider.Configure(config)
*reply = ResourceProviderConfigureResponse{
Warnings: warnings,
Error: err,
}
return nil
}

View File

@ -0,0 +1,34 @@
package rpc
import (
"reflect"
"testing"
"github.com/hashicorp/terraform/terraform"
)
func TestResourceProvider_configure(t *testing.T) {
p := new(terraform.MockResourceProvider)
client, server := testClientServer(t)
server.RegisterName("ResourceProvider", &ResourceProviderServer{
Provider: p,
})
provider := &ResourceProvider{Client: client}
// Configure
config := map[string]interface{}{"foo": "bar"}
w, e := provider.Configure(config)
if !p.ConfigureCalled {
t.Fatal("configure should be called")
}
if !reflect.DeepEqual(p.ConfigureConfig, config) {
t.Fatalf("bad: %#v", p.ConfigureConfig)
}
if w != nil {
t.Fatalf("bad: %#v", w)
}
if e != nil {
t.Fatalf("bad: %#v", e)
}
}

45
rpc/rpc_test.go Normal file
View File

@ -0,0 +1,45 @@
package rpc
import (
"net"
"net/rpc"
"testing"
)
func testConn(t *testing.T) (net.Conn, net.Conn) {
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("err: %s", err)
}
var serverConn net.Conn
doneCh := make(chan struct{})
go func() {
defer close(doneCh)
defer l.Close()
var err error
serverConn, err = l.Accept()
if err != nil {
t.Fatalf("err: %s", err)
}
}()
clientConn, err := net.Dial("tcp", l.Addr().String())
if err != nil {
t.Fatalf("err: %s", err)
}
<-doneCh
return clientConn, serverConn
}
func testClientServer(t *testing.T) (*rpc.Client, *rpc.Server) {
clientConn, serverConn := testConn(t)
server := rpc.NewServer()
go server.ServeConn(serverConn)
client := rpc.NewClient(clientConn)
return client, server
}

View File

@ -12,7 +12,7 @@ type ResourceProvider interface {
// Resources returns all the available resource types that this provider // Resources returns all the available resource types that this provider
// knows how to manage. // knows how to manage.
Resources() []ResourceType //Resources() []ResourceType
} }
// ResourceType is a type of resource that a resource provider can manage. // ResourceType is a type of resource that a resource provider can manage.

View File

@ -0,0 +1,16 @@
package terraform
// MockResourceProvider implements ResourceProvider but mocks out all the
// calls for testing purposes.
type MockResourceProvider struct {
ConfigureCalled bool
ConfigureConfig map[string]interface{}
ConfigureReturnWarnings []string
ConfigureReturnError error
}
func (p *MockResourceProvider) Configure(c map[string]interface{}) ([]string, error) {
p.ConfigureCalled = true
p.ConfigureConfig = c
return p.ConfigureReturnWarnings, p.ConfigureReturnError
}