Skip to content

Commit

Permalink
Merge pull request #6 from scribe/implementation
Browse files Browse the repository at this point in the history
Implementation
  • Loading branch information
rpmoore authored Apr 24, 2019
2 parents 5d9bf3d + b88fb26 commit 3bcc1c2
Show file tree
Hide file tree
Showing 14 changed files with 328 additions and 54 deletions.
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
.gradle

# Ignore Gradle build output directory
build
build/
out/
.kotlintest/

# Ignore Java specific files
*.class

.idea
*.iml
*.iml

.DS_Store
11 changes: 6 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@ tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}

val test by tasks.getting(Test::class) {
useJUnitPlatform { }
}

dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${project.property("kotlinxCoroutines")}")
implementation("com.github.ajalt:clikt:${project.property("clikt")}")
implementation("io.github.microutils:kotlin-logging:${project.property("kotlinLogging")}")
implementation("org.jlleitschuh.guice:kotlin-guiced-core:${project.property("kotlinGuiced")}")
implementation("com.spectralogic.ds3:ds3-sdk:${project.property("ds3")}")

testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
testImplementation("org.assertj:assertj-core:${project.property("assertj")}")
testImplementation("io.kotlintest:kotlintest-runner-junit5:${project.property("kotlintest")}")
testImplementation("io.mockk:mockk:${project.property("mockk")}")
}

