Hotlistid 741888 (#16)

* [65464133]: Update tests for handling concurrent writes. Add Unlocking of Mutex in Negative case.

* Fix testcase for testing concurrency.

* Add couple more tests.

* Fix test to cover more cases.
diff --git a/data/data.go b/data/data.go
index 537ffe0..8eded28 100644
--- a/data/data.go
+++ b/data/data.go
@@ -63,6 +63,18 @@
 	return d.db.Ping()
 }
 
+func (d *ApidDb) SetMaxIdleConns(n int) {
+	 d.db.SetMaxIdleConns(n)
+}
+
+func (d *ApidDb) SetMaxOpenConns(n int) {
+	d.db.SetMaxOpenConns(n)
+}
+
+func (d *ApidDb) SetConnMaxLifetime(du time.Duration) {
+	d.db.SetConnMaxLifetime(du)
+}
+
 func (d *ApidDb) Prepare(query string) (*sql.Stmt, error) {
 	return d.db.Prepare(query)
 }
@@ -83,6 +95,7 @@
 	d.mutex.Lock()
 	tx, err := d.db.Begin()
 	if err != nil {
+		d.mutex.Unlock()
 		return nil, err
 	}
 	return &Tx{
diff --git a/data/data_test.go b/data/data_test.go
index 71dfb26..f17511b 100644
--- a/data/data_test.go
+++ b/data/data_test.go
@@ -26,7 +26,7 @@
 )
 
 const (
-	count    = 5000
+	count    = 500
 	setupSql = `
 		CREATE TABLE test_1 (id INTEGER PRIMARY KEY, counter TEXT);
 		CREATE TABLE test_2 (id INTEGER PRIMARY KEY, counter TEXT);`
@@ -48,7 +48,6 @@
 		_, err = apid.Data().DBVersionForID("common", "base")
 		Expect(err).To(HaveOccurred())
 	})
-
 	It("should be able to change versions of a datbase", func() {
 		var versions []string
 		var dbs []apid.DB
@@ -82,8 +81,10 @@
 		Expect(data.DBPath(id)).ShouldNot(BeAnExistingFile())
 	})
 
-	It("should handle concurrent read & serialized write", func() {
+	It("should handle concurrent read & serialized write, and throttle", func() {
 		db, err := apid.Data().DBForID("test")
+		db.SetMaxOpenConns(10)
+		db.SetMaxIdleConns(10)
 		Expect(err).NotTo(HaveOccurred())
 		setup(db)
 		finished := make(chan bool, count+1)
@@ -104,11 +105,15 @@
 
 		for i := 0; i < count+1; i++ {
 			<-finished
+			// Since conns are shared, will always be <= 10
+			Expect(db.Stats().OpenConnections).Should(BeNumerically("<=", 10))
 		}
 	}, 10)
 
 	It("should handle concurrent write", func() {
 		db, err := apid.Data().DBForID("test_write")
+		db.SetMaxOpenConns(10)
+		db.SetMaxIdleConns(10)
 		Expect(err).NotTo(HaveOccurred())
 		setup(db)
 		finished := make(chan bool, count)
@@ -122,6 +127,8 @@
 
 		for i := 0; i < count; i++ {
 			<-finished
+			// Only one connection should get opened, as connections are serialized.
+			Expect(db.Stats().OpenConnections).To(Equal(1))
 		}
 	}, 10)
 })
diff --git a/data_service.go b/data_service.go
index c606e10..355566d 100644
--- a/data_service.go
+++ b/data_service.go
@@ -17,6 +17,7 @@
 import (
 	"context"
 	"database/sql"
+	"time"
 )
 
 type DataService interface {
@@ -40,6 +41,9 @@
 	QueryRow(query string, args ...interface{}) *sql.Row
 	Begin() (Tx, error)
 	Stats() sql.DBStats
+	SetConnMaxLifetime(d time.Duration)
+	SetMaxIdleConns(n int)
+	SetMaxOpenConns(n int)
 	//Close() error
 	//Stats() sql.DBStats
 	//Driver() driver.Driver