Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,12 @@ interface EventRepository {
): Event

suspend fun deleteAll()

/**
* Uses raw SQL insertion commands to insert events into the database.
* This is useful for bulk inserts or when the events are pre-formatted as SQL commands
* Only use this method in debugging or testing scenarios where you have control over the SQL commands.
* it throws an exception if called in production code.
*/
suspend fun executeRawEventInsertions(rawSqlInsertStatements: List<String>)
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,7 @@ internal open class EventRepositoryImpl @Inject constructor(

throw t
}

override suspend fun executeRawEventInsertions(rawSqlInsertStatements: List<String>) =
eventLocalDataSource.executeRawEventInsertions(rawSqlInsertStatements)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.database.sqlite.SQLiteException
import com.simprints.core.DispatcherIO
import com.simprints.core.NonCancellableIO
import com.simprints.core.tools.json.JsonHelper
import com.simprints.infra.events.BuildConfig
import com.simprints.infra.events.event.domain.models.Event
import com.simprints.infra.events.event.domain.models.EventType
import com.simprints.infra.events.event.domain.models.scope.EventScope
Expand Down Expand Up @@ -174,6 +175,23 @@ internal open class EventLocalDataSource @Inject constructor(
eventDao.deleteAll()
}

suspend fun executeRawEventInsertions(rawSqlInsertStatements: List<String>) = useRoom(writingContext) {
// this method should only be used in debug builds for testing purposes
check(BuildConfig.DEBUG) { "executeRawEventInsertions should only be used in debug builds for testing purposes" }

val sqliteDb = eventDatabaseFactory.get().openHelper.writableDatabase
sqliteDb.beginTransaction()
try {
rawSqlInsertStatements.forEach {
sqliteDb.execSQL(it)
}
} catch (e: Exception) {
e.printStackTrace()
}
sqliteDb.setTransactionSuccessful()
sqliteDb.endTransaction()
}

companion object {
// Actual limit is 999, but it is better to leave some wiggle room
private const val SQLITE_VARIABLE_LIMIT = 900
Expand Down
73 changes: 56 additions & 17 deletions testing/data-generator/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
# 📦 Debug-Only Biometric Data Generator

This module allows developers to insert **bulk biometric enrollment records** directly into the local SID database for **developer testing**, **performance testing**, and **E2E test setup**. It is only available in **debug builds** and should never be shipped in production.
This module enables developers to insert **bulk biometric enrollment records** and **session events** into the local SID database for **testing and E2E setup**.
**Debug builds only** — never ship in production.

---

## 🚀 How to Use
## Table of Contents

Use the following ADB command to trigger bulk record generation via an explicit `Intent`. This will insert fingerprint and face templates using pre-configured logic.
- [Features](#features)
- [Usage](#usage)
- [Biometric Records Generation](#biometric-records-generation)
- [Session Event Generation](#session-event-generation)
- [Parameters](#parameters)
- [Face Template Image](#face-template-image)

### ✅ Example Command
---

## Features

- Bulk insert of biometric enrollment records (fingerprint, face)
- Bulk generation of session events (enrol, identify, verify, etc.)
- Designed for performance, E2E, and sync testing

---

## Usage

### Biometric Records Generation

Populate the database with many enrollment records for 1:1 and 1:N biometric matching tests.

**Command:**
```bash
adb shell am start \
-a com.simprints.test.GENERATE_ENROLLMENT_RECORDS \
Expand All @@ -22,10 +43,7 @@ adb shell am start \
--es EXTRA_FINGER_ORDER.NEC_1 "RIGHT_INDEX_FINGER,LEFT_THUMB" \
--es EXTRA_FIRST_SUBJECT_ID "d9a6c3f7-a6c3-d9a6-c3f7-a6c3d9a6c3f7"
```

---

## 🧠 Parameters
### Parameters

| Key | Description |
| ------------------------------ |----------------------------------------------|
Expand All @@ -37,13 +55,34 @@ adb shell am start \
| `EXTRA_FINGER_ORDER.*` | Comma-separated finger order for each format |
| `EXTRA_FIRST_SUBJECT_ID` | UUID of the first subject |

---

## 🖼️ Face Template Image

This generator uses a static face image to create biometric templates.
📍![Face image](./FACE-IMAGE.png)


### Session Event Generation
Simulate real-world usage and server sync by generating session events.
**Command:**
```bash
adb shell am start \
-a com.simprints.test.GENERATE_SESSION_EVENTS \
--es EXTRA_PROJECT_ID "oPru9XTAI2hE2nDFD5vZ" \
--es EXTRA_MODULE_ID "module-abc" \
--es EXTRA_ATTENDANT_ID "user-xyz" \
--ei EXTRA_ENROL_COUNT 2 \
--ei EXTRA_IDENTIFY_COUNT 2 \
--ei EXTRA_VERIFY_COUNT 2 \
--ei EXTRA_CONFIRM_IDENTIFY_COUNT 2 \
--ei EXTRA_ENROL_LAST_COUNT 2
```
### Parameters
| Key | Type | Description |
|-----------------------------|--------|-----------------------------------------------------------------------|
| `EXTRA_PROJECT_ID` | String | The ID of the project to associate with the generated session events. |
| `EXTRA_MODULE_ID` | String | The module identifier |
| `EXTRA_ATTENDANT_ID` | String | The ID of the field worker |
| `EXTRA_ENROL_COUNT` | Int | Number of enrolment sessions generate. |
| `EXTRA_IDENTIFY_COUNT` | Int | Number of identification sessions to generate. |
| `EXTRA_VERIFY_COUNT` | Int | Number of verification sessions to generate. |
| `EXTRA_CONFIRM_IDENTIFY_COUNT` | Int | Number of confirm-identification sessions to generate. |
| `EXTRA_ENROL_LAST_COUNT` | Int | Number of last enrolment sessions to generate . |

---
### Face Template Image
Face Template Image
A static face image is used for template generation:
📍<img src="./FACE-IMAGE.png" alt="Face image"></img>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'AUTHORIZATION',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":2,"result":"AUTHORIZED","userInfo":{"projectId":"__project_id__","userId":{"className":"TokenizableString.Raw","value":"__module_id__"}},"type":"AUTHORIZATION"},"type":"AUTHORIZATION","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'BIOMETRIC_REFERENCE_CREATION',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":1,"id":"__event_id__","modality":"FACE","captureIds":["872271c4-695d-495d-910a-efde23097f8a","6ed2bfa5-d076-40ee-af33-ce7f4c826e23"],"type":"BIOMETRIC_REFERENCE_CREATION"},"type":"BIOMETRIC_REFERENCE_CREATION","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CALLBACK_CONFIRMATION',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":3,"identificationOutcome":true,"type":"CALLBACK_CONFIRMATION"},"type":"CALLBACK_CONFIRMATION","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CALLBACK_ENROLMENT',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":3,"guid":"872271c4-695d-495d-910a-efde23097f8a","type":"CALLBACK_ENROLMENT"},"type":"CALLBACK_ENROLMENT","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CALLBACK_IDENTIFICATION',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":3,"sessionId":"872271c4-695d-495d-910a-efde23097f8a","scores":[{"guid":"872271c4-695d-495d-910a-efde23097f8a","confidence":1,"confidenceMatch":"MEDIUM"}],"type":"CALLBACK_IDENTIFICATION"},"type":"CALLBACK_IDENTIFICATION","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CALLBACK_VERIFICATION',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":3,"score":{"guid":"872271c4-695d-495d-910a-efde23097f8a","confidence":1,"confidenceMatch":"MEDIUM"},"type":"CALLBACK_VERIFICATION"},"type":"CALLBACK_VERIFICATION","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CALLOUT_CONFIRMATION_V3',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":3,"projectId":"__project_id__","selectedGuid":"872271c4-695d-495d-910a-efde23097f8a","sessionId":"6ed2bfa5-d076-40ee-af33-ce7f4c826e23","metadata":"DEFAULT_METADATA","type":"CALLOUT_CONFIRMATION_V3"},"type":"CALLOUT_CONFIRMATION_V3","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CALLOUT_ENROLMENT_V3',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":3,"projectId":"__project_id__","userId":{"className":"TokenizableString.Raw","value":"__module_id__"},"moduleId":{"className":"TokenizableString.Raw","value":"user-xyz"},"metadata":"DEFAULT_METADATA","biometricDataSource":"SIMPRINTS","type":"CALLOUT_ENROLMENT_V3"},"type":"CALLOUT_ENROLMENT_V3","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CALLOUT_IDENTIFICATION_V3',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":3,"projectId":"__project_id__","userId":{"className":"TokenizableString.Raw","value":"__module_id__"},"moduleId":{"className":"TokenizableString.Raw","value":"user-xyz"},"metadata":"DEFAULT_METADATA","biometricDataSource":"SIMPRINTS","type":"CALLOUT_IDENTIFICATION_V3"},"type":"CALLOUT_IDENTIFICATION_V3","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CALLOUT_VERIFICATION_V3',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":3,"projectId":"__project_id__","userId":{"className":"TokenizableString.Raw","value":"__attended_id__"},"moduleId":{"className":"TokenizableString.Raw","value":"__module_id__"},"verifyGuid":"6ed2bfa5-d076-40ee-af33-ce7f4c826e23","metadata":"DEFAULT_METADATA","biometricDataSource":"SIMPRINTS","type":"CALLOUT_VERIFICATION_V3"},"type":"CALLOUT_VERIFICATION_V3","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CANDIDATE_READ',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":2,"candidateId":"872271c4-695d-495d-910a-efde23097f8a","localResult":"FOUND","remoteResult":"NOT_FOUND","endedAt":{"ms":1754153597998,"isTrustworthy":false},"type":"CANDIDATE_READ"},"type":"CANDIDATE_READ","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'COMPLETION_CHECK',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":2,"completed":true,"type":"COMPLETION_CHECK"},"type":"COMPLETION_CHECK","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CONNECTIVITY_SNAPSHOT',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":3,"connections":[{"type":"MOBILE","state":"CONNECTED"}],"type":"CONNECTIVITY_SNAPSHOT"},"type":"CONNECTIVITY_SNAPSHOT","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
13 changes: 13 additions & 0 deletions testing/data-generator/src/debug/assets/dummy_events/CONSENT.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'CONSENT',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":2,"endedAt":{"ms":1754153597998,"isTrustworthy":false},"consentType":"INDIVIDUAL","result":"ACCEPTED","type":"CONSENT"},"type":"CONSENT","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
13 changes: 13 additions & 0 deletions testing/data-generator/src/debug/assets/dummy_events/ENROLMENT.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'ENROLMENT_V4',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":4,"subjectId":"872271c4-695d-495d-910a-efde23097f8a","projectId":"__project_id__","moduleId":{"className":"TokenizableString.Raw","value":"__module_id__"},"attendantId":{"className":"TokenizableString.Raw","value":"user-xyz"},"biometricReferenceIds":["872271c4-695d-495d-910a-efde23097f8a","6ed2bfa5-d076-40ee-af33-ce7f4c826e23"],"type":"ENROLMENT_V4"},"type":"ENROLMENT_V4","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'FACE_CAPTURE',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"id":"__event_id__","createdAt":{"ms":1754153597998,"isTrustworthy":false},"endedAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":4,"attemptNb":0,"qualityThreshold":1.0,"result":"VALID","isAutoCapture":false,"isFallback":true,"face":{"yaw":0.0,"roll":1.0,"quality":2.0,"format":"RANK_ONE_1_23"},"type":"FACE_CAPTURE"},"type":"FACE_CAPTURE","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
INSERT INTO
DbEvent
VALUES
(
'__event_id__',
'FACE_CAPTURE_BIOMETRICS',
'__project_id__',
'__session_id__',
'{"id":"__event_id__","payload":{"id":"__event_id__","createdAt":{"ms":1754153597998,"isTrustworthy":false},"eventVersion":1,"face":{"yaw":1.0,"roll":0.0,"template":"template","quality":1.0,"format":"RANK_ONE_1_23"},"type":"FACE_CAPTURE_BIOMETRICS"},"type":"FACE_CAPTURE_BIOMETRICS","scopeId":"__scope_id__","projectId":"__project_id__"}',
1754153597998,
0,
NULL
);
Loading