Make now runs lint and any unit tests.

Also update vendored voltha-go to add new api updates

Change-Id: I08e11ae043b1db46fed4cc64fddc890a6729dedf
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/coreIf/logical_device_agent_if.go b/vendor/github.com/opencord/voltha-go/rw_core/coreIf/logical_device_agent_if.go
index 8394fac..c2614b2 100644
--- a/vendor/github.com/opencord/voltha-go/rw_core/coreIf/logical_device_agent_if.go
+++ b/vendor/github.com/opencord/voltha-go/rw_core/coreIf/logical_device_agent_if.go
@@ -20,9 +20,9 @@
 package coreIf
 
 import (
-	"github.com/opencord/voltha-protos/go/voltha"
 	"github.com/opencord/voltha-go/rw_core/graph"
 	"github.com/opencord/voltha-go/rw_core/utils"
+	"github.com/opencord/voltha-protos/go/voltha"
 )
 
 // LogicalAgent represents a generic agent
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/flow_decomposition/flow_decomposer.go b/vendor/github.com/opencord/voltha-go/rw_core/flow_decomposition/flow_decomposer.go
index ec2904f..41fdc4a 100644
--- a/vendor/github.com/opencord/voltha-go/rw_core/flow_decomposition/flow_decomposer.go
+++ b/vendor/github.com/opencord/voltha-go/rw_core/flow_decomposition/flow_decomposer.go
@@ -22,11 +22,11 @@
 	"fmt"
 	"github.com/gogo/protobuf/proto"
 	"github.com/opencord/voltha-go/common/log"
-	ofp "github.com/opencord/voltha-protos/go/openflow_13"
-	"github.com/opencord/voltha-protos/go/voltha"
 	"github.com/opencord/voltha-go/rw_core/coreIf"
 	"github.com/opencord/voltha-go/rw_core/graph"
 	fu "github.com/opencord/voltha-go/rw_core/utils"
+	ofp "github.com/opencord/voltha-protos/go/openflow_13"
+	"github.com/opencord/voltha-protos/go/voltha"
 	"math/big"
 )
 
@@ -463,6 +463,18 @@
 	return 0
 }
 
+func GetTunnelId(flow *ofp.OfpFlowStats) uint64 {
+	if flow == nil {
+		return 0
+	}
+	for _, field := range GetOfbFields(flow) {
+		if field.Type == TUNNEL_ID {
+			return field.GetTunnelId()
+		}
+	}
+	return 0
+}
+
 //GetMetaData - legacy get method (only want lower 32 bits)
 func GetMetaData(flow *ofp.OfpFlowStats) uint32 {
 	if flow == nil {
@@ -518,6 +530,18 @@
 	return (md >> 32) & 0xffffffff
 }
 
+// Extract the child device port from a flow that contains the parent device peer port.  Typically the UNI port of an
+// ONU child device.  Per TST agreement this will be the lower 32 bits of tunnel id reserving upper 32 bits for later
+// use
+func GetChildPortFromTunnelId(flow *ofp.OfpFlowStats) uint32 {
+	tid := GetTunnelId(flow)
+	if tid == 0 {
+		return 0
+	}
+	// Per TST agreement we are keeping any child port id (uni port id) in the lower 32 bits
+	return uint32(tid & 0xffffffff)
+}
+
 func HasNextTable(flow *ofp.OfpFlowStats) bool {
 	if flow == nil {
 		return false
@@ -751,9 +775,10 @@
 }
 
 //DecomposeRules decomposes per-device flows and flow-groups from the flows and groups defined on a logical device
-func (fd *FlowDecomposer) DecomposeRules(agent coreIf.LogicalDeviceAgent, flows ofp.Flows, groups ofp.FlowGroups) *fu.DeviceRules {
+func (fd *FlowDecomposer) DecomposeRules(agent coreIf.LogicalDeviceAgent, flows ofp.Flows, groups ofp.FlowGroups, includeDefaultFlows bool) *fu.DeviceRules {
 	rules := agent.GetAllDefaultRules()
 	deviceRules := rules.Copy()
+	devicesToUpdate := make(map[string]string)
 
 	groupMap := make(map[uint32]*ofp.OfpGroupEntry)
 	for _, groupEntry := range groups.Items {
@@ -766,9 +791,15 @@
 		for deviceId, flowAndGroups := range decomposedRules.Rules {
 			deviceRules.CreateEntryIfNotExist(deviceId)
 			deviceRules.Rules[deviceId].AddFrom(flowAndGroups)
+			devicesToUpdate[deviceId] = deviceId
 		}
 	}
-	return deviceRules
+	if includeDefaultFlows {
+		return deviceRules
+	}
+	updatedDeviceRules := deviceRules.FilterRules(devicesToUpdate)
+
+	return updatedDeviceRules
 }
 
 // Handles special case of any controller-bound flow for a parent device
@@ -804,6 +835,7 @@
 			}
 		}
 	}
+
 	return newDeviceRules
 }
 
@@ -840,6 +872,7 @@
 				MatchFields: []*ofp.OfpOxmOfbField{
 					InPort(egressHop.Ingress),
 					VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | inputPort),
+					TunnelId(uint64(inputPort)),
 				},
 				Actions: []*ofp.OfpAction{
 					PushVlan(0x8100),
@@ -859,6 +892,7 @@
 					VlanVid(uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000),
 					VlanPcp(0),
 					Metadata_ofp(uint64(inputPort)),
+					TunnelId(uint64(inputPort)),
 				},
 				Actions: []*ofp.OfpAction{
 					PopVlan(),
@@ -869,6 +903,7 @@
 		}
 	}
 	deviceRules.AddFlowsAndGroup(egressHop.DeviceID, fg)
+
 	return deviceRules
 }
 
@@ -895,6 +930,7 @@
 			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
 			MatchFields: []*ofp.OfpOxmOfbField{
 				InPort(ingressHop.Ingress),
+				TunnelId(uint64(inPortNo)),
 			},
 			Actions: GetActions(flow),
 		}
@@ -939,6 +975,7 @@
 				KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
 				MatchFields: []*ofp.OfpOxmOfbField{
 					InPort(egressHop.Ingress), //egress_hop.ingress_port.port_no
+					TunnelId(uint64(inPortNo)),
 				},
 				Actions: []*ofp.OfpAction{
 					Output(egressHop.Egress),
@@ -958,6 +995,7 @@
 				KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
 				MatchFields: []*ofp.OfpOxmOfbField{
 					InPort(egressHop.Ingress),
+					TunnelId(uint64(inPortNo)),
 				},
 			}
 			// Augment the matchfields with the ofpfields from the flow
@@ -1020,6 +1058,7 @@
 			MatchFields: []*ofp.OfpOxmOfbField{
 				InPort(ingressHop.Ingress),
 				Metadata_ofp(innerTag),
+				TunnelId(uint64(portNumber)),
 			},
 			Actions: GetActions(flow),
 		}
@@ -1039,6 +1078,7 @@
 			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
 			MatchFields: []*ofp.OfpOxmOfbField{
 				InPort(ingressHop.Ingress),
+				TunnelId(uint64(inPortNo)),
 			},
 			Actions: GetActions(flow),
 		}
@@ -1052,6 +1092,7 @@
 		fg.AddFlow(MkFlowStat(fa))
 		deviceRules.AddFlowsAndGroup(ingressHop.DeviceID, fg)
 	}
+
 	return deviceRules
 }
 
