Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tests/acre_test.go → integration/acre_test.gox
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests
package integration

import (
"testing"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests
package integration

import (
"context"
Expand Down
15 changes: 15 additions & 0 deletions integration/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package integration

import "github.com/opentdf/opentdf-v2-poc/internal/config"

var Config *config.Config

func init() {
Config = &config.Config{}

Config.DB.User = "postgres"
Config.DB.Password = "postgres"
Config.DB.Host = "localhost"
Config.DB.Port = 5432
Config.DB.Database = "opentdf-test"
}
193 changes: 193 additions & 0 deletions integration/fixtures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
package integration

import (
"context"
"log/slog"
"os"
"strings"

"github.com/opentdf/opentdf-v2-poc/internal/db"
"gopkg.in/yaml.v2"
)

var fixtureFilename = "testdata/fixtures.yaml"

type fixtureMetadata struct {
TableName string `yaml:"table_name"`
Columns []string `yaml:"columns"`
}
type fixtureData struct {
Namespaces struct {
Metadata fixtureMetadata `yaml:"metadata"`
Data map[string]struct {
Id string `yaml:"id"`
Name string `yaml:"name"`
} `yaml:"data"`
} `yaml:"namespaces"`
Attributes struct {
Metadata fixtureMetadata `yaml:"metadata"`
Data map[string]struct {
Id string `yaml:"id"`
NamespaceId string `yaml:"namespace_id"`
Name string `yaml:"name"`
Rule string `yaml:"rule"`
} `yaml:"data"`
} `yaml:"attributes"`
AttributeValues struct {
Metadata fixtureMetadata `yaml:"metadata"`
Data map[string]struct {
Id string `yaml:"id"`
AttributeDefinitionId string `yaml:"attribute_definition_id"`
Value string `yaml:"value"`
Members []string `yaml:"members"`
} `yaml:"data"`
} `yaml:"attribute_values"`
SubjectMappings struct {
Metadata fixtureMetadata `yaml:"metadata"`
Data map[string]struct {
Id string `yaml:"id"`
Operator string `yaml:"operator"`
SubjectAttribute string `yaml:"subject_attribute"`
SubjectAttributeValues []string `yaml:"subject_attribute_values"`
} `yaml:"data"`
} `yaml:"subject_mappings"`
}

type Fixtures struct {
db *db.Client
d fixtureData
}

func NewFixture(dbClient *db.Client) Fixtures {
f := Fixtures{
db: dbClient,
}

slog.Info("🏠 loading fixtures")
c, err := os.ReadFile(fixtureFilename)
if err != nil {
slog.Error("could not read "+fixtureFilename, slog.String("error", err.Error()))
panic(err)
}

if err := yaml.Unmarshal(c, &f.d); err != nil {
slog.Error("could not unmarshal "+fixtureFilename, slog.String("error", err.Error()))
panic(err)
}

return f
}

func (f *Fixtures) provisionData() {
slog.Info("📦 provisioning namespace data", slog.String("table", f.d.Namespaces.Metadata.TableName))
var namespaceRows int64
for key, d := range f.d.Namespaces.Data {
namespaceRows += f.execInsert(
key,
f.d.Namespaces.Metadata.TableName,
f.d.Namespaces.Metadata.Columns,
[]string{
dbStringWrap(d.Id),
dbStringWrap(d.Name),
},
)
}

slog.Info("📦 provisioning attribute data", slog.String("table", f.d.Attributes.Metadata.TableName))
var attributeRows int64
for key, d := range f.d.Attributes.Data {
attributeRows += f.execInsert(
key,
f.d.Attributes.Metadata.TableName,
f.d.Attributes.Metadata.Columns,
[]string{
dbStringWrap(d.Id),
dbStringWrap(d.NamespaceId),
dbStringWrap(d.Name),
dbStringWrap(d.Rule),
},
)
}

slog.Info("📦 provisioning attribute value data", slog.String("table", f.d.AttributeValues.Metadata.TableName))
var attributeValueRows int64
for key, d := range f.d.AttributeValues.Data {
attributeValueRows += f.execInsert(
key,
f.d.AttributeValues.Metadata.TableName,
f.d.AttributeValues.Metadata.Columns,
[]string{
dbStringWrap(d.Id),
dbStringWrap(d.AttributeDefinitionId),
dbStringWrap(d.Value),
dbUUIDArrayWrap(d.Members),
},
)
}

slog.Info("📦 provisioning subject mapping data", slog.String("table", f.d.SubjectMappings.Metadata.TableName))
var subjectMappingRows int64
for key, d := range f.d.SubjectMappings.Data {
subjectMappingRows += f.execInsert(
key,
f.d.SubjectMappings.Metadata.TableName,
f.d.SubjectMappings.Metadata.Columns,
[]string{
dbStringWrap(d.Id),
dbStringWrap(d.Operator),
dbStringWrap(d.SubjectAttribute),
dbStringArrayWrap(d.SubjectAttributeValues),
},
)
}

slog.Info("📦 provisioned fixtures data", slog.Int64("namespace_rows", namespaceRows), slog.Int64("attribute_rows", attributeRows), slog.Int64("attribute_value_rows", attributeValueRows), slog.Int64("subject_mapping_rows", subjectMappingRows))
}

func dbStringArrayWrap(values []string) string {
// if len(values) == 0 {
// return "null"
// }
var vs []string
for _, v := range values {
vs = append(vs, dbStringWrap(v))
}
return "ARRAY [" + strings.Join(vs, ",") + "]"
}

func dbUUIDArrayWrap(v []string) string {
return "(" + dbStringArrayWrap(v) + ")" + "::uuid[]"
}

func dbStringWrap(v string) string {
return "'" + v + "'"
}

func dbTableName(v string) string {
return db.Schema + "." + v
}

func (f *Fixtures) execInsert(key string, table string, columns []string, values []string) int64 {
sql := "INSERT INTO " + dbTableName(table) + " (" + strings.Join(columns, ",") + ") VALUES (" + strings.Join(values, ",") + ")"
pconn, err := f.db.Exec(context.Background(), sql)
if err != nil {
slog.Error("could not provision data", slog.String("table_name", table), slog.String("error", err.Error()))
panic(err)
}
return pconn.RowsAffected()
}

func (f *Fixtures) truncateAllTables() {
slog.Info("🗑 truncating all tables")
sql := "TRUNCATE TABLE " +
dbTableName(f.d.Namespaces.Metadata.TableName) + ", " +
dbTableName(f.d.Attributes.Metadata.TableName) + ", " +
dbTableName(f.d.AttributeValues.Metadata.TableName) + ", " +
dbTableName(f.d.SubjectMappings.Metadata.TableName) + " CASCADE"

_, err := f.db.Exec(context.Background(), sql)
if err != nil {
slog.Error("could not truncate tables", slog.String("error", err.Error()))
panic(err)
}
}
93 changes: 55 additions & 38 deletions tests/main_test.go → integration/main_test.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,39 @@
package tests
package integration

import (
"context"
"fmt"
"log/slog"
"os"
"testing"
"time"

"github.com/creasty/defaults"
"github.com/opentdf/opentdf-v2-poc/cmd"
"github.com/opentdf/opentdf-v2-poc/internal/config"
"github.com/opentdf/opentdf-v2-poc/internal/db"
"github.com/opentdf/opentdf-v2-poc/internal/opa"
"github.com/opentdf/opentdf-v2-poc/internal/server"
tc "github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)

var DBClient *db.Client
var fixtures Fixtures

func init() {
fmt.Print("=====================================================================================\n\n")
fmt.Print(" Integration Tests\n\n")
fmt.Print(" Testcontainers is used to run these integration tests. To get this working please\n")
fmt.Print(" ensure you have Docker installed and running. If you are using Podman, please set\n")
fmt.Print(" the following environment variables:\n\n")
fmt.Print(" export TESTCONTAINERS_PODMAN=true;\n")
fmt.Print(" export TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED=true;\n")
fmt.Print(" export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock;\n\n")
fmt.Print(" For more information please see: https://www.testcontainers.org/\n\n")
fmt.Print("=====================================================================================\n\n")
}

func TestMain(m *testing.M) {
ctx := context.Background()
conf := &config.Config{}
// conf := &config.Config{}
conf := Config

if err := defaults.Set(conf); err != nil {
slog.Error("could not set defaults", slog.String("error", err.Error()))
Expand Down Expand Up @@ -58,6 +72,7 @@ func TestMain(m *testing.M) {
Started: true,
}

slog.Info("📀 starting postgres container")
postgres, err := tc.GenericContainer(context.Background(), req)
if err != nil {
slog.Error("could not start postgres container", slog.String("error", err.Error()))
Expand All @@ -66,6 +81,7 @@ func TestMain(m *testing.M) {

// Cleanup the container
defer func() {
slog.Info("🛑 stopping postgres container")
if err := postgres.Terminate(ctx); err != nil {
slog.Error("could not stop postgres container", slog.String("error", err.Error()))
return
Expand All @@ -84,47 +100,48 @@ func TestMain(m *testing.M) {

conf.DB.Port = port.Int()

dbClient, err := db.NewClient(conf.DB)
DBClient, err := db.NewClient(conf.DB)
if err != nil {
slog.Error("issue creating database client", slog.String("error", err.Error()))
panic(err)
}

applied, err := dbClient.RunMigrations()
applied, err := DBClient.RunMigrations()
if err != nil {
slog.Error("issue running migrations", slog.String("error", err.Error()))
panic(err)
}

slog.Info("applied migrations", slog.Int("count", applied))

otdf, err := server.NewOpenTDFServer(conf.Server)
if err != nil {
slog.Error("issue creating opentdf server", slog.String("error", err.Error()))
panic(err)
}
defer otdf.Stop()

slog.Info("starting opa engine")
// Start the opa engine
conf.OPA.Embedded = true
eng, err := opa.NewEngine(conf.OPA)
if err != nil {
slog.Error("could not start opa engine", slog.String("error", err.Error()))
panic(err)
}
defer eng.Stop(context.Background())

// Register the services
err = cmd.RegisterServices(*conf, otdf, dbClient, eng)
if err != nil {
slog.Error("issue registering services", slog.String("error", err.Error()))
panic(err)
}

// Start the server
slog.Info("starting opentdf server", slog.Int("grpcPort", conf.Server.Grpc.Port), slog.Int("httpPort", conf.Server.HTTP.Port))
otdf.Run()
slog.Info("🚚 applied migrations", slog.Int("count", applied))

fixtures = NewFixture(DBClient)

// otdf, err := server.NewOpenTDFServer(conf.Server)
// if err != nil {
// slog.Error("issue creating opentdf server", slog.String("error", err.Error()))
// panic(err)
// }
// defer otdf.Stop()

// slog.Info("starting opa engine")
// // Start the opa engine
// conf.OPA.Embedded = true
// eng, err := opa.NewEngine(conf.OPA)
// if err != nil {
// slog.Error("could not start opa engine", slog.String("error", err.Error()))
// panic(err)
// }
// defer eng.Stop(context.Background())

// // Register the services
// err = cmd.RegisterServices(*conf, otdf, dbClient, eng)
// if err != nil {
// slog.Error("issue registering services", slog.String("error", err.Error()))
// panic(err)
// }

// // Start the server
// slog.Info("starting opentdf server", slog.Int("grpcPort", conf.Server.Grpc.Port), slog.Int("httpPort", conf.Server.HTTP.Port))
// otdf.Run()

m.Run()
}
Loading