Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Refactored validation of entity classes [#1561](https://github.com/ie3-institute/PowerSystemDataModel/issues/1561)
- Changed `operationTime` to `operationFrom` and `operationUntil` in read the docs [1507](https://github.com/ie3-institute/PowerSystemDataModel/issues/1507)
- Refactored validation of value classes [#1561](https://github.com/ie3-institute/PowerSystemDataModel/issues/1561)
- Updated `Couchbase` version within the tests [#1586](https://github.com/ie3-institute/PowerSystemDataModel/issues/1586)

## [8.1.0] - 2025-07-25

Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ dependencies {

// testing
testImplementation "org.apache.groovy:groovy:$groovyBinaryVersion"
testImplementation 'org.apache.groovy:groovy-json:5.0.4'

testImplementation "org.junit.platform:junit-platform-launcher:$junitVersion"
testImplementation "org.junit.jupiter:junit-jupiter:$junitVersion"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class CouchbaseWeatherSourceCosmoIT extends Specification implements TestContain
BucketDefinition bucketDefinition = new BucketDefinition("ie3_in")

@Shared
CouchbaseContainer couchbaseContainer = new CouchbaseContainer("couchbase/server:6.6.0")
CouchbaseContainer couchbaseContainer = new CouchbaseContainer("couchbase/server:8.0.0")
.withBucket(bucketDefinition)
.withExposedPorts(8091, 8092, 8093, 8094, 11210)
.withStartupAttempts(3) // 3 attempts because startup (node renaming) sometimes fails when executed too early
Expand All @@ -42,26 +42,65 @@ class CouchbaseWeatherSourceCosmoIT extends Specification implements TestContain
static String coordinateIdColumnName = "coordinateid"

def setupSpec() {
// Copy import file with json array of documents into docker
MountableFile couchbaseWeatherJsonsFile = getMountableFile("_weather/cosmo/weather.json")
couchbaseContainer.copyFileToContainer(couchbaseWeatherJsonsFile, "/home/weather_cosmo.json")

// create an index for the document keys
couchbaseContainer.execInContainer("cbq",
"-e", "http://localhost:8093",
"-u", couchbaseContainer.username,
"-p", couchbaseContainer.password,
"-s", "CREATE index id_idx ON `" + bucketDefinition.name + "` (META().id);")

//import the json documents from the copied file
couchbaseContainer.execInContainer("cbimport", "json",
"-cluster", "http://localhost:8091",
"--bucket", "ie3_in",
"--username", couchbaseContainer.username,
"--password", couchbaseContainer.password,
"--format", "list",
"--generate-key", "weather::%" + coordinateIdColumnName + "%::%time%",
"--dataset", "file:///home/weather_cosmo.json")
// Create connector to import the data from json document
def importConnector = new CouchbaseConnector(
couchbaseContainer.connectionString,
bucketDefinition.name,
couchbaseContainer.username,
couchbaseContainer.password,
Duration.ofSeconds(30))

// Wait for bucket to be ready
println "Waiting for Couchbase bucket to be ready..."
int maxTries = 10
boolean ready = false
for (int i = 0; i < maxTries; i++) {
try {
importConnector.getSourceFields()
ready = true
println "Couchbase bucket ready"
break
} catch (Exception ex) {
if (i % 10 == 0) {
println "Waiting for bucket... (try ${i+1})"
}
sleep(1000)
}
}

if (!ready) {
println "Couchbase bucket did not become ready in time!"
System.out.flush()
throw new RuntimeException("Couchbase bucket did not become ready in time!")
}

// Insert test data from JSON file
println "Inserting test data from JSON file..."
def jsonFile = new File("src/test/resources/edu/ie3/datamodel/io/source/couchbase/_weather/cosmo/weather.json")
def jsonSlurper = new groovy.json.JsonSlurper()
def weatherDocs = jsonSlurper.parse(jsonFile) as List
def insertCount = 0
weatherDocs.each { doc ->
try {
def coordinateId = doc["coordinateid"]
def time = doc["time"]
def key = "weather::${coordinateId}::${time}"
importConnector.persist(key, doc).join()
insertCount++
} catch (Exception ex) {
println "WARNING: Failed to insert document for coordinateid ${doc["coordinateid"]} and time ${doc["time"]}: ${ex.message}"
}
}
println "Inserted ${insertCount}/${weatherDocs.size()} test documents from JSON file"
importConnector.shutdown()
System.out.flush()

// increased timeout to deal with CI under high load
def connector = new CouchbaseConnector(
Expand All @@ -73,11 +112,14 @@ class CouchbaseWeatherSourceCosmoIT extends Specification implements TestContain
def dtfPattern = "yyyy-MM-dd'T'HH:mm:ssxxx"
def weatherFactory = new CosmoTimeBasedWeatherValueFactory()
source = new CouchbaseWeatherSource(connector, CosmoWeatherTestData.coordinateSource, coordinateIdColumnName, weatherFactory, dtfPattern)
println "setupSpec completed"
System.out.flush()
}

def "The test container can establish a valid connection"() {
when:
def connector = new CouchbaseConnector(couchbaseContainer.connectionString, bucketDefinition.name, couchbaseContainer.username, couchbaseContainer.password)

then:
connector.connectionValid
}
Expand Down Expand Up @@ -119,8 +161,6 @@ class CouchbaseWeatherSourceCosmoIT extends Specification implements TestContain
equalsIgnoreUUID(coordinateToTimeSeries.get(CosmoWeatherTestData.COORDINATE_193187), timeSeries193187)
}



def "A CouchbaseWeatherSource can read all weather data in a given time interval"() {
given:
def timeInterval = new ClosedInterval(CosmoWeatherTestData.TIME_15H, CosmoWeatherTestData.TIME_17H)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import edu.ie3.test.common.IconWeatherTestData
import edu.ie3.test.helper.TestContainerHelper
import edu.ie3.test.helper.WeatherSourceTestHelper
import edu.ie3.util.interval.ClosedInterval
import groovy.json.JsonSlurper
import org.testcontainers.couchbase.BucketDefinition
import org.testcontainers.couchbase.CouchbaseContainer
import org.testcontainers.spock.Testcontainers
Expand All @@ -28,7 +29,7 @@ class CouchbaseWeatherSourceIconIT extends Specification implements TestContaine
BucketDefinition bucketDefinition = new BucketDefinition("ie3_in")

@Shared
CouchbaseContainer couchbaseContainer = new CouchbaseContainer("couchbase/server:6.6.0")
CouchbaseContainer couchbaseContainer = new CouchbaseContainer("couchbase/server:8.0.0")
.withBucket(bucketDefinition)
.withExposedPorts(8091, 8092, 8093, 8094, 11210)
.withStartupAttempts(3) // 3 attempts because startup (node renaming) sometimes fails when executed too early
Expand All @@ -39,26 +40,65 @@ class CouchbaseWeatherSourceIconIT extends Specification implements TestContaine
static String coordinateIdColumnName = "coordinateid"

def setupSpec() {
// Copy import file with json array of documents into docker
def couchbaseWeatherJsonsFile = getMountableFile("_weather/icon/weather.json")
couchbaseContainer.copyFileToContainer(couchbaseWeatherJsonsFile, "/home/weather_icon.json")

// create an index for the document keys
couchbaseContainer.execInContainer("cbq",
"-e", "http://localhost:8093",
"-u", couchbaseContainer.username,
"-p", couchbaseContainer.password,
"-s", "CREATE index id_idx ON `" + bucketDefinition.name + "` (META().id);")

//import the json documents from the copied file
couchbaseContainer.execInContainer("cbimport", "json",
"-cluster", "http://localhost:8091",
"--bucket", "ie3_in",
"--username", couchbaseContainer.username,
"--password", couchbaseContainer.password,
"--format", "list",
"--generate-key", "weather::%" + coordinateIdColumnName + "%::%time%",
"--dataset", "file:///home/weather_icon.json")
// Create connector to import the data from json document
def importConnector = new CouchbaseConnector(
couchbaseContainer.connectionString,
bucketDefinition.name,
couchbaseContainer.username,
couchbaseContainer.password,
Duration.ofSeconds(30))

// Wait for bucket to be ready
println "Waiting for Couchbase bucket to be ready..."
int maxTries = 10
boolean ready = false
for (int i = 0; i < maxTries; i++) {
try {
importConnector.getSourceFields()
ready = true
println "Couchbase bucket ready"
break
} catch (Exception ex) {
if (i % 10 == 0) {
println "Waiting for bucket... (try ${i+1})"
}
sleep(1000)
}
}

if (!ready) {
println "Couchbase bucket did not become ready in time!"
System.out.flush()
throw new RuntimeException("Couchbase bucket did not become ready in time!")
}

// Insert test data from JSON file
println "Inserting test data from JSON file..."
def jsonFile = new File("src/test/resources/edu/ie3/datamodel/io/source/couchbase/_weather/icon/weather.json")
def jsonSlurper = new groovy.json.JsonSlurper()
def weatherDocs = jsonSlurper.parse(jsonFile) as List
def insertCount = 0
weatherDocs.each { doc ->
try {
def coordinateId = doc["coordinateid"]
def time = doc["time"]
def key = "weather::${coordinateId}::${time}"
importConnector.persist(key, doc).join()
insertCount++
} catch (Exception ex) {
println "WARNING: Failed to insert document for coordinateid ${doc["coordinateid"]} and time ${doc["time"]}: ${ex.message}"
}
}
println "Inserted ${insertCount}/${weatherDocs.size()} test documents from JSON file"
importConnector.shutdown()
System.out.flush()

// increased timeout to deal with CI under high load
def connector = new CouchbaseConnector(
Expand All @@ -70,6 +110,8 @@ class CouchbaseWeatherSourceIconIT extends Specification implements TestContaine
def dtfPattern = "yyyy-MM-dd'T'HH:mm:ssxxx"
def weatherFactory = new IconTimeBasedWeatherValueFactory()
source = new CouchbaseWeatherSource(connector, IconWeatherTestData.coordinateSource, coordinateIdColumnName, weatherFactory, dtfPattern)
println "setupSpec completed"
System.out.flush()
}

def "The test container can establish a valid connection"() {
Expand Down