package db_test import ( "context" "net/url" "strings" "testing" "github.com/Masterminds/semver" "github.com/go-flucky/flucky/pkg/storage/db" "github.com/go-flucky/flucky/pkg/types" "github.com/go-flucky/flucky/test/goldenfiles" "github.com/stretchr/testify/require" ) type test struct { Name string Test func(*testing.T) } var ( database db.Database postgresContainerImage string = "docker.io/postgres/postgres" storageEndpointString string = "postgres://flucky:flucky@markus-pc.trier.cryptic.systems/postgres?sslmode=disable" goldenDevicesFilePath string = "test/goldenfiles/json/goldenDevices.json" goldenSensorsFilePath string = "test/goldenfiles/json/goldenSensors.json" goldenMeasuredValuesFilePath string = "test/goldenfiles/json/goldenMeasuredValuesUncompressedRounded.json" goldenPressuresFilePath string = "test/goldenfiles/json/goldenPressuresUncompressedRounded.json" goldenHumiditiesFilePath string = "test/goldenfiles/json/goldenHumiditiesUncompressedRounded.json" goldenTemperaturesFilePath string = "test/goldenfiles/json/goldenTemperaturesUncompressedRounded.json" goldenDevices []*types.Device goldenSensors []*types.Sensor goldenMeasuredValues []*types.MeasuredValue goldenPressures []*types.MeasuredValue goldenHumidites []*types.MeasuredValue goldenTemperatures []*types.MeasuredValue ) func load(t *testing.T) { require := require.New(t) d, err := goldenfiles.GetGoldenDevices(goldenDevicesFilePath) require.NoError(err) goldenDevices = d s, err := goldenfiles.GetGoldenSensors(goldenSensorsFilePath) require.NoError(err) goldenSensors = s hum, err := goldenfiles.GetGoldenMeasuredValues(goldenHumiditiesFilePath) require.NoError(err) goldenHumidites = hum mv, err := goldenfiles.GetGoldenMeasuredValues(goldenMeasuredValuesFilePath) require.NoError(err) goldenMeasuredValues = mv pres, err := goldenfiles.GetGoldenMeasuredValues(goldenPressuresFilePath) require.NoError(err) goldenPressures = pres temp, err := goldenfiles.GetGoldenMeasuredValues(goldenTemperaturesFilePath) require.NoError(err) goldenTemperatures = temp } func TestPostgres(t *testing.T) { require := require.New(t) load(t) storageEndpoint, err := url.Parse(storageEndpointString) require.Nil(err) db, err := db.New(storageEndpoint) database = db require.Nil(err) tests := []*test{ &test{ Name: "schema", Test: testSchemaCreate, }, &test{ Name: "insertInfo", Test: testInsertInfo, }, &test{ Name: "insertDevices", Test: testInsertDevices, }, &test{ Name: "insertSensors", Test: testInsertSensors, }, &test{ Name: "insertHumidity", Test: testInsertHumidity, }, &test{ Name: "insertPressure", Test: testInsertPressure, }, &test{ Name: "insertTemperatures", Test: testInsertTemperatures, }, &test{ Name: "selectHumidities", Test: testSelectHumidities, }, &test{ Name: "selectPressures", Test: testSelectPressures, }, &test{ Name: "selectTemperatures", Test: testSelectTemperatures, }, // &test{ // Name: "selectMeasuredValues", // Test: testSelectMeasuredValues, // }, &test{ Name: "deleteHumidities", Test: testDeleteHumidity, }, &test{ Name: "deleteInfo", Test: testDeleteInfo, }, &test{ Name: "deletePressures", Test: testDeletePressures, }, &test{ Name: "deleteTemperatures", Test: testDeleteTemperatures, }, &test{ Name: "insertMeasuredValues", Test: testInsertMeasuredValues, }, &test{ Name: "deleteMeasuredValues", Test: testDeleteMeasuredValues, }, &test{ Name: "deleteSensors", Test: testDeleteSensors, }, &test{ Name: "deleteDevices", Test: testDeleteDevices, }, &test{ Name: "updateInfo", Test: testUpdateInfo, }, } for _, test := range tests { t.Run(test.Name, test.Test) } } func testSchemaCreate(t *testing.T) { require := require.New(t) homePath := "pkg/storage/db/sql/psql/schema" sqlAssetFiles, err := db.AssetDir(homePath) require.NoError(err) ctx := context.Background() for _, sqlAssetFile := range sqlAssetFiles { fromVersion, err := semver.NewVersion(strings.ReplaceAll(sqlAssetFile, ".sql", "")) require.NoError(err) err = database.Schema(ctx, fromVersion) require.NoError(err) } } func testInsertDevices(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.InsertDevices(ctx, goldenDevices) require.NoError(err) for _, goldenDevice := range goldenDevices { testDevice, err := database.SelectDeviceByID(ctx, goldenDevice.ID) require.NoError(err) goldenfiles.CompareMeasuredValues(t, goldenDevice, testDevice) } } func testInsertSensors(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.InsertSensors(ctx, goldenSensors) require.NoError(err) for _, goldenSensor := range goldenSensors { testSensor, err := database.SelectSensorByID(ctx, goldenSensor.ID) require.NoError(err) goldenfiles.CompareMeasuredValues(t, goldenSensor, testSensor) } } func testInsertHumidity(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.InsertMeasuredValues(ctx, goldenHumidites) require.NoError(err) for _, goldenHumidity := range goldenHumidites { testHumidity, err := database.SelectHumidityByID(ctx, goldenHumidity.ID) require.NoError(err) goldenfiles.CompareMeasuredValues(t, []*types.MeasuredValue{testHumidity}, []*types.MeasuredValue{testHumidity}) } } func testInsertInfo(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.InsertInfo(ctx, "test", "value") require.NoError(err) value, err := database.SelectInfo(ctx, "test") require.NoError(err) require.Equal("value", value) } func testInsertMeasuredValues(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.InsertMeasuredValues(ctx, goldenMeasuredValues) require.NoError(err) for _, goldenMeasuredValue := range goldenMeasuredValues { testMeasuredValue, err := database.SelectMeasuredValuesByIDAndType(ctx, goldenMeasuredValue.ID, goldenMeasuredValue.ValueType) require.NoError(err) goldenfiles.CompareMeasuredValues(t, []*types.MeasuredValue{goldenMeasuredValue}, []*types.MeasuredValue{testMeasuredValue}) } } func testInsertPressure(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.InsertMeasuredValues(ctx, goldenPressures) require.NoError(err) for _, goldenPressure := range goldenPressures { testPressure, err := database.SelectPressureByID(ctx, goldenPressure.ID) require.NoError(err) goldenfiles.CompareMeasuredValues(t, []*types.MeasuredValue{testPressure}, []*types.MeasuredValue{testPressure}) } } func testInsertTemperatures(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.InsertMeasuredValues(ctx, goldenTemperatures) require.NoError(err) for _, goldenTemperature := range goldenTemperatures { testTemperature, err := database.SelectTemperatureByID(ctx, goldenTemperature.ID) require.NoError(err) goldenfiles.CompareMeasuredValues(t, []*types.MeasuredValue{goldenTemperature}, []*types.MeasuredValue{testTemperature}) } } func testSelectHumidities(t *testing.T) { require := require.New(t) ctx := context.Background() humidities, err := database.SelectHumidities(ctx) require.NoError(err) goldenfiles.CompareMeasuredValues(t, goldenHumidites, humidities) } func testSelectMeasuredValues(t *testing.T) { require := require.New(t) ctx := context.Background() measuredValues, err := database.SelectMeasuredValues(ctx) require.NoError(err) goldenfiles.CompareMeasuredValues(t, goldenMeasuredValues, measuredValues) } func testSelectPressures(t *testing.T) { require := require.New(t) ctx := context.Background() pressures, err := database.SelectPressures(ctx) require.NoError(err) goldenfiles.CompareMeasuredValues(t, goldenPressures, pressures) } func testSelectTemperatures(t *testing.T) { require := require.New(t) ctx := context.Background() temperatures, err := database.SelectTemperatures(ctx) require.NoError(err) goldenfiles.CompareMeasuredValues(t, goldenTemperatures, temperatures) } func testDeleteDevices(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.DeleteDevices(ctx, goldenDevices) require.NoError(err) for _, goldenDevice := range goldenDevices { _, err := database.SelectDeviceByID(ctx, goldenDevice.ID) require.Error(err) } } func testDeleteSensors(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.DeleteSensors(ctx, goldenSensors) require.NoError(err) for _, goldenSensor := range goldenSensors { _, err := database.SelectDeviceByID(ctx, goldenSensor.ID) require.Error(err) } } func testDeleteHumidity(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.DeleteMeasuredValues(ctx, goldenHumidites) require.NoError(err) for _, goldenHumidity := range goldenHumidites { _, err := database.SelectHumidityByID(ctx, goldenHumidity.ID) require.Error(err) } } func testDeleteInfo(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.DeleteInfo(ctx, "test") require.NoError(err) _, err = database.SelectInfo(ctx, "test") require.Error(err) } func testDeleteMeasuredValues(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.DeleteMeasuredValues(ctx, goldenMeasuredValues) require.NoError(err) for _, goldenMeasuredValue := range goldenMeasuredValues { _, err := database.SelectPressureByID(ctx, goldenMeasuredValue.ID) require.Error(err) } } func testDeletePressures(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.DeleteMeasuredValues(ctx, goldenPressures) require.NoError(err) for _, goldenPressure := range goldenPressures { _, err := database.SelectPressureByID(ctx, goldenPressure.ID) require.Error(err) } } func testDeleteTemperatures(t *testing.T) { require := require.New(t) ctx := context.Background() err := database.DeleteMeasuredValues(ctx, goldenTemperatures) require.NoError(err) for _, goldenTemperature := range goldenTemperatures { _, err := database.SelectTemperatureByID(ctx, goldenTemperature.ID) require.Error(err) } } func testUpdateInfo(t *testing.T) { require := require.New(t) ctx := context.Background() // VALID err := database.InsertInfo(ctx, "key", "value") require.NoError(err) err = database.UpdateInfo(ctx, "key", "value2") require.NoError(err) value, err := database.SelectInfo(ctx, "key") require.NoError(err) require.Equal("value2", value) err = database.DeleteInfo(ctx, "key") require.NoError(err) // INVALID err = database.UpdateInfo(ctx, "key2", "value") require.Error(err) }