Search in sources :

Example 1 with ValidationRule

use of edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule in project gtfs-realtime-validator by CUTR-at-USF.

the class TimestampValidatorTest method testE017.

@Test
public void testE017() {
    TimestampValidator timestampValidator = new TimestampValidator();
    Map<ValidationRule, Integer> expected = new HashMap<>();
    GtfsRealtime.TripDescriptor.Builder tripDescriptorBuilder = GtfsRealtime.TripDescriptor.newBuilder();
    // Set valid trip_id = 1.1
    tripDescriptorBuilder.setTripId("1.1");
    final long CURRENT_TIME_MILLIS = TimeUnit.SECONDS.toMillis(MIN_POSIX_TIME);
    /**
     * No previous feed message (i.e., it's the first iteration) - no errors
     */
    feedHeaderBuilder.setTimestamp(MIN_POSIX_TIME);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    GtfsRealtime.FeedMessage currentIteration = feedMessageBuilder.setEntity(0, feedEntityBuilder.build()).build();
    // No previous iteration - no errors
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, currentIteration, null, null);
    expected.clear();
    TestUtils.assertResults(expected, results);
    /**
     * Change the trip_id for the previous iteration, but keep the same timestamp - 1 error
     */
    // Set valid trip_id = 1.2
    tripDescriptorBuilder.setTripId("1.2");
    feedHeaderBuilder.setTimestamp(MIN_POSIX_TIME);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    GtfsRealtime.FeedMessage previousIteration = feedMessageBuilder.setEntity(0, feedEntityBuilder.build()).build();
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, currentIteration, previousIteration, null);
    expected.put(E017, 1);
    TestUtils.assertResults(expected, results);
    /**
     * Change the header timestamp for the current iteration so both trip_id and header.timestamp are
     * different from previous iteration - no errors
     */
    feedHeaderBuilder.setTimestamp(MIN_POSIX_TIME + 1);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME + 1);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME + 1);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    currentIteration = feedMessageBuilder.setEntity(0, feedEntityBuilder.build()).build();
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, currentIteration, previousIteration, null);
    expected.clear();
    TestUtils.assertResults(expected, results);
    clearAndInitRequiredFeedFields();
}
Also used : HashMap(java.util.HashMap) TimestampValidator(edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.TimestampValidator) ValidationRule(edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule) GtfsRealtime(com.google.transit.realtime.GtfsRealtime) Test(org.junit.Test) FeedMessageTest(edu.usf.cutr.gtfsrtvalidator.lib.test.FeedMessageTest)

Example 2 with ValidationRule

use of edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule in project gtfs-realtime-validator by CUTR-at-USF.

the class TimestampValidatorTest method testW007.

/**
 * W007 - Refresh interval is more than 35 seconds
 */
@Test
public void testW007() {
    TimestampValidator timestampValidator = new TimestampValidator();
    Map<ValidationRule, Integer> expected = new HashMap<>();
    GtfsRealtime.TripDescriptor.Builder tripDescriptorBuilder = GtfsRealtime.TripDescriptor.newBuilder();
    // Set valid trip_id = 1.1
    tripDescriptorBuilder.setTripId("1.1");
    final long CURRENT_TIME_MILLIS = TimeUnit.SECONDS.toMillis(MIN_POSIX_TIME);
    /**
     * No previous feed message (i.e., it's the first iteration) - no warnings
     */
    feedHeaderBuilder.setTimestamp(MIN_POSIX_TIME + 36);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME + 36);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME + 36);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    GtfsRealtime.FeedMessage currentIteration = feedMessageBuilder.setEntity(0, feedEntityBuilder.build()).build();
    // No previous iteration - no errors
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, currentIteration, null, null);
    expected.clear();
    TestUtils.assertResults(expected, results);
    /**
     * Set the previous iteration header timestamp so interval is than TimestampValidator.MINIMUM_REFRESH_INTERVAL_SECONDS - no warnings
     */
    feedHeaderBuilder.setTimestamp(MIN_POSIX_TIME + 10);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME + 10);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME + 10);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    GtfsRealtime.FeedMessage previousIteration = feedMessageBuilder.setEntity(0, feedEntityBuilder.build()).build();
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, currentIteration, previousIteration, null);
    expected.clear();
    TestUtils.assertResults(expected, results);
    /**
     * Set the previous iteration header timestamp so interval is more TimestampValidator.MINIMUM_REFRESH_INTERVAL_SECONDS - 1 warning
     */
    feedHeaderBuilder.setTimestamp(MIN_POSIX_TIME);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    previousIteration = feedMessageBuilder.setEntity(0, feedEntityBuilder.build()).build();
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, currentIteration, previousIteration, null);
    expected.put(W007, 1);
    TestUtils.assertResults(expected, results);
    clearAndInitRequiredFeedFields();
}
Also used : HashMap(java.util.HashMap) TimestampValidator(edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.TimestampValidator) ValidationRule(edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule) GtfsRealtime(com.google.transit.realtime.GtfsRealtime) Test(org.junit.Test) FeedMessageTest(edu.usf.cutr.gtfsrtvalidator.lib.test.FeedMessageTest)

Example 3 with ValidationRule

use of edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule in project gtfs-realtime-validator by CUTR-at-USF.

the class TimestampValidatorTest method testE050.

/**
 * E050 - timestamp is in the future.  Tolerance is defined in TimestampValidator.IN_FUTURE_TOLERANCE_SECONDS.
 */
@Test
public void testE050() {
    TimestampValidator timestampValidator = new TimestampValidator();
    Map<ValidationRule, Integer> expected = new HashMap<>();
    GtfsRealtime.TripDescriptor.Builder tripDescriptorBuilder = GtfsRealtime.TripDescriptor.newBuilder();
    // "Current time" in milliseconds for test - let's use 100 seconds after the minimum valid POSIX TIME (for our validator)
    final long CURRENT_TIME_MILLIS = TimeUnit.SECONDS.toMillis(MIN_POSIX_TIME + 100);
    // Good timestamp (seconds) - 50 seconds behind "current time"
    final long RECENT = TimeUnit.MILLISECONDS.toSeconds(CURRENT_TIME_MILLIS) - 50;
    // Good timestamp (seconds) - in the future by 60 seconds, but still within the 60 second tolerance, so shouldn't log error
    final long FUTURE_60_SEC = TimeUnit.MILLISECONDS.toSeconds(CURRENT_TIME_MILLIS) + 60;
    // Bad future timestamp (SECONDS) - 60 seconds in the future
    final long FUTURE_61_SEC = TimeUnit.MILLISECONDS.toSeconds(CURRENT_TIME_MILLIS) + 61;
    /**
     * All timestamps are in the past - no errors
     */
    feedHeaderBuilder.setTimestamp(RECENT);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(RECENT);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(RECENT);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.clear();
    TestUtils.assertResults(expected, results);
    /**
     * All timestamps are in the future, but only by 60 seconds (within the tolerance) - no errors
     */
    feedHeaderBuilder.setTimestamp(FUTURE_60_SEC);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(FUTURE_60_SEC);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(FUTURE_60_SEC);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.clear();
    TestUtils.assertResults(expected, results);
    /**
     * Header timestamp is 61 seconds in future (outside of 60 second tolerance)- one error
     */
    feedHeaderBuilder.setTimestamp(FUTURE_61_SEC);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.put(E050, 1);
    TestUtils.assertResults(expected, results);
    // Check prefix text for error occurrence
    assertEquals("header.timestamp 19:02:41 (1104537761) is 1 min 1 sec greater than 19:01:40 (1104537700000)", results.get(0).getOccurrenceList().get(0).getPrefix());
    /**
     * Header and TripUpdate are 61 seconds in future- 2 errors
     */
    tripUpdateBuilder.setTimestamp(FUTURE_61_SEC);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.put(E050, 2);
    TestUtils.assertResults(expected, results);
    /**
     * Header, TripUpdate, and VehiclePosition are 61 seconds in future - 3 errors
     */
    vehiclePositionBuilder.setTimestamp(FUTURE_61_SEC);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.put(E050, 3);
    TestUtils.assertResults(expected, results);
    clearAndInitRequiredFeedFields();
}
Also used : HashMap(java.util.HashMap) TimestampValidator(edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.TimestampValidator) ValidationRule(edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule) Test(org.junit.Test) FeedMessageTest(edu.usf.cutr.gtfsrtvalidator.lib.test.FeedMessageTest)

Example 4 with ValidationRule

use of edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule in project gtfs-realtime-validator by CUTR-at-USF.

the class TimestampValidatorTest method testE012.

@Test
public void testE012() {
    TimestampValidator timestampValidator = new TimestampValidator();
    Map<ValidationRule, Integer> expected = new HashMap<>();
    GtfsRealtime.TripDescriptor.Builder tripDescriptorBuilder = GtfsRealtime.TripDescriptor.newBuilder();
    final long CURRENT_TIME_MILLIS = TimeUnit.SECONDS.toMillis(MIN_POSIX_TIME);
    /**
     * Header timestamp greater than other entities - no error
     */
    feedHeaderBuilder.setTimestamp(MIN_POSIX_TIME + 1);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.clear();
    TestUtils.assertResults(expected, results);
    /**
     * Header timestamp equal to other entities - no error
     */
    feedHeaderBuilder.setTimestamp(MIN_POSIX_TIME);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.clear();
    TestUtils.assertResults(expected, results);
    /**
     * Header timestamp less than VehiclePosition timestamp - 1 error
     */
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME + 1);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.put(E012, 1);
    TestUtils.assertResults(expected, results);
    /**
     * Header timestamp less than TripUpdate timestamp - 1 error
     */
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME + 1);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    // Feed header timestamp is less than TripUpdate - we should see one error of type E012
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.put(E012, 1);
    TestUtils.assertResults(expected, results);
    /**
     * Header timestamp less than TripUpdate and VehiclePosition timestamps - 2 results
     */
    tripUpdateBuilder.setTimestamp(MIN_POSIX_TIME + 1);
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder);
    vehiclePositionBuilder.setTimestamp(MIN_POSIX_TIME + 1);
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    // Feed header timestamp is less than VehiclePosition and TripUpdate - we should see two results of type E012
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.put(E012, 2);
    TestUtils.assertResults(expected, results);
    clearAndInitRequiredFeedFields();
}
Also used : HashMap(java.util.HashMap) TimestampValidator(edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.TimestampValidator) ValidationRule(edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule) Test(org.junit.Test) FeedMessageTest(edu.usf.cutr.gtfsrtvalidator.lib.test.FeedMessageTest)

