diff --git a/.github/workflows/build.yml b/.github/workflows/build_and_test.yml similarity index 50% rename from .github/workflows/build.yml rename to .github/workflows/build_and_test.yml index aaa63bd..6fbbf0b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build_and_test.yml @@ -1,18 +1,25 @@ -name: Build application +name: Build and test -on: [pull_request, push] +on: + pull_request: + push: + branches: + - main jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: Set up JDK 19 + - uses: actions/checkout@v3 + - name: Set up JDK 20 uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: 19 + java-version: 20 cache: gradle - name: Build with Gradle run: ./gradlew build --no-daemon + - name: Run unit tests + run: ./gradlew test --no-daemon + diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml new file mode 100644 index 0000000..85c8a48 --- /dev/null +++ b/.github/workflows/integration_test.yml @@ -0,0 +1,53 @@ +name: Integration test + +on: + pull_request: + push: + branches: + - main + +jobs: + test: + runs-on: macos-11 + strategy: + matrix: + api-level: [33, 34] + target: ["default"] + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: Gradle cache + uses: gradle/gradle-build-action@v2 + + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: "oracle" + java-version: "17" + + - name: AVD cache + uses: actions/cache@v3 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-${{ matrix.api-level }} + + - name: Instrumentation Tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + target: ${{ matrix.target }} + arch: x86_64 + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + script: ./gradlew connectedCheck --stacktrace + + - name: Upload Reports + uses: actions/upload-artifact@v3 + with: + name: Test-Reports + path: app/build/reports + if: always() diff --git a/.github/workflows/validate-gradle-wrapper.yml b/.github/workflows/validate-gradle-wrapper.yml index baffddb..19f09cc 100644 --- a/.github/workflows/validate-gradle-wrapper.yml +++ b/.github/workflows/validate-gradle-wrapper.yml @@ -1,6 +1,10 @@ name: Validate Gradle Wrapper -on: [pull_request, push] +on: + pull_request: + push: + branches: + - main jobs: validation: diff --git a/Changelog.md b/Changelog.md new file mode 100644 index 0000000..cc57c55 --- /dev/null +++ b/Changelog.md @@ -0,0 +1,6 @@ +# Changelog + +# v1.0.1 +- Mib Catalog: Fix issue with refreshing name of selected node +- Mib Catalog: Show description in bottom sheet - if any +- Dependency updates \ No newline at end of file diff --git a/README.md b/README.md index e724a5e..7d52716 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A free software GPL v3 Android SNMP reader app. - Show basic system information - Custom queries with your OIDs, in single-query and recursive-query mode - Integrated exchangeable MIB-Catalog (see documentation for more information) - - Use the built-in MIB catalog (RFC 1213 + common MIBs of *net-snmp*) or generate and import your own as + - Use the built-in MIB catalog (RFC 1213 + common MIBs of *net-snmp*) or generate and import your own as described [here](./docs/MIB_catalog_guide.md) - QR-code support for SNMP connections - No tracking, no ads diff --git a/app/build.gradle b/app/build.gradle index 87d95f9..8c04869 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,7 +33,7 @@ android { applicationId "org.emschu.snmp.cockpit" minSdk 24 targetSdk 34 - versionCode 50 + versionCode 52 versionName versionCode.toString() resourceConfigurations += ['en', 'de'] @@ -112,7 +112,7 @@ dependencies { implementation "androidx.core:core-ktx:$coreKtxVersion" implementation "androidx.appcompat:appcompat:$appCompatVersion" - implementation 'androidx.activity:activity-compose:1.7.2' + implementation 'androidx.activity:activity-compose:1.8.2' implementation "com.google.android.material:material:$googleMaterialVersion" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinGradlePluginVersion" @@ -120,7 +120,7 @@ dependencies { implementation "androidx.compose.foundation:foundation:$compose_version" implementation "androidx.compose.foundation:foundation-layout:$compose_version" - implementation "androidx.compose.material3:material3:1.1.1" + implementation "androidx.compose.material3:material3:1.1.2" implementation "androidx.compose.material:material-icons-core:$compose_version" implementation "androidx.compose.material:material-icons-extended:$compose_version" @@ -146,7 +146,7 @@ dependencies { implementation "androidx.navigation:navigation-compose:$navigationComposeVersion" implementation "androidx.navigation:navigation-ui-ktx:$navigationComposeVersion" implementation 'androidx.preference:preference-ktx:1.2.1' - implementation 'androidx.work:work-runtime:2.8.1' + implementation 'androidx.work:work-runtime:2.9.0' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutinesVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutinesVersion" diff --git a/app/src/androidTest/java/org/emschu/snmp/cockpit/OidCatalogTest.kt b/app/src/androidTest/java/org/emschu/snmp/cockpit/OidCatalogTest.kt index 9e0659a..64033ae 100644 --- a/app/src/androidTest/java/org/emschu/snmp/cockpit/OidCatalogTest.kt +++ b/app/src/androidTest/java/org/emschu/snmp/cockpit/OidCatalogTest.kt @@ -36,7 +36,7 @@ class OidCatalogTest : AbstractCockpitAppTest() { Assert.assertEquals("laIndex", OIDCatalog.getAsnByOid("1.3.6.1.4.1.2021.10.1.1.1")) Assert.assertEquals("", OIDCatalog.getAsnByOid("")) - // these oid does not exist + // these oid do not exist Assert.assertEquals("", OIDCatalog.getAsnByOid("2.1")) Assert.assertEquals("ipAdEntAddr", OIDCatalog.getAsnByOid("1.3.6.1.2.1.4.20.1.1.192.168.178.21")) } diff --git a/app/src/main/java/org/emschu/snmp/cockpit/SnmpCockpitApp.kt b/app/src/main/java/org/emschu/snmp/cockpit/SnmpCockpitApp.kt index d2fe4af..b0289f6 100644 --- a/app/src/main/java/org/emschu/snmp/cockpit/SnmpCockpitApp.kt +++ b/app/src/main/java/org/emschu/snmp/cockpit/SnmpCockpitApp.kt @@ -43,10 +43,6 @@ class SnmpCockpitApp : Application(), Configuration.Provider { dbHelper = CockpitDbHelper(context!!) } - override fun getWorkManagerConfiguration(): Configuration = Configuration.Builder() - .setMinimumLoggingLevel(if (BuildConfig.DEBUG) android.util.Log.DEBUG else android.util.Log.ERROR) - .build() - companion object { @JvmStatic @SuppressLint("StaticFieldLeak") @@ -83,4 +79,9 @@ class SnmpCockpitApp : Application(), Configuration.Provider { fun isConnectedToWifi(): Boolean = cockpitStateManager.networkAvailabilityObservable.value ?: true } + + override val workManagerConfiguration: Configuration + get() = Configuration.Builder() + .setMinimumLoggingLevel(if (BuildConfig.DEBUG) android.util.Log.DEBUG else android.util.Log.ERROR) + .build() } \ No newline at end of file diff --git a/app/src/main/java/org/emschu/snmp/cockpit/snmp/OIDCatalog.kt b/app/src/main/java/org/emschu/snmp/cockpit/snmp/OIDCatalog.kt index 977f3e0..a0e27c6 100644 --- a/app/src/main/java/org/emschu/snmp/cockpit/snmp/OIDCatalog.kt +++ b/app/src/main/java/org/emschu/snmp/cockpit/snmp/OIDCatalog.kt @@ -83,15 +83,30 @@ object OIDCatalog { * @return */ fun getAsnByOid(oid: String): String? { + val jsonCatalogItem = findItem(oid) + return jsonCatalogItem?.name + } + + /** + * get description an oid and strip last number (usually index) of oid for catalog lookup + * + * @param oid + * @return + */ + fun getSysDescrByOid(oid: String): String? { + val jsonCatalogItem = findItem(oid) + return jsonCatalogItem?.description + } + + private fun findItem(oid: String): JsonCatalogItem? { var key = oid while (!mapOidKey.containsKey(key) && key.contains('.')) { key = oid.substring(0, key.lastIndexOf('.')) } if (key == "" || !mapOidKey.containsKey(key)) { - return "" + return null } - val jsonCatalogItem = mapOidKey[key] - return jsonCatalogItem?.name + return mapOidKey[key] } fun load(mibCatalogManager: MibCatalogManager) { diff --git a/app/src/main/java/org/emschu/snmp/cockpit/ui/components/BottomSheet.kt b/app/src/main/java/org/emschu/snmp/cockpit/ui/components/BottomSheet.kt index eb7ff3f..778a8f1 100644 --- a/app/src/main/java/org/emschu/snmp/cockpit/ui/components/BottomSheet.kt +++ b/app/src/main/java/org/emschu/snmp/cockpit/ui/components/BottomSheet.kt @@ -22,14 +22,37 @@ import android.content.Context import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll -import androidx.compose.material.* -import androidx.compose.runtime.* +import androidx.compose.material.Button +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.Card +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.MaterialTheme +import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.Text +import androidx.compose.material.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -108,7 +131,7 @@ fun BottomSheetContent( modifier = Modifier.padding(4.dp), ) } - val name: String = remember { + val name: String = remember(oidQuery.value) { OIDCatalog.getAsnByOid(oidQuery.value) ?: oidQuery.value } Row { @@ -118,6 +141,18 @@ fun BottomSheetContent( ) Text(name) } + val description: String = remember(oidQuery.value) { + OIDCatalog.getSysDescrByOid(oidQuery.value) ?: oidQuery.value + } + if (description != oidQuery.value) { + Row { + Text( + "Description:", fontWeight = FontWeight.Bold, + modifier = Modifier.padding(end = 2.dp) + ) + Text(description) + } + } val deviceList = SnmpCockpitApp.deviceManager.deviceConnectionList Row(modifier = Modifier.padding(vertical = 4.dp)) { if (deviceList.isEmpty()) { @@ -240,13 +275,13 @@ private fun BottomSheetViewPreviewLight() { private fun ConnectionSelectorLight() { val deviceConnectionLists = listOf( DeviceConnection(DeviceConfiguration(DeviceConfiguration.SNMP_VERSION.v1), - remember { mutableStateOf(SystemQuery()) }), + remember { mutableStateOf(SystemQuery()) }), DeviceConnection(DeviceConfiguration(DeviceConfiguration.SNMP_VERSION.v1), - remember { mutableStateOf(SystemQuery()) }), + remember { mutableStateOf(SystemQuery()) }), DeviceConnection(DeviceConfiguration(DeviceConfiguration.SNMP_VERSION.v1), - remember { mutableStateOf(SystemQuery()) }), + remember { mutableStateOf(SystemQuery()) }), DeviceConnection(DeviceConfiguration(DeviceConfiguration.SNMP_VERSION.v1), - remember { mutableStateOf(SystemQuery()) }), + remember { mutableStateOf(SystemQuery()) }), ) CockpitTheme(darkTheme = false) { diff --git a/build.gradle b/build.gradle index 1a542a9..57bab6b 100644 --- a/build.gradle +++ b/build.gradle @@ -4,19 +4,19 @@ apply plugin: 'org.sonarqube' buildscript { ext { compose_version = '1.5.0' - compose_version_ui = '1.5.0' + compose_version_ui = '1.5.4' kotlin_version = '1.8.10' compilerExtensionVersion = '1.4.4' kotlinGradlePluginVersion = '1.8.10' latestAboutLibsRelease = '10.9.1' - navigationComposeVersion = '2.7.0' + navigationComposeVersion = '2.7.6' junitVersion = '4.13.2' espressoVersion = '3.5.0' coreKtxVersion = '1.10.1' kotlinCoroutinesVersion = '1.7.3' appCompatVersion = '1.6.1' - googleMaterialVersion = '1.9.0' - lifecycleVersion = '2.5.1' + googleMaterialVersion = '1.11.0' + lifecycleVersion = '2.6.2' androidJUnitExtVersion = '1.1.5' } repositories { @@ -27,7 +27,7 @@ buildscript { } } dependencies { - classpath 'com.android.tools.build:gradle:8.1.4' + classpath 'com.android.tools.build:gradle:8.2.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinGradlePluginVersion" classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:4.4.1.3373" classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:${latestAboutLibsRelease}" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d23393d..e4e797d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Nov 19 12:06:34 CET 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME