[VOL-2235] Mocks and interfaces for rw-core

This update consists of mocks that are used by the rw-core
during unit testing.  It also includes interfaces used for unit
tests.

Change-Id: I20ca1455c358113c3aa897acc6355e0ddbc614b7
diff --git a/vendor/github.com/prometheus/procfs/net_unix.go b/vendor/github.com/prometheus/procfs/net_unix.go
new file mode 100644
index 0000000..240340a
--- /dev/null
+++ b/vendor/github.com/prometheus/procfs/net_unix.go
@@ -0,0 +1,275 @@
+// Copyright 2018 The Prometheus Authors
+// 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 procfs
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"strconv"
+	"strings"
+)
+
+// For the proc file format details,
+// see https://elixir.bootlin.com/linux/v4.17/source/net/unix/af_unix.c#L2815
+// and https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/net.h#L48.
+
+const (
+	netUnixKernelPtrIdx = iota
+	netUnixRefCountIdx
+	_
+	netUnixFlagsIdx
+	netUnixTypeIdx
+	netUnixStateIdx
+	netUnixInodeIdx
+
+	// Inode and Path are optional.
+	netUnixStaticFieldsCnt = 6
+)
+
+const (
+	netUnixTypeStream    = 1
+	netUnixTypeDgram     = 2
+	netUnixTypeSeqpacket = 5
+
+	netUnixFlagListen = 1 << 16
+
+	netUnixStateUnconnected  = 1
+	netUnixStateConnecting   = 2
+	netUnixStateConnected    = 3
+	netUnixStateDisconnected = 4
+)
+
+var errInvalidKernelPtrFmt = errors.New("Invalid Num(the kernel table slot number) format")
+
+// NetUnixType is the type of the type field.
+type NetUnixType uint64
+
+// NetUnixFlags is the type of the flags field.
+type NetUnixFlags uint64
+
+// NetUnixState is the type of the state field.
+type NetUnixState uint64
+
+// NetUnixLine represents a line of /proc/net/unix.
+type NetUnixLine struct {
+	KernelPtr string
+	RefCount  uint64
+	Protocol  uint64
+	Flags     NetUnixFlags
+	Type      NetUnixType
+	State     NetUnixState
+	Inode     uint64
+	Path      string
+}
+
+// NetUnix holds the data read from /proc/net/unix.
+type NetUnix struct {
+	Rows []*NetUnixLine
+}
+
+// NewNetUnix returns data read from /proc/net/unix.
+func NewNetUnix() (*NetUnix, error) {
+	fs, err := NewFS(DefaultMountPoint)
+	if err != nil {
+		return nil, err
+	}
+
+	return fs.NewNetUnix()
+}
+
+// NewNetUnix returns data read from /proc/net/unix.
+func (fs FS) NewNetUnix() (*NetUnix, error) {
+	return NewNetUnixByPath(fs.proc.Path("net/unix"))
+}
+
+// NewNetUnixByPath returns data read from /proc/net/unix by file path.
+// It might returns an error with partial parsed data, if an error occur after some data parsed.
+func NewNetUnixByPath(path string) (*NetUnix, error) {
+	f, err := os.Open(path)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	return NewNetUnixByReader(f)
+}
+
+// NewNetUnixByReader returns data read from /proc/net/unix by a reader.
+// It might returns an error with partial parsed data, if an error occur after some data parsed.
+func NewNetUnixByReader(reader io.Reader) (*NetUnix, error) {
+	nu := &NetUnix{
+		Rows: make([]*NetUnixLine, 0, 32),
+	}
+	scanner := bufio.NewScanner(reader)
+	// Omit the header line.
+	scanner.Scan()
+	header := scanner.Text()
+	// From the man page of proc(5), it does not contain an Inode field,
+	// but in actually it exists.
+	// This code works for both cases.
+	hasInode := strings.Contains(header, "Inode")
+
+	minFieldsCnt := netUnixStaticFieldsCnt
+	if hasInode {
+		minFieldsCnt++
+	}
+	for scanner.Scan() {
+		line := scanner.Text()
+		item, err := nu.parseLine(line, hasInode, minFieldsCnt)
+		if err != nil {
+			return nu, err
+		}
+		nu.Rows = append(nu.Rows, item)
+	}
+
+	return nu, scanner.Err()
+}
+
+func (u *NetUnix) parseLine(line string, hasInode bool, minFieldsCnt int) (*NetUnixLine, error) {
+	fields := strings.Fields(line)
+	fieldsLen := len(fields)
+	if fieldsLen < minFieldsCnt {
+		return nil, fmt.Errorf(
+			"Parse Unix domain failed: expect at least %d fields but got %d",
+			minFieldsCnt, fieldsLen)
+	}
+	kernelPtr, err := u.parseKernelPtr(fields[netUnixKernelPtrIdx])
+	if err != nil {
+		return nil, fmt.Errorf("Parse Unix domain num(%s) failed: %s", fields[netUnixKernelPtrIdx], err)
+	}
+	users, err := u.parseUsers(fields[netUnixRefCountIdx])
+	if err != nil {
+		return nil, fmt.Errorf("Parse Unix domain ref count(%s) failed: %s", fields[netUnixRefCountIdx], err)
+	}
+	flags, err := u.parseFlags(fields[netUnixFlagsIdx])
+	if err != nil {
+		return nil, fmt.Errorf("Parse Unix domain flags(%s) failed: %s", fields[netUnixFlagsIdx], err)
+	}
+	typ, err := u.parseType(fields[netUnixTypeIdx])
+	if err != nil {
+		return nil, fmt.Errorf("Parse Unix domain type(%s) failed: %s", fields[netUnixTypeIdx], err)
+	}
+	state, err := u.parseState(fields[netUnixStateIdx])
+	if err != nil {
+		return nil, fmt.Errorf("Parse Unix domain state(%s) failed: %s", fields[netUnixStateIdx], err)
+	}
+	var inode uint64
+	if hasInode {
+		inodeStr := fields[netUnixInodeIdx]
+		inode, err = u.parseInode(inodeStr)
+		if err != nil {
+			return nil, fmt.Errorf("Parse Unix domain inode(%s) failed: %s", inodeStr, err)
+		}
+	}
+
+	nuLine := &NetUnixLine{
+		KernelPtr: kernelPtr,
+		RefCount:  users,
+		Type:      typ,
+		Flags:     flags,
+		State:     state,
+		Inode:     inode,
+	}
+
+	// Path field is optional.
+	if fieldsLen > minFieldsCnt {
+		pathIdx := netUnixInodeIdx + 1
+		if !hasInode {
+			pathIdx--
+		}
+		nuLine.Path = fields[pathIdx]
+	}
+
+	return nuLine, nil
+}
+
+func (u NetUnix) parseKernelPtr(str string) (string, error) {
+	if !strings.HasSuffix(str, ":") {
+		return "", errInvalidKernelPtrFmt
+	}
+	return str[:len(str)-1], nil
+}
+
+func (u NetUnix) parseUsers(hexStr string) (uint64, error) {
+	return strconv.ParseUint(hexStr, 16, 32)
+}
+
+func (u NetUnix) parseProtocol(hexStr string) (uint64, error) {
+	return strconv.ParseUint(hexStr, 16, 32)
+}
+
+func (u NetUnix) parseType(hexStr string) (NetUnixType, error) {
+	typ, err := strconv.ParseUint(hexStr, 16, 16)
+	if err != nil {
+		return 0, err
+	}
+	return NetUnixType(typ), nil
+}
+
+func (u NetUnix) parseFlags(hexStr string) (NetUnixFlags, error) {
+	flags, err := strconv.ParseUint(hexStr, 16, 32)
+	if err != nil {
+		return 0, err
+	}
+	return NetUnixFlags(flags), nil
+}
+
+func (u NetUnix) parseState(hexStr string) (NetUnixState, error) {
+	st, err := strconv.ParseInt(hexStr, 16, 8)
+	if err != nil {
+		return 0, err
+	}
+	return NetUnixState(st), nil
+}
+
+func (u NetUnix) parseInode(inodeStr string) (uint64, error) {
+	return strconv.ParseUint(inodeStr, 10, 64)
+}
+
+func (t NetUnixType) String() string {
+	switch t {
+	case netUnixTypeStream:
+		return "stream"
+	case netUnixTypeDgram:
+		return "dgram"
+	case netUnixTypeSeqpacket:
+		return "seqpacket"
+	}
+	return "unknown"
+}
+
+func (f NetUnixFlags) String() string {
+	switch f {
+	case netUnixFlagListen:
+		return "listen"
+	default:
+		return "default"
+	}
+}
+
+func (s NetUnixState) String() string {
+	switch s {
+	case netUnixStateUnconnected:
+		return "unconnected"
+	case netUnixStateConnecting:
+		return "connecting"
+	case netUnixStateConnected:
+		return "connected"
+	case netUnixStateDisconnected:
+		return "disconnected"
+	}
+	return "unknown"
+}