application {
Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
assertj=3.11.1
clikt=1.7.0
kotlinGuiced=0.0.5
kotlinLogging=1.6.24
kotlinxCoroutines=1.1.1
ds3=5.0.4
mockk=1.9.3.kotlin12
kotlintest=3.3.2
21 changes: 4 additions & 17 deletions src/main/kotlin/com/spectralogic/bp/bench/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,14 @@
*/
package com.spectralogic.bp.bench

import com.github.ajalt.clikt.core.CliktCommand
import com.google.inject.Guice
import com.google.inject.name.Named
import com.google.inject.name.Names
import com.spectralogic.bp.bench.cli.GetFromTapeCommand
import com.spectralogic.bp.bench.cli.MainCommand
import com.spectralogic.bp.bench.cli.SustainedWriteCommand
import com.spectralogic.bp.bench.cli.WriteToTapeCommand
import org.jlleitschuh.guice.module


fun main(args: Array<String>) {
Guice
.createInjector(
module {
bind<CliktCommand>().to<MainCommand>()
bind<CliktCommand>().annotatedWith(Names.named("GetFromTape")).to<GetFromTapeCommand>()
bind<CliktCommand>().annotatedWith(Names.named("SustainedWrite")).to<SustainedWriteCommand>()
bind<CliktCommand>().annotatedWith(Names.named("WriteToTape")).to<WriteToTapeCommand>()
}
)
.getInstance(CliktCommand::class.java)
MainCommand(
WriteToTapeCommand(),
GetFromTapeCommand()
)
.main(args)
}
23 changes: 23 additions & 0 deletions src/main/kotlin/com/spectralogic/bp/bench/cli/AzInputStream.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* ****************************************************************************
* Copyright 2014-2019 Spectra Logic Corporation. All Rights Reserved.
* ***************************************************************************
*/

package com.spectralogic.bp.bench.cli

import java.io.InputStream

class AZInputStream : InputStream() {
private var currentCharacter = 'a'

override fun read(): Int {
val charToReturn = currentCharacter

currentCharacter = currentCharacter.inc()
if (currentCharacter == '{') {
currentCharacter = 'a'
}
return charToReturn.toInt()
}
}
45 changes: 45 additions & 0 deletions src/main/kotlin/com/spectralogic/bp/bench/cli/BpCommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* ****************************************************************************
* Copyright 2014-2019 Spectra Logic Corporation. All Rights Reserved.
* ***************************************************************************
*/

package com.spectralogic.bp.bench.cli

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.prompt
import com.github.ajalt.clikt.parameters.options.validate

abstract class BpCommand(
help: String = "",
epilog: String = "",
name: String? = null,
invokeWithoutSubcommand: Boolean = false,
printHelpOnEmptyArgs: Boolean = false
) : CliktCommand(help, epilog, name, invokeWithoutSubcommand, printHelpOnEmptyArgs) {
internal val endpoint by option(
"-bp",
"--blackpearl",
envvar = "BP_DATA_ENDPOINT",
help = "The data path on the Black Pearl.\nSet with BP_DATA_ENDPOINT"
).prompt("Black Pearl data path").validate { require(it.isNotEmpty()) { "Black Pearl data path cannot be empty" } }
internal val clientId: String by option(
"-a",
"--accessid",
envvar = "BP_ACCESS_ID",
help = "The access ID of the user you want to transfer as\nSet with BP_ACCESS_ID"
).prompt("Black Pearl access id?").validate { require(it.isNotEmpty()) { "User name cannot be empty" } }
internal val secretKey: String by option(
"-s",
"--secretkey",
envvar = "BP_SECRET_KEY",
help = "The secret key of the user you want to transfer as\nSet with BP_SECRET_KEY"
).prompt("Black Pearl secret key?").validate { require(it.isNotEmpty()) { "Password cannot be empty" } }
internal val bucket: String by option(
"-b",
"--bucket",
envvar = "BP_BUCKET",
help = "The bucket to use for benchmarking.\nSet with BP_BUCKET"
).prompt("Target Black Pearl bucket").validate { require(it.isNotEmpty()) { "Bucket name cannot be empty" } }
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@
* Copyright 2014-2019 Spectra Logic Corporation. All Rights Reserved.
* ***************************************************************************
*/

package com.spectralogic.bp.bench.cli

import com.github.ajalt.clikt.core.CliktCommand
import com.spectralogic.ds3client.Ds3ClientBuilder
import com.spectralogic.ds3client.helpers.Ds3ClientHelpers
import com.spectralogic.ds3client.models.common.Credentials
import java.nio.channels.Channels

class GetFromTapeCommand :
BpCommand(name = "get", help = "Attempt to download all objects in the target <BUCKET> without disk IO") {

class GetFromTapeCommand: CliktCommand() {
override fun run() {
echo("Get")
val client = Ds3ClientHelpers.wrap(
Ds3ClientBuilder.create(endpoint, Credentials(clientId, secretKey))
.withHttps(false)
.build()
)
client.startReadAllJob(bucket)
.transfer { PositionableReadOnlySeekableByteChannel(Channels.newChannel(AZInputStream())) }
}
}
16 changes: 6 additions & 10 deletions src/main/kotlin/com/spectralogic/bp/bench/cli/MainCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,22 @@ import com.github.ajalt.clikt.core.findObject
import com.github.ajalt.clikt.core.subcommands
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
import com.google.inject.Inject
import com.google.inject.name.Named

class MainCommand
@Inject constructor(
@Named("SustainedWrite") sustainedWriteCommand: CliktCommand,
@Named("WriteToTape") writeToTapeCommand: CliktCommand,
@Named("GetFromTape") getFromTapeCommand: CliktCommand
)
: CliktCommand(name = "bpBench") {
constructor(
writeToTapeCommand: CliktCommand,
getFromTapeCommand: CliktCommand
) :
CliktCommand(name = "bpBench") {

init {
subcommands(
sustainedWriteCommand,
writeToTapeCommand,
getFromTapeCommand
)
}

val verbose by option("-v", "--verbose", help = "enable verbose output").flag()
private val verbose by option("-v", "--verbose", help = "enable verbose output").flag()

override fun run() {
findObject { verbose }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* ****************************************************************************
* Copyright 2014-2019 Spectra Logic Corporation. All Rights Reserved.
* ***************************************************************************
*/

package com.spectralogic.bp.bench.cli

import java.nio.ByteBuffer
import java.nio.channels.ReadableByteChannel
import java.nio.channels.SeekableByteChannel

/**
* Wraps a non-seekable ReadableByteChannel in order to satisfy the SeekableByteChannel interface.
* Despite position being tracked, setting the position does not actually perform a seek.
* This is used in FileSourceImpl to implement the AToZInputStream test tool.
*/
class PositionableReadOnlySeekableByteChannel(private val channel: ReadableByteChannel) : SeekableByteChannel {

private var size = 0L
private var position = 0L

override fun read(dst: ByteBuffer): Int {
val bytesRead = channel.read(dst)
size += bytesRead.toLong()
position += bytesRead.toLong()
return bytesRead
}

override fun write(src: ByteBuffer): Int {
val l = src.remaining()
size += l
position += l
src.position(src.position() + l)
return l
}

override fun position(): Long {
return position
}

override fun position(newPosition: Long): SeekableByteChannel {
this.position = newPosition
return this
}

override fun size(): Long {
return size
}

override fun truncate(size: Long): SeekableByteChannel {
return this
}

override fun isOpen(): Boolean {
return channel.isOpen
}

override fun close() {
channel.close()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
* Copyright 2014-2019 Spectra Logic Corporation. All Rights Reserved.
* ***************************************************************************
*/

package com.spectralogic.bp.bench.cli

import com.github.ajalt.clikt.core.CliktCommand
package com.spectralogic.bp.bench.cli

class SustainedWriteCommand: CliktCommand() {
enum class SizeUnits(val power: Double) {
B(0.0),
KB(3.0),
MB(6.0),
GB(9.0),
TB(12.0);

override fun run() {
echo("Sustained Write")
companion object {
fun parse(name: String) = SizeUnits.valueOf(name.trim().toUpperCase())
fun names() = SizeUnits.values().map { it.name }.toTypedArray()
}
}
Loading

0 comments on commit 3bcc1c2

Please sign in to comment.