Skip to content

Commit 04f3b66

Browse files
committed
initial commit, composite restructure from DM-2 [https://github.com/uds-se/droidmate]
0 parents  commit 04f3b66

File tree

26 files changed

+2772
-0
lines changed

26 files changed

+2772
-0
lines changed

.gitignore

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
### Gradle ###
2+
.gradle
3+
build
4+
local.gradle
5+
# See: https://intellij-support.jetbrains.com/entries/23393067-How-to-manage-projects-under-Version-Control-Systems
6+
**/.idea/libraries
7+
8+
### Java ####
9+
*.class
10+
11+
### Android SDK ###
12+
bin/
13+
gen/
14+
# Local configuration file (sdk path, etc)
15+
local.properties
16+
17+
### IntelliJ IDEA ###
18+
.idea
19+
*.iml
20+
**/*.iws
21+
**/*.eml
22+
**/.idea/workspace.xml
23+
**/.idea/tasks.xml
24+
**/.idea/misc.xml
25+
/.idea
26+
.iml
27+
out/
28+
# Proguard folder generated by IntelliJ
29+
proguard_logs/
30+
31+
32+
### Eclipse ###
33+
# project files
34+
.classpath
35+
.project
36+
# Proguard folder generated by Eclipse
37+
proguard/
38+
39+
# Temporary stuff
40+
out

build.gradle

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
plugins {
2+
id 'java'
3+
id 'org.jetbrains.kotlin.jvm'
4+
}
5+
apply from: file("../../../versions.gradle")
6+
7+
8+
version '1.0-SNAPSHOT'
9+
10+
sourceCompatibility = 1.8
11+
12+
repositories {
13+
mavenCentral()
14+
}
15+
16+
dependencies {
17+
compile group: 'org.droidmate', name: 'deviceDaemonLib', version: project.ext.driverLib_version
18+
19+
// we need the jdk dependency instead of stdlib to have enhanced java features like tue 'use' function for try-with-resources
20+
compile group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: project.ext.kotlin_version
21+
compile "org.jetbrains.kotlin:kotlin-reflect:${project.ext.kotlin_version}" // because we need reflection to get annotated property values
22+
compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
23+
compile 'com.natpryce:konfig:1.6.6.0' // configuration library
24+
25+
testCompile group: 'junit', name: 'junit', version: '4.12'
26+
}
27+
28+
compileKotlin {
29+
kotlinOptions.jvmTarget = "1.8"
30+
}
31+
compileTestKotlin {
32+
kotlinOptions.jvmTarget = "1.8"
33+
}

settings.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
rootProject.name = "explorationModel"
2+
3+
includeBuild ('../../deviceCommonLib/deviceDaemonLib')
4+
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// DroidMate, an automated execution generator for Android apps.
2+
// Copyright (C) 2012-2018. Saarland University
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
//
17+
// Current Maintainers:
18+
// Nataniel Borges Jr. <nataniel dot borges at cispa dot saarland>
19+
// Jenny Hotzkow <jenny dot hotzkow at cispa dot saarland>
20+
//
21+
// Former Maintainers:
22+
// Konrad Jamrozik <jamrozik at st dot cs dot uni-saarland dot de>
23+
//
24+
// web: www.droidmate.org
25+
26+
@file:Suppress("ReplaceSingleLineLet")
27+
28+
package org.droidmate.explorationModel
29+
30+
import kotlinx.coroutines.*
31+
import kotlinx.coroutines.channels.*
32+
import kotlin.coroutines.CoroutineContext
33+
import kotlin.coroutines.coroutineContext
34+
35+
// we have exactly one thread who is going to handle our model actors
36+
// (we use an own thread to avoid blocking issues for mono/duo-cores, where the default thread-pool only has size 1)
37+
private val actorThreadPool = newFixedThreadPoolContext (1,name="actor-thread")
38+
interface Actor<in E>: CoroutineScope{
39+
suspend fun onReceive(msg: E)
40+
}
41+
42+
/** REMARK: buffered channel currently have some race condition bug when the full capacity is reached.
43+
* In particular, these sender are not properly woken up unless there is a print statement in the receiving loop of this actor
44+
* (which probably eliminates any potential race condition due to sequential console access)*/
45+
internal inline fun<reified MsgType> Actor<MsgType>.create() = actor<MsgType>(capacity = Channel.UNLIMITED){
46+
for (msg in channel) onReceive(msg)
47+
}
48+
49+
/** in principle adding any element to a collection would be a fast task, however due to the potential timeout for the widget.uid computation
50+
* the state id may be delayed as well and the hash function of Widget and State base on this id.
51+
* Therefore this computation and the set management was taken from the critical path of the execution by using this actor
52+
*/
53+
class CollectionActor<T>(private val actorState: MutableCollection<T>, private val actorName: String): Actor<CollectionMsg<T, Any?>> {
54+
override val coroutineContext: CoroutineContext = actorThreadPool + CoroutineName(actorName)
55+
56+
override suspend fun onReceive(msg: CollectionMsg<T, Any?>){
57+
// println("[${Thread.currentThread().name}] START msg handling ${msg::class.simpleName}: ${actorState.size}")
58+
when(msg){
59+
is Add -> actorState.add( msg.elem )
60+
is AddAll -> actorState.addAll( msg.elements )
61+
is Get -> msg.response.complete( msg.predicate(actorState) )
62+
is GetAll ->
63+
if(actorState is Set<*>) msg.response.complete( actorState.toSet() )
64+
else msg.response.complete( actorState.toList() )
65+
} //.run{ /* do nothing but keep this .run to ensure when raises compile error if not all sealed class cases are implemented */ }
66+
// println("[${Thread.currentThread().name}] msg handling ${msg::class.simpleName}: ${actorState.size}")
67+
}
68+
override fun toString(): String = actorName
69+
}
70+
@kotlin.Suppress("unused")
71+
sealed class CollectionMsg<T,out R>
72+
73+
class Add<T>(val elem: T): CollectionMsg<T, Any>()
74+
class AddAll<T>(val elements: Collection<T>): CollectionMsg<T, Any>()
75+
class GetAll<T,R>(val response: CompletableDeferred<R>): CollectionMsg<T, R>()
76+
/** this method allows to retrieve a specific element as determined by @predicate,
77+
* however the predicate should only contain very cheap computations as otherwise the WHOLE exploration performance would suffer.
78+
* For more expensive computations please retrieve the whole collection via [GetAll] and perform your operation on the result
79+
*/
80+
class Get<T,R>(inline val predicate:(Collection<T>)->R, val response: CompletableDeferred<R>): CollectionMsg<T, R>()
81+
82+
/** this method allows to retrieve a specific element as determined by @predicate,
83+
* however the predicate should only contain very cheap computations as otherwise the WHOLE exploration performance would suffer.
84+
* For more expensive computations please retrieve the whole collection via [getAll] and perform your operation on the result
85+
*/
86+
suspend inline fun<reified T, reified R: Any?> SendChannel<CollectionMsg<T, R?>>.getOrNull(noinline predicate:(Collection<T>)->R): R?
87+
= this.let{actor -> with(CompletableDeferred<R>()){ actor.send(Get(predicate, this)); this.await()} }
88+
89+
/** this method allows to retrieve a specific element as determined by @predicate,
90+
* however the predicate should only contain very cheap computations as otherwise the WHOLE exploration performance would suffer.
91+
* For more expensive computations please retrieve the whole collection via [getAll] and perform your operation on the result
92+
*/
93+
suspend inline fun<reified T, reified R: Any> SendChannel<CollectionMsg<T, R?>>.get(noinline predicate:(Collection<T>)->R): R
94+
= this.let{actor -> with(CompletableDeferred<R?>()){ actor.send(Get(predicate, this)); this.await()} }!!
95+
96+
/** @return a copy of the actors current private collection (actorState) */
97+
suspend inline fun<reified T, reified R> SendChannel<CollectionMsg<T, R>>.getAll(): R
98+
= this.let{actor -> with(CompletableDeferred<R>()){ actor.send(GetAll(this)); this.await()} }
99+
100+
/** @return (blocking) a copy of the actors current private collection (actorState).
101+
* !!! This method should not be called from coroutine */
102+
inline fun<reified T, reified R> SendChannel<CollectionMsg<T, R>>.S_getAll(): R
103+
= this.let{actor -> with(CompletableDeferred<R>()){ actor.sendBlocking(GetAll(this)); runBlocking {await()}} }

0 commit comments

Comments
 (0)