There's some cleanup to be done in `FeatureMigrationIT` and related classes.

- [x] Convert `static` `preMigrationHook` and `postMigrationHook` to use instance members, retrieved from the `internalCluster()`
- [x] Use Hamcrest matchers as described [in this comment](https://github.com/elastic/elasticsearch/pull/84192/files#r812224067) for better failure output
- [x] Rename `createSimpleSettings` to `createSettings`
- [x] Rename `createSimpleMapping` to `createMapping`
- [x] add support for unknown fields https://github.com/elastic/elasticsearch/pull/84258#pullrequestreview-890890422
server/src/main/java/org/elasticsearch/upgrades/SystemIndexMigrationTaskState.java
PARSER.declareString(constructorArg(), CURRENT_INDEX_FIELD);
        PARSER.declareString(constructorArg(), CURRENT_FEATURE_FIELD);
        PARSER.declareObject(constructorArg(), (p, c) -> p.map(), FEATURE_METADATA_MAP_FIELD);
    }
    private final String currentIndex;
    private final String currentFeature;
    private final Map<String, Object> featureCallbackMetadata;
    public SystemIndexMigrationTaskState(String currentIndex, String currentFeature, Map<String, Object> featureCallbackMetadata) {
        this.currentIndex = Objects.requireNonNull(currentIndex);
        this.currentFeature = Objects.requireNonNull(currentFeature);
        this.featureCallbackMetadata = Objects.requireNonNullElse(featureCallbackMetadata, new HashMap<>());
    }
    public SystemIndexMigrationTaskState(StreamInput in) throws IOException {
        this.currentIndex = in.readString();
        this.currentFeature = in.readString();
        this.featureCallbackMetadata = in.readMap();
    }
    /**
     * Gets the name of the index that's currently being migrated.
     */
    public String getCurrentIndex() {
        return currentIndex;
    }
    /**
     * Gets the name of the feature which owns the index that's currently being migrated.
     */
    public String getCurrentFeature() {
        return currentFeature;
    }
    /**