Vendor TO GOlang go-sqlmock

Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/f9f7cfa0
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/f9f7cfa0
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/f9f7cfa0

Branch: refs/heads/master
Commit: f9f7cfa06217d5b3d4c1ba4bd026982b8d8fcaba
Parents: 4fd7feb
Author: Robert Butts <robert.o.bu...@gmail.com>
Authored: Mon Jul 17 21:53:50 2017 -0600
Committer: Dewayne Richardson <dewr...@apache.org>
Committed: Thu Aug 10 09:46:02 2017 -0600

----------------------------------------------------------------------
 .../vendor/gopkg.in/DATA-DOG/go-sqlmock/LICENSE |  28 +
 .../gopkg.in/DATA-DOG/go-sqlmock/README.md      | 223 +++++
 .../gopkg.in/DATA-DOG/go-sqlmock/argument.go    |  24 +
 .../DATA-DOG/go-sqlmock/argument_test.go        |  58 ++
 .../gopkg.in/DATA-DOG/go-sqlmock/driver.go      |  78 ++
 .../gopkg.in/DATA-DOG/go-sqlmock/driver_test.go | 112 +++
 .../DATA-DOG/go-sqlmock/examples/basic/basic.go |  40 +
 .../go-sqlmock/examples/basic/basic_test.go     |  58 ++
 .../DATA-DOG/go-sqlmock/examples/blog/blog.go   |  81 ++
 .../go-sqlmock/examples/blog/blog_test.go       | 102 ++
 .../DATA-DOG/go-sqlmock/examples/doc.go         |   1 +
 .../go-sqlmock/examples/orders/orders.go        | 121 +++
 .../go-sqlmock/examples/orders/orders_test.go   | 108 ++
 .../DATA-DOG/go-sqlmock/expectations.go         | 344 +++++++
 .../go-sqlmock/expectations_before_go18.go      |  52 +
 .../DATA-DOG/go-sqlmock/expectations_go18.go    |  66 ++
 .../go-sqlmock/expectations_go18_test.go        |  64 ++
 .../DATA-DOG/go-sqlmock/expectations_test.go    | 154 +++
 .../gopkg.in/DATA-DOG/go-sqlmock/result.go      |  39 +
 .../gopkg.in/DATA-DOG/go-sqlmock/result_test.go |  62 ++
 .../vendor/gopkg.in/DATA-DOG/go-sqlmock/rows.go | 144 +++
 .../gopkg.in/DATA-DOG/go-sqlmock/rows_go18.go   |  20 +
 .../DATA-DOG/go-sqlmock/rows_go18_test.go       |  92 ++
 .../gopkg.in/DATA-DOG/go-sqlmock/rows_test.go   | 265 +++++
 .../gopkg.in/DATA-DOG/go-sqlmock/sqlmock.go     | 525 ++++++++++
 .../DATA-DOG/go-sqlmock/sqlmock_go18.go         | 101 ++
 .../DATA-DOG/go-sqlmock/sqlmock_go18_test.go    | 426 ++++++++
 .../DATA-DOG/go-sqlmock/sqlmock_test.go         | 998 +++++++++++++++++++
 .../gopkg.in/DATA-DOG/go-sqlmock/statement.go   |  27 +
 .../DATA-DOG/go-sqlmock/statement_test.go       |  33 +
 .../gopkg.in/DATA-DOG/go-sqlmock/stubs_test.go  |  76 ++
 .../vendor/gopkg.in/DATA-DOG/go-sqlmock/util.go |  13 +
 .../gopkg.in/DATA-DOG/go-sqlmock/util_test.go   |  21 +
 33 files changed, 4556 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/LICENSE
