blob: a35196c195629f348c120e7f44ab4fe3345bc414 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Tests for the storage model.
// These tests only test the exported API of the storage model.
//
// NOTE: These tests cannot be run in parallel on the same machine because they
// interact with a fixed database on the machine.
package storage_test
import (
"fmt"
"testing"
_ "github.com/go-sql-driver/mysql"
"github.com/rubenv/sql-migrate"
"v.io/x/lib/dbutil"
"v.io/x/playground/compilerd/storage"
)
var (
dataSourceName = "playground_test@tcp(localhost:3306)/playground_test?parseTime=true"
)
// setup cleans the database, runs migrations, and connects to the database.
// It returns a teardown function that closes the database connection.
func setup(t *testing.T) func() {
// Migrate down then up.
migrations := &migrate.FileMigrationSource{
Dir: "../../migrations",
}
migrate.SetTable("migrations")
sqlConfig := dbutil.SqlConfig{
DataSourceName: dataSourceName,
TLSDisable: true,
}
activeSqlConfig, err := sqlConfig.Activate("")
db, err := activeSqlConfig.NewSqlDBConn("SERIALIZABLE")
if err != nil {
t.Fatalf("Error opening database: %v", err)
}
// Remove any existing tables.
tableNames := []string{"bundle_link", "bundle_data", "migrations"}
for _, tableName := range tableNames {
db.Exec("DROP TABLE " + tableName)
}
if _, err = migrate.Exec(db, "mysql", migrations, migrate.Up); err != nil {
t.Fatalf("Error migrating up: %v", err)
}
if err := db.Close(); err != nil {
t.Fatalf("db.Close() failed: %v", err)
}
// Connect to the storage.
if err := storage.Connect(activeSqlConfig); err != nil {
t.Fatalf("storage.Connect(%v) failed: %v", activeSqlConfig, err)
}
teardown := func() {
if err := storage.Close(); err != nil {
t.Fatalf("storage.Close() failed: %v", err)
}
}
return teardown
}
func TestGetBundleDataByLinkId(t *testing.T) {
defer setup(t)()
// Get with a unknown id should return ErrNotFound.
id := "foobar"
if _, err := storage.GetBundleDataByLinkId(id); err != storage.ErrNotFound {
t.Errorf("Expected GetBundleDataByLinkId with unknown id to return ErrNotFound, but instead got %v", err)
}
// Add a bundle.
json := []byte("mock_json_data")
bLink, _, err := storage.StoreBundleLinkAndData(json)
if err != nil {
t.Fatalf("Expected StoreBundleLinkAndData(%v) not to error, but got %v", json, err)
}
// Bundle should exist.
gotBdata, err := storage.GetBundleDataByLinkId(bLink.Id)
if err != nil {
t.Errorf("Expected GetBundleDataByLinkId(%v) not to error, but got %v", bLink.Id, err)
}
// Bundle should have expected json.
if got, want := gotBdata.Json, string(json); got != want {
t.Errorf("Expected %v to equal %v.", got, want)
}
}
func assertValidLinkDataPair(json string, bLink *storage.BundleLink, bData *storage.BundleData) error {
if string(bLink.Hash) != string(bData.Hash) {
return fmt.Errorf("Expected %v to equal %v", string(bLink.Hash), string(bData.Hash))
}
if bLink.Id == "" {
return fmt.Errorf("Expected bundle link to have id.")
}
if bData.Json != json {
return fmt.Errorf("Expected %v to equal %v", bData.Json, json)
}
return nil
}
func TestStoreBundleLinkAndData(t *testing.T) {
defer setup(t)()
mockJson := []byte("bizbaz")
// Storing the json once should succeed.
bLink1, bData1, err := storage.StoreBundleLinkAndData(mockJson)
if err != nil {
t.Fatalf("StoreBundleLinkAndData(%v) failed: %v", mockJson, err)
}
if err := assertValidLinkDataPair(string(mockJson), bLink1, bData1); err != nil {
t.Fatalf("Got invalid link data pair: %v", err)
}
// Storing the bundle again should succeed.
bLink2, bData2, err := storage.StoreBundleLinkAndData(mockJson)
if err != nil {
t.Fatalf("StoreBundleLinkAndData(%v) failed: %v", mockJson, err)
}
if err := assertValidLinkDataPair(string(mockJson), bLink2, bData2); err != nil {
t.Error("Got invalid link data pair: %v", err)
}
// Bundle links should have different ids.
if bLink1.Id == bLink2.Id {
t.Errorf("Expected bundle links to have different ids, but got %v and %v", bLink1.Id, bLink2.Id)
}
// Bundle datas should have equal hashes.
if want, got := string(bData1.Hash), string(bData2.Hash); want != got {
t.Errorf("Expected bundle datas to have equal hashes, but got %v and %v", want, got)
}
}