diff --git a/tests/afrouter/templates/client.go b/tests/afrouter/templates/client.go
new file mode 100644
index 0000000..d384baf
--- /dev/null
+++ b/tests/afrouter/templates/client.go
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+	"fmt"
+	"errors"
+	"encoding/json"
+	"google.golang.org/grpc"
+	"golang.org/x/net/context"
+	"github.com/opencord/voltha-go/common/log"
+	// Values generated by the go template
+	{{range .Imports}}
+	"{{.}}"
+	{{end}}
+	{{range .ProtoImports}}
+	{{.Short}} "{{.Package}}"
+	{{end}}
+	// End go template values
+)
+
+{{if .Ct}}{{else}}
+type clientCtl struct {
+	send func(string, interface{}, string) error
+	cncl  context.CancelFunc
+	ctx context.Context
+}
+{{end}}
+
+type {{.Name}}ClientConn struct {
+	conn * grpc.ClientConn
+	control * clientCtl
+}
+
+
+var {{.Name}}Client *{{.Name}}ClientConn
+
+
+func {{.Name}}Connect() (*{{.Name}}ClientConn, error)  {
+	log.Infof("Connecting client {{.Name}} to addr:127.0.0.1, port:{{.Port}}")
+	// Dial doesn't block, it just returns and continues connecting in the background.
+	// Check back later to confirm and increase the connection count.
+	cl := &{{.Name}}ClientConn{control:&clientCtl{}}
+	ctx, cnclFnc := context.WithCancel(context.Background())
+	cl.control.cncl = cnclFnc
+	cl.control.ctx = ctx
+	if conn, err := grpc.Dial("127.0.0.1:{{.Port}}", grpc.WithInsecure()); err != nil {
+		log.Errorf("Dialng connection :%v",err)
+		return nil, err
+	} else {
+		cl.conn = conn
+	}
+	{{.Name}}Client = cl
+	cl.control.send = {{.Name}}Send
+	clients["{{.Name}}"] = cl.control
+	return cl, nil
+}
+
+// This function will make the requested RPC with the supplied
+// parameter and validate that the response matches the expected
+// value provided. It will return nil if successful or an error
+// if not.
+func {{.Name}}Send(mthd string, param interface{}, expect string) error {
+	switch mthd {
+	{{range .Methods}}
+		case "{{.Name}}":
+		switch t := param.(type) {
+			case *{{.Param}}:
+	{{if .Ss}}
+			_=t
+	{{else if .Cs}}
+			_=t
+	{{else}}
+			client := {{.Pkg}}.New{{.Svc}}Client({{$.Name}}Client.conn)
+			res, err := client.{{.Name}}(context.Background(), t)
+			if err != nil {
+				return errors.New("Error sending method {{.Name}}")
+			}
+			// Marshal the result and compare it to the expected
+			// value.
+			if resS,err := json.Marshal(res); err == nil {
+				if string(resS) != expect {
+					return errors.New("Unexpected result on method {{.Name}}")
+				}
+			} else {
+				return errors.New("Error Marshaling the reply for method {{.Name}}")
+			}
+			default:
+					return errors.New("Invalid parameter type for method {{.Name}}")
+	{{end}}
+		}
+	{{end}}
+		default:
+			return errors.New(fmt.Sprintf("Unexpected method %s in send", mthd))
+	}
+	return nil
+}
+
diff --git a/tests/afrouter/templates/clientInit.go b/tests/afrouter/templates/clientInit.go
new file mode 100644
index 0000000..e8f4836
--- /dev/null
+++ b/tests/afrouter/templates/clientInit.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+var clients map[string]*clientCtl
+
+func clientInit() error {
+	clients = make(map[string]*clientCtl)
+	{{range .}}
+	if _,err := {{.Name}}Connect(); err != nil {
+		return err
+	}
+	{{end}}
+	return nil
+}
+
+
diff --git a/tests/afrouter/templates/main.go b/tests/afrouter/templates/main.go
new file mode 100644
index 0000000..5c094d9
--- /dev/null
+++ b/tests/afrouter/templates/main.go
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// The template for the tester.
+// This template is filled in by the
+// test driver based on the configuration.
+
+package main
+
+import (
+	"os"
+	"time"
+	"os/exec"
+	"strings"
+	"context"
+	"github.com/opencord/voltha-go/common/log"
+)
+
+var resFile *os.File
+
+func startSut(cmdStr string) (context.CancelFunc, error) {
+	var err error = nil
+
+	cmdAry := strings.Fields(cmdStr)
+	log.Infof("Running the affinity router: %s",cmdStr)
+	//ctx, cncl := context.WithCancel(context.Background())
+	ctx, cncl := context.WithCancel(context.Background())
+	cmd := exec.CommandContext(ctx, cmdAry[0], cmdAry[1:]...)
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err = cmd.Start(); err != nil {
+		log.Errorf("Failed to run the affinity router: %s %v", cmdStr,err)
+	}
+	time.Sleep(1 * time.Second) // Give the command time to get started
+	return cncl, err
+}
+
+func cleanUp(cncl context.CancelFunc) {
+	cncl()
+	// Give the child processes time to terminate
+	time.Sleep(1 * time.Second)
+}
+
+func main() {
+	var err error
+
+	// Setup logging
+	if _, err = log.SetDefaultLogger(log.JSON, 0, nil); err != nil {
+		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
+	}
+
+	defer log.CleanUp()
+
+	// Open the results file to write the results to
+	if resFile, err = os.OpenFile(os.Args[1], os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err != nil {
+		log.Errorf("Could not append to the results file")
+	}
+
+	defer resFile.Close()
+
+	// Initialize the servers
+	if err := serverInit(); err != nil {
+		log.Errorf("Error initializing server: %v", err)
+		return
+	}
+
+	// Start the sofware under test
+	cnclFunc, err := startSut("./{{.Command}}");
+	defer cleanUp(cnclFunc)
+	if  err != nil {
+		return
+	}
+
+	// Initialize the clients
+	if err := clientInit(); err != nil {
+		log.Errorf("Error initializing client: %v", err)
+		return
+	}
+
+	log.Infof("The servers are: %v",servers)
+
+	// Run all the test cases now
+	log.Infof("Executing tests")
+	resFile.Write([]byte("Executing tests\n"))
+	runTests()
+
+}
diff --git a/tests/afrouter/templates/runAll.go b/tests/afrouter/templates/runAll.go
new file mode 100644
index 0000000..b85e4c7
--- /dev/null
+++ b/tests/afrouter/templates/runAll.go
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// The template for the tester.
+// This template is filled in by the
+// test driver based on the configuration.
+
+package main
+
+import (
+	"os"
+	//"time"
+	"fmt"
+	"os/exec"
+	"io/ioutil"
+	"github.com/opencord/voltha-go/common/log"
+)
+
+func main() {
+	var cmd *exec.Cmd
+	var cmdStr string
+	// Setup logging
+	if _, err := log.SetDefaultLogger(log.JSON, 0, nil); err != nil {
+		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
+	}
+
+	defer log.CleanUp()
+
+	log.Info("Running tests")
+	{{range .}}
+	if err:= os.Chdir(os.Args[1]); err != nil {
+		log.Error("Could not change directory to %s: %v", os.Args[1], err)
+	}
+	cmdStr =  "./"+"{{.}}"[:len("{{.}}")-5]
+	log.Infof("Running test %s",cmdStr)
+	cmd = exec.Command(cmdStr, "results.txt")
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err := cmd.Run(); err != nil {
+		log.Errorf("Test '%s' failed", cmdStr)
+	}
+	{{end}}
+	// Open the results file and output it.
+	if resFile, err := ioutil.ReadFile("results.txt"); err == nil {
+		fmt.Println(string(resFile))
+	} else {
+		log.Error("Could not load the results file 'results.txt'")
+	}
+	log.Info("Tests complete")
+}
diff --git a/tests/afrouter/templates/runTests.go b/tests/afrouter/templates/runTests.go
new file mode 100644
index 0000000..3b0f6d4
--- /dev/null
+++ b/tests/afrouter/templates/runTests.go
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package main
+
+import (
+	"fmt"
+	"time"
+	"errors"
+	"encoding/json"
+	"github.com/opencord/voltha-go/common/log"
+	{{range .Imports}}
+	_ "{{.}}"
+	{{end}}
+	{{range .ProtoImports}}
+	{{.Short}} "{{.Package}}"
+	{{end}}
+)
+
+func runTests() {
+	{{range $k,$v := .Tests}}
+	if err := test{{$k}}(); err == nil {
+		resFile.Write([]byte("\tTest Successful\n"))
+	} else {
+		resFile.Write([]byte("\tTest Failed\n"))
+	}
+	{{end}}
+	time.Sleep(5 * time.Second)
+}
+
+{{range $k,$v := .Tests}}
+func test{{$k}}() error {
+	var rtrn error = nil
+	// Announce the test being run
+	resFile.Write([]byte("******************** Running test case: {{$v.Name}}\n"))
+	// Acquire the client used to run the test
+	cl := clients["{{$v.Send.Client}}"]
+	// Create the server's reply data structure
+	repl := &reply{repl:&{{$v.Send.ExpectType}}{{$v.Send.Expect}}}
+	// Send the reply data structure to each of the servers
+	{{range $s := .Srvr}}
+	if servers["{{$s.Name}}"] == nil {
+		log.Error("Server '{{$s.Name}}' is nil")
+		return errors.New("GAAK")
+	}
+	servers["{{$s.Name}}"].replyData <- repl
+	{{end}}
+
+	// Now call the RPC with the data provided
+	if expct,err := json.Marshal(repl.repl); err != nil {
+		log.Errorf("Marshaling the reply for test {{$v.Name}}: %v",err)
+	} else {
+		if err := cl.send("{{$v.Send.Method}}",
+							&{{$v.Send.ParamType}}{{$v.Send.Param}},
+							string(expct)); err != nil {
+			log.Errorf("Test case {{$v.Name}} failed!: %v", err)
+
+		}
+	}
+
+	// Now read the servers' information to validate it
+	var s *serverCtl
+	var payload string
+	var i *incoming
+	if pld, err := json.Marshal(&{{$v.Send.ParamType}}{{$v.Send.Param}}); err != nil {
+		log.Errorf("Marshaling paramter for test {{$v.Name}}: %v", err)
+	} else {
+		payload = string(pld)
+	}
+	{{range $s := .Srvr}}
+	s = servers["{{$s.Name}}"]
+	i = <-s.incmg
+	if i.payload != payload {
+		log.Errorf("Mismatched payload for test {{$v.Name}}, %s:%s", i.payload, payload)
+		resFile.Write([]byte(fmt.Sprintf("Mismatched payload expected %s, got %s\n", payload, i.payload)))
+		rtrn = errors.New("Failed")
+	}
+	{{range $m := $s.Meta}}
+	if mv,ok := i.meta["{{$m.Key}}"]; ok == true {
+		if "{{$m.Val}}" != mv[0] {
+			log.Errorf("Mismatched metadata for test {{$v.Name}}, %s:%s", mv[0], "{{$m.Val}}")
+			resFile.Write([]byte(fmt.Sprintf("Mismatched metadata on server %s expected %s, got %s\n", "{{$s.Name}}", "{{$m.Val}}", mv[0])))
+			rtrn = errors.New("Failed")
+		}
+	}
+	{{end}}
+	{{end}}
+
+	return rtrn
+}
+{{end}}
+
+
diff --git a/tests/afrouter/templates/server.go b/tests/afrouter/templates/server.go
new file mode 100644
index 0000000..8461d38
--- /dev/null
+++ b/tests/afrouter/templates/server.go
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// The template for the tester.
+// This template is filled in by the
+// test driver based on the configuration.
+
+package main
+
+import (
+	"fmt"
+	"net"
+	"errors"
+	"encoding/json"
+	"google.golang.org/grpc"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc/metadata"
+	"github.com/opencord/voltha-go/common/log"
+	// Values generated by the go template
+	{{range .Imports}}
+	"{{.}}"
+	{{end}}
+	{{range .ProtoImports}}
+	{{.Short}} "{{.Package}}"
+	{{end}}
+	// End go template values
+)
+
+// The channels to get fed the expected results by the test driver.
+//var {{.Name}}Meta <-chan string
+////var {{.Name}}Payload <-chan string
+
+{{if .Ct}}{{else}}
+type reply struct {
+	repl interface{}
+}
+type incoming struct {
+	meta metadata.MD
+	payload string
+}
+type  serverCtl struct {
+	replyData chan * reply
+	incmg chan * incoming
+}
+{{end}}
+
+type {{.Name}}TestServer struct {
+	control *serverCtl
+	srv *grpc.Server
+}
+
+/*
+func init() {
+	{{if .Ct}}{{else}}
+	if _, err := log.SetDefaultLogger(log.JSON, 0, nil); err != nil {
+		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
+	}
+	{{end}}
+	{{.Name}}ListenAndServe()
+}
+*/
+
+
+func {{.Name}}ListenAndServe() error {
+	var s {{.Name}}TestServer
+
+	s.control = &serverCtl{replyData:make(chan *reply,1), incmg:make(chan *incoming,1)}
+	servers["{{.Name}}"] = s.control
+
+	log.Debugf("Starting server %s on port %d", "{{.Name}}", {{.Port}})
+	// THe test head always uses localhost 127.0.0.1
+	addr := fmt.Sprintf("127.0.0.1:%d", {{.Port}})
+
+	// Create the gRPC server
+	s.srv = grpc.NewServer()
+
+{{range .ProtoImports}}
+	// Register the handler object
+	{{.Short}}.Register{{.Service}}Server(s.srv, s)
+{{end}}
+
+	// Create the channel to listen on
+	lis, err := net.Listen("tcp", addr)
+	if err != nil {
+		log.Errorf("could not listen on %s: %s", addr, err)
+		return err
+	}
+
+	// Serve and Listen
+	go func() {
+		if err = s.srv.Serve(lis); err != nil {
+			log.Errorf("grpc serve error: %s", err)
+			return
+		}
+	}()
+
+	return err
+}
+
+{{range .Methods}}
+{{if .Ss}}
+func (ts {{$.Name}}TestServer) {{.Name}}(in *{{.Param}}, srvr {{.Pkg}}.{{.Svc}}_{{.Name}}Server) error {
+	return nil
+}
+{{else if .Cs}}
+func (ts {{$.Name}}TestServer) {{.Name}}({{.Pkg}}.{{.Svc}}_{{.Name}}Server) error {
+	return nil
+}
+{{else}}
+func  (ts {{$.Name}}TestServer) {{.Name}}(ctx context.Context, in *{{.Param}}) (*{{.Rtrn}}, error) {
+	var r * incoming = &incoming{}
+	// Read the metadata
+	if md,ok := metadata.FromIncomingContext(ctx); ok == false {
+		log.Error("Getting matadata during call to {{.Name}}")
+	} else {
+		r.meta = md.Copy()
+	}
+	// Read the data sent to the function
+	if parm,err := json.Marshal(in); err != nil {
+		log.Error("Marshalling the {{.Param}} for {{.Name}}")
+	} else {
+		r.payload = string(parm)
+	}
+	// Send the server information back to the test framework
+	ts.control.incmg <- r
+	// Read the value that needs to be returned from the channel
+	d := <-ts.control.replyData
+	switch r := d.repl.(type) {
+		case *{{.Rtrn}}:
+			return r, nil
+		default:
+			return nil, errors.New("Mismatched type in call to {{.Name}}")
+	}
+	return &{{.Rtrn}}{},nil
+}
+{{end}}
+{{end}}
+
diff --git a/tests/afrouter/templates/serverInit.go b/tests/afrouter/templates/serverInit.go
new file mode 100644
index 0000000..e97e6ff
--- /dev/null
+++ b/tests/afrouter/templates/serverInit.go
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+var servers map[string]*serverCtl
+
+func serverInit() error {
+	servers = make(map[string]*serverCtl)
+	{{range .}}
+	if err := {{.Name}}ListenAndServe(); err != nil {
+		return err
+	}
+	{{end}}
+	return nil
+}
+
+
