-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
01dd2ea
commit eb8dd67
Showing
28 changed files
with
543 additions
and
373 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,57 @@ | ||
plugins { | ||
id 'com.android.library' | ||
id 'org.jetbrains.kotlin.android' | ||
id 'org.jetbrains.kotlin.plugin.serialization' | ||
} | ||
|
||
android { | ||
compileSdk 32 | ||
|
||
defaultConfig { | ||
minSdk 21 | ||
minSdk 17 | ||
targetSdk 32 | ||
|
||
multiDexEnabled = true | ||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
consumerProguardFiles "consumer-rules.pro" | ||
} | ||
|
||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
} | ||
} | ||
|
||
compileOptions { | ||
sourceCompatibility JavaVersion.VERSION_1_8 | ||
targetCompatibility JavaVersion.VERSION_1_8 | ||
sourceCompatibility JavaVersion.VERSION_11 | ||
targetCompatibility JavaVersion.VERSION_11 | ||
} | ||
kotlinOptions { | ||
jvmTarget = '1.8' | ||
freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn" | ||
} | ||
|
||
} | ||
|
||
dependencies { | ||
androidTestImplementation 'org.testng:testng:7.4.0' | ||
def coroutines_version = '1.6.4' | ||
|
||
implementation 'androidx.core:core-ktx:1.7.0' | ||
implementation 'androidx.core:core-ktx:1.8.0' | ||
implementation 'androidx.appcompat:appcompat:1.4.2' | ||
implementation "androidx.multidex:multidex:2.0.1" | ||
|
||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3" | ||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" | ||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" | ||
|
||
implementation 'com.google.android.material:material:1.6.1' | ||
implementation 'com.github.OperatorFoundation:ShapeshifterAndroidKotlin:3.1.0' | ||
implementation 'com.beust:klaxon:5.5' | ||
|
||
testImplementation 'junit:junit:4.13.2' | ||
|
||
androidTestImplementation 'androidx.test.ext:junit:1.1.3' | ||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' | ||
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" | ||
} |
58 changes: 58 additions & 0 deletions
58
CanaryLibrary/src/androidTest/java/com/example/CanaryLibrary/ExampleInstrumentedTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.example.CanaryLibrary | ||
|
||
import android.os.Environment | ||
import androidx.test.platform.app.InstrumentationRegistry | ||
import kotlinx.coroutines.ExperimentalCoroutinesApi | ||
import kotlinx.coroutines.test.runTest | ||
import org.junit.Test | ||
import org.junit.Assert.* | ||
import org.operatorfoundation.shapeshifter.shadow.kotlin.ShadowConfig | ||
|
||
class ExampleInstrumentedTest { | ||
@Test | ||
fun useAppContext() { | ||
// Context of the app under test. | ||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext | ||
assertEquals("CanaryLibrary.test", appContext.packageName) | ||
} | ||
|
||
@OptIn(ExperimentalCoroutinesApi::class) | ||
@Test | ||
fun createCanaryInstance() = runTest { | ||
// ***** This is the actual API for the Canary Library ****** | ||
val configDirectory = Environment.getStorageDirectory() | ||
val canary = Canary(configDirectory) | ||
assertNotNull(canary) | ||
canary.runTest() | ||
} | ||
|
||
@OptIn(ExperimentalCoroutinesApi::class) | ||
@Test | ||
fun createCanaryTest() = runTest { | ||
val configDirectory = Environment.getStorageDirectory() | ||
val chirp = CanaryTest(configDirectory, 1) | ||
|
||
chirp.begin() | ||
} | ||
|
||
@Test | ||
fun checkSetupEmptyConfigDir() | ||
{ | ||
val configDirectory = Environment.getStorageDirectory() | ||
val chirp = CanaryTest(configDirectory, 1) | ||
|
||
assertFalse(chirp.checkSetup()) | ||
} | ||
|
||
@OptIn(ExperimentalCoroutinesApi::class) | ||
@Test | ||
fun testController() = runTest { | ||
val testController = TestController() | ||
val shadowConfig = ShadowConfig("", "DarkStar") | ||
val canaryConfig = CanaryConfig<ShadowConfig>("", 1234, shadowConfig) | ||
val transport = Transport("ShadowExample", TransportType.shadow, canaryConfig) | ||
|
||
val result = testController.runTransportTest(transport) | ||
assertNotNull(result) | ||
} | ||
} |
24 changes: 0 additions & 24 deletions
24
CanaryLibrary/src/androidTest/java/com/example/canarylibrary/ExampleInstrumentedTest.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="com.example.canarylibrary"> | ||
|
||
package="CanaryLibrary"> | ||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> | ||
</manifest> |
23 changes: 23 additions & 0 deletions
23
CanaryLibrary/src/main/java/com/example/CanaryLibrary/Canary.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.example.CanaryLibrary | ||
|
||
import kotlinx.coroutines.MainScope | ||
import kotlinx.coroutines.launch | ||
import java.io.File | ||
|
||
class Canary(configDirectoryFile: File, timesToRun: Int = 1) | ||
{ | ||
private var chirp: CanaryTest | ||
|
||
init | ||
{ | ||
chirp = CanaryTest(configDirectoryFile, timesToRun) | ||
} | ||
|
||
fun runTest() | ||
{ | ||
// TODO: Better coroutines | ||
MainScope().launch { | ||
chirp.begin() | ||
} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
CanaryLibrary/src/main/java/com/example/CanaryLibrary/CanaryConfig.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.example.CanaryLibrary | ||
|
||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable | ||
data class CanaryConfig<out T : Any>(val serverIP: String, val serverPort: Int, val transportConfig: T) | ||
{ | ||
|
||
} |
117 changes: 117 additions & 0 deletions
117
CanaryLibrary/src/main/java/com/example/CanaryLibrary/CanaryTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package com.example.CanaryLibrary | ||
|
||
import kotlinx.serialization.decodeFromString | ||
import kotlinx.serialization.json.Json | ||
import org.operatorfoundation.shapeshifter.shadow.kotlin.ShadowConfig | ||
import java.io.File | ||
|
||
class CanaryTest(val configDirectory: File, val timesToRun: Int = 1, var saveDirectory: File? = null) | ||
{ | ||
suspend fun begin() | ||
{ | ||
println("\n attempting to run tests...\n") | ||
|
||
// Make sure we have everything we need first | ||
if (!checkSetup()) | ||
{ | ||
return | ||
} | ||
|
||
runAllTests() | ||
} | ||
|
||
private suspend fun runAllTests() | ||
{ | ||
val testController = TestController() | ||
|
||
for (i in 1..timesToRun) | ||
{ | ||
println("\n***************************\nRunning test batch $i of $timesToRun\n***************************\n") | ||
|
||
for (transport in testingTransports) | ||
{ | ||
println("\n 🧪 Starting test for ${transport.name} 🧪") | ||
testController.test(transport) | ||
} | ||
} | ||
} | ||
|
||
fun checkSetup(): Boolean | ||
{ | ||
if (saveDirectory != null) | ||
{ | ||
// Does the save directory exist? | ||
if (!saveDirectory!!.exists()) | ||
{ | ||
println("\n‼️ The selected save directory does not exist at ${saveDirectory!!.path}.\n") | ||
return false | ||
} | ||
else if (!saveDirectory!!.isDirectory) | ||
{ | ||
println("\n‼️ The selected save directory is not a directory. Please select a directory for saving your results. \nSelected path: ${saveDirectory!!.path}.\n") | ||
return false | ||
} | ||
|
||
println("\n✔️ User selected save directory: ${saveDirectory!!.path}\n") | ||
} | ||
|
||
// Does the Config Directory Exist? | ||
if (!configDirectory.exists()) | ||
{ | ||
println("\n‼️ The selected config directory does not exist at ${configDirectory.path}.\n") | ||
return false | ||
} | ||
else if (!configDirectory.isDirectory) | ||
{ | ||
println("\n‼️ The selected config directory is not a directory. Please select the directory where your transport config files are located. \nSelected path: ${configDirectory.path}.\n") | ||
return false | ||
} | ||
|
||
println("\n✔️ Config directory: ${configDirectory.path}\n") | ||
|
||
if (!prepareTransports()) | ||
{ | ||
return false | ||
} | ||
|
||
println("✔️ Check setup complete") | ||
return true | ||
} | ||
|
||
private fun prepareTransports(): Boolean | ||
{ | ||
// Get a list of all of the files in the config directory | ||
// return false if we are unable to retrieve a list of files | ||
val configFiles = configDirectory.listFiles() ?: return false | ||
|
||
if (configFiles.isEmpty()) | ||
{ | ||
println("\n ‼️ There are no config files in the selected directory: ${configDirectory.path}") | ||
return false | ||
} | ||
|
||
configFiles.forEach { configFile -> | ||
for (transportType in possibleTransportTypes) | ||
{ | ||
// Check each file name to see if it contains the name of a supported transport | ||
if (configFile.name.contains(transportType.name, true)) | ||
{ | ||
val configString = configFile.readText() | ||
val canaryConfig: CanaryConfig<ShadowConfig> = Json.decodeFromString(configString) | ||
|
||
val maybeNewTransport = Transport(configFile.name, transportType, canaryConfig) | ||
testingTransports += maybeNewTransport | ||
println("\n✔️ ${maybeNewTransport.name} test is ready\n") | ||
} | ||
} | ||
} | ||
|
||
if (testingTransports.isEmpty()) | ||
{ | ||
println("‼️ There were no valid transport configs in the provided directory. Ending test.\nConfig Directory: $configDirectory.path") | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
CanaryLibrary/src/main/java/com/example/CanaryLibrary/Globals.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.example.CanaryLibrary | ||
|
||
var testingTransports = arrayOf<Transport>() | ||
|
||
val possibleTransportTypes = arrayOf(TransportType.shadow) | ||
val httpRequestString = "GET / HTTP/1.0\r\nConnection: close\r\n\r\n" | ||
val canaryString = "Yeah!\n" | ||
val resultsFileName = "CanaryResults.csv" | ||
|
70 changes: 70 additions & 0 deletions
70
CanaryLibrary/src/main/java/com/example/CanaryLibrary/TestController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.example.CanaryLibrary | ||
|
||
import android.os.Environment | ||
import android.os.Environment.MEDIA_MOUNTED | ||
import java.io.File | ||
import java.util.* | ||
|
||
|
||
class TestController() | ||
{ | ||
suspend fun runTransportTest(transport: Transport): TestResult? | ||
{ | ||
// Connection test | ||
val connectionTest = TransportConnectionTest(transport) | ||
val success = connectionTest.run() | ||
|
||
// Save the result to a file | ||
val hostString = transport.serverIP + ":${transport.port}" | ||
val result = TestResult(hostString, Date(), transport.name, success) | ||
save(result, transport.name) | ||
|
||
return null | ||
} | ||
|
||
// Saves the provided test results to a csv file with a filename that contains a timestamp. | ||
// If a file with this name already exists it will append the results to the end of the file. | ||
// - Parameter result: The test result information to be saved. The type is a TestResult struct. | ||
// - Returns: A boolean value indicating whether or not the results were saved successfully. | ||
fun save(result: TestResult, testName: String): Boolean | ||
{ | ||
if (Environment.getExternalStorageState() != MEDIA_MOUNTED) | ||
{ | ||
println("Unable to save the results file: external storage is not available for reading/writing") | ||
return false | ||
} | ||
|
||
val extDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) | ||
val saveFile = File(extDir, resultsFileName) | ||
|
||
// Make sure the Documents directory exists. | ||
extDir.mkdirs() | ||
|
||
if (!saveFile.exists()) | ||
{ | ||
// Make a new csv file for our test results | ||
saveFile.createNewFile() | ||
|
||
// The first row should be our labels | ||
val labelRow = "TestDate, ServerIP, Transport, Success\n" | ||
saveFile.appendText(labelRow) | ||
} | ||
|
||
// Add out newest test results to the file | ||
val resultString = "${result.testDate}, ${result.hostString}, $testName, ${result.success}\n" | ||
saveFile.appendText(resultString) | ||
|
||
return saveFile.exists() | ||
} | ||
|
||
suspend fun test(transport: Transport) { | ||
println("Testing ${transport.name} transport...") | ||
|
||
val transportTestResult = runTransportTest(transport) | ||
|
||
if (transportTestResult == null) | ||
{ | ||
println("\n Received a null result when testing ${transport.name} transport. \n") | ||
} | ||
} | ||
} |
Oops, something went wrong.