SuperX-Kernmodul
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

285 lines
12 KiB

package de.superx.dbt.model;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.nio.file.Path;
import java.util.List;
import java.util.StringJoiner;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import de.superx.BIATestUtils;
import de.superx.BaseDbTest;
import de.superx.bianalysis.ReportDefinition;
import de.superx.bianalysis.models.Right;
import de.superx.bianalysis.rest.BiAnalysisApi;
import de.superx.dbt.DbtAction;
import de.superx.dbt.DbtRunRequest;
import de.superx.dbt.DbtRunResult;
import de.superx.dbt.DbtWrapper;
import de.superx.dbt.DbtExecutionState;
import de.superx.rest.EtlJobApi;
import de.superx.rest.model.Result;
import de.superx.rest.model.Row;
import de.superx.util.PathAndFileUtils;
public class DbtRunAndMeasureTest extends BaseDbTest {
static Logger logger = LoggerFactory.getLogger(DbtRunAndMeasureTest.class);
@Autowired
BiAnalysisApi biAnalysis;
@Autowired
EtlJobApi api;
@Autowired
DbtWrapper dbtWrapper;
private JdbcTemplate jt;
@Before
public void setUp() {
jt = new JdbcTemplate(dataSource);
setRight(Right.CREATE_ANALYSIS);
}
public static final String BI_ANALYSIS_FIXTURES = String.join(File.separator,
"test",
"resources",
"db",
"fixtures"
);
/*
* Idee: Wir holen uns Kennzahlen/Auswertungen mit Hilfe der "BI-Analysen".
* Dann ändern wir etwas im Vorsystem (oder hier, für die Testfälle, erstmal nur
* im staging-area, welches die Vorsystemdaten 1:1 abbilden sollte!?), lassen
* die dbt-Transformation laufen, und prüfen ein weiteres Mal die Auswertung.
* Die Änderungen im Vorsystem sollten ihre Entsprechung in der Auswertung haben.
* 1. Testfall: Wir prüfen die Propagierung der Änderung des Geschlechts eines
* Bewerbers.
*/
@Test
public void testTransferOfChanges() throws InterruptedException {
String requestFile = BI_ANALYSIS_FIXTURES + File.separator + "applicants_by_gender_request.json";
ReportDefinition definition = BIATestUtils.getReportDefinitionFromFile(requestFile);
// Ausgangslage feststellen und merken
Result result_before = null;
try {
result_before = biAnalysis.getReport(definition);
} catch (Exception e) {
throw new RuntimeException(e);
}
// ids der Genderschlüssel "männlich"/"weiblich" ermitteln
String gender_sql = "SELECT id, defaulttext FROM staging.k_gender WHERE defaulttext IN ('männlich', 'weiblich');";
SqlRowSet gender_rows = jt.queryForRowSet(gender_sql);
gender_rows.beforeFirst();
int male_key_id = -1;
int female_key_id = -1;
while(gender_rows.next()) {
if (gender_rows.getString("defaulttext").equals("männlich")) {
male_key_id = gender_rows.getInt("id");
} else if (gender_rows.getString("defaulttext").equals("weiblich")) {
female_key_id = gender_rows.getInt("id");
}
}
// einen männlichen Bewerber raussuchen und seine Personen-Id merken
String person_id_sql = "SELECT id FROM staging.person WHERE id IN " +
"(SELECT person_id FROM staging.applicant) AND k_gender_id = " + male_key_id + " LIMIT 1;";
SqlRowSet applicants = jt.queryForRowSet(person_id_sql);
applicants.beforeFirst();
int applicant_person_id = -1;
while(applicants.next()) {
applicant_person_id = applicants.getInt("id");
}
// Geschlecht des Bewerbers auf "weiblich" ändern
String alter_applicant_sql = "UPDATE staging.person SET k_gender_id = " + female_key_id +
" WHERE id = " + applicant_person_id;
jt.execute(alter_applicant_sql);
// Bewerber nach dim_person_applicant inkrementell laden
DbtRunRequest request = new DbtRunRequest(DbtAction.BUILD, "hisinone", "+dim_person_applicant");
DbtRunResult result = dbtWrapper.execute(request);
if (result.getState() != DbtExecutionState.SUCCESS) {
List<String> errors = result.getErrorMessages();
StringJoiner joiner = new StringJoiner("\n");
for (String error : errors) {
joiner.add(error);
}
Assert.fail(joiner.toString());
}
// Lage nach Änderung und dbt-Transformation feststellen
Result result_after = null;
try {
result_after = biAnalysis.getReport(definition);
} catch (Exception e) {
throw new RuntimeException(e);
}
// Werte vergleichen: Wegen Änderung sollte ein Bewerber weniger, eine Bewerbering mehr sein
Long male_before = lookupValue(result_before,"app_basic:3", "männlich","Kennzahl|app_basic:80");
Long female_before = lookupValue(result_before,"app_basic:3", "weiblich","Kennzahl|app_basic:80");
Long male_after = lookupValue(result_after,"app_basic:3", "männlich", "Kennzahl|app_basic:80");
Long female_after = lookupValue(result_after,"app_basic:3", "weiblich","Kennzahl|app_basic:80");
assertEquals("Anzahl der männlichen Bewerber sollte um 1 abgenommen haben",
male_before.intValue(), male_after.intValue() + 1);
assertEquals("Anzahl der weiblichen Bewerber sollte um 1 zugenommen haben",
female_before.intValue(), female_after.intValue() - 1);
// Geschlecht des Bewerbers wieder auf "männlich" ändern
// Soll danach noch dbt laufen? (erstmal weg lassen)
String reset_applicant_sql = "UPDATE staging.person SET k_gender_id = " + male_key_id +
" WHERE id = " + applicant_person_id;
jt.execute(reset_applicant_sql);
}
/*
* Wir prüfen das Entfernen der Bewerbernummer nach "Löschung" eines Bewerbers.
*/
@Test
public void testRemoveApplicantNumber() throws InterruptedException {
String requestFile = BI_ANALYSIS_FIXTURES + File.separator + "applicants_by_applicantnumber.json";
ReportDefinition definition = BIATestUtils.getReportDefinitionFromFile(requestFile);
// Ausgangslage feststellen und merken
Result result_before = null;
try {
result_before = biAnalysis.getReport(definition);
} catch (Exception e) {
throw new RuntimeException(e);
}
// einen Bewerber raussuchen und seine Bewerber-Id merken
String person_id_sql = "SELECT DISTINCT p.id, a.id AS applicant_id, a.applicantnumber "
+ "FROM staging.applicant AS a "
+ "JOIN staging.person AS p ON a.person_id = p.id "
+ "LEFT JOIN presentation.fact_application AS fa ON fa.applicant_id = a.id "
+ "WHERE fa.applicant_id IS NOT NULL ORDER BY id LIMIT 1";
SqlRowSet person_applicants = jt.queryForRowSet(person_id_sql);
person_applicants.beforeFirst();
int person_id = -1;
int applicantnumber = -1;
int applicant_id = -1;
while(person_applicants.next()) {
person_id = person_applicants.getInt("id");
applicantnumber = person_applicants.getInt("applicantnumber");
applicant_id = person_applicants.getInt("applicant_id");
}
int dummy_id = -10;
// Löschen eines Bewerbers durch Änderung der Bewerberid simulieren
String alter_person_sql = "UPDATE staging.applicant SET (id, person_id) = (" + dummy_id + ", " + dummy_id + ")" +
" WHERE id = " + applicant_id + ";";
jt.execute(alter_person_sql);
// Bewerber nach dim_person_applicant inkrementell laden
DbtRunRequest request = new DbtRunRequest(DbtAction.BUILD, "hisinone", "+dim_person_applicant");
DbtRunResult result = dbtWrapper.execute(request);
if (result.getState() != DbtExecutionState.SUCCESS) {
List<String> errors = result.getErrorMessages();
StringJoiner joiner = new StringJoiner("\n");
for (String error : errors) {
joiner.add(error);
}
Assert.fail(joiner.toString());
}
// Lage nach Änderung und dbt-Transformation feststellen
Result result_after = null;
try {
result_after = biAnalysis.getReport(definition);
} catch (Exception e) {
throw new RuntimeException(e);
}
// Werte vergleichen: Wegen Änderung sollte ein Bewerber keine Bewerbernummer mehr haben
Long no_number_before = lookupValue(result_before, "app_basic:162","n. v.","Kennzahl|app_basic:80");
Long no_number_after = lookupValue(result_after, "app_basic:162","n. v.","Kennzahl|app_basic:80");
if(no_number_before == null) {
no_number_before = Long.valueOf(0);
}
if(no_number_after == null) {
no_number_after = Long.valueOf(0);
}
// Zurücksetzen der Änderungen, durch das ändern der id hat sich auch die snapshot-Tabelle aktualisiert
// Soll danach noch dbt laufen? (erstmal weg lassen)
String reset_applicant_sql = "UPDATE staging.applicant SET (id, person_id) = (" + applicant_id + ", "+ dummy_id + " )" +
" WHERE id = " + dummy_id + ";";
String reset_applicant_sql2 = "UPDATE presentation.dim_person_applicant SET applicantnumber = " + applicantnumber +
" WHERE src_person_id = " + person_id + ";";
String reset_applicant_snapshot_sql = "UPDATE snapshots.person_academicdegree_snapshot SET dbt_valid_to = NULL" +
" WHERE id = " + person_id + ";";
String delete_dummy_applicant_sql = "DELETE FROM snapshots.person_academicdegree_snapshot WHERE id = " + dummy_id + ";";
//jt.execute(reset_applicant_sql + reset_applicant_sql2 + reset_applicant_snapshot_sql + delete_dummy_applicant_sql);
assertEquals("Anzahl der Bewerber ohne Bewerbernummer sollte um 1 zugenommen haben",
no_number_before.intValue() + 1, no_number_after.intValue());
}
/*
* Wir prüfen das die Bewerbernamen nie in Auswertungen ausgegeben werden.
*/
@Test
public void testNeverNameForApplicants() throws InterruptedException {
String requestFile = BI_ANALYSIS_FIXTURES + File.separator + "applicants_by_name.json";
ReportDefinition definition = BIATestUtils.getReportDefinitionFromFile(requestFile);
// Result erstellen
Result result = null;
try {
result = biAnalysis.getReport(definition);
} catch (Exception e) {
throw new RuntimeException(e);
}
// Anzahl der Bewerber herausfinden (Es gibt auch Bewerber ohne Bewerbung, die werden nicht betrachtet)
String count_applicants_sql = "SELECT COUNT(DISTINCT person_id) FROM presentation.fact_application;";
SqlRowSet count_applicants = jt.queryForRowSet(count_applicants_sql);
count_applicants.beforeFirst();
int applicant_count = 0;
while(count_applicants.next()) {
applicant_count = count_applicants.getInt("count");
}
// Bewerber sollen nie Namen haben
Long numberOfApplicantsWithoutNames = lookupValue(result, "app_basic:12391","n. v.","Kennzahl|app_basic:80");
if(numberOfApplicantsWithoutNames == null) {
numberOfApplicantsWithoutNames = Long.valueOf(0);
}
assertEquals("Anzahl der Bewerber mit n. v. als Namen sollte der gleichen Anzahl an Bewerbern entsprechen",
applicant_count, numberOfApplicantsWithoutNames.intValue());
}
private static Long lookupValue(Result result, String key, String value, String measure_key) {
for (Row row : result.rows) {
String rvalue = (String)row.cells.get(key);
if (value.equals(rvalue)) {
return (Long)row.cells.get(measure_key);
}
}
return null;
}
}