diff --git a/tests/afrouter/tester.go b/tests/afrouter/tester.go
new file mode 100644
index 0000000..e3d883c
--- /dev/null
+++ b/tests/afrouter/tester.go
@@ -0,0 +1,591 @@
+/*
+ * 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.
+ */
+// gRPC affinity router with active/active backends
+
+package main
+
+// Command line parameters and parsing
+import (
+	"os"
+	"fmt"
+	"flag"
+	"path"
+	//"bufio"
+	"errors"
+	"os/exec"
+	"strconv"
+	"io/ioutil"
+	"encoding/json"
+	"text/template"
+	"github.com/golang/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
+	pb "github.com/golang/protobuf/protoc-gen-go/descriptor"
+)
+
+type TestConfig struct {
+	configFile *string
+	logLevel *int
+	grpcLog *bool
+	Suites []string `json:"suites"`
+}
+
+
+type Connection struct {
+	Name string `json:"name"`
+	Port string `json:"port"`
+}
+
+type ProtoFile struct {
+	ImportPath string `json:"importPath"`
+	Service string `json:"service"`
+	Package string `json:"package"`
+}
+
+type ProtoSubst struct {
+	From string `json:"from"`
+	To string `json:"to"`
+}
+
+type Environment struct {
+	Command string `json:"cmdLine"`
+	ProtoFiles []ProtoFile `json:"protoFiles"`
+	ProtoDesc string `json:"protoDesc"`
+	Clients []Connection `json:"clients"`
+	Servers []Connection `json:"servers"`
+	Imports []string `json:"imports"`
+	ProtoSubsts []ProtoSubst `json:"protoSubst"`
+}
+
+type Rpc struct {
+	Client string `json:"client"`
+	Method string `json:"method"`
+	Param string `json:"param"`
+	Expect string `json:"expect"`
+}
+
+type MetaD struct {
+	Key string `json:"key"`
+	Val string `json:"value"`
+}
+
+type Server struct {
+	Name string `json:"name"`
+	Meta []MetaD `json:"meta"`
+}
+
+type Test struct {
+	Name string `json:"name"`
+	Send Rpc `json:"send"`
+	Servers []Server `json:"servers"`
+}
+
+type TestSuite struct {
+	Env Environment `json:"environment"`
+	Tests []Test `json:"tests"`
+}
+
+type ProtoImport struct {
+	Service string
+	Short string
+	Package string
+}
+
+type SendItem struct {
+	Client string
+	Method string
+	Param string
+	ParamType string
+	Expect string
+	ExpectType string
+}
+
+type TestCase struct {
+	Name string
+	Send SendItem
+	Srvr []Server
+}
+
+type TestList struct {
+	ProtoImports []ProtoImport
+	Imports []string
+	Tests []TestCase
+}
+
+type ClientConfig struct {
+	Ct int
+	Name string
+	Port string
+	Imports []string
+	Methods map[string]*mthd
+	ProtoImports []ProtoImport
+}
+
+type ServerConfig struct {
+	Ct int
+	Name string
+	Port string
+	Imports []string
+	Methods map[string]*mthd
+	ProtoImports []ProtoImport
+}
+
+type mthd struct {
+	Pkg string
+	Svc string
+	Name string
+	Param string
+	Rtrn string
+	Ss bool // Server streaming 
+	Cs bool // Clieent streaming 
+}
+
+
+func parseCmd() (*TestConfig, error) {
+	config := &TestConfig{}
+	cmdParse := flag.NewFlagSet(path.Base(os.Args[0]), flag.ContinueOnError);
+	config.configFile = cmdParse.String("config", "suites.json", "The configuration file for the affinity router tester")
+	config.logLevel = cmdParse.Int("logLevel", 0, "The log level for the affinity router tester")
+	config.grpcLog = cmdParse.Bool("grpclog", false, "Enable GRPC logging")
+
+	err := cmdParse.Parse(os.Args[1:]);
+	if err != nil {
+		//return err
+		return nil, errors.New("Error parsing the command line");
+	}
+	return config, nil
+}
+
+func (conf * TestConfig) loadConfig() error {
+
+	configF, err := os.Open(*conf.configFile);
+	log.Info("Loading configuration from: ", *conf.configFile)
+	if err != nil {
+		log.Error(err)
+		return err
+	}
+
+	defer configF.Close()
+
+	if configBytes, err := ioutil.ReadAll(configF); err != nil {
+		log.Error(err)
+		return err
+	} else if err := json.Unmarshal(configBytes, conf); err != nil {
+		log.Error(err)
+		return err
+	}
+
+	return nil
+}
+
+func (suite * TestSuite) loadSuite(fileN string)  error {
+	suiteF, err := os.Open(fileN);
+	log.Info("Loading test suite from: ", fileN)
+	if err != nil {
+		log.Error(err)
+		return err
+	}
+
+	defer suiteF.Close()
+
+	if suiteBytes, err := ioutil.ReadAll(suiteF); err != nil {
+		log.Error(err)
+		return err
+	} else if err := json.Unmarshal(suiteBytes, suite); err != nil {
+		log.Error(err)
+		return err
+	}
+
+	return nil
+}
+
+func loadProtoMap(fileName string, pkg string, svc string, substs []ProtoSubst) (map[string]*mthd, error) {
+	var mthds map[string]*mthd = make(map[string]*mthd)
+	var rtrn_err bool
+
+	// Load the protobuf descriptor file
+	protoDescriptor := &pb.FileDescriptorSet{}
+	fb, err := ioutil.ReadFile(fileName);
+	if err != nil {
+		log.Errorf("Could not open proto file '%s'",fileName)
+		rtrn_err = true
+	}
+	err = proto.Unmarshal(fb, protoDescriptor)
+	if err != nil {
+		log.Errorf("Could not unmarshal %s, %v", "proto.pb", err)
+		rtrn_err = true
+	}
+
+	var substM  map[string]string = make(map[string]string)
+	// Create a substitution map
+	log.Debugf("Creating import map")
+	for _,v := range substs {
+		log.Debugf("Mapping from %s to %s", v.From, v.To)
+		substM[v.From] = v.To
+	}
+
+
+	// Build the a map containing the method as the key
+	// and the paramter and return types as the fields
+	for _,f := range protoDescriptor.File {
+		if *f.Package == pkg {
+			for _, s:= range f.Service {
+				if *s.Name == svc {
+					log.Debugf("Loading package data '%s' for service '%s'", *f.Package, *s.Name)
+					// Now create a map keyed by method name with the value being the
+					// field number of the route selector.
+					//var ok bool
+					for _,m := range s.Method {
+						// Find the input type in the messages and extract the
+						// field number and save it for future reference.
+						log.Debugf("Processing method (%s(%s) (%s){}",*m.Name, (*m.InputType)[1:], (*m.OutputType)[1:])
+						mthds[*m.Name] = &mthd{Pkg:pkg, Svc:svc, Name:*m.Name, Param:(*m.InputType)[1:],
+												Rtrn:(*m.OutputType)[1:]}
+						if m.ClientStreaming != nil && *m.ClientStreaming == true {
+							log.Debugf("Method %s is a client streaming method", *m.Name)
+							mthds[*m.Name].Cs = true
+						}
+						if m.ServerStreaming != nil && *m.ServerStreaming == true {
+							log.Debugf("Method %s is a server streaming method", *m.Name)
+							mthds[*m.Name].Ss = true
+						}
+						// Perform the required substitutions
+						if _,ok := substM[mthds[*m.Name].Param]; ok == true {
+							mthds[*m.Name].Param = substM[mthds[*m.Name].Param]
+						}
+						if _,ok := substM[mthds[*m.Name].Rtrn]; ok == true {
+							mthds[*m.Name].Rtrn = substM[mthds[*m.Name].Rtrn]
+						}
+					}
+				}
+			}
+		}
+	}
+	if rtrn_err {
+		return nil,errors.New(fmt.Sprintf("Failed to load protobuf descriptor file '%s'",fileName))
+	}
+	return mthds, nil
+}
+
+// Server source code generation
+func generateServers(conf *TestConfig, suiteDir string, ts * TestSuite,
+						t *template.Template) error {
+	var servers []ServerConfig
+
+	for k,v := range ts.Env.Servers {
+		log.Infof("Generating the code for server[%d]: %s", k, v.Name)
+		sc := &ServerConfig{Name:v.Name, Port:v.Port, Ct:k, Imports:ts.Env.Imports}
+		for k1,v1 := range ts.Env.ProtoFiles {
+			imp := &ProtoImport{Short:"pb"+strconv.Itoa(k1),
+								Package:v1.ImportPath+v1.Package,
+								Service:v1.Service}
+			imp = &ProtoImport{Short:v1.Package,
+								Package:v1.ImportPath+v1.Package,
+								Service:v1.Service}
+			sc.ProtoImports = append(sc.ProtoImports, *imp)
+			// Compile the template from the file
+			log.Debugf("Proto substs: %v", ts.Env.ProtoSubsts)
+			if mthds, err := loadProtoMap(ts.Env.ProtoDesc, v1.Package,
+											v1.Service, ts.Env.ProtoSubsts); err != nil {
+				log.Errorf("Unable to process proto descriptor file %s for package: %s, service: %s",
+						ts.Env.ProtoDesc, v1.Package, v1.Service)
+				return err
+			} else {
+				//Generate all the function calls required by the 
+				sc.Methods = mthds
+			}
+		}
+		log.Debugf("Server: %v", *sc)
+		// Save this server for the next steop
+		servers = append(servers, *sc)
+		// Open an output file to put the output in.
+		if f,err := os.Create(suiteDir+"/"+v.Name+".go"); err == nil {
+			defer f.Close()
+			//if err := t.ExecuteTemplate(os.Stdout, "server.go", *sc); err != nil {}
+			if err := t.ExecuteTemplate(f, "server.go", *sc); err != nil {
+				log.Errorf("Unable to execute template for server[%d]: %s: %v", k, v.Name, err)
+				return err
+			}
+		}
+	}
+	// Generate the server initialization code
+	if f,err := os.Create(suiteDir+"/serverInit.go"); err == nil {
+		defer f.Close()
+		//if err := t.ExecuteTemplate(os.Stdout, "server.go", *sc); err != nil {}
+		if err := t.ExecuteTemplate(f, "serverInit.go", servers); err != nil {
+			log.Errorf("Unable to execute template for serverInit.go: %v", err)
+			return err
+		}
+	}
+
+	return nil
+}
+
+func generateClients(conf *TestConfig, suiteDir string, ts * TestSuite,
+						t *template.Template) error {
+	var clients []ClientConfig
+	for k,v := range ts.Env.Clients {
+		log.Infof("Generating the code for client[%d]: %s", k, v.Name)
+		cc := &ClientConfig{Name:v.Name, Port:v.Port, Ct:k, Imports:ts.Env.Imports}
+		// TODO: This loop makes no sense, the only proto map that would remain
+		// after this loop is the last one loaded. Fix this to load the map
+		// for all services not just the last one.
+		for _,v1 := range ts.Env.ProtoFiles {
+			imp := &ProtoImport{Short:v1.Package,
+								Package:v1.ImportPath+v1.Package,
+								Service:v1.Service}
+			cc.ProtoImports = append(cc.ProtoImports, *imp)
+			// Compile the template from the file
+			log.Debugf("Proto substs: %v", ts.Env.ProtoSubsts)
+			if mthds, err := loadProtoMap(ts.Env.ProtoDesc, v1.Package,
+											v1.Service, ts.Env.ProtoSubsts); err != nil {
+				log.Errorf("Unable to process proto descriptor file %s for package: %s, service: %s",
+						ts.Env.ProtoDesc, v1.Package, v1.Service)
+				return err
+			} else {
+				//Generate all the function calls required by the 
+				cc.Methods = mthds
+			}
+		}
+		clients = append(clients, *cc)
+		if f,err := os.Create(suiteDir+"/"+v.Name+".go"); err == nil {
+			_=f
+			defer f.Close()
+			if err := t.ExecuteTemplate(f, "client.go", cc); err != nil {
+				log.Errorf("Unable to execute template for client.go: %v", err)
+				return err
+			}
+		} else {
+			log.Errorf("Couldn't create file %s : %v", suiteDir+"/client.go", err)
+			return err
+		}
+	}
+	if f,err := os.Create(suiteDir+"/clientInit.go"); err == nil {
+		defer f.Close()
+		//if err := t.ExecuteTemplate(os.Stdout, "server.go", *sc); err != nil {}
+		if err := t.ExecuteTemplate(f, "clientInit.go", clients); err != nil {
+			log.Errorf("Unable to execute template for clientInit.go: %v", err)
+			return err
+		}
+	}
+	return nil
+}
+
+func serverExists(srvr string, ts * TestSuite) bool {
+	for _,v := range ts.Env.Servers {
+		if v.Name == srvr {
+			return true
+		}
+	}
+	return false
+}
+func generateTestCases(conf *TestConfig, suiteDir string, ts * TestSuite,
+						t *template.Template) error {
+	var mthdMap map[string]*mthd
+	// Generate the test cases
+	log.Info("Generating the test cases: runTests.go")
+	tc := &TestList{Imports:ts.Env.Imports}
+
+	// Load the proto descriptor file
+	// TODO: This loop makes no sense, the only proto map that would remain
+	// after this loop is the last one loaded. Fix this to load the map
+	// for all services not just the last one.
+	for _,v := range ts.Env.ProtoFiles {
+		imp := &ProtoImport{Short:v.Package,
+							Package:v.ImportPath+v.Package,
+							Service:v.Service}
+		tc.ProtoImports = append(tc.ProtoImports, *imp)
+		// Compile the template from the file
+		log.Debugf("Proto substs: %v", ts.Env.ProtoSubsts)
+		if mthds, err := loadProtoMap(ts.Env.ProtoDesc, v.Package,
+										v.Service, ts.Env.ProtoSubsts); err != nil {
+			log.Errorf("Unable to process proto descriptor file %s for package: %s, service: %s",
+					ts.Env.ProtoDesc, v.Package, v.Service)
+			return err
+		} else {
+			mthdMap = mthds
+		}
+	}
+	// Create the test data structure for the template
+	for _,v := range ts.Tests {
+		var test TestCase
+
+		test.Name = v.Name
+		test.Send.Client = v.Send.Client
+		test.Send.Method = v.Send.Method
+		test.Send.Param = v.Send.Param
+		test.Send.ParamType = mthdMap[test.Send.Method].Param
+		test.Send.Expect = v.Send.Expect
+		test.Send.ExpectType = mthdMap[test.Send.Method].Rtrn
+		for _,v1 := range v.Servers {
+			var srvr Server
+			if serverExists(v1.Name, ts) == false {
+				log.Errorf("Server '%s' is not defined!!", v1.Name)
+				return errors.New(fmt.Sprintf("Failed to build test case %s", v.Name))
+			}
+			srvr.Name = v1.Name
+			srvr.Meta = v1.Meta
+			test.Srvr = append(test.Srvr, srvr)
+		}
+		tc.Tests = append(tc.Tests, test)
+	}
+	if f,err := os.Create(suiteDir+"/runTests.go"); err == nil {
+		if err := t.ExecuteTemplate(f, "runTests.go", tc); err != nil {
+				log.Errorf("Unable to execute template for runTests.go: %v", err)
+		}
+		f.Close()
+	} else {
+		log.Errorf("Couldn't create file %s : %v", suiteDir+"/runTests.go", err)
+	}
+	return nil
+}
+
+func generateTestSuites(conf *TestConfig, srcDir string, outDir string) error {
+
+	// Create a directory for the tests
+	if err := os.Mkdir(srcDir, 0777); err != nil {
+		log.Errorf("Unable to create directory 'tests':%v\n", err)
+		return err
+	}
+
+	for k,v := range conf.Suites {
+	    var suiteDir string = srcDir+"/"+v
+		log.Debugf("Suite[%d] - %s", k, v)
+		ts := &TestSuite{}
+		ts.loadSuite(v)
+		log.Debugf("Suite %s: %v", v, ts)
+		log.Info("Processing test suite %s", v)
+
+		t := template.Must(template.New("").ParseFiles("../templates/server.go",
+														"../templates/serverInit.go",
+														"../templates/client.go",
+														"../templates/clientInit.go",
+														"../templates/runTests.go",
+														"../templates/main.go"))
+		// Create a directory for he source code for this test suite
+		if err := os.Mkdir(suiteDir, 0777); err != nil {
+			log.Errorf("Unable to create directory '%s':%v\n", v, err)
+			return err
+		}
+		// Generate the server source files
+		if err := generateServers(conf, suiteDir, ts, t); err != nil {
+			log.Errorf("Unable to generate server source files: %v", err)
+			return err
+		}
+		// Generate the client source files
+		if err := generateClients(conf, suiteDir, ts, t); err != nil {
+			log.Errorf("Unable to generate client source files: %v", err)
+			return err
+		}
+		// Generate the test case source file
+		if err := generateTestCases(conf, suiteDir, ts, t); err != nil {
+			log.Errorf("Unable to generate test case source file: %v", err)
+			return err
+		}
+
+		// Finally generate the main file
+		log.Info("Generating main.go")
+		if f,err := os.Create(suiteDir+"/main.go"); err == nil {
+			if err := t.ExecuteTemplate(f, "main.go", ts.Env); err != nil {
+					log.Errorf("Unable to execute template for main.go: %v", err)
+			}
+			f.Close()
+		} else {
+			log.Errorf("Couldn't create file %s : %v", suiteDir+"/main.go", err)
+		}
+
+		log.Infof("Compiling test suite: %s in directory %s", v, suiteDir)
+		if err := os.Chdir(suiteDir); err != nil {
+			log.Errorf("Could not change to directory '%s':%v",suiteDir, err)
+		}
+		cmd := exec.Command("go", "build", "-o", outDir+"/"+v[:len(v)-5])
+		cmd.Stdin = os.Stdin
+		cmd.Stdout = os.Stdout
+		cmd.Stderr = os.Stderr
+		if err := cmd.Run(); err != nil {
+			log.Errorf("Error running the compile command:%v", err)
+		}
+		if err := os.Chdir("../../suites"); err != nil {
+			log.Errorf("Could not change to directory '%s':%v","../../suites", err)
+		}
+
+		// Now generate the test cases
+
+	}
+	return nil
+
+}
+
+func generateTestDriver(conf *TestConfig, srcDir string, outDir string) error {
+	// Generate the main test driver file
+	if err := os.Mkdir(srcDir, 0777); err != nil {
+		log.Errorf("Unable to create directory 'driver':%v\n", err)
+		return err
+	}
+	t := template.Must(template.New("").ParseFiles("../templates/runAll.go"))
+	if f,err := os.Create(srcDir+"/runAll.go"); err == nil {
+		if err := t.ExecuteTemplate(f, "runAll.go", conf.Suites); err != nil {
+				log.Errorf("Unable to execute template for main.go: %v", err)
+		}
+		f.Close()
+	} else {
+		log.Errorf("Couldn't create file %s : %v", srcDir+"/runAll.go", err)
+	}
+
+	// Compile the test driver file
+	log.Info("Compiling the test driver")
+	if err := os.Chdir("../tests/driver"); err != nil {
+		log.Errorf("Could not change to directory 'driver':%v", err)
+	}
+	cmd := exec.Command("go", "build", "-o", outDir+"/runAll")
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if err := cmd.Run(); err != nil {
+		log.Errorf("Error running the compile command:%v", err)
+	}
+	if err := os.Chdir("../../suites"); err != nil {
+		log.Errorf("Could not change to directory 'driver':%v",err)
+	}
+
+	return nil
+}
+
+
+func main() {
+
+	conf,err := parseCmd()
+	if err != nil {
+		fmt.Printf("Error: %v\n", err)
+		return
+	}
+
+	// Setup logging
+	if _, err := log.SetDefaultLogger(log.JSON, *conf.logLevel, nil); err != nil {
+		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
+	}
+
+	defer log.CleanUp()
+
+	// Parse the config file
+	if err := conf.loadConfig(); err != nil {
+		log.Error(err)
+	}
+
+	generateTestSuites(conf, "../tests", "/src/tests")
+	generateTestDriver(conf, "../tests/driver", "/src/tests")
+	return
+}
+
