summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opendc-compute/opendc-compute-workload/build.gradle.kts1
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt6
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt11
-rw-r--r--opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt55
-rw-r--r--opendc-trace/opendc-trace-opendc/build.gradle.kts (renamed from opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt)34
-rw-r--r--opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt (renamed from opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt)8
-rw-r--r--opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt (renamed from opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt)8
-rw-r--r--opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt (renamed from opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt)8
-rw-r--r--opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt (renamed from opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt)8
-rw-r--r--opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt (renamed from opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt)12
-rw-r--r--opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt82
-rw-r--r--opendc-trace/opendc-trace-opendc/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat1
-rw-r--r--opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt117
-rw-r--r--opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquetbin0 -> 1582 bytes
-rw-r--r--opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquetbin0 -> 83524 bytes
-rw-r--r--settings.gradle.kts1
16 files changed, 245 insertions, 107 deletions
diff --git a/opendc-compute/opendc-compute-workload/build.gradle.kts b/opendc-compute/opendc-compute-workload/build.gradle.kts
index d67bbc66..a651633d 100644
--- a/opendc-compute/opendc-compute-workload/build.gradle.kts
+++ b/opendc-compute/opendc-compute-workload/build.gradle.kts
@@ -33,6 +33,7 @@ dependencies {
api(projects.opendcCompute.opendcComputeSimulator)
implementation(projects.opendcTrace.opendcTraceParquet)
+ implementation(projects.opendcTrace.opendcTraceOpendc)
implementation(projects.opendcTrace.opendcTraceAzure)
implementation(projects.opendcTrace.opendcTraceBitbrains)
implementation(projects.opendcSimulator.opendcSimulatorCore)
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt
index 46176609..afc0fce9 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt
+++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/ComputeWorkloadLoader.kt
@@ -23,9 +23,9 @@
package org.opendc.compute.workload
import mu.KotlinLogging
-import org.opendc.compute.workload.trace.bp.BPTraceFormat
import org.opendc.simulator.compute.workload.SimTraceWorkload
import org.opendc.trace.*
+import org.opendc.trace.opendc.OdcVmTraceFormat
import java.io.File
import java.util.*
import java.util.concurrent.ConcurrentHashMap
@@ -43,9 +43,9 @@ public class ComputeWorkloadLoader(private val baseDir: File) {
private val logger = KotlinLogging.logger {}
/**
- * The [BPTraceFormat] instance to load the traces
+ * The [OdcVmTraceFormat] instance to load the traces
*/
- private val format = BPTraceFormat()
+ private val format = OdcVmTraceFormat()
/**
* The cache of workloads.
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt
index 20d0fef1..50f3a669 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt
+++ b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/TraceConverter.kt
@@ -34,12 +34,11 @@ import org.apache.avro.generic.GenericRecordBuilder
import org.apache.parquet.avro.AvroParquetWriter
import org.apache.parquet.hadoop.ParquetWriter
import org.apache.parquet.hadoop.metadata.CompressionCodecName
-import org.opendc.compute.workload.trace.bp.BP_RESOURCES_SCHEMA
-import org.opendc.compute.workload.trace.bp.BP_RESOURCE_STATES_SCHEMA
import org.opendc.trace.*
import org.opendc.trace.azure.AzureTraceFormat
import org.opendc.trace.bitbrains.BitbrainsExTraceFormat
import org.opendc.trace.bitbrains.BitbrainsTraceFormat
+import org.opendc.trace.opendc.OdcVmTraceFormat
import org.opendc.trace.util.parquet.LocalOutputFile
import java.io.File
import java.util.*
@@ -106,7 +105,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") {
logger.info { "Building resources table" }
val metaWriter = AvroParquetWriter.builder<GenericData.Record>(LocalOutputFile(metaParquet))
- .withSchema(BP_RESOURCES_SCHEMA)
+ .withSchema(OdcVmTraceFormat.RESOURCES_SCHEMA)
.withCompressionCodec(CompressionCodecName.ZSTD)
.enablePageWriteChecksum()
.build()
@@ -117,7 +116,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") {
logger.info { "Building resource states table" }
val writer = AvroParquetWriter.builder<GenericData.Record>(LocalOutputFile(traceParquet))
- .withSchema(BP_RESOURCE_STATES_SCHEMA)
+ .withSchema(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA)
.withCompressionCodec(CompressionCodecName.ZSTD)
.enableDictionaryEncoding()
.enablePageWriteChecksum()
@@ -170,7 +169,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") {
continue
}
- val builder = GenericRecordBuilder(BP_RESOURCES_SCHEMA)
+ val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCES_SCHEMA)
builder["id"] = id
builder["submissionTime"] = startTime
@@ -207,7 +206,7 @@ internal class TraceConverterCli : CliktCommand(name = "trace-converter") {
continue
}
- val builder = GenericRecordBuilder(BP_RESOURCE_STATES_SCHEMA)
+ val builder = GenericRecordBuilder(OdcVmTraceFormat.RESOURCE_STATES_SCHEMA)
builder["id"] = id
val timestamp = reader.get(RESOURCE_STATE_TIMESTAMP).toEpochMilli()
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt b/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt
deleted file mode 100644
index 4f6dbce3..00000000
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/Schemas.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2021 AtLarge Research
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package org.opendc.compute.workload.trace.bp
-
-import org.apache.avro.Schema
-import org.apache.avro.SchemaBuilder
-
-/**
- * Schema for the resources table in the trace.
- */
-public val BP_RESOURCES_SCHEMA: Schema = SchemaBuilder
- .record("meta")
- .namespace("org.opendc.trace.capelin")
- .fields()
- .requiredString("id")
- .requiredLong("submissionTime")
- .requiredLong("endTime")
- .requiredInt("maxCores")
- .requiredLong("requiredMemory")
- .endRecord()
-
-/**
- * Schema for the resource states table in the trace.
- */
-public val BP_RESOURCE_STATES_SCHEMA: Schema = SchemaBuilder
- .record("meta")
- .namespace("org.opendc.trace.capelin")
- .fields()
- .requiredString("id")
- .requiredLong("time")
- .requiredLong("duration")
- .requiredInt("cores")
- .requiredDouble("cpuUsage")
- .requiredLong("flops")
- .endRecord()
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt b/opendc-trace/opendc-trace-opendc/build.gradle.kts
index 9662476d..b9c242a1 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTraceFormat.kt
+++ b/opendc-trace/opendc-trace-opendc/build.gradle.kts
@@ -20,28 +20,20 @@
* SOFTWARE.
*/
-package org.opendc.compute.workload.trace.bp
+description = "Support for OpenDC-specific trace formats"
-import org.opendc.trace.spi.TraceFormat
-import java.net.URL
-import java.nio.file.Paths
-import kotlin.io.path.exists
+/* Build configuration */
+plugins {
+ `kotlin-library-conventions`
+ `testing-conventions`
+ `jacoco-conventions`
+}
-/**
- * A format implementation for the GWF trace format.
- */
-public class BPTraceFormat : TraceFormat {
- /**
- * The name of this trace format.
- */
- override val name: String = "bitbrains-parquet"
+dependencies {
+ api(platform(projects.opendcPlatform))
+ api(projects.opendcTrace.opendcTraceApi)
+
+ implementation(projects.opendcTrace.opendcTraceParquet)
- /**
- * Open a Bitbrains Parquet trace.
- */
- override fun open(url: URL): BPTrace {
- val path = Paths.get(url.toURI())
- require(path.exists()) { "URL $url does not exist" }
- return BPTrace(path)
- }
+ testRuntimeOnly(libs.slf4j.simple)
}
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt
index 958ed49d..32a71052 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTable.kt
+++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTable.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.workload.trace.bp
+package org.opendc.trace.opendc
import org.apache.avro.generic.GenericRecord
import org.opendc.trace.*
@@ -28,9 +28,9 @@ import org.opendc.trace.util.parquet.LocalParquetReader
import java.nio.file.Path
/**
- * The resource state [Table] in the Bitbrains Parquet format.
+ * The resource state [Table] in the OpenDC virtual machine trace format.
*/
-internal class BPResourceStateTable(private val path: Path) : Table {
+internal class OdcVmResourceStateTable(private val path: Path) : Table {
override val name: String = TABLE_RESOURCE_STATES
override val isSynthetic: Boolean = false
@@ -44,7 +44,7 @@ internal class BPResourceStateTable(private val path: Path) : Table {
override fun newReader(): TableReader {
val reader = LocalParquetReader<GenericRecord>(path.resolve("trace.parquet"))
- return BPResourceStateTableReader(reader)
+ return OdcVmResourceStateTableReader(reader)
}
override fun newReader(partition: String): TableReader {
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt
index 655da2b6..8850ad39 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceStateTableReader.kt
+++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceStateTableReader.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.workload.trace.bp
+package org.opendc.trace.opendc
import org.apache.avro.generic.GenericRecord
import org.opendc.trace.*
@@ -29,9 +29,9 @@ import java.time.Duration
import java.time.Instant
/**
- * A [TableReader] implementation for the Bitbrains Parquet format.
+ * A [TableReader] implementation for the OpenDC virtual machine trace format.
*/
-internal class BPResourceStateTableReader(private val reader: LocalParquetReader<GenericRecord>) : TableReader {
+internal class OdcVmResourceStateTableReader(private val reader: LocalParquetReader<GenericRecord>) : TableReader {
/**
* The current record.
*/
@@ -99,5 +99,5 @@ internal class BPResourceStateTableReader(private val reader: LocalParquetReader
reader.close()
}
- override fun toString(): String = "BPResourceStateTableReader"
+ override fun toString(): String = "OdcVmResourceStateTableReader"
}
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt
index 75782486..9927afee 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTable.kt
+++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTable.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.workload.trace.bp
+package org.opendc.trace.opendc
import org.apache.avro.generic.GenericRecord
import org.opendc.trace.*
@@ -28,9 +28,9 @@ import org.opendc.trace.util.parquet.LocalParquetReader
import java.nio.file.Path
/**
- * The resource [Table] in the Bitbrains Parquet format.
+ * The resource [Table] for the OpenDC virtual machine trace format.
*/
-internal class BPResourceTable(private val path: Path) : Table {
+internal class OdcVmResourceTable(private val path: Path) : Table {
override val name: String = TABLE_RESOURCES
override val isSynthetic: Boolean = false
@@ -44,7 +44,7 @@ internal class BPResourceTable(private val path: Path) : Table {
override fun newReader(): TableReader {
val reader = LocalParquetReader<GenericRecord>(path.resolve("meta.parquet"))
- return BPResourceTableReader(reader)
+ return OdcVmResourceTableReader(reader)
}
override fun newReader(partition: String): TableReader {
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt
index 323ee9d0..fe4379e6 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPResourceTableReader.kt
+++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmResourceTableReader.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.workload.trace.bp
+package org.opendc.trace.opendc
import org.apache.avro.generic.GenericRecord
import org.opendc.trace.*
@@ -28,9 +28,9 @@ import org.opendc.trace.util.parquet.LocalParquetReader
import java.time.Instant
/**
- * A [TableReader] implementation for the Bitbrains Parquet format.
+ * A [TableReader] implementation for the resources table in the OpenDC virtual machine trace format.
*/
-internal class BPResourceTableReader(private val reader: LocalParquetReader<GenericRecord>) : TableReader {
+internal class OdcVmResourceTableReader(private val reader: LocalParquetReader<GenericRecord>) : TableReader {
/**
* The current record.
*/
@@ -99,5 +99,5 @@ internal class BPResourceTableReader(private val reader: LocalParquetReader<Gene
reader.close()
}
- override fun toString(): String = "BPResourceTableReader"
+ override fun toString(): String = "OdcVmResourceTableReader"
}
diff --git a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt
index b4e64fab..3e5029b4 100644
--- a/opendc-compute/opendc-compute-workload/src/main/kotlin/org/opendc/compute/workload/trace/bp/BPTrace.kt
+++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTrace.kt
@@ -20,7 +20,7 @@
* SOFTWARE.
*/
-package org.opendc.compute.workload.trace.bp
+package org.opendc.trace.opendc
import org.opendc.trace.TABLE_RESOURCES
import org.opendc.trace.TABLE_RESOURCE_STATES
@@ -29,9 +29,9 @@ import org.opendc.trace.Trace
import java.nio.file.Path
/**
- * A [Trace] in the Bitbrains Parquet format.
+ * A [Trace] in the OpenDC virtual machine trace format.
*/
-public class BPTrace internal constructor(private val path: Path) : Trace {
+public class OdcVmTrace internal constructor(private val path: Path) : Trace {
override val tables: List<String> = listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES)
override fun containsTable(name: String): Boolean =
@@ -39,11 +39,11 @@ public class BPTrace internal constructor(private val path: Path) : Trace {
override fun getTable(name: String): Table? {
return when (name) {
- TABLE_RESOURCES -> BPResourceTable(path)
- TABLE_RESOURCE_STATES -> BPResourceStateTable(path)
+ TABLE_RESOURCES -> OdcVmResourceTable(path)
+ TABLE_RESOURCE_STATES -> OdcVmResourceStateTable(path)
else -> null
}
}
- override fun toString(): String = "BPTrace[$path]"
+ override fun toString(): String = "OdcVmTrace[$path]"
}
diff --git a/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt
new file mode 100644
index 00000000..b69b5edf
--- /dev/null
+++ b/opendc-trace/opendc-trace-opendc/src/main/kotlin/org/opendc/trace/opendc/OdcVmTraceFormat.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.trace.opendc
+
+import org.apache.avro.Schema
+import org.apache.avro.SchemaBuilder
+import org.opendc.trace.spi.TraceFormat
+import java.net.URL
+import java.nio.file.Paths
+import kotlin.io.path.exists
+
+/**
+ * A [TraceFormat] implementation of the OpenDC virtual machine trace format.
+ */
+public class OdcVmTraceFormat : TraceFormat {
+ /**
+ * The name of this trace format.
+ */
+ override val name: String = "opendc-vm"
+
+ /**
+ * Open a Bitbrains Parquet trace.
+ */
+ override fun open(url: URL): OdcVmTrace {
+ val path = Paths.get(url.toURI())
+ require(path.exists()) { "URL $url does not exist" }
+ return OdcVmTrace(path)
+ }
+
+ public companion object {
+ /**
+ * Schema for the resources table in the trace.
+ */
+ @JvmStatic
+ public val RESOURCES_SCHEMA: Schema = SchemaBuilder
+ .record("resource")
+ .namespace("org.opendc.trace.opendc")
+ .fields()
+ .requiredString("id")
+ .requiredLong("submissionTime")
+ .requiredLong("endTime")
+ .requiredInt("maxCores")
+ .requiredLong("requiredMemory")
+ .endRecord()
+
+ /**
+ * Schema for the resource states table in the trace.
+ */
+ @JvmStatic
+ public val RESOURCE_STATES_SCHEMA: Schema = SchemaBuilder
+ .record("resource_state")
+ .namespace("org.opendc.trace.opendc")
+ .fields()
+ .requiredString("id")
+ .requiredLong("time")
+ .requiredLong("duration")
+ .requiredInt("cores")
+ .requiredDouble("cpuUsage")
+ .requiredLong("flops")
+ .endRecord()
+ }
+}
diff --git a/opendc-trace/opendc-trace-opendc/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat b/opendc-trace/opendc-trace-opendc/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat
new file mode 100644
index 00000000..94094af4
--- /dev/null
+++ b/opendc-trace/opendc-trace-opendc/src/main/resources/META-INF/services/org.opendc.trace.spi.TraceFormat
@@ -0,0 +1 @@
+org.opendc.trace.opendc.OdcVmTraceFormat
diff --git a/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt b/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt
new file mode 100644
index 00000000..21f1174c
--- /dev/null
+++ b/opendc-trace/opendc-trace-opendc/src/test/kotlin/org/opendc/trace/opendc/OdcVmTraceFormatTest.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.trace.opendc
+
+import org.junit.jupiter.api.Assertions.*
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertDoesNotThrow
+import org.junit.jupiter.api.assertThrows
+import org.opendc.trace.*
+import java.io.File
+import java.net.URL
+
+/**
+ * Test suite for the [OdcVmTraceFormat] implementation.
+ */
+internal class OdcVmTraceFormatTest {
+ private val format = OdcVmTraceFormat()
+
+ @Test
+ fun testTraceExists() {
+ val url = File("src/test/resources/trace").toURI().toURL()
+ assertDoesNotThrow { format.open(url) }
+ }
+
+ @Test
+ fun testTraceDoesNotExists() {
+ val url = File("src/test/resources/trace").toURI().toURL()
+ assertThrows<IllegalArgumentException> {
+ format.open(URL(url.toString() + "help"))
+ }
+ }
+
+ @Test
+ fun testTables() {
+ val url = File("src/test/resources/trace").toURI().toURL()
+ val trace = format.open(url)
+
+ assertEquals(listOf(TABLE_RESOURCES, TABLE_RESOURCE_STATES), trace.tables)
+ }
+
+ @Test
+ fun testTableExists() {
+ val url = File("src/test/resources/trace").toURI().toURL()
+ val table = format.open(url).getTable(TABLE_RESOURCE_STATES)
+
+ assertNotNull(table)
+ assertDoesNotThrow { table!!.newReader() }
+ }
+
+ @Test
+ fun testTableDoesNotExist() {
+ val url = File("src/test/resources/trace").toURI().toURL()
+ val trace = format.open(url)
+
+ assertFalse(trace.containsTable("test"))
+ assertNull(trace.getTable("test"))
+ }
+
+ @Test
+ fun testResources() {
+ val url = File("src/test/resources/trace").toURI().toURL()
+ val trace = format.open(url)
+
+ val reader = trace.getTable(TABLE_RESOURCES)!!.newReader()
+
+ assertAll(
+ { assertTrue(reader.nextRow()) },
+ { assertEquals("1019", reader.get(RESOURCE_ID)) },
+ { assertTrue(reader.nextRow()) },
+ { assertEquals("1023", reader.get(RESOURCE_ID)) },
+ { assertTrue(reader.nextRow()) },
+ { assertEquals("1052", reader.get(RESOURCE_ID)) },
+ { assertTrue(reader.nextRow()) },
+ { assertEquals("1073", reader.get(RESOURCE_ID)) },
+ { assertFalse(reader.nextRow()) }
+ )
+
+ reader.close()
+ }
+
+ @Test
+ fun testSmoke() {
+ val url = File("src/test/resources/trace").toURI().toURL()
+ val trace = format.open(url)
+
+ val reader = trace.getTable(TABLE_RESOURCE_STATES)!!.newReader()
+
+ assertAll(
+ { assertTrue(reader.nextRow()) },
+ { assertEquals("1019", reader.get(RESOURCE_STATE_ID)) },
+ { assertEquals(1376314846, reader.get(RESOURCE_STATE_TIMESTAMP).epochSecond) },
+ { assertEquals(0.0, reader.getDouble(RESOURCE_STATE_CPU_USAGE), 0.01) }
+ )
+
+ reader.close()
+ }
+}
diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet
new file mode 100644
index 00000000..d6ff09d8
--- /dev/null
+++ b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/meta.parquet
Binary files differ
diff --git a/opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet
new file mode 100644
index 00000000..5b6fa6b7
--- /dev/null
+++ b/opendc-trace/opendc-trace-opendc/src/test/resources/trace/trace.parquet
Binary files differ
diff --git a/settings.gradle.kts b/settings.gradle.kts
index f77fb676..26bd0b11 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -52,6 +52,7 @@ include(":opendc-trace:opendc-trace-wtf")
include(":opendc-trace:opendc-trace-wfformat")
include(":opendc-trace:opendc-trace-bitbrains")
include(":opendc-trace:opendc-trace-azure")
+include(":opendc-trace:opendc-trace-opendc")
include(":opendc-trace:opendc-trace-parquet")
include(":opendc-harness:opendc-harness-api")
include(":opendc-harness:opendc-harness-engine")