----------------------------------------------------------------------
diff --git a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/LICENSE 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/LICENSE
new file mode 100644
index 0000000..7f8bedf
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/LICENSE
@@ -0,0 +1,28 @@
+The three clause BSD license (http://en.wikipedia.org/wiki/BSD_licenses)
+
+Copyright (c) 2013-2017, DATA-DOG team
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+* The name DataDog.lt may not be used to endorse or promote products
+  derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/README.md
----------------------------------------------------------------------
diff --git a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/README.md 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/README.md
new file mode 100644
index 0000000..f3d5487
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/README.md
@@ -0,0 +1,223 @@
+[![Build 
Status](https://travis-ci.org/DATA-DOG/go-sqlmock.png)](https://travis-ci.org/DATA-DOG/go-sqlmock)
+[![GoDoc](https://godoc.org/github.com/DATA-DOG/go-sqlmock?status.png)](https://godoc.org/github.com/DATA-DOG/go-sqlmock)
+[![codecov.io](https://codecov.io/github/DATA-DOG/go-sqlmock/branch/master/graph/badge.svg)](https://codecov.io/github/DATA-DOG/go-sqlmock)
+
+# Sql driver mock for Golang
+
+**sqlmock** is a mock library implementing 
[sql/driver](https://godoc.org/database/sql/driver). Which has one and only
+purpose - to simulate any **sql** driver behavior in tests, without needing a 
real database connection. It helps to
+maintain correct **TDD** workflow.
+
+- this library is now complete and stable. (you may not find new changes for 
this reason)
+- supports concurrency and multiple connections.
+- supports **go1.8** Context related feature mocking and Named sql parameters.
+- does not require any modifications to your source code.
+- the driver allows to mock any sql driver method behavior.
+- has strict by default expectation order matching.
+- has no third party dependencies.
+
+## Install
+
+    go get gopkg.in/DATA-DOG/go-sqlmock.v1
+
+## Documentation and Examples
+
+Visit [godoc](http://godoc.org/github.com/DATA-DOG/go-sqlmock) for general 
examples and public api reference.
+See **.travis.yml** for supported **go** versions.
+Different use case, is to functionally test with a real database - 
[go-txdb](https://github.com/DATA-DOG/go-txdb)
+all database related actions are isolated within a single transaction so the 
database can remain in the same state.
+
+See implementation examples:
+
+- [blog API 
server](https://github.com/DATA-DOG/go-sqlmock/tree/master/examples/blog)
+- [the same orders 
example](https://github.com/DATA-DOG/go-sqlmock/tree/master/examples/orders)
+
+### Something you may want to test
+
+``` go
+package main
+
+import "database/sql"
+
+func recordStats(db *sql.DB, userID, productID int64) (err error) {
+       tx, err := db.Begin()
+       if err != nil {
+               return
+       }
+
+       defer func() {
+               switch err {
+               case nil:
+                       err = tx.Commit()
+               default:
+                       tx.Rollback()
+               }
+       }()
+
+       if _, err = tx.Exec("UPDATE products SET views = views + 1"); err != 
nil {
+               return
+       }
+       if _, err = tx.Exec("INSERT INTO product_viewers (user_id, product_id) 
VALUES (?, ?)", userID, productID); err != nil {
+               return
+       }
+       return
+}
+
+func main() {
+       // @NOTE: the real connection is not required for tests
+       db, err := sql.Open("mysql", "root@/blog")
+       if err != nil {
+               panic(err)
+       }
+       defer db.Close()
+
+       if err = recordStats(db, 1 /*some user id*/, 5 /*some product id*/); 
err != nil {
+               panic(err)
+       }
+}
+```
+
+### Tests with sqlmock
+
+``` go
+package main
+
+import (
+       "fmt"
+       "testing"
+
+       "gopkg.in/DATA-DOG/go-sqlmock.v1"
+)
+
+// a successful case
+func TestShouldUpdateStats(t *testing.T) {
+       db, mock, err := sqlmock.New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       mock.ExpectBegin()
+       mock.ExpectExec("UPDATE 
products").WillReturnResult(sqlmock.NewResult(1, 1))
+       mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 
3).WillReturnResult(sqlmock.NewResult(1, 1))
+       mock.ExpectCommit()
+
+       // now we execute our method
+       if err = recordStats(db, 2, 3); err != nil {
+               t.Errorf("error was not expected while updating stats: %s", err)
+       }
+
+       // we make sure that all expectations were met
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}
+
+// a failing test case
+func TestShouldRollbackStatUpdatesOnFailure(t *testing.T) {
+       db, mock, err := sqlmock.New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       mock.ExpectBegin()
+       mock.ExpectExec("UPDATE 
products").WillReturnResult(sqlmock.NewResult(1, 1))
+       mock.ExpectExec("INSERT INTO product_viewers").
+               WithArgs(2, 3).
+               WillReturnError(fmt.Errorf("some error"))
+       mock.ExpectRollback()
+
+       // now we execute our method
+       if err = recordStats(db, 2, 3); err == nil {
+               t.Errorf("was expecting an error, but there was none")
+       }
+
+       // we make sure that all expectations were met
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}
+```
+
+## Matching arguments like time.Time
+
+There may be arguments which are of `struct` type and cannot be compared 
easily by value like `time.Time`. In this case
+**sqlmock** provides an 
[Argument](https://godoc.org/github.com/DATA-DOG/go-sqlmock#Argument) interface 
which
+can be used in more sophisticated matching. Here is a simple example of time 
argument matching:
+
+``` go
+type AnyTime struct{}
+
+// Match satisfies sqlmock.Argument interface
+func (a AnyTime) Match(v driver.Value) bool {
+       _, ok := v.(time.Time)
+       return ok
+}
+
+func TestAnyTimeArgument(t *testing.T) {
+       t.Parallel()
+       db, mock, err := New()
+       if err != nil {
+               t.Errorf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       mock.ExpectExec("INSERT INTO users").
+               WithArgs("john", AnyTime{}).
+               WillReturnResult(NewResult(1, 1))
+
+       _, err = db.Exec("INSERT INTO users(name, created_at) VALUES (?, ?)", 
"john", time.Now())
+       if err != nil {
+               t.Errorf("error '%s' was not expected, while inserting a row", 
err)
+       }
+
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}
+```
+
+It only asserts that argument is of `time.Time` type.
+
+## Run tests
+
+    go test -race
+
+## Change Log
+
+- **2017-02-09** - implemented support for **go1.8** features. **Rows** 
interface was changed to struct
+  but contains all methods as before and should maintain backwards 
compatibility. **ExpectedQuery.WillReturnRows** may now
+  accept multiple row sets.
+- **2016-11-02** - `db.Prepare()` was not validating expected prepare SQL
+  query. It should still be validated even if Exec or Query is not
+  executed on that prepared statement.
+- **2016-02-23** - added **sqlmock.AnyArg()** function to provide any kind
+  of argument matcher.
+- **2016-02-23** - convert expected arguments to driver.Value as natural
+  driver does, the change may affect time.Time comparison and will be
+  stricter. See [issue](https://github.com/DATA-DOG/go-sqlmock/issues/31).
+- **2015-08-27** - **v1** api change, concurrency support, all known issues 
fixed.
+- **2014-08-16** instead of **panic** during reflect type mismatch when 
comparing query arguments - now return error
+- **2014-08-14** added **sqlmock.NewErrorResult** which gives an option to 
return driver.Result with errors for
+interface methods, see [issue](https://github.com/DATA-DOG/go-sqlmock/issues/5)
+- **2014-05-29** allow to match arguments in more sophisticated ways, by 
providing an **sqlmock.Argument** interface
+- **2014-04-21** introduce **sqlmock.New()** to open a mock database 
connection for tests. This method
+calls sql.DB.Ping to ensure that connection is open, see 
[issue](https://github.com/DATA-DOG/go-sqlmock/issues/4).
+This way on Close it will surely assert if all expectations are met, even if 
database was not triggered at all.
+The old way is still available, but it is advisable to call db.Ping manually 
before asserting with db.Close.
+- **2014-02-14** RowsFromCSVString is now a part of Rows interface named as 
FromCSVString.
+It has changed to allow more ways to construct rows and to easily extend this 
API in future.
+See [issue 1](https://github.com/DATA-DOG/go-sqlmock/issues/1)
+**RowsFromCSVString** is deprecated and will be removed in future
+
+## Contributions
+
+Feel free to open a pull request. Note, if you wish to contribute an extension 
to public (exported methods or types) -
+please open an issue before, to discuss whether these changes can be accepted. 
All backward incompatible changes are
+and will be treated cautiously
+
+## License
+
+The [three clause BSD license](http://en.wikipedia.org/wiki/BSD_licenses)
+

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/argument.go
----------------------------------------------------------------------
diff --git a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/argument.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/argument.go
new file mode 100644
index 0000000..7727481
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/argument.go
@@ -0,0 +1,24 @@
+package sqlmock
+
+import "database/sql/driver"
+
+// Argument interface allows to match
+// any argument in specific way when used with
+// ExpectedQuery and ExpectedExec expectations.
+type Argument interface {
+       Match(driver.Value) bool
+}
+
+// AnyArg will return an Argument which can
+// match any kind of arguments.
+//
+// Useful for time.Time or similar kinds of arguments.
+func AnyArg() Argument {
+       return anyArgument{}
+}
+
+type anyArgument struct{}
+
+func (a anyArgument) Match(_ driver.Value) bool {
+       return true
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/argument_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/argument_test.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/argument_test.go
new file mode 100644
index 0000000..3088ed4
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/argument_test.go
@@ -0,0 +1,58 @@
+package sqlmock
+
+import (
+       "database/sql/driver"
+       "testing"
+       "time"
+)
+
+type AnyTime struct{}
+
+// Match satisfies sqlmock.Argument interface
+func (a AnyTime) Match(v driver.Value) bool {
+       _, ok := v.(time.Time)
+       return ok
+}
+
+func TestAnyTimeArgument(t *testing.T) {
+       t.Parallel()
+       db, mock, err := New()
+       if err != nil {
+               t.Errorf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       mock.ExpectExec("INSERT INTO users").
+               WithArgs("john", AnyTime{}).
+               WillReturnResult(NewResult(1, 1))
+
+       _, err = db.Exec("INSERT INTO users(name, created_at) VALUES (?, ?)", 
"john", time.Now())
+       if err != nil {
+               t.Errorf("error '%s' was not expected, while inserting a row", 
err)
+       }
+
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}
+
+func TestByteSliceArgument(t *testing.T) {
+       t.Parallel()
+       db, mock, err := New()
+       if err != nil {
+               t.Errorf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       username := []byte("user")
+       mock.ExpectExec("INSERT INTO 
users").WithArgs(username).WillReturnResult(NewResult(1, 1))
+
+       _, err = db.Exec("INSERT INTO users(username) VALUES (?)", username)
+       if err != nil {
+               t.Errorf("error '%s' was not expected, while inserting a row", 
err)
+       }
+
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/driver.go
----------------------------------------------------------------------
diff --git a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/driver.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/driver.go
new file mode 100644
index 0000000..2a480fe
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/driver.go
@@ -0,0 +1,78 @@
+package sqlmock
+
+import (
+       "database/sql"
+       "database/sql/driver"
+       "fmt"
+       "sync"
+)
+
+var pool *mockDriver
+
+func init() {
+       pool = &mockDriver{
+               conns: make(map[string]*sqlmock),
+       }
+       sql.Register("sqlmock", pool)
+}
+
+type mockDriver struct {
+       sync.Mutex
+       counter int
+       conns   map[string]*sqlmock
+}
+
+func (d *mockDriver) Open(dsn string) (driver.Conn, error) {
+       d.Lock()
+       defer d.Unlock()
+
+       c, ok := d.conns[dsn]
+       if !ok {
+               return c, fmt.Errorf("expected a connection to be available, 
but it is not")
+       }
+
+       c.opened++
+       return c, nil
+}
+
+// New creates sqlmock database connection
+// and a mock to manage expectations.
+// Pings db so that all expectations could be
+// asserted.
+func New() (*sql.DB, Sqlmock, error) {
+       pool.Lock()
+       dsn := fmt.Sprintf("sqlmock_db_%d", pool.counter)
+       pool.counter++
+
+       smock := &sqlmock{dsn: dsn, drv: pool, ordered: true}
+       pool.conns[dsn] = smock
+       pool.Unlock()
+
+       return smock.open()
+}
+
+// NewWithDSN creates sqlmock database connection
+// with a specific DSN and a mock to manage expectations.
+// Pings db so that all expectations could be asserted.
+//
+// This method is introduced because of sql abstraction
+// libraries, which do not provide a way to initialize
+// with sql.DB instance. For example GORM library.
+//
+// Note, it will error if attempted to create with an
+// already used dsn
+//
+// It is not recommended to use this method, unless you
+// really need it and there is no other way around.
+func NewWithDSN(dsn string) (*sql.DB, Sqlmock, error) {
+       pool.Lock()
+       if _, ok := pool.conns[dsn]; ok {
+               pool.Unlock()
+               return nil, nil, fmt.Errorf("cannot create a new mock database 
with the same dsn: %s", dsn)
+       }
+       smock := &sqlmock{dsn: dsn, drv: pool, ordered: true}
+       pool.conns[dsn] = smock
+       pool.Unlock()
+
+       return smock.open()
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/driver_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/driver_test.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/driver_test.go
new file mode 100644
index 0000000..1a65c1c
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/driver_test.go
@@ -0,0 +1,112 @@
+package sqlmock
+
+import (
+       "fmt"
+       "testing"
+)
+
+type void struct{}
+
+func (void) Print(...interface{}) {}
+
+func ExampleNew() {
+       db, mock, err := New()
+       if err != nil {
+               fmt.Println("expected no error, but got:", err)
+               return
+       }
+       defer db.Close()
+       // now we can expect operations performed on db
+       mock.ExpectBegin().WillReturnError(fmt.Errorf("an error will occur on 
db.Begin() call"))
+}
+
+func TestShouldOpenConnectionIssue15(t *testing.T) {
+       db, mock, err := New()
+       if err != nil {
+               t.Errorf("expected no error, but got: %s", err)
+       }
+       if len(pool.conns) != 1 {
+               t.Errorf("expected 1 connection in pool, but there is: %d", 
len(pool.conns))
+       }
+
+       smock, _ := mock.(*sqlmock)
+       if smock.opened != 1 {
+               t.Errorf("expected 1 connection on mock to be opened, but there 
is: %d", smock.opened)
+       }
+
+       // defer so the rows gets closed first
+       defer func() {
+               if smock.opened != 0 {
+                       t.Errorf("expected no connections on mock to be opened, 
but there is: %d", smock.opened)
+               }
+       }()
+
+       mock.ExpectQuery("SELECT").WillReturnRows(NewRows([]string{"one", 
"two"}).AddRow("val1", "val2"))
+       rows, err := db.Query("SELECT")
+       if err != nil {
+               t.Errorf("unexpected error: %s", err)
+       }
+       defer rows.Close()
+
+       mock.ExpectExec("UPDATE").WillReturnResult(NewResult(1, 1))
+       if _, err = db.Exec("UPDATE"); err != nil {
+               t.Errorf("unexpected error: %s", err)
+       }
+
+       // now there should be two connections open
+       if smock.opened != 2 {
+               t.Errorf("expected 2 connection on mock to be opened, but there 
is: %d", smock.opened)
+       }
+
+       mock.ExpectClose()
+       if err = db.Close(); err != nil {
+               t.Errorf("expected no error on close, but got: %s", err)
+       }
+
+       // one is still reserved for rows
+       if smock.opened != 1 {
+               t.Errorf("expected 1 connection on mock to be still reserved 
for rows, but there is: %d", smock.opened)
+       }
+}
+
+func TestTwoOpenConnectionsOnTheSameDSN(t *testing.T) {
+       db, mock, err := New()
+       if err != nil {
+               t.Errorf("expected no error, but got: %s", err)
+       }
+       db2, mock2, err := New()
+       if err != nil {
+               t.Errorf("expected no error, but got: %s", err)
+       }
+       if len(pool.conns) != 2 {
+               t.Errorf("expected 2 connection in pool, but there is: %d", 
len(pool.conns))
+       }
+
+       if db == db2 {
+               t.Errorf("expected not the same database instance, but it is 
the same")
+       }
+       if mock == mock2 {
+               t.Errorf("expected not the same mock instance, but it is the 
same")
+       }
+}
+
+func TestWrongDSN(t *testing.T) {
+       t.Parallel()
+       db, _, _ := New()
+       defer db.Close()
+       if _, err := db.Driver().Open("wrong_dsn"); err == nil {
+               t.Error("expected error on Open")
+       }
+}
+
+func TestNewDSN(t *testing.T) {
+       if _, _, err := NewWithDSN("sqlmock_db_99"); err != nil {
+               t.Errorf("expected no error on NewWithDSN, but got: %s", err)
+       }
+}
+
+func TestDuplicateNewDSN(t *testing.T) {
+       if _, _, err := NewWithDSN("sqlmock_db_1"); err == nil {
+               t.Error("expected error on NewWithDSN")
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/basic/basic.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/basic/basic.go
 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/basic/basic.go
new file mode 100644
index 0000000..0fbf98d
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/basic/basic.go
@@ -0,0 +1,40 @@
+package main
+
+import "database/sql"
+
+func recordStats(db *sql.DB, userID, productID int64) (err error) {
+       tx, err := db.Begin()
+       if err != nil {
+               return
+       }
+
+       defer func() {
+               switch err {
+               case nil:
+                       err = tx.Commit()
+               default:
+                       tx.Rollback()
+               }
+       }()
+
+       if _, err = tx.Exec("UPDATE products SET views = views + 1"); err != 
nil {
+               return
+       }
+       if _, err = tx.Exec("INSERT INTO product_viewers (user_id, product_id) 
VALUES (?, ?)", userID, productID); err != nil {
+               return
+       }
+       return
+}
+
+func main() {
+       // @NOTE: the real connection is not required for tests
+       db, err := sql.Open("mysql", "root@/blog")
+       if err != nil {
+               panic(err)
+       }
+       defer db.Close()
+
+       if err = recordStats(db, 1 /*some user id*/, 5 /*some product id*/); 
err != nil {
+               panic(err)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/basic/basic_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/basic/basic_test.go
 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/basic/basic_test.go
new file mode 100644
index 0000000..0825f90
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/basic/basic_test.go
@@ -0,0 +1,58 @@
+package main
+
+import (
+       "fmt"
+       "testing"
+
+       "github.com/DATA-DOG/go-sqlmock"
+)
+
+// a successful case
+func TestShouldUpdateStats(t *testing.T) {
+       db, mock, err := sqlmock.New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       mock.ExpectBegin()
+       mock.ExpectExec("UPDATE 
products").WillReturnResult(sqlmock.NewResult(1, 1))
+       mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 
3).WillReturnResult(sqlmock.NewResult(1, 1))
+       mock.ExpectCommit()
+
+       // now we execute our method
+       if err = recordStats(db, 2, 3); err != nil {
+               t.Errorf("error was not expected while updating stats: %s", err)
+       }
+
+       // we make sure that all expectations were met
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}
+
+// a failing test case
+func TestShouldRollbackStatUpdatesOnFailure(t *testing.T) {
+       db, mock, err := sqlmock.New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       mock.ExpectBegin()
+       mock.ExpectExec("UPDATE 
products").WillReturnResult(sqlmock.NewResult(1, 1))
+       mock.ExpectExec("INSERT INTO product_viewers").
+               WithArgs(2, 3).
+               WillReturnError(fmt.Errorf("some error"))
+       mock.ExpectRollback()
+
+       // now we execute our method
+       if err = recordStats(db, 2, 3); err == nil {
+               t.Errorf("was expecting an error, but there was none")
+       }
+
+       // we make sure that all expectations were met
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/blog/blog.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/blog/blog.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/blog/blog.go
new file mode 100644
index 0000000..c4aec06
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/blog/blog.go
@@ -0,0 +1,81 @@
+package main
+
+import (
+       "database/sql"
+       "encoding/json"
+       "net/http"
+)
+
+type api struct {
+       db *sql.DB
+}
+
+type post struct {
+       ID    int
+       Title string
+       Body  string
+}
+
+func (a *api) posts(w http.ResponseWriter, r *http.Request) {
+       rows, err := a.db.Query("SELECT id, title, body FROM posts")
+       if err != nil {
+               a.fail(w, "failed to fetch posts: "+err.Error(), 500)
+               return
+       }
+       defer rows.Close()
+
+       var posts []*post
+       for rows.Next() {
+               p := &post{}
+               if err := rows.Scan(&p.ID, &p.Title, &p.Body); err != nil {
+                       a.fail(w, "failed to scan post: "+err.Error(), 500)
+                       return
+               }
+               posts = append(posts, p)
+       }
+       if rows.Err() != nil {
+               a.fail(w, "failed to read all posts: "+rows.Err().Error(), 500)
+               return
+       }
+
+       data := struct {
+               Posts []*post
+       }{posts}
+
+       a.ok(w, data)
+}
+
+func main() {
+       // @NOTE: the real connection is not required for tests
+       db, err := sql.Open("mysql", "root@/blog")
+       if err != nil {
+               panic(err)
+       }
+       app := &api{db: db}
+       http.HandleFunc("/posts", app.posts)
+       http.ListenAndServe(":8080", nil)
+}
+
+func (a *api) fail(w http.ResponseWriter, msg string, status int) {
+       w.Header().Set("Content-Type", "application/json")
+
+       data := struct {
+               Error string
+       }{Error: msg}
+
+       resp, _ := json.Marshal(data)
+       w.WriteHeader(status)
+       w.Write(resp)
+}
+
+func (a *api) ok(w http.ResponseWriter, data interface{}) {
+       w.Header().Set("Content-Type", "application/json")
+
+       resp, err := json.Marshal(data)
+       if err != nil {
+               w.WriteHeader(http.StatusInternalServerError)
+               a.fail(w, "oops something evil has happened", 500)
+               return
+       }
+       w.Write(resp)
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/blog/blog_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/blog/blog_test.go
 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/blog/blog_test.go
new file mode 100644
index 0000000..aa1881a
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/blog/blog_test.go
@@ -0,0 +1,102 @@
+package main
+
+import (
+       "bytes"
+       "encoding/json"
+       "fmt"
+       "net/http"
+       "net/http/httptest"
+       "testing"
+
+       "github.com/DATA-DOG/go-sqlmock"
+)
+
+func (a *api) assertJSON(actual []byte, data interface{}, t *testing.T) {
+       expected, err := json.Marshal(data)
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when marshaling 
expected json data", err)
+       }
+
+       if bytes.Compare(expected, actual) != 0 {
+               t.Errorf("the expected json: %s is different from actual %s", 
expected, actual)
+       }
+}
+
+func TestShouldGetPosts(t *testing.T) {
+       db, mock, err := sqlmock.New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       // create app with mocked db, request and response to test
+       app := &api{db}
+       req, err := http.NewRequest("GET", "http://localhost/posts";, nil)
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected while creating 
request", err)
+       }
+       w := httptest.NewRecorder()
+
+       // before we actually execute our api function, we need to expect 
required DB actions
+       rows := sqlmock.NewRows([]string{"id", "title", "body"}).
+               AddRow(1, "post 1", "hello").
+               AddRow(2, "post 2", "world")
+
+       mock.ExpectQuery("^SELECT (.+) FROM posts$").WillReturnRows(rows)
+
+       // now we execute our request
+       app.posts(w, req)
+
+       if w.Code != 200 {
+               t.Fatalf("expected status code to be 200, but got: %d", w.Code)
+       }
+
+       data := struct {
+               Posts []*post
+       }{Posts: []*post{
+               {ID: 1, Title: "post 1", Body: "hello"},
+               {ID: 2, Title: "post 2", Body: "world"},
+       }}
+       app.assertJSON(w.Body.Bytes(), data, t)
+
+       // we make sure that all expectations were met
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}
+
+func TestShouldRespondWithErrorOnFailure(t *testing.T) {
+       db, mock, err := sqlmock.New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       // create app with mocked db, request and response to test
+       app := &api{db}
+       req, err := http.NewRequest("GET", "http://localhost/posts";, nil)
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected while creating 
request", err)
+       }
+       w := httptest.NewRecorder()
+
+       // before we actually execute our api function, we need to expect 
required DB actions
+       mock.ExpectQuery("^SELECT (.+) FROM 
posts$").WillReturnError(fmt.Errorf("some error"))
+
+       // now we execute our request
+       app.posts(w, req)
+
+       if w.Code != 500 {
+               t.Fatalf("expected status code to be 500, but got: %d", w.Code)
+       }
+
+       data := struct {
+               Error string
+       }{"failed to fetch posts: some error"}
+       app.assertJSON(w.Body.Bytes(), data, t)
+
+       // we make sure that all expectations were met
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/doc.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/doc.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/doc.go
new file mode 100644
index 0000000..c7842af
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/doc.go
@@ -0,0 +1 @@
+package examples

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/orders/orders.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/orders/orders.go
 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/orders/orders.go
new file mode 100644
index 0000000..fb7e47e
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/orders/orders.go
@@ -0,0 +1,121 @@
+package main
+
+import (
+       "database/sql"
+       "fmt"
+       "log"
+
+       "github.com/kisielk/sqlstruct"
+)
+
+const ORDER_PENDING = 0
+const ORDER_CANCELLED = 1
+
+type User struct {
+       Id       int     `sql:"id"`
+       Username string  `sql:"username"`
+       Balance  float64 `sql:"balance"`
+}
+
+type Order struct {
+       Id          int     `sql:"id"`
+       Value       float64 `sql:"value"`
+       ReservedFee float64 `sql:"reserved_fee"`
+       Status      int     `sql:"status"`
+}
+
+func cancelOrder(id int, db *sql.DB) (err error) {
+       tx, err := db.Begin()
+       if err != nil {
+               return
+       }
+
+       var order Order
+       var user User
+       sql := fmt.Sprintf(`
+SELECT %s, %s
+FROM orders AS o
+INNER JOIN users AS u ON o.buyer_id = u.id
+WHERE o.id = ?
+FOR UPDATE`,
+               sqlstruct.ColumnsAliased(order, "o"),
+               sqlstruct.ColumnsAliased(user, "u"))
+
+       // fetch order to cancel
+       rows, err := tx.Query(sql, id)
+       if err != nil {
+               tx.Rollback()
+               return
+       }
+
+       defer rows.Close()
+       // no rows, nothing to do
+       if !rows.Next() {
+               tx.Rollback()
+               return
+       }
+
+       // read order
+       err = sqlstruct.ScanAliased(&order, rows, "o")
+       if err != nil {
+               tx.Rollback()
+               return
+       }
+
+       // ensure order status
+       if order.Status != ORDER_PENDING {
+               tx.Rollback()
+               return
+       }
+
+       // read user
+       err = sqlstruct.ScanAliased(&user, rows, "u")
+       if err != nil {
+               tx.Rollback()
+               return
+       }
+       rows.Close() // manually close before other prepared statements
+
+       // refund order value
+       sql = "UPDATE users SET balance = balance + ? WHERE id = ?"
+       refundStmt, err := tx.Prepare(sql)
+       if err != nil {
+               tx.Rollback()
+               return
+       }
+       defer refundStmt.Close()
+       _, err = refundStmt.Exec(order.Value+order.ReservedFee, user.Id)
+       if err != nil {
+               tx.Rollback()
+               return
+       }
+
+       // update order status
+       order.Status = ORDER_CANCELLED
+       sql = "UPDATE orders SET status = ?, updated = NOW() WHERE id = ?"
+       orderUpdStmt, err := tx.Prepare(sql)
+       if err != nil {
+               tx.Rollback()
+               return
+       }
+       defer orderUpdStmt.Close()
+       _, err = orderUpdStmt.Exec(order.Status, order.Id)
+       if err != nil {
+               tx.Rollback()
+               return
+       }
+       return tx.Commit()
+}
+
+func main() {
+       // @NOTE: the real connection is not required for tests
+       db, err := sql.Open("mysql", "root:@/orders")
+       if err != nil {
+               log.Fatal(err)
+       }
+       defer db.Close()
+       err = cancelOrder(1, db)
+       if err != nil {
+               log.Fatal(err)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/orders/orders_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/orders/orders_test.go
 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/orders/orders_test.go
new file mode 100644
index 0000000..7562b8f
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/examples/orders/orders_test.go
@@ -0,0 +1,108 @@
+package main
+
+import (
+       "fmt"
+       "testing"
+
+       "github.com/DATA-DOG/go-sqlmock"
+)
+
+// will test that order with a different status, cannot be cancelled
+func TestShouldNotCancelOrderWithNonPendingStatus(t *testing.T) {
+       // open database stub
+       db, mock, err := sqlmock.New()
+       if err != nil {
+               t.Errorf("An error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       // columns are prefixed with "o" since we used sqlstruct to generate 
them
+       columns := []string{"o_id", "o_status"}
+       // expect transaction begin
+       mock.ExpectBegin()
+       // expect query to fetch order and user, match it with regexp
+       mock.ExpectQuery("SELECT (.+) FROM orders AS o INNER JOIN users AS u 
(.+) FOR UPDATE").
+               WithArgs(1).
+               WillReturnRows(sqlmock.NewRows(columns).FromCSVString("1,1"))
+       // expect transaction rollback, since order status is "cancelled"
+       mock.ExpectRollback()
+
+       // run the cancel order function
+       err = cancelOrder(1, db)
+       if err != nil {
+               t.Errorf("Expected no error, but got %s instead", err)
+       }
+       // we make sure that all expectations were met
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}
+
+// will test order cancellation
+func TestShouldRefundUserWhenOrderIsCancelled(t *testing.T) {
+       // open database stub
+       db, mock, err := sqlmock.New()
+       if err != nil {
+               t.Errorf("An error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       // columns are prefixed with "o" since we used sqlstruct to generate 
them
+       columns := []string{"o_id", "o_status", "o_value", "o_reserved_fee", 
"u_id", "u_balance"}
+       // expect transaction begin
+       mock.ExpectBegin()
+       // expect query to fetch order and user, match it with regexp
+       mock.ExpectQuery("SELECT (.+) FROM orders AS o INNER JOIN users AS u 
(.+) FOR UPDATE").
+               WithArgs(1).
+               WillReturnRows(sqlmock.NewRows(columns).AddRow(1, 0, 25.75, 
3.25, 2, 10.00))
+       // expect user balance update
+       mock.ExpectPrepare("UPDATE users SET balance").ExpectExec().
+               WithArgs(25.75+3.25, 2).                  // refund amount, 
user id
+               WillReturnResult(sqlmock.NewResult(0, 1)) // no insert id, 1 
affected row
+       // expect order status update
+       mock.ExpectPrepare("UPDATE orders SET status").ExpectExec().
+               WithArgs(ORDER_CANCELLED, 1).             // status, id
+               WillReturnResult(sqlmock.NewResult(0, 1)) // no insert id, 1 
affected row
+       // expect a transaction commit
+       mock.ExpectCommit()
+
+       // run the cancel order function
+       err = cancelOrder(1, db)
+       if err != nil {
+               t.Errorf("Expected no error, but got %s instead", err)
+       }
+       // we make sure that all expectations were met
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}
+
+// will test order cancellation
+func TestShouldRollbackOnError(t *testing.T) {
+       // open database stub
+       db, mock, err := sqlmock.New()
+       if err != nil {
+               t.Errorf("An error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       // expect transaction begin
+       mock.ExpectBegin()
+       // expect query to fetch order and user, match it with regexp
+       mock.ExpectQuery("SELECT (.+) FROM orders AS o INNER JOIN users AS u 
(.+) FOR UPDATE").
+               WithArgs(1).
+               WillReturnError(fmt.Errorf("Some error"))
+       // should rollback since error was returned from query execution
+       mock.ExpectRollback()
+
+       // run the cancel order function
+       err = cancelOrder(1, db)
+       // error should return back
+       if err == nil {
+               t.Error("Expected error, but got none")
+       }
+       // we make sure that all expectations were met
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations.go
new file mode 100644
index 0000000..415759e
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations.go
@@ -0,0 +1,344 @@
+package sqlmock
+
+import (
+       "database/sql/driver"
+       "fmt"
+       "regexp"
+       "strings"
+       "sync"
+       "time"
+)
+
+// an expectation interface
+type expectation interface {
+       fulfilled() bool
+       Lock()
+       Unlock()
+       String() string
+}
+
+// common expectation struct
+// satisfies the expectation interface
+type commonExpectation struct {
+       sync.Mutex
+       triggered bool
+       err       error
+}
+
+func (e *commonExpectation) fulfilled() bool {
+       return e.triggered
+}
+
+// ExpectedClose is used to manage *sql.DB.Close expectation
+// returned by *Sqlmock.ExpectClose.
+type ExpectedClose struct {
+       commonExpectation
+}
+
+// WillReturnError allows to set an error for *sql.DB.Close action
+func (e *ExpectedClose) WillReturnError(err error) *ExpectedClose {
+       e.err = err
+       return e
+}
+
+// String returns string representation
+func (e *ExpectedClose) String() string {
+       msg := "ExpectedClose => expecting database Close"
+       if e.err != nil {
+               msg += fmt.Sprintf(", which should return error: %s", e.err)
+       }
+       return msg
+}
+
+// ExpectedBegin is used to manage *sql.DB.Begin expectation
+// returned by *Sqlmock.ExpectBegin.
+type ExpectedBegin struct {
+       commonExpectation
+       delay time.Duration
+}
+
+// WillReturnError allows to set an error for *sql.DB.Begin action
+func (e *ExpectedBegin) WillReturnError(err error) *ExpectedBegin {
+       e.err = err
+       return e
+}
+
+// String returns string representation
+func (e *ExpectedBegin) String() string {
+       msg := "ExpectedBegin => expecting database transaction Begin"
+       if e.err != nil {
+               msg += fmt.Sprintf(", which should return error: %s", e.err)
+       }
+       return msg
+}
+
+// WillDelayFor allows to specify duration for which it will delay
+// result. May be used together with Context
+func (e *ExpectedBegin) WillDelayFor(duration time.Duration) *ExpectedBegin {
+       e.delay = duration
+       return e
+}
+
+// ExpectedCommit is used to manage *sql.Tx.Commit expectation
+// returned by *Sqlmock.ExpectCommit.
+type ExpectedCommit struct {
+       commonExpectation
+}
+
+// WillReturnError allows to set an error for *sql.Tx.Close action
+func (e *ExpectedCommit) WillReturnError(err error) *ExpectedCommit {
+       e.err = err
+       return e
+}
+
+// String returns string representation
+func (e *ExpectedCommit) String() string {
+       msg := "ExpectedCommit => expecting transaction Commit"
+       if e.err != nil {
+               msg += fmt.Sprintf(", which should return error: %s", e.err)
+       }
+       return msg
+}
+
+// ExpectedRollback is used to manage *sql.Tx.Rollback expectation
+// returned by *Sqlmock.ExpectRollback.
+type ExpectedRollback struct {
+       commonExpectation
+}
+
+// WillReturnError allows to set an error for *sql.Tx.Rollback action
+func (e *ExpectedRollback) WillReturnError(err error) *ExpectedRollback {
+       e.err = err
+       return e
+}
+
+// String returns string representation
+func (e *ExpectedRollback) String() string {
+       msg := "ExpectedRollback => expecting transaction Rollback"
+       if e.err != nil {
+               msg += fmt.Sprintf(", which should return error: %s", e.err)
+       }
+       return msg
+}
+
+// ExpectedQuery is used to manage *sql.DB.Query, *dql.DB.QueryRow, 
*sql.Tx.Query,
+// *sql.Tx.QueryRow, *sql.Stmt.Query or *sql.Stmt.QueryRow expectations.
+// Returned by *Sqlmock.ExpectQuery.
+type ExpectedQuery struct {
+       queryBasedExpectation
+       rows  driver.Rows
+       delay time.Duration
+}
+
+// WithArgs will match given expected args to actual database query arguments.
+// if at least one argument does not match, it will return an error. For 
specific
+// arguments an sqlmock.Argument interface can be used to match an argument.
+func (e *ExpectedQuery) WithArgs(args ...driver.Value) *ExpectedQuery {
+       e.args = args
+       return e
+}
+
+// WillReturnError allows to set an error for expected database query
+func (e *ExpectedQuery) WillReturnError(err error) *ExpectedQuery {
+       e.err = err
+       return e
+}
+
+// WillDelayFor allows to specify duration for which it will delay
+// result. May be used together with Context
+func (e *ExpectedQuery) WillDelayFor(duration time.Duration) *ExpectedQuery {
+       e.delay = duration
+       return e
+}
+
+// String returns string representation
+func (e *ExpectedQuery) String() string {
+       msg := "ExpectedQuery => expecting Query or QueryRow which:"
+       msg += "\n  - matches sql: '" + e.sqlRegex.String() + "'"
+
+       if len(e.args) == 0 {
+               msg += "\n  - is without arguments"
+       } else {
+               msg += "\n  - is with arguments:\n"
+               for i, arg := range e.args {
+                       msg += fmt.Sprintf("    %d - %+v\n", i, arg)
+               }
+               msg = strings.TrimSpace(msg)
+       }
+
+       if e.rows != nil {
+               msg += fmt.Sprintf("\n  - %s", e.rows)
+       }
+
+       if e.err != nil {
+               msg += fmt.Sprintf("\n  - should return error: %s", e.err)
+       }
+
+       return msg
+}
+
+// ExpectedExec is used to manage *sql.DB.Exec, *sql.Tx.Exec or *sql.Stmt.Exec 
expectations.
+// Returned by *Sqlmock.ExpectExec.
+type ExpectedExec struct {
+       queryBasedExpectation
+       result driver.Result
+       delay  time.Duration
+}
+
+// WithArgs will match given expected args to actual database exec operation 
arguments.
+// if at least one argument does not match, it will return an error. For 
specific
+// arguments an sqlmock.Argument interface can be used to match an argument.
+func (e *ExpectedExec) WithArgs(args ...driver.Value) *ExpectedExec {
+       e.args = args
+       return e
+}
+
+// WillReturnError allows to set an error for expected database exec action
+func (e *ExpectedExec) WillReturnError(err error) *ExpectedExec {
+       e.err = err
+       return e
+}
+
+// WillDelayFor allows to specify duration for which it will delay
+// result. May be used together with Context
+func (e *ExpectedExec) WillDelayFor(duration time.Duration) *ExpectedExec {
+       e.delay = duration
+       return e
+}
+
+// String returns string representation
+func (e *ExpectedExec) String() string {
+       msg := "ExpectedExec => expecting Exec which:"
+       msg += "\n  - matches sql: '" + e.sqlRegex.String() + "'"
+
+       if len(e.args) == 0 {
+               msg += "\n  - is without arguments"
+       } else {
+               msg += "\n  - is with arguments:\n"
+               var margs []string
+               for i, arg := range e.args {
+                       margs = append(margs, fmt.Sprintf("    %d - %+v", i, 
arg))
+               }
+               msg += strings.Join(margs, "\n")
+       }
+
+       if e.result != nil {
+               res, _ := e.result.(*result)
+               msg += "\n  - should return Result having:"
+               msg += fmt.Sprintf("\n      LastInsertId: %d", res.insertID)
+               msg += fmt.Sprintf("\n      RowsAffected: %d", res.rowsAffected)
+               if res.err != nil {
+                       msg += fmt.Sprintf("\n      Error: %s", res.err)
+               }
+       }
+
+       if e.err != nil {
+               msg += fmt.Sprintf("\n  - should return error: %s", e.err)
+       }
+
+       return msg
+}
+
+// WillReturnResult arranges for an expected Exec() to return a particular
+// result, there is sqlmock.NewResult(lastInsertID int64, affectedRows int64) 
method
+// to build a corresponding result. Or if actions needs to be tested against 
errors
+// sqlmock.NewErrorResult(err error) to return a given error.
+func (e *ExpectedExec) WillReturnResult(result driver.Result) *ExpectedExec {
+       e.result = result
+       return e
+}
+
+// ExpectedPrepare is used to manage *sql.DB.Prepare or *sql.Tx.Prepare 
expectations.
+// Returned by *Sqlmock.ExpectPrepare.
+type ExpectedPrepare struct {
+       commonExpectation
+       mock      *sqlmock
+       sqlRegex  *regexp.Regexp
+       statement driver.Stmt
+       closeErr  error
+       delay     time.Duration
+}
+
+// WillReturnError allows to set an error for the expected *sql.DB.Prepare or 
*sql.Tx.Prepare action.
+func (e *ExpectedPrepare) WillReturnError(err error) *ExpectedPrepare {
+       e.err = err
+       return e
+}
+
+// WillReturnCloseError allows to set an error for this prapared statement 
Close action
+func (e *ExpectedPrepare) WillReturnCloseError(err error) *ExpectedPrepare {
+       e.closeErr = err
+       return e
+}
+
+// WillDelayFor allows to specify duration for which it will delay
+// result. May be used together with Context
+func (e *ExpectedPrepare) WillDelayFor(duration time.Duration) 
*ExpectedPrepare {
+       e.delay = duration
+       return e
+}
+
+// ExpectQuery allows to expect Query() or QueryRow() on this prepared 
statement.
+// this method is convenient in order to prevent duplicating sql query string 
matching.
+func (e *ExpectedPrepare) ExpectQuery() *ExpectedQuery {
+       eq := &ExpectedQuery{}
+       eq.sqlRegex = e.sqlRegex
+       e.mock.expected = append(e.mock.expected, eq)
+       return eq
+}
+
+// ExpectExec allows to expect Exec() on this prepared statement.
+// this method is convenient in order to prevent duplicating sql query string 
matching.
+func (e *ExpectedPrepare) ExpectExec() *ExpectedExec {
+       eq := &ExpectedExec{}
+       eq.sqlRegex = e.sqlRegex
+       e.mock.expected = append(e.mock.expected, eq)
+       return eq
+}
+
+// String returns string representation
+func (e *ExpectedPrepare) String() string {
+       msg := "ExpectedPrepare => expecting Prepare statement which:"
+       msg += "\n  - matches sql: '" + e.sqlRegex.String() + "'"
+
+       if e.err != nil {
+               msg += fmt.Sprintf("\n  - should return error: %s", e.err)
+       }
+
+       if e.closeErr != nil {
+               msg += fmt.Sprintf("\n  - should return error on Close: %s", 
e.closeErr)
+       }
+
+       return msg
+}
+
+// query based expectation
+// adds a query matching logic
+type queryBasedExpectation struct {
+       commonExpectation
+       sqlRegex *regexp.Regexp
+       args     []driver.Value
+}
+
+func (e *queryBasedExpectation) attemptMatch(sql string, args []namedValue) 
(err error) {
+       if !e.queryMatches(sql) {
+               return fmt.Errorf(`could not match sql: "%s" with expected 
regexp "%s"`, sql, e.sqlRegex.String())
+       }
+
+       // catch panic
+       defer func() {
+               if e := recover(); e != nil {
+                       _, ok := e.(error)
+                       if !ok {
+                               err = fmt.Errorf(e.(string))
+                       }
+               }
+       }()
+
+       err = e.argsMatches(args)
+       return
+}
+
+func (e *queryBasedExpectation) queryMatches(sql string) bool {
+       return e.sqlRegex.MatchString(sql)
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_before_go18.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_before_go18.go
 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_before_go18.go
new file mode 100644
index 0000000..146f240
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_before_go18.go
@@ -0,0 +1,52 @@
+// +build !go1.8
+
+package sqlmock
+
+import (
+       "database/sql/driver"
+       "fmt"
+       "reflect"
+)
+
+// WillReturnRows specifies the set of resulting rows that will be returned
+// by the triggered query
+func (e *ExpectedQuery) WillReturnRows(rows *Rows) *ExpectedQuery {
+       e.rows = &rowSets{sets: []*Rows{rows}}
+       return e
+}
+
+func (e *queryBasedExpectation) argsMatches(args []namedValue) error {
+       if nil == e.args {
+               return nil
+       }
+       if len(args) != len(e.args) {
+               return fmt.Errorf("expected %d, but got %d arguments", 
len(e.args), len(args))
+       }
+       for k, v := range args {
+               // custom argument matcher
+               matcher, ok := e.args[k].(Argument)
+               if ok {
+                       // @TODO: does it make sense to pass value instead of 
named value?
+                       if !matcher.Match(v.Value) {
+                               return fmt.Errorf("matcher %T could not match 
%d argument %T - %+v", matcher, k, args[k], args[k])
+                       }
+                       continue
+               }
+
+               dval := e.args[k]
+               // convert to driver converter
+               darg, err := driver.DefaultParameterConverter.ConvertValue(dval)
+               if err != nil {
+                       return fmt.Errorf("could not convert %d argument %T - 
%+v to driver value: %s", k, e.args[k], e.args[k], err)
+               }
+
+               if !driver.IsValue(darg) {
+                       return fmt.Errorf("argument %d: non-subset type %T 
returned from Value", k, darg)
+               }
+
+               if !reflect.DeepEqual(darg, v.Value) {
+                       return fmt.Errorf("argument %d expected [%T - %+v] does 
not match actual [%T - %+v]", k, darg, darg, v.Value, v.Value)
+               }
+       }
+       return nil
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_go18.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_go18.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_go18.go
new file mode 100644
index 0000000..2b4b44e
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_go18.go
@@ -0,0 +1,66 @@
+// +build go1.8
+
+package sqlmock
+
+import (
+       "database/sql"
+       "database/sql/driver"
+       "fmt"
+       "reflect"
+)
+
+// WillReturnRows specifies the set of resulting rows that will be returned
+// by the triggered query
+func (e *ExpectedQuery) WillReturnRows(rows ...*Rows) *ExpectedQuery {
+       sets := make([]*Rows, len(rows))
+       for i, r := range rows {
+               sets[i] = r
+       }
+       e.rows = &rowSets{sets: sets}
+       return e
+}
+
+func (e *queryBasedExpectation) argsMatches(args []namedValue) error {
+       if nil == e.args {
+               return nil
+       }
+       if len(args) != len(e.args) {
+               return fmt.Errorf("expected %d, but got %d arguments", 
len(e.args), len(args))
+       }
+       // @TODO should we assert either all args are named or ordinal?
+       for k, v := range args {
+               // custom argument matcher
+               matcher, ok := e.args[k].(Argument)
+               if ok {
+                       if !matcher.Match(v.Value) {
+                               return fmt.Errorf("matcher %T could not match 
%d argument %T - %+v", matcher, k, args[k], args[k])
+                       }
+                       continue
+               }
+
+               dval := e.args[k]
+               if named, isNamed := dval.(sql.NamedArg); isNamed {
+                       dval = named.Value
+                       if v.Name != named.Name {
+                               return fmt.Errorf("named argument %d: name: 
\"%s\" does not match expected: \"%s\"", k, v.Name, named.Name)
+                       }
+               } else if k+1 != v.Ordinal {
+                       return fmt.Errorf("argument %d: ordinal position: %d 
does not match expected: %d", k, k+1, v.Ordinal)
+               }
+
+               // convert to driver converter
+               darg, err := driver.DefaultParameterConverter.ConvertValue(dval)
+               if err != nil {
+                       return fmt.Errorf("could not convert %d argument %T - 
%+v to driver value: %s", k, e.args[k], e.args[k], err)
+               }
+
+               if !driver.IsValue(darg) {
+                       return fmt.Errorf("argument %d: non-subset type %T 
returned from Value", k, darg)
+               }
+
+               if !reflect.DeepEqual(darg, v.Value) {
+                       return fmt.Errorf("argument %d expected [%T - %+v] does 
not match actual [%T - %+v]", k, darg, darg, v.Value, v.Value)
+               }
+       }
+       return nil
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_go18_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_go18_test.go
 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_go18_test.go
new file mode 100644
index 0000000..5f30d2f
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_go18_test.go
@@ -0,0 +1,64 @@
+// +build go1.8
+
+package sqlmock
+
+import (
+       "database/sql"
+       "database/sql/driver"
+       "testing"
+)
+
+func TestQueryExpectationNamedArgComparison(t *testing.T) {
+       e := &queryBasedExpectation{}
+       against := []namedValue{{Value: int64(5), Name: "id"}}
+       if err := e.argsMatches(against); err != nil {
+               t.Errorf("arguments should match, since the no expectation was 
set, but got err: %s", err)
+       }
+
+       e.args = []driver.Value{
+               sql.Named("id", 5),
+               sql.Named("s", "str"),
+       }
+
+       if err := e.argsMatches(against); err == nil {
+               t.Error("arguments should not match, since the size is not the 
same")
+       }
+
+       against = []namedValue{
+               {Value: int64(5), Name: "id"},
+               {Value: "str", Name: "s"},
+       }
+
+       if err := e.argsMatches(against); err != nil {
+               t.Errorf("arguments should have matched, but it did not: %v", 
err)
+       }
+
+       against = []namedValue{
+               {Value: int64(5), Name: "id"},
+               {Value: "str", Name: "username"},
+       }
+
+       if err := e.argsMatches(against); err == nil {
+               t.Error("arguments matched, but it should have not due to Name")
+       }
+
+       e.args = []driver.Value{int64(5), "str"}
+
+       against = []namedValue{
+               {Value: int64(5), Ordinal: 0},
+               {Value: "str", Ordinal: 1},
+       }
+
+       if err := e.argsMatches(against); err == nil {
+               t.Error("arguments matched, but it should have not due to wrong 
Ordinal position")
+       }
+
+       against = []namedValue{
+               {Value: int64(5), Ordinal: 1},
+               {Value: "str", Ordinal: 2},
+       }
+
+       if err := e.argsMatches(against); err != nil {
+               t.Errorf("arguments should have matched, but it did not: %v", 
err)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_test.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_test.go
new file mode 100644
index 0000000..2e3c097
--- /dev/null
+++ 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/expectations_test.go
@@ -0,0 +1,154 @@
+package sqlmock
+
+import (
+       "database/sql/driver"
+       "fmt"
+       "regexp"
+       "testing"
+       "time"
+)
+
+func TestQueryExpectationArgComparison(t *testing.T) {
+       e := &queryBasedExpectation{}
+       against := []namedValue{{Value: int64(5), Ordinal: 1}}
+       if err := e.argsMatches(against); err != nil {
+               t.Errorf("arguments should match, since the no expectation was 
set, but got err: %s", err)
+       }
+
+       e.args = []driver.Value{5, "str"}
+
+       against = []namedValue{{Value: int64(5), Ordinal: 1}}
+       if err := e.argsMatches(against); err == nil {
+               t.Error("arguments should not match, since the size is not the 
same")
+       }
+
+       against = []namedValue{
+               {Value: int64(3), Ordinal: 1},
+               {Value: "str", Ordinal: 2},
+       }
+       if err := e.argsMatches(against); err == nil {
+               t.Error("arguments should not match, since the first argument 
(int value) is different")
+       }
+
+       against = []namedValue{
+               {Value: int64(5), Ordinal: 1},
+               {Value: "st", Ordinal: 2},
+       }
+       if err := e.argsMatches(against); err == nil {
+               t.Error("arguments should not match, since the second argument 
(string value) is different")
+       }
+
+       against = []namedValue{
+               {Value: int64(5), Ordinal: 1},
+               {Value: "str", Ordinal: 2},
+       }
+       if err := e.argsMatches(against); err != nil {
+               t.Errorf("arguments should match, but it did not: %s", err)
+       }
+
+       const longForm = "Jan 2, 2006 at 3:04pm (MST)"
+       tm, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)")
+       e.args = []driver.Value{5, tm}
+
+       against = []namedValue{
+               {Value: int64(5), Ordinal: 1},
+               {Value: tm, Ordinal: 2},
+       }
+       if err := e.argsMatches(against); err != nil {
+               t.Error("arguments should match, but it did not")
+       }
+
+       e.args = []driver.Value{5, AnyArg()}
+       if err := e.argsMatches(against); err != nil {
+               t.Errorf("arguments should match, but it did not: %s", err)
+       }
+}
+
+func TestQueryExpectationArgComparisonBool(t *testing.T) {
+       var e *queryBasedExpectation
+
+       e = &queryBasedExpectation{args: []driver.Value{true}}
+       against := []namedValue{
+               {Value: true, Ordinal: 1},
+       }
+       if err := e.argsMatches(against); err != nil {
+               t.Error("arguments should match, since arguments are the same")
+       }
+
+       e = &queryBasedExpectation{args: []driver.Value{false}}
+       against = []namedValue{
+               {Value: false, Ordinal: 1},
+       }
+       if err := e.argsMatches(against); err != nil {
+               t.Error("arguments should match, since argument are the same")
+       }
+
+       e = &queryBasedExpectation{args: []driver.Value{true}}
+       against = []namedValue{
+               {Value: false, Ordinal: 1},
+       }
+       if err := e.argsMatches(against); err == nil {
+               t.Error("arguments should not match, since argument is 
different")
+       }
+
+       e = &queryBasedExpectation{args: []driver.Value{false}}
+       against = []namedValue{
+               {Value: true, Ordinal: 1},
+       }
+       if err := e.argsMatches(against); err == nil {
+               t.Error("arguments should not match, since argument is 
different")
+       }
+}
+
+func TestQueryExpectationSqlMatch(t *testing.T) {
+       e := &ExpectedExec{}
+
+       e.sqlRegex = regexp.MustCompile("SELECT x FROM")
+       if !e.queryMatches("SELECT x FROM someting") {
+               t.Errorf("Sql must have matched the query")
+       }
+
+       e.sqlRegex = regexp.MustCompile("SELECT COUNT\\(x\\) FROM")
+       if !e.queryMatches("SELECT COUNT(x) FROM someting") {
+               t.Errorf("Sql must have matched the query")
+       }
+}
+
+func ExampleExpectedExec() {
+       db, mock, _ := New()
+       result := NewErrorResult(fmt.Errorf("some error"))
+       mock.ExpectExec("^INSERT (.+)").WillReturnResult(result)
+       res, _ := db.Exec("INSERT something")
+       _, err := res.LastInsertId()
+       fmt.Println(err)
+       // Output: some error
+}
+
+func TestBuildQuery(t *testing.T) {
+       db, mock, _ := New()
+       query := `
+               SELECT
+                       name,
+                       email,
+                       address,
+                       anotherfield
+               FROM user
+               where
+                       name    = 'John'
+                       and
+                       address = 'Jakarta'
+
+       `
+
+       mock.ExpectQuery(query)
+       mock.ExpectExec(query)
+       mock.ExpectPrepare(query)
+
+       db.QueryRow(query)
+       db.Exec(query)
+       db.Prepare(query)
+
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Error(err)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/result.go
----------------------------------------------------------------------
diff --git a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/result.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/result.go
new file mode 100644
index 0000000..a63e72b
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/result.go
@@ -0,0 +1,39 @@
+package sqlmock
+
+import (
+       "database/sql/driver"
+)
+
+// Result satisfies sql driver Result, which
+// holds last insert id and rows affected
+// by Exec queries
+type result struct {
+       insertID     int64
+       rowsAffected int64
+       err          error
+}
+
+// NewResult creates a new sql driver Result
+// for Exec based query mocks.
+func NewResult(lastInsertID int64, rowsAffected int64) driver.Result {
+       return &result{
+               insertID:     lastInsertID,
+               rowsAffected: rowsAffected,
+       }
+}
+
+// NewErrorResult creates a new sql driver Result
+// which returns an error given for both interface methods
+func NewErrorResult(err error) driver.Result {
+       return &result{
+               err: err,
+       }
+}
+
+func (r *result) LastInsertId() (int64, error) {
+       return r.insertID, r.err
+}
+
+func (r *result) RowsAffected() (int64, error) {
+       return r.rowsAffected, r.err
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/result_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/result_test.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/result_test.go
new file mode 100644
index 0000000..08d47c9
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/result_test.go
@@ -0,0 +1,62 @@
+package sqlmock
+
+import (
+       "fmt"
+       "testing"
+)
+
+// used for examples
+var mock = &sqlmock{}
+
+func ExampleNewErrorResult() {
+       db, mock, _ := New()
+       result := NewErrorResult(fmt.Errorf("some error"))
+       mock.ExpectExec("^INSERT (.+)").WillReturnResult(result)
+       res, _ := db.Exec("INSERT something")
+       _, err := res.LastInsertId()
+       fmt.Println(err)
+       // Output: some error
+}
+
+func ExampleNewResult() {
+       var lastInsertID, affected int64
+       result := NewResult(lastInsertID, affected)
+       mock.ExpectExec("^INSERT (.+)").WillReturnResult(result)
+       fmt.Println(mock.ExpectationsWereMet())
+       // Output: there is a remaining expectation which was not matched: 
ExpectedExec => expecting Exec which:
+       //   - matches sql: '^INSERT (.+)'
+       //   - is without arguments
+       //   - should return Result having:
+       //       LastInsertId: 0
+       //       RowsAffected: 0
+}
+
+func TestShouldReturnValidSqlDriverResult(t *testing.T) {
+       result := NewResult(1, 2)
+       id, err := result.LastInsertId()
+       if 1 != id {
+               t.Errorf("Expected last insert id to be 1, but got: %d", id)
+       }
+       if err != nil {
+               t.Errorf("expected no error, but got: %s", err)
+       }
+       affected, err := result.RowsAffected()
+       if 2 != affected {
+               t.Errorf("Expected affected rows to be 2, but got: %d", 
affected)
+       }
+       if err != nil {
+               t.Errorf("expected no error, but got: %s", err)
+       }
+}
+
+func TestShouldReturnErroeSqlDriverResult(t *testing.T) {
+       result := NewErrorResult(fmt.Errorf("some error"))
+       _, err := result.LastInsertId()
+       if err == nil {
+               t.Error("expected error, but got none")
+       }
+       _, err = result.RowsAffected()
+       if err == nil {
+               t.Error("expected error, but got none")
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows.go
----------------------------------------------------------------------
diff --git a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows.go
new file mode 100644
index 0000000..39f9f83
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows.go
@@ -0,0 +1,144 @@
+package sqlmock
+
+import (
+       "database/sql/driver"
+       "encoding/csv"
+       "fmt"
+       "io"
+       "strings"
+)
+
+// CSVColumnParser is a function which converts trimmed csv
+// column string to a []byte representation. currently
+// transforms NULL to nil
+var CSVColumnParser = func(s string) []byte {
+       switch {
+       case strings.ToLower(s) == "null":
+               return nil
+       }
+       return []byte(s)
+}
+
+type rowSets struct {
+       sets []*Rows
+       pos  int
+}
+
+func (rs *rowSets) Columns() []string {
+       return rs.sets[rs.pos].cols
+}
+
+func (rs *rowSets) Close() error {
+       return rs.sets[rs.pos].closeErr
+}
+
+// advances to next row
+func (rs *rowSets) Next(dest []driver.Value) error {
+       r := rs.sets[rs.pos]
+       r.pos++
+       if r.pos > len(r.rows) {
+               return io.EOF // per interface spec
+       }
+
+       for i, col := range r.rows[r.pos-1] {
+               dest[i] = col
+       }
+
+       return r.nextErr[r.pos-1]
+}
+
+// transforms to debuggable printable string
+func (rs *rowSets) String() string {
+       msg := "should return rows:\n"
+       if len(rs.sets) == 1 {
+               for n, row := range rs.sets[0].rows {
+                       msg += fmt.Sprintf("    row %d - %+v\n", n, row)
+               }
+               return strings.TrimSpace(msg)
+       }
+       for i, set := range rs.sets {
+               msg += fmt.Sprintf("    result set: %d\n", i)
+               for n, row := range set.rows {
+                       msg += fmt.Sprintf("      row %d - %+v\n", n, row)
+               }
+       }
+       return strings.TrimSpace(msg)
+}
+
+// Rows is a mocked collection of rows to
+// return for Query result
+type Rows struct {
+       cols     []string
+       rows     [][]driver.Value
+       pos      int
+       nextErr  map[int]error
+       closeErr error
+}
+
+// NewRows allows Rows to be created from a
+// sql driver.Value slice or from the CSV string and
+// to be used as sql driver.Rows
+func NewRows(columns []string) *Rows {
+       return &Rows{cols: columns, nextErr: make(map[int]error)}
+}
+
+// CloseError allows to set an error
+// which will be returned by rows.Close
+// function.
+//
+// The close error will be triggered only in cases
+// when rows.Next() EOF was not yet reached, that is
+// a default sql library behavior
+func (r *Rows) CloseError(err error) *Rows {
+       r.closeErr = err
+       return r
+}
+
+// RowError allows to set an error
+// which will be returned when a given
+// row number is read
+func (r *Rows) RowError(row int, err error) *Rows {
+       r.nextErr[row] = err
+       return r
+}
+
+// AddRow composed from database driver.Value slice
+// return the same instance to perform subsequent actions.
+// Note that the number of values must match the number
+// of columns
+func (r *Rows) AddRow(values ...driver.Value) *Rows {
+       if len(values) != len(r.cols) {
+               panic("Expected number of values to match number of columns")
+       }
+
+       row := make([]driver.Value, len(r.cols))
+       for i, v := range values {
+               row[i] = v
+       }
+
+       r.rows = append(r.rows, row)
+       return r
+}
+
+// FromCSVString build rows from csv string.
+// return the same instance to perform subsequent actions.
+// Note that the number of values must match the number
+// of columns
+func (r *Rows) FromCSVString(s string) *Rows {
+       res := strings.NewReader(strings.TrimSpace(s))
+       csvReader := csv.NewReader(res)
+
+       for {
+               res, err := csvReader.Read()
+               if err != nil || res == nil {
+                       break
+               }
+
+               row := make([]driver.Value, len(r.cols))
+               for i, v := range res {
+                       row[i] = CSVColumnParser(strings.TrimSpace(v))
+               }
+               r.rows = append(r.rows, row)
+       }
+       return r
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_go18.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_go18.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_go18.go
new file mode 100644
index 0000000..4ecf84e
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_go18.go
@@ -0,0 +1,20 @@
+// +build go1.8
+
+package sqlmock
+
+import "io"
+
+// Implement the "RowsNextResultSet" interface
+func (rs *rowSets) HasNextResultSet() bool {
+       return rs.pos+1 < len(rs.sets)
+}
+
+// Implement the "RowsNextResultSet" interface
+func (rs *rowSets) NextResultSet() error {
+       if !rs.HasNextResultSet() {
+               return io.EOF
+       }
+
+       rs.pos++
+       return nil
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_go18_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_go18_test.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_go18_test.go
new file mode 100644
index 0000000..297e7c0
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_go18_test.go
@@ -0,0 +1,92 @@
+// +build go1.8
+
+package sqlmock
+
+import (
+       "fmt"
+       "testing"
+)
+
+func TestQueryMultiRows(t *testing.T) {
+       t.Parallel()
+       db, mock, err := New()
+       if err != nil {
+               t.Errorf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       rs1 := NewRows([]string{"id", "title"}).AddRow(5, "hello world")
+       rs2 := 
NewRows([]string{"name"}).AddRow("gopher").AddRow("john").AddRow("jane").RowError(2,
 fmt.Errorf("error"))
+
+       mock.ExpectQuery("SELECT (.+) FROM articles WHERE id = \\?;SELECT name 
FROM users").
+               WithArgs(5).
+               WillReturnRows(rs1, rs2)
+
+       rows, err := db.Query("SELECT id, title FROM articles WHERE id = 
?;SELECT name FROM users", 5)
+       if err != nil {
+               t.Errorf("error was not expected, but got: %v", err)
+       }
+       defer rows.Close()
+
+       if !rows.Next() {
+               t.Error("expected a row to be available in first result set")
+       }
+
+       var id int
+       var name string
+
+       err = rows.Scan(&id, &name)
+       if err != nil {
+               t.Errorf("error was not expected, but got: %v", err)
+       }
+
+       if id != 5 || name != "hello world" {
+               t.Errorf("unexpected row values id: %v name: %v", id, name)
+       }
+
+       if rows.Next() {
+               t.Error("was not expecting next row in first result set")
+       }
+
+       if !rows.NextResultSet() {
+               t.Error("had to have next result set")
+       }
+
+       if !rows.Next() {
+               t.Error("expected a row to be available in second result set")
+       }
+
+       err = rows.Scan(&name)
+       if err != nil {
+               t.Errorf("error was not expected, but got: %v", err)
+       }
+
+       if name != "gopher" {
+               t.Errorf("unexpected row name: %v", name)
+       }
+
+       if !rows.Next() {
+               t.Error("expected a row to be available in second result set")
+       }
+
+       err = rows.Scan(&name)
+       if err != nil {
+               t.Errorf("error was not expected, but got: %v", err)
+       }
+
+       if name != "john" {
+               t.Errorf("unexpected row name: %v", name)
+       }
+
+       if rows.Next() {
+               t.Error("expected next row to produce error")
+       }
+
+       if rows.Err() == nil {
+               t.Error("expected an error, but there was none")
+       }
+
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Errorf("there were unfulfilled expections: %s", err)
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/f9f7cfa0/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_test.go
----------------------------------------------------------------------
diff --git 
a/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_test.go 
b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_test.go
new file mode 100644
index 0000000..56e834e
--- /dev/null
+++ b/traffic_ops_golang/vendor/gopkg.in/DATA-DOG/go-sqlmock/rows_test.go
@@ -0,0 +1,265 @@
+package sqlmock
+
+import (
+       "database/sql"
+       "fmt"
+       "testing"
+)
+
+func ExampleRows() {
+       db, mock, err := New()
+       if err != nil {
+               fmt.Println("failed to open sqlmock database:", err)
+       }
+       defer db.Close()
+
+       rows := NewRows([]string{"id", "title"}).
+               AddRow(1, "one").
+               AddRow(2, "two")
+
+       mock.ExpectQuery("SELECT").WillReturnRows(rows)
+
+       rs, _ := db.Query("SELECT")
+       defer rs.Close()
+
+       for rs.Next() {
+               var id int
+               var title string
+               rs.Scan(&id, &title)
+               fmt.Println("scanned id:", id, "and title:", title)
+       }
+
+       if rs.Err() != nil {
+               fmt.Println("got rows error:", rs.Err())
+       }
+       // Output: scanned id: 1 and title: one
+       // scanned id: 2 and title: two
+}
+
+func ExampleRows_rowError() {
+       db, mock, err := New()
+       if err != nil {
+               fmt.Println("failed to open sqlmock database:", err)
+       }
+       defer db.Close()
+
+       rows := NewRows([]string{"id", "title"}).
+               AddRow(0, "one").
+               AddRow(1, "two").
+               RowError(1, fmt.Errorf("row error"))
+       mock.ExpectQuery("SELECT").WillReturnRows(rows)
+
+       rs, _ := db.Query("SELECT")
+       defer rs.Close()
+
+       for rs.Next() {
+               var id int
+               var title string
+               rs.Scan(&id, &title)
+               fmt.Println("scanned id:", id, "and title:", title)
+       }
+
+       if rs.Err() != nil {
+               fmt.Println("got rows error:", rs.Err())
+       }
+       // Output: scanned id: 0 and title: one
+       // got rows error: row error
+}
+
+func ExampleRows_closeError() {
+       db, mock, err := New()
+       if err != nil {
+               fmt.Println("failed to open sqlmock database:", err)
+       }
+       defer db.Close()
+
+       rows := NewRows([]string{"id", "title"}).CloseError(fmt.Errorf("close 
error"))
+       mock.ExpectQuery("SELECT").WillReturnRows(rows)
+
+       rs, _ := db.Query("SELECT")
+
+       // Note: that close will return error only before rows EOF
+       // that is a default sql package behavior. If you run rs.Next()
+       // it will handle the error internally and return nil bellow
+       if err := rs.Close(); err != nil {
+               fmt.Println("got error:", err)
+       }
+
+       // Output: got error: close error
+}
+
+func TestAllowsToSetRowsErrors(t *testing.T) {
+       t.Parallel()
+       db, mock, err := New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       rows := NewRows([]string{"id", "title"}).
+               AddRow(0, "one").
+               AddRow(1, "two").
+               RowError(1, fmt.Errorf("error"))
+       mock.ExpectQuery("SELECT").WillReturnRows(rows)
+
+       rs, err := db.Query("SELECT")
+       if err != nil {
+               t.Fatalf("unexpected error: %s", err)
+       }
+       defer rs.Close()
+
+       if !rs.Next() {
+               t.Fatal("expected the first row to be available")
+       }
+       if rs.Err() != nil {
+               t.Fatalf("unexpected error: %s", rs.Err())
+       }
+
+       if rs.Next() {
+               t.Fatal("was not expecting the second row, since there should 
be an error")
+       }
+       if rs.Err() == nil {
+               t.Fatal("expected an error, but got none")
+       }
+
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Fatal(err)
+       }
+}
+
+func TestRowsCloseError(t *testing.T) {
+       t.Parallel()
+       db, mock, err := New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       rows := NewRows([]string{"id"}).CloseError(fmt.Errorf("close error"))
+       mock.ExpectQuery("SELECT").WillReturnRows(rows)
+
+       rs, err := db.Query("SELECT")
+       if err != nil {
+               t.Fatalf("unexpected error: %s", err)
+       }
+
+       if err := rs.Close(); err == nil {
+               t.Fatal("expected a close error")
+       }
+
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Fatal(err)
+       }
+}
+
+func TestQuerySingleRow(t *testing.T) {
+       t.Parallel()
+       db, mock, err := New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       rows := NewRows([]string{"id"}).
+               AddRow(1).
+               AddRow(2)
+       mock.ExpectQuery("SELECT").WillReturnRows(rows)
+
+       var id int
+       if err := db.QueryRow("SELECT").Scan(&id); err != nil {
+               t.Fatalf("unexpected error: %s", err)
+       }
+
+       mock.ExpectQuery("SELECT").WillReturnRows(NewRows([]string{"id"}))
+       if err := db.QueryRow("SELECT").Scan(&id); err != sql.ErrNoRows {
+               t.Fatal("expected sql no rows error")
+       }
+
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Fatal(err)
+       }
+}
+
+func TestRowsScanError(t *testing.T) {
+       t.Parallel()
+       db, mock, err := New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       r := NewRows([]string{"col1", "col2"}).AddRow("one", 
"two").AddRow("one", nil)
+       mock.ExpectQuery("SELECT").WillReturnRows(r)
+
+       rs, err := db.Query("SELECT")
+       if err != nil {
+               t.Fatalf("unexpected error: %s", err)
+       }
+       defer rs.Close()
+
+       var one, two string
+       if !rs.Next() || rs.Err() != nil || rs.Scan(&one, &two) != nil {
+               t.Fatal("unexpected error on first row scan")
+       }
+
+       if !rs.Next() || rs.Err() != nil {
+               t.Fatal("unexpected error on second row read")
+       }
+
+       err = rs.Scan(&one, &two)
+       if err == nil {
+               t.Fatal("expected an error for scan, but got none")
+       }
+
+       if err := mock.ExpectationsWereMet(); err != nil {
+               t.Fatal(err)
+       }
+}
+
+func TestCSVRowParser(t *testing.T) {
+       t.Parallel()
+       rs := NewRows([]string{"col1", "col2"}).FromCSVString("a,NULL")
+       db, mock, err := New()
+       if err != nil {
+               t.Fatalf("an error '%s' was not expected when opening a stub 
database connection", err)
+       }
+       defer db.Close()
+
+       mock.ExpectQuery("SELECT").WillReturnRows(rs)
+
+       rw, err := db.Query("SELECT")
+       if err != nil {
+               t.Fatalf("unexpected error: %s", err)
+       }
+       defer rw.Close()
+       var col1 string
+       var col2 []byte
+
+       rw.Next()
+       if err = rw.Scan(&col1, &col2); err != nil {
+               t.Fatalf("unexpected error: %s", err)
+       }
+       if col1 != "a" {
+               t.Fatalf("expected col1 to be 'a', but got [%T]:%+v", col1, 
col1)
+       }
+       if col2 != nil {
+               t.Fatalf("expected col2 to be nil, but got [%T]:%+v", col2, 
col2)
+       }
+}
+
+func TestWrongNumberOfValues(t *testing.T) {
+       // Open new mock database
+       db, mock, err := New()
+       if err != nil {
+               fmt.Println("error creating mock database")
+               return
+       }
+       defer db.Close()
+       defer func() {
+               recover()
+       }()
+       mock.ExpectQuery("SELECT ID FROM 
TABLE").WithArgs(101).WillReturnRows(NewRows([]string{"ID"}).AddRow(101, 
"Hello"))
+       db.Query("SELECT ID FROM TABLE", 101)
+       // shouldn't reach here
+       t.Error("expected panic from query")
+}

Reply via email to