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
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; |
|
} |
|
}
|
|
|