@@ -1080,6 +1121,7 @@
 			KV: fu.OfpFlowModArgs{"priority": uint64(flow.Priority), "cookie": flow.Cookie},
 			MatchFields: []*ofp.OfpOxmOfbField{
 				InPort(ingressHop.Ingress),
+				TunnelId(uint64(inPortNo)),
 			},
 			Actions: []*ofp.OfpAction{
 				Output(ingressHop.Egress),
@@ -1230,10 +1272,9 @@
 
 	inPortNo := GetInPort(flow)
 	outPortNo := GetOutPort(flow)
-
 	deviceRules := fu.NewDeviceRules()
-
 	route := agent.GetRoute(inPortNo, outPortNo)
+
 	switch len(route) {
 	case 0:
 		log.Errorw("no-route", log.Fields{"inPortNo": inPortNo, "outPortNo": outPortNo, "comment": "deleting-flow"})
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/graph/device_graph.go b/vendor/github.com/opencord/voltha-go/rw_core/graph/device_graph.go
index 376df16..5583023 100644
--- a/vendor/github.com/opencord/voltha-go/rw_core/graph/device_graph.go
+++ b/vendor/github.com/opencord/voltha-go/rw_core/graph/device_graph.go
@@ -139,7 +139,7 @@
 	// Build the graph
 	var device *voltha.Device
 	for _, logicalPort := range dg.logicalPorts {
-		device, _ = dg.getDevice(logicalPort.DeviceId)
+		device, _ = dg.getDevice(logicalPort.DeviceId, false)
 		dg.GGraph = dg.addDevice(device, dg.GGraph, &dg.devicesAdded, &dg.portsAdded, dg.boundaryPorts)
 	}
 
@@ -148,6 +148,7 @@
 
 // AddPort adds a port to the graph.  If the graph is empty it will just invoke ComputeRoutes function
 func (dg *DeviceGraph) AddPort(lp *voltha.LogicalPort) {
+	log.Debugw("Addport", log.Fields{"logicalPort": lp})
 	//  If the graph does not exist invoke ComputeRoutes.
 	if len(dg.boundaryPorts) == 0 {
 		dg.ComputeRoutes([]*voltha.LogicalPort{lp})
@@ -161,12 +162,14 @@
 
 	//	If the port is already part of the boundary ports, do nothing
 	if dg.portExist(portId) {
-		fmt.Println("port exists")
 		return
 	}
+	// Add the port to the set of boundary ports
+	dg.boundaryPorts[portId] = lp.OfpPort.PortNo
+
 	// Add the device where this port is located to the device graph. If the device is already added then
 	// only the missing port will be added
-	device, _ := dg.getDevice(lp.DeviceId)
+	device, _ := dg.getDevice(lp.DeviceId, false)
 	dg.GGraph = dg.addDevice(device, dg.GGraph, &dg.devicesAdded, &dg.portsAdded, dg.boundaryPorts)
 
 	if lp.RootPort {
@@ -184,6 +187,7 @@
 }
 
 func (dg *DeviceGraph) Print() error {
+	log.Debugw("Print", log.Fields{"graph": dg.logicalDeviceId, "boundaryPorts": dg.boundaryPorts})
 	if level, err := log.GetPackageLogLevel(); err == nil && level == log.DebugLevel {
 		output := ""
 		routeNumber := 1
@@ -197,7 +201,11 @@
 			output += fmt.Sprintf("%d:{%s=>%s}   ", routeNumber, key, fmt.Sprintf("[%s]", val))
 			routeNumber += 1
 		}
-		log.Debugw("graph_routes", log.Fields{"lDeviceId": dg.logicalDeviceId, "Routes": output})
+		if len(dg.Routes) == 0 {
+			log.Debugw("no-routes-found", log.Fields{"lDeviceId": dg.logicalDeviceId, "Graph": dg.GGraph.String()})
+		} else {
+			log.Debugw("graph_routes", log.Fields{"lDeviceId": dg.logicalDeviceId, "Routes": output})
+		}
 	}
 	return nil
 }
@@ -205,14 +213,16 @@
 //getDevice returns the device either from the local cache (default) or from the model.
 //TODO: Set a cache timeout such that we do not use invalid data.  The full device lifecycle should also
 //be taken in consideration
-func (dg *DeviceGraph) getDevice(id string) (*voltha.Device, error) {
-	dg.cachedDevicesLock.RLock()
-	if d, exist := dg.cachedDevices[id]; exist {
+func (dg *DeviceGraph) getDevice(id string, useCache bool) (*voltha.Device, error) {
+	if useCache {
+		dg.cachedDevicesLock.RLock()
+		if d, exist := dg.cachedDevices[id]; exist {
+			dg.cachedDevicesLock.RUnlock()
+			//log.Debugw("getDevice - returned from cache", log.Fields{"deviceId": id})
+			return d, nil
+		}
 		dg.cachedDevicesLock.RUnlock()
-		//log.Debugw("getDevice - returned from cache", log.Fields{"deviceId": id})
-		return d, nil
 	}
-	dg.cachedDevicesLock.RUnlock()
 	//	Not cached
 	if d, err := dg.getDeviceFromModel(id); err != nil {
 		log.Errorw("device-not-found", log.Fields{"deviceId": id, "error": err})
@@ -251,13 +261,13 @@
 		}
 		for _, peer := range port.Peers {
 			if _, exist := (*devicesAdded)[peer.DeviceId]; !exist {
-				d, _ := dg.getDevice(peer.DeviceId)
+				d, _ := dg.getDevice(peer.DeviceId, true)
 				g = dg.addDevice(d, g, devicesAdded, portsAdded, boundaryPorts)
-			} else {
-				peerPortId = concatDeviceIdPortId(peer.DeviceId, peer.PortNo)
-				g.AddEdge(goraph.StringID(portId), goraph.StringID(peerPortId), 1)
-				g.AddEdge(goraph.StringID(peerPortId), goraph.StringID(portId), 1)
 			}
+			peerPortId = concatDeviceIdPortId(peer.DeviceId, peer.PortNo)
+			g.AddEdge(goraph.StringID(portId), goraph.StringID(peerPortId), 1)
+			g.AddEdge(goraph.StringID(peerPortId), goraph.StringID(portId), 1)
+
 		}
 	}
 	return g
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/utils/core_utils.go b/vendor/github.com/opencord/voltha-go/rw_core/utils/core_utils.go
index 1e1ed9f..cf77d59 100644
--- a/vendor/github.com/opencord/voltha-go/rw_core/utils/core_utils.go
+++ b/vendor/github.com/opencord/voltha-go/rw_core/utils/core_utils.go
@@ -15,6 +15,13 @@
  */
 package utils
 
+import (
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+	"reflect"
+	"time"
+)
+
 type DeviceID struct {
 	Id string
 }
@@ -22,3 +29,61 @@
 type LogicalDeviceID struct {
 	Id string
 }
+
+//WaitForNilOrErrorResponses waits on a variadic number of channels for either a nil response or an error
+//response. If an error is received from a given channel then the returned error array will contain that error.
+//The error will be at the index corresponding to the order in which the channel appear in the parameter list.
+//If no errors is found then nil is returned.  This method also takes in a timeout in milliseconds. If a
+//timeout is obtained then this function will stop waiting for the remaining responses and abort.
+func WaitForNilOrErrorResponses(timeout int64, chnls ...chan interface{}) []error {
+	// Create a timeout channel
+	tChnl := make(chan *interface{})
+	go func() {
+		time.Sleep(time.Duration(timeout) * time.Millisecond)
+		tChnl <- nil
+	}()
+
+	errorsReceived := false
+	errors := make([]error, len(chnls))
+	cases := make([]reflect.SelectCase, len(chnls)+1)
+	for i, ch := range chnls {
+		cases[i] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)}
+	}
+	// Add the timeout channel
+	cases[len(chnls)] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(tChnl)}
+
+	resultsReceived := make([]bool, len(errors)+1)
+	remaining := len(cases) - 1
+	for remaining > 0 {
+		index, value, ok := reflect.Select(cases)
+		if !ok { // closed channel
+			//Set the channel at that index to nil to disable this case, hence preventing it from interfering with other cases.
+			cases[index].Chan = reflect.ValueOf(nil)
+			errors[index] = status.Errorf(codes.Internal, "channel closed")
+			errorsReceived = true
+		} else if index == len(chnls) { // Timeout has occurred
+			for k := range errors {
+				if !resultsReceived[k] {
+					errors[k] = status.Errorf(codes.Aborted, "timeout")
+				}
+			}
+			errorsReceived = true
+			break
+		} else if value.IsNil() { // Nil means a good response
+			//do nothing
+		} else if err, ok := value.Interface().(error); ok { // error returned
+			errors[index] = err
+			errorsReceived = true
+		} else { // unknown value
+			errors[index] = status.Errorf(codes.Internal, "%s", value)
+			errorsReceived = true
+		}
+		resultsReceived[index] = true
+		remaining -= 1
+	}
+
+	if errorsReceived {
+		return errors
+	}
+	return nil
+}
diff --git a/vendor/github.com/opencord/voltha-go/rw_core/utils/flow_utils.go b/vendor/github.com/opencord/voltha-go/rw_core/utils/flow_utils.go
index 10be81a..0c485bb 100644
--- a/vendor/github.com/opencord/voltha-go/rw_core/utils/flow_utils.go
+++ b/vendor/github.com/opencord/voltha-go/rw_core/utils/flow_utils.go
@@ -172,7 +172,9 @@
 func (dr *DeviceRules) Copy() *DeviceRules {
 	copyDR := NewDeviceRules()
 	for key, val := range dr.Rules {
-		copyDR.Rules[key] = val.Copy()
+		if val != nil {
+			copyDR.Rules[key] = val.Copy()
+		}
 	}
 	return copyDR
 }
@@ -183,6 +185,16 @@
 	}
 }
 
+func (dr *DeviceRules) FilterRules(deviceIds map[string]string) *DeviceRules {
+	filteredDR := NewDeviceRules()
+	for key, val := range dr.Rules {
+		if _, exist := deviceIds[key]; exist {
+			filteredDR.Rules[key] = val.Copy()
+		}
+	}
+	return filteredDR
+}
+
 func (dr *DeviceRules) AddFlow(deviceId string, flow *ofp.OfpFlowStats) {
 	if _, exist := dr.Rules[deviceId]; !exist {
 		dr.Rules[deviceId] = NewFlowsAndGroups()