Example 5 with ValidationRule

use of edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule in project gtfs-realtime-validator by CUTR-at-USF.

the class TimestampValidatorTest method testE048.

/**
 * E048 - header` `timestamp` not populated (GTFS-rt v2.0 and higher)
 */
@Test
public void testE048() {
    TimestampValidator timestampValidator = new TimestampValidator();
    Map<ValidationRule, Integer> expected = new HashMap<>();
    GtfsRealtime.TripDescriptor.Builder tripDescriptorBuilder = GtfsRealtime.TripDescriptor.newBuilder();
    final long CURRENT_TIME_MILLIS = TimeUnit.SECONDS.toMillis(MIN_POSIX_TIME);
    // Set version to v2.0
    feedHeaderBuilder.setGtfsRealtimeVersion("2.0");
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    // Timestamp will be zero initially in FeedHeader, TripUpdate and VehiclePosition. Should return 2 W003 results, and 1 E048 for header
    vehiclePositionBuilder.setVehicle(GtfsRealtime.VehicleDescriptor.newBuilder());
    feedEntityBuilder.setVehicle(vehiclePositionBuilder.build());
    tripUpdateBuilder.setTrip(tripDescriptorBuilder.build());
    feedEntityBuilder.setTripUpdate(tripUpdateBuilder.build());
    feedMessageBuilder.setEntity(0, feedEntityBuilder.build());
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.put(W001, 2);
    expected.put(E048, 1);
    TestUtils.assertResults(expected, results);
    // Populate timestamp to any value greater than zero in FeedHeader
    feedHeaderBuilder.setTimestamp(MIN_POSIX_TIME);
    feedMessageBuilder.setHeader(feedHeaderBuilder.build());
    // Invalid timestamp in TripUpdate and VehiclePosition. Should return 2 W001 warnings, and no E048 errors
    results = timestampValidator.validate(CURRENT_TIME_MILLIS, gtfsData, gtfsDataMetadata, feedMessageBuilder.build(), null, null);
    expected.clear();
    expected.put(W001, 2);
    TestUtils.assertResults(expected, results);
    clearAndInitRequiredFeedFields();
}
Also used : HashMap(java.util.HashMap) TimestampValidator(edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.TimestampValidator) ValidationRule(edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule) Test(org.junit.Test) FeedMessageTest(edu.usf.cutr.gtfsrtvalidator.lib.test.FeedMessageTest)

Aggregations

ValidationRule (edu.usf.cutr.gtfsrtvalidator.lib.model.ValidationRule)65 Test (org.junit.Test)62 HashMap (java.util.HashMap)59 FeedMessageTest (edu.usf.cutr.gtfsrtvalidator.lib.test.FeedMessageTest)58 GtfsRealtime (com.google.transit.realtime.GtfsRealtime)23 TripDescriptorValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.TripDescriptorValidator)14 StopTimeUpdateValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.StopTimeUpdateValidator)13 TimestampValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.TimestampValidator)11 VehicleValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.VehicleValidator)8 ErrorListHelperModel (edu.usf.cutr.gtfsrtvalidator.lib.model.helper.ErrorListHelperModel)6 MessageLogModel (edu.usf.cutr.gtfsrtvalidator.lib.model.MessageLogModel)4 OccurrenceModel (edu.usf.cutr.gtfsrtvalidator.lib.model.OccurrenceModel)4 FrequencyTypeZeroValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.FrequencyTypeZeroValidator)3 HeaderValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.HeaderValidator)3 CrossFeedDescriptorValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.CrossFeedDescriptorValidator)2 StopValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.StopValidator)2 GtfsMetadata (edu.usf.cutr.gtfsrtvalidator.lib.validation.GtfsMetadata)1 StopLocationTypeValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.gtfs.StopLocationTypeValidator)1 FrequencyTypeOneValidator (edu.usf.cutr.gtfsrtvalidator.lib.validation.rules.FrequencyTypeOneValidator)1 Field (java.lang.reflect.Field)1