Commit 654edb82 authored by augier's avatar augier

Add Jenkinsfle

parent 43a4da69
Pipeline #2031 passed with stage
pipeline {
agent {
docker {
image "bitriseio/docker-android"
args "-v /etc/passwd:/etc/passwd:ro -u root --privileged"
}
}
environment {
MIN_SDK_IMAGE = "system-images;android-21;default;x86_64"
TARGET_SDK_IMAGE = "system-images;android-28;default;x86_64"
ANDROID_HOME = "/opt/android-sdk-linux"
}
options {
buildDiscarder(logRotator(numToKeepStr: "2"))
skipStagesAfterUnstable()
gitLabConnection('GitlabFeneas')
}
triggers {
gitlab(triggerOnPush: true, triggerOnMergeRequest: true, branchFilterType: 'All')
}
stages {
stage("Pre") {
steps {
library "android-pipeline-steps"
sh "apt-get install net-tools"
}
}
stage("Compile") {
steps {
sh "./gradlew compileReleaseSources"
}
}
stage("Static analysis") {
steps {
sh "./gradlew lintRelease --continue"
androidLint pattern: "**/lint-results-*.xml"
publishHTML([
allowMissing : false,
alwaysLinkToLastBuild: true,
keepAll : false,
reportDir : "$WORKSPACE/app/build/reports/",
reportFiles : "lint-results-release.html",
reportName : "HTML Report",
reportTitles : ""
])
}
}
stage("Unit tests") {
steps {
sh "./gradlew testReleaseUnitTest --info"
junit "**/test-results/**/*.xml"
publishHTML([
allowMissing : false,
alwaysLinkToLastBuild: true,
keepAll : false,
reportDir : "$WORKSPACE/app/build/reports/tests/testReleaseUnitTest",
reportFiles : "index.html",
reportName : "Junit test report",
reportTitles : ""
])
}
}
stage("Instrumented tests on min SDK image") {
steps {
withAvd(hardwareProfile: "Nexus 5X", systemImage: env.MIN_SDK_IMAGE, headless: true) {
sh "./gradlew clean connectedDebugAndroidTest"
}
}
}
stage("Instrumented tests on target SDK image") {
steps {
withAvd(hardwareProfile: "Nexus 5X", systemImage: env.TARGET_SDK_IMAGE, headless: true) {
sh "./gradlew clean connectedDebugAndroidTest"
}
}
}
// stage("Build APK") {
// steps {
// withAvd(hardwareProfile: "Nexus 5X", systemImage: env.MIN_SDK_IMAGE, headless: true) {
// sh "./gradlew assembleDebug"
// archiveArtifacts "**/*.apk"
// }
// }
// }
}
post {
failure {
updateGitlabCommitStatus name: "build", state: "failed"
}
success {
updateGitlabCommitStatus name: "build", state: "success"
}
always {
sh "chown -R jenkins ${env.WORKSPACE}"
}
}
}
\ No newline at end of file
......@@ -23,6 +23,16 @@ android {
}
}
testOptions {
unitTests.all {
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen { false }
showStandardStreams = true
}
}
}
lintOptions {
disable "AllowBackup", "VectorPath", "GradleDependency"
}
......@@ -73,8 +83,8 @@ spotless {
kotlin {
ktlint().userData([
"trim_trailing_whitespace": true,
"insert_final_newline": true,
"max_line_length": 120,
"insert_final_newline" : true,
"max_line_length" : 120,
])
}
format "xml", {
......
......@@ -11,6 +11,8 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
abstract class FreshRSSDabatabaseBaseTest {
open val testDB get() = "migration-test"
@get:Rule
......@@ -27,7 +29,7 @@ abstract class FreshRSSDabatabaseBaseTest {
private lateinit var _database: SQLiteDatabase
val database: SQLiteDatabase
get() {
if (!::_database.isInitialized || !_database.isOpen) {
if(!::_database.isInitialized || !_database.isOpen) {
_database = SQLiteDatabase.openDatabase(
targetContext.getDatabasePath(testDB).absolutePath,
null, SQLiteDatabase.OPEN_READWRITE
......@@ -47,24 +49,24 @@ abstract class FreshRSSDabatabaseBaseTest {
fun migrateDatabase(database: SupportSQLiteDatabase, from: Int, to: Int) {
val migrations = FreshRSSDabatabase_Migrations.build()
(from until to).forEach { version ->
(from until to).forEach {version ->
val migration = migrations[version - 1]
val nextPreMigrationScript = "migration-test-${migration.endVersion}-before.sql"
val nextPostMigrationScript = "migration-test-${migration.endVersion}-after.sql"
assets.list("database")?.find { it == nextPreMigrationScript }?.let { execSQLWithImports(database, it) }
assets.list("database")?.find {it == nextPreMigrationScript}?.let {execSQLWithImports(database, it)}
helper.runMigrationsAndValidate(testDB, migration.endVersion, true, migration)
assets.list("database")?.find { it == nextPostMigrationScript }?.let { execSQLWithImports(database, it) }
assets.list("database")?.find {it == nextPostMigrationScript}?.let {execSQLWithImports(database, it)}
}
}
fun execSQLWithImports(sqlMgr: SupportSQLiteDatabase, name: String) {
val importRegex = "^--\\s*import\\s*:\\s*(\\S+).*$"
assets.open("database/${name.replace(".sql", "")}.sql").bufferedReader().lines().forEachOrdered { sql ->
if (sql.matches(importRegex.toRegex())) {
assets.open("database/${name.replace(".sql", "")}.sql").reader().readLines().forEach {sql ->
if(sql.matches(importRegex.toRegex())) {
val matcher = importRegex.toPattern().matcher(sql)
while (matcher.find()) execSQLWithImports(sqlMgr, matcher.group(1))
} else if (!sql.startsWith("--", true)) {
while(matcher.find()) execSQLWithImports(sqlMgr, matcher.group(1))
} else if(!sql.startsWith("--", true)) {
sqlMgr.execSQL(sql)
}
}
......
......@@ -37,8 +37,10 @@ class MilliSecTimestampDeserializer: LocalDateTimeDeserializer() {
}
class PublishedDateDeserializer: LocalDateTimeDeserializer() {
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): LocalDateTime =
LocalDateTime((p?.valueAsLong ?: 0L) * 1000L)
override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): LocalDateTime {
val tz = if(_format.isTimezoneExplicit) _format.timeZone else DateTimeZone.forTimeZone(ctxt?.timeZone)
return LocalDateTime((p?.valueAsLong ?: 0L) * 1000L, tz)
}
}
object TagsDeserializer: ResponseDeserializable<List<String>> {
......
package fr.chenry.android.freshrss.store.api.models
import fr.chenry.android.freshrss.utils.JACKSON_OBJECT_MAPPER
import org.joda.time.DateTimeZone
import org.joda.time.LocalDateTime
import org.junit.Assert.assertEquals
import org.junit.Test
......@@ -15,9 +16,9 @@ class ContentItemsHandlerTest {
val items: ContentItems = listOf(
ContentItem(
"tag:google.com,2005:reader/item/00058167f526c8be",
LocalDateTime("2019-02-08T20:39:38.127"),
LocalDateTime("2019-02-08T20:39:38.127"),
LocalDateTime("2019-01-14T20:18:00.000"),
LocalDateTime("2019-02-08T20:39:38.127", DateTimeZone.UTC),
LocalDateTime("2019-02-08T20:39:38.127", DateTimeZone.UTC),
LocalDateTime("2019-01-14T19:18:00.000", DateTimeZone.UTC),
"Eolas contre Institut pour la Justice : Episode 1. Le Compteur Fantôme.",
listOf(Href("http://localhost/post/2019/01/14/abcd")),
listOf(
......@@ -31,9 +32,9 @@ class ContentItemsHandlerTest {
),
ContentItem(
"tag:google.com,2005:reader/item/00058167f526c759",
LocalDateTime("2019-02-08T20:39:38.127"),
LocalDateTime("2019-02-08T20:39:38.127"),
LocalDateTime("2018-09-20T14:10:00.000"),
LocalDateTime("2019-02-08T20:39:38.127", DateTimeZone.UTC),
LocalDateTime("2019-02-08T20:39:38.127", DateTimeZone.UTC),
LocalDateTime("2018-09-20T12:10:00.000", DateTimeZone.UTC),
"Petite leçon de droit à l’attention de Madame Le Pen (et de M. Mélenchon qui passait par là)",
listOf(Href("http://localhost/post/2019/01/14/defg")),
listOf(
......@@ -64,9 +65,9 @@ class ContentItemsHandlerTest {
val items: ContentItems = listOf(
ContentItem(
"tag:google.com,2005:reader/item/00058167f526c8be",
LocalDateTime("2019-02-08T20:39:38.127"),
LocalDateTime("2019-02-08T20:39:38.127"),
LocalDateTime("2019-01-14T20:18:00.000"),
LocalDateTime("2019-02-08T20:39:38.127", DateTimeZone.UTC),
LocalDateTime("2019-02-08T20:39:38.127", DateTimeZone.UTC),
LocalDateTime("2019-01-14T19:18:00.000", DateTimeZone.UTC),
"Eolas contre Institut pour la Justice : Episode 1. Le Compteur Fantôme.",
listOf(Href("http://localhost/post/2019/01/14/abcd")),
listOf(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment