diff --git a/src/Learning/KWDRRuleLibrary/KWDRDateTime.cpp b/src/Learning/KWDRRuleLibrary/KWDRDateTime.cpp index a54659757..d65a3f3ee 100644 --- a/src/Learning/KWDRRuleLibrary/KWDRDateTime.cpp +++ b/src/Learning/KWDRRuleLibrary/KWDRDateTime.cpp @@ -890,7 +890,7 @@ Timestamp KWDRAddSeconds::ComputeTimestampResult(const KWObject* kwoObject) cons // Ajout des jours a la timestamp, si validite des operandes if (tsTimestamp.Check() and cSeconds != KWContinuous::GetMissingValue()) - tsTimestamp.AddSeconds((int)floor(cSeconds + 0.5)); + tsTimestamp.AddSeconds(cSeconds); // Sinon, on rend un timestamp invalide else tsTimestamp.Reset(); diff --git a/src/Learning/KWData/KWAttributeBlock.cpp b/src/Learning/KWData/KWAttributeBlock.cpp index 12b412036..03a9c5a5d 100644 --- a/src/Learning/KWData/KWAttributeBlock.cpp +++ b/src/Learning/KWData/KWAttributeBlock.cpp @@ -208,7 +208,7 @@ boolean KWAttributeBlock::Check() const metaData.GetExternalValueAt(sDefaultValueMetaDataKey) + ") should not be specified for a categorical sparse variable block"); } - else if (not metaData.IsDoubleTypeAt(sDefaultValueMetaDataKey)) + else if (not metaData.IsStringTypeAt(sDefaultValueMetaDataKey)) { bOk = false; AddError("Meta-data " + sDefaultValueMetaDataKey + " (" + diff --git a/src/Learning/KWDataUtils/KWKey.cpp b/src/Learning/KWDataUtils/KWKey.cpp index 61fa01e44..c123c37d4 100644 --- a/src/Learning/KWDataUtils/KWKey.cpp +++ b/src/Learning/KWDataUtils/KWKey.cpp @@ -59,7 +59,7 @@ const ALString KWKey::GetObjectLabel() const if (svFields.GetAt(i).GetLength() <= nFieldMaxLength) sFieldLabel = svFields.GetAt(i); else - sFieldLabel = svFields.GetAt(i).Right(nFieldMaxLength) + "..."; + sFieldLabel = svFields.GetAt(i).Left(nFieldMaxLength) + "..."; // Ajout du libelle du champ de cle sLabel += sFieldLabel; diff --git a/src/Learning/KWDataUtils/KWKeyPositionSampleExtractorTask.cpp b/src/Learning/KWDataUtils/KWKeyPositionSampleExtractorTask.cpp index 05403417a..c96d32e14 100644 --- a/src/Learning/KWDataUtils/KWKeyPositionSampleExtractorTask.cpp +++ b/src/Learning/KWDataUtils/KWKeyPositionSampleExtractorTask.cpp @@ -17,6 +17,7 @@ KWKeyPositionSampleExtractorTask::KWKeyPositionSampleExtractorTask() nReadSizeMin = 0; nReadSizeMax = 0; nReadBufferSize = 0; + lFilePos = 0; // Variables partagees DeclareSharedParameter(&shared_ivKeyFieldIndexes); @@ -690,7 +691,7 @@ boolean KWKeyPositionSampleExtractorTask::SlaveProcess() LongintToReadableString(recordKeyPosition->GetLineIndex() - previousRecordKeyPosition->GetLineIndex()) + " lines before", - nCumulatedLineNumber + inputFile.GetCurrentLineIndex() - 1); + nCumulatedLineNumber + inputFile.GetCurrentLineIndex()); delete recordKeyPosition; bOk = false; break; diff --git a/src/Learning/KWUserInterface/KWMTClassBuilderView.cpp b/src/Learning/KWUserInterface/KWMTClassBuilderView.cpp index 510cc275c..1d91829fc 100644 --- a/src/Learning/KWUserInterface/KWMTClassBuilderView.cpp +++ b/src/Learning/KWUserInterface/KWMTClassBuilderView.cpp @@ -104,7 +104,7 @@ boolean KWMTClassBuilderView::BuildMultiTableClass() // Verification de la specification du dictionnaire secondaire if (sSecondaryDictionaryName == "") { - AddError("Missing secondary dictionary name"); + AddError("Missing dictionary name"); bOk = false; } @@ -112,14 +112,21 @@ boolean KWMTClassBuilderView::BuildMultiTableClass() kwcSecondaryClass = KWClassDomain::GetCurrentDomain()->LookupClass(sSecondaryDictionaryName); if (bOk and kwcSecondaryClass == NULL) { - AddError("Secondary dictionary " + sSecondaryDictionaryName + " does not exist"); + AddError("Dictionary " + sSecondaryDictionaryName + " does not exist"); bOk = false; } // Erreur s'il s'agit d'un dictionnaire racine if (bOk and kwcSecondaryClass->GetRoot()) { - AddError("Secondary dictionary " + sSecondaryDictionaryName + " should not be a Root dictionary"); + AddError("Dictionary " + sSecondaryDictionaryName + " should not be a Root dictionary"); + bOk = false; + } + + // Erreur s'il n'y a pas de cle + if (bOk and kwcSecondaryClass->GetKeyAttributeNumber() == 0) + { + AddError("Missing key in dictionary " + sSecondaryDictionaryName); bOk = false; } diff --git a/src/Learning/MODL/MODL.cpp b/src/Learning/MODL/MODL.cpp index 2808a48c5..64718c7ae 100644 --- a/src/Learning/MODL/MODL.cpp +++ b/src/Learning/MODL/MODL.cpp @@ -37,7 +37,6 @@ int main(int argc, char** argv) // Choix du repertoire de lancement pour le debugage sous Windows (a commenter apres fin du debug) // SetWindowsDebugDir("Standard", "IrisLight"); - SetWindowsDebugDir("SparseData", "ReadSparseFormatCKeysError"); // Parametrage des logs memoires depuis les variables d'environnement, pris en compte dans KWLearningProject // KhiopsMemStatsLogFileName, KhiopsMemStatsLogFrequency, KhiopsMemStatsLogToCollect diff --git a/src/Parallel/PLParallelTask/PLFileConcatenater.cpp b/src/Parallel/PLParallelTask/PLFileConcatenater.cpp index 7f9ecb647..a0c983bea 100644 --- a/src/Parallel/PLParallelTask/PLFileConcatenater.cpp +++ b/src/Parallel/PLParallelTask/PLFileConcatenater.cpp @@ -156,10 +156,6 @@ boolean PLFileConcatenater::Concatenate(const StringVector* svChunkURIs, const O dTaskPercent = dProgressionEnd - dProgressionBegin; nChunkIndex = 0; - // Si rien a faire, on sort - if (svChunkURIs->GetSize() == 0) - return true; - // Lancement des serveurs de fichiers si on n'est pas dans une tache if (GetProcessId() == 0) { @@ -168,7 +164,10 @@ boolean PLFileConcatenater::Concatenate(const StringVector* svChunkURIs, const O // Memoire disponible sur la machine lRemainingMemory = RMResourceManager::GetRemainingAvailableMemory(); - nInputPreferredSize = PLRemoteFileService::GetPreferredBufferSize(svChunkURIs->GetAt(0)); + if (svChunkURIs->GetSize() > 0) + nInputPreferredSize = PLRemoteFileService::GetPreferredBufferSize(svChunkURIs->GetAt(0)); + else + nInputPreferredSize = SystemFile::nMinPreferredBufferSize; nOutputPreferredSize = PLRemoteFileService::GetPreferredBufferSize(sOutputFileName); if (lRemainingMemory >= nInputPreferredSize + nOutputPreferredSize) @@ -176,7 +175,7 @@ boolean PLFileConcatenater::Concatenate(const StringVector* svChunkURIs, const O nOutputBufferSize = nOutputPreferredSize; lInputBufferSize = lRemainingMemory - nOutputBufferSize; - // Ajustement de la taille a un multiple de preferred size + // Ajustement de la taille a un multiple de preferred size if (lInputBufferSize > nInputPreferredSize) lInputBufferSize = (lInputBufferSize / nInputPreferredSize) * nInputPreferredSize; diff --git a/test/LearningTest/cmd/python/check_results.py b/test/LearningTest/cmd/python/check_results.py index 5b96f895a..a891d48e0 100644 --- a/test/LearningTest/cmd/python/check_results.py +++ b/test/LearningTest/cmd/python/check_results.py @@ -391,6 +391,13 @@ def check_results(test): # Comparaison si ok if ref_file_lines is not None and test_file_lines is not None: + # Cas des fichier stdout et stderr, que l'on filtre du prefix de process id + if file_name in [STDOUT_ERROR_LOG, STDERR_ERROR_LOG]: + ref_file_lines = filter_process_id_prefix_from_lines(ref_file_lines) + test_file_lines = filter_process_id_prefix_from_lines( + test_file_lines + ) + # Mise en forme specifique des message utilisateur (error, warning) pour les traiter des facon identique # dans les cas des fichiers de log utilisateur et json contains_user_messages = False @@ -1061,6 +1068,22 @@ def is_specific_line_pair_sequential(line1, line2): return result_lines +def filter_process_id_prefix_from_lines(lines): + """retourne les lignes sans l'eventuel prefixe de process id, du type '[0] '""" + output_lines = [] + for line in lines: + # En parallelle, une ligne vide peut contenir le numero du process entre crochets + pos_end = -1 + is_process_id = len(line) > 0 and line[0] == "[" + if is_process_id: + pos_end = line.find("]") + is_process_id = pos_end > 0 and line[1:pos_end].isdigit() + if is_process_id: + line = line[pos_end + 1 :].lstrip() + output_lines.append(line) + return output_lines + + def check_file_lines( ref_file_path: str, test_file_path, ref_file_lines, test_file_lines, log_file=None ): @@ -1413,6 +1436,7 @@ def filter_khiops_temp_dir(value): # cas general de comparaison de cellules [eval_res, threshold_res] = check_cell(field_ref, field_test) + # truncature des champs affiches dans les messages d'erreur if len(field_test) > max_field_length: field_test = field_test[0:max_field_length] + "..."