blob: 409b212386f8160f7f25b033ada1d5a1e3f0afe2 [file] [log] [blame]
package sqlsubscriptionstore
import (
"context"
"sort"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.skia.org/infra/go/sql/pool"
"go.skia.org/infra/perf/go/sql/sqltest"
"go.skia.org/infra/perf/go/subscription"
pb "go.skia.org/infra/perf/go/subscription/proto/v1"
)
func setUp(t *testing.T) (subscription.Store, pool.Pool) {
db := sqltest.NewSpannerDBForTests(t, "subscriptionstore")
store, err := New(db)
require.NoError(t, err)
return store, db
}
// Insert two valid subscriptions and ensure they're queryable.
func TestInsert_ValidSubscriptions(t *testing.T) {
ctx := context.Background()
store, db := setUp(t)
s := []*pb.Subscription{
{
Name: "Test Subscription 1",
Revision: "abcd",
BugLabels: []string{"A", "B"},
Hotlists: []string{"C", "D"},
BugComponent: "Component1>Subcomponent1",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
},
{
Name: "Test Subscription 2",
Revision: "abcd",
BugLabels: []string{"1", "2"},
Hotlists: []string{"3", "4"},
BugComponent: "Component2>Subcomponent2",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
},
}
tx, err := db.Begin(ctx)
require.NoError(t, err)
err = store.InsertSubscriptions(ctx, s, tx)
require.NoError(t, err)
err = tx.Commit(ctx)
require.NoError(t, err)
actual := getSubscriptionsFromDb(t, ctx, db)
assert.ElementsMatch(t, actual, s)
}
// Test inserting two subscriptions with same primary key. The transaction
// should fail on second insert and no subscriptions should live in the DB
// due to transaction rollback.
func TestInsert_DuplicateSubscriptionKeys(t *testing.T) {
ctx := context.Background()
store, db := setUp(t)
s := []*pb.Subscription{
{
Name: "Test Subscription 1",
Revision: "abcd",
BugLabels: []string{"A", "B"},
Hotlists: []string{"C", "D"},
BugComponent: "Component1>Subcomponent1",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
},
{
Name: "Test Subscription 1",
Revision: "abcd",
BugLabels: []string{"1", "2"},
Hotlists: []string{"3", "4"},
BugComponent: "Component2>Subcomponent2",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
},
}
tx, err := db.Begin(ctx)
require.NoError(t, err)
err = store.InsertSubscriptions(ctx, s, tx)
require.Error(t, err)
err = tx.Rollback(ctx)
require.NoError(t, err)
actual := getSubscriptionsFromDb(t, ctx, db)
assert.Empty(t, actual)
}
// Test inserting two subscriptions with the same name but different revisions.
// The transaction should succeed.
func TestInsert_SameNameDifferentRevision(t *testing.T) {
ctx := context.Background()
store, db := setUp(t)
s1 := &pb.Subscription{
Name: "Test Subscription",
Revision: "abcd",
BugLabels: []string{"A", "B"},
Hotlists: []string{"C", "D"},
BugComponent: "Component1>Subcomponent1",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
}
s2 := &pb.Subscription{
Name: "Test Subscription",
Revision: "efgh",
BugLabels: []string{"1", "2"},
Hotlists: []string{"3", "4"},
BugComponent: "Component2>Subcomponent2",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
}
tx, err := db.Begin(ctx)
require.NoError(t, err)
err = store.InsertSubscriptions(ctx, []*pb.Subscription{s1, s2}, tx)
require.NoError(t, err)
err = tx.Commit(ctx)
require.NoError(t, err)
actual := getSubscriptionsFromDb(t, ctx, db)
assert.ElementsMatch(t, actual, []*pb.Subscription{s1, s2})
}
func TestInsert_EmptyList(t *testing.T) {
ctx := context.Background()
store, db := setUp(t)
s := []*pb.Subscription{}
tx, err := db.Begin(ctx)
require.NoError(t, err)
err = store.InsertSubscriptions(ctx, s, tx)
require.NoError(t, err)
err = tx.Commit(ctx)
require.NoError(t, err)
actual := getSubscriptionsFromDb(t, ctx, db)
assert.Empty(t, actual)
}
func TestGet_ValidSubscription(t *testing.T) {
ctx := context.Background()
store, db := setUp(t)
s := &pb.Subscription{
Name: "Test Subscription 1",
Revision: "abcd",
BugLabels: []string{"A", "B"},
Hotlists: []string{"C", "D"},
BugComponent: "Component1>Subcomponent1",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
}
insertSubscriptionToDb(t, ctx, db, s, true)
actual, err := store.GetSubscription(ctx, "Test Subscription 1", "abcd")
require.NoError(t, err)
assert.Equal(t, actual, s)
}
func TestGet_AllSubscriptionsUniqByName(t *testing.T) {
ctx := context.Background()
store, db := setUp(t)
s := &pb.Subscription{
Name: "Test Subscription 1",
Revision: "abcd",
BugLabels: []string{"A", "B"},
Hotlists: []string{"C", "D"},
BugComponent: "Component1>Subcomponent1",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
}
s1 := &pb.Subscription{
Name: "Test Subscription 2",
Revision: "bcde",
BugLabels: []string{"A", "B"},
Hotlists: []string{"C", "D"},
BugComponent: "Component1>Subcomponent1",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
}
insertSubscriptionToDb(t, ctx, db, s, true)
insertSubscriptionToDb(t, ctx, db, s1, false)
actual, err := store.GetAllSubscriptions(ctx)
require.NoError(t, err)
expected := []*pb.Subscription{s, s1}
sort.Slice(actual, func(i int, j int) bool {
return actual[i].Name < actual[j].Name
})
assert.Equal(t, actual, expected)
}
// Test that checks nil is returned when retrieving a non-existent subscription.
func TestGet_NonExistent(t *testing.T) {
ctx := context.Background()
store, _ := setUp(t)
sub, err := store.GetSubscription(ctx, "Fake Subscription", "abcd")
require.NoError(t, err)
assert.Nil(t, sub)
}
// Tests that we only retrieve latest subscriptions according to
// version.
func TestGet_AllActiveSubscriptions(t *testing.T) {
ctx := context.Background()
store, db := setUp(t)
s := &pb.Subscription{
Name: "Test Subscription 1",
Revision: "abcd",
BugLabels: []string{"A", "B"},
Hotlists: []string{"C", "D"},
BugComponent: "Component1>Subcomponent1",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
}
s1 := &pb.Subscription{
Name: "Test Subscription 2",
Revision: "bcde",
BugLabels: []string{"A", "B"},
Hotlists: []string{"C", "D"},
BugComponent: "Component1>Subcomponent1",
BugPriority: 1,
BugSeverity: 2,
BugCcEmails: []string{
"abcd@efg.com",
"1234@567.com",
},
ContactEmail: "test@owner.com",
}
insertSubscriptionToDb(t, ctx, db, s, true)
insertSubscriptionToDb(t, ctx, db, s1, false)
actual, err := store.GetAllActiveSubscriptions(ctx)
require.NoError(t, err)
expected := []*pb.Subscription{s}
assert.Equal(t, actual, expected)
}
func insertSubscriptionToDb(t *testing.T, ctx context.Context, db pool.Pool, subscription *pb.Subscription, is_active bool) {
const query = `INSERT INTO Subscriptions
(name, revision, bug_labels, hotlists, bug_component, bug_priority, bug_severity, bug_cc_emails, contact_email, is_active)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`
if _, err := db.Exec(ctx, query, subscription.Name, subscription.Revision, subscription.BugLabels, subscription.Hotlists, subscription.BugComponent, subscription.BugPriority, subscription.BugSeverity, subscription.BugCcEmails, subscription.ContactEmail, is_active); err != nil {
require.NoError(t, err)
}
}
func getSubscriptionsFromDb(t *testing.T, ctx context.Context, db pool.Pool) []*pb.Subscription {
actual := []*pb.Subscription{}
rows, _ := db.Query(ctx, "SELECT name, revision, bug_labels, hotlists, bug_component, bug_priority, bug_severity, bug_cc_emails, contact_email FROM Subscriptions")
for rows.Next() {
subscriptionInDb := &pb.Subscription{}
if err := rows.Scan(&subscriptionInDb.Name, &subscriptionInDb.Revision, &subscriptionInDb.BugLabels, &subscriptionInDb.Hotlists, &subscriptionInDb.BugComponent, &subscriptionInDb.BugPriority, &subscriptionInDb.BugSeverity, &subscriptionInDb.BugCcEmails, &subscriptionInDb.ContactEmail); err != nil {
require.NoError(t, err)
}
actual = append(actual, subscriptionInDb)
}
return actual
}