Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Values generated by Faker are changing on regeneration #14549

Closed
1 task done
kaidohallik opened this issue Apr 1, 2021 · 6 comments · Fixed by #14595 or #14743
Closed
1 task done

Values generated by Faker are changing on regeneration #14549

kaidohallik opened this issue Apr 1, 2021 · 6 comments · Fixed by #14595 or #14743

Comments

@kaidohallik
Copy link
Contributor

Overview of the issue

In Angular entity update test

there are related entity objects with primary keys generated by Faker.

If for the related entity is not yet called resetFakerSeed()

then in every regeneration different fake values are generated.

The same values are generated in those cases:

  • if server generation is not skipped then in server sub generator resetFakerSeed() is already called for every entity and always the same value is generated
  • if you are lucky and entities generation order is suitable (referenced entities are generated before) then the same value is generated

But if neither of the above conditions is met then every regeneration generates the different values.

Entities generation order is calculated based on entity changelogDate:

function isBefore(e1, e2) {
return e1.definition.changelogDate - e2.definition.changelogDate;
}

The same problem may occur elsewhere where in entities is used Faker data for related entities.

Motivation for or Use Case

Regeneration should generate the same content as initial generation.

Reproduce the error

Generate application with: jhipster --skip-server

Create entities.jdl with content:

entity Entity1 {
    field1 String
}

Generate first entity with: jhipster import-jdl entities.jdl

Change entities.jdl to:

entity Entity1 {
    field1 String
}
entity Entity2 {
    field2 String
}
relationship OneToMany {
    Entity2{entity1} to Entity1{entity2}
}

Run again: jhipster import-jdl entities.jdl

If now regenerating entities for example with:

jhipster entities

then every time new random Entity2 id-s are generated because Entity1 is generated before Entity2 and resetFakerSeed() for Entity2 is not called yet.

Related issues
Suggest a Fix
JHipster Version(s)
jhipster@0.0.1-SNAPSHOT C:\projects\teest\jhipster-faker3
`-- generator-jhipster@7.0.0 -> C:\projects\contro\generator-jhipster

JHipster configuration, a .yo-rc.json file generated in the root folder
.yo-rc.json file
{
  "generator-jhipster": {
    "skipServer": true,
    "blueprints": [],
    "otherModules": [],
    "applicationType": "monolith",
    "baseName": "jhipster",
    "jhipsterVersion": "7.0.0",
    "skipClient": false,
    "skipUserManagement": false,
    "skipCheckLengthOfIdentifier": false,
    "skipFakeData": false,
    "jhiPrefix": "jhi",
    "entitySuffix": "",
    "dtoSuffix": "DTO",
    "testFrameworks": [],
    "pages": [],
    "creationTimestamp": 1617277519460,
    "clientFramework": "angularX",
    "withAdminUi": true,
    "clientTheme": "none",
    "enableTranslation": true,
    "nativeLanguage": "en",
    "clientPackageManager": "npm",
    "clientThemeVariant": "",
    "languages": ["en", "et"],
    "packageName": "com.mycompany.myapp",
    "cacheProvider": "ehcache",
    "websocket": false,
    "databaseType": "sql",
    "prodDatabaseType": "postgresql",
    "devDatabaseType": "h2Disk",
    "searchEngine": false,
    "buildTool": "maven",
    "serverPort": "8080",
    "authenticationType": "jwt",
    "serviceDiscoveryType": false,
    "enableHibernateCache": true,
    "reactive": false,
    "entities": ["Entity1", "Entity2"],
    "lastLiquibaseTimestamp": 1617278155000
  }
}
JDL for the Entity configuration(s) entityName.json files generated in the .jhipster directory
JDL entity definitions
entity Entity1 {
  field1 String
}
entity Entity2 {
  field2 String
}
relationship OneToMany {
  Entity2{entity1} to Entity1{entity2}
}


Environment and Tools

openjdk version "11.0.8" 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.8+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.8+10, mixed mode)

git version 2.31.1.windows.1

node: v14.16.0

npm: 7.7.6

Docker version 20.10.5, build 55c4c88

docker-compose version 1.28.5, build c4eb3a1f

Browsers and Operating System

Windows 10

  • Checking this box is mandatory (this is just to show you read everything)
@mshima
Copy link
Member

mshima commented Apr 4, 2021

@kaidohallik can you try calling resetFakerSeed after it was created?

entityWithConfig.resetFakerSeed = (suffix = '') =>

@kaidohallik
Copy link
Contributor Author

@mshima If calling resetFakerSeed after it was created then this fixes this issue.
Should we remove all other resetFakerSeed() calls and leave only this new one?

@mshima
Copy link
Member

mshima commented Apr 5, 2021

Should we remove all other resetFakerSeed() calls and leave only this new one?

Thinking about this, we can replace the others call, with

const templatePath = generator.templatePath(source);
if (generator.resetFakerSeed) {
  generator.resetFakerSeed(templatePath);
}

before

const promise = ejs.renderFile(generator.templatePath(source), context, options);

With this change, files will be reproducible independently. An additional call to the faker at any file will not change others files.

@kaidohallik
Copy link
Contributor Author

Adding generator.resetFakerSeed to function renderContent in file utils.js doesn't improve reproducibility in the current generator version.

Calling entityWithConfig.resetFakerSeed() after it was created is still needed to achieve reproducible build because faker is used in entity context:

const faker = entityWithConfig.faker;

So for related entity this is in related entity context.

I'll do PR which adds call to resetFakerSeed after this is created and removes other unnecessary resetFakerSeed calls.

@kaidohallik
Copy link
Contributor Author

I created #14595 for fix. If I tried to remove resetFakerSeed from other places then:

  • in the existing project first regeneration in some places different fake values were generated (next regenerations generated the same values)
  • generator tests didn't pass

So I added only one line for fix.

@mshima mshima reopened this Apr 6, 2021
@mshima
Copy link
Member

mshima commented Apr 6, 2021

I will take a look at #14549 (comment) later.
I think it will improve long term reproducibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment