Datacenter build and management service
https://github.com/joyent/conch-api/blob/master/lib/Conch/Validation.pm
package Conch::Validation::DeviceValidation;
## either:
use Mojo::Base 'Conch::Validation';
## or, if you want to use Moo features:
use Moo;
use strictures 2;
extends 'Conch::Validation';
use constant name => 'device_validation';
use constant version => 1;
use constant category => 'CPU';
use constant description => q/Description of the validation/;
sub validate {
my ($self, $input_data) = @_;
my $device = $self->device;
my $device_settings = $self->device_settings;
my $device_location = $self->device_location;
my $hardware_vendor = $self->hardware_product_vendor;
my $hardware_name = $self->hardware_product_name;
$self->register_result(expected => 'hello', got => $input_data->{hello});
}
Conch::Validation provides the base class to define and execute Conch
Validations. Validations extend this class by implementing a “validate”
method. This method receives the input data (a HASHREF
) to be validated.
The validation logic in the “validate” method will evaluate the input data and register one or more validation results with the “register_result” method. The logic may use device, device settings, hardware product name, hardware product vendor, and other details to dispatch conditions and evaluation.
Conch Validations should also define values for the name
, version
,
category
, and description
attributes. These attributes are used in the
identification of the validation and validation result storage in the
Validation System infrastructure.
Testing Conch Validations should be done with “test_validation” in Test::Conch::Validation with TAP-based tests. This functions tests that Validations define the required attributes and methods, and allow you to test the validation logic by running test cases against expected results.
The validator name, provided by the validator module.
The validator version, provided by the validator module.
The validator description, provided by the validator module.
The validator category, provided by the validator module.
A logging object.
Conch::DB::Result::Device object under validation. Use in validation logic to dispatch on Device attributes.
my $device = $self->device;
if ($device->asset_tag eq '...') {...}
Any additional data related to devices may be read as normal using DBIx::Class interfaces. The result object is built using a read-only database handle, so attempts to alter the data will not be permitted.
Conch::DB::Result::DeviceLocation object for the device being validated.
This is useful in writing validation logic that may depend on the rack or location in the rack a device occupies.
my $datacenter_name = $self->device_location->rack->datacenter->name;
my $rack_unit_start = $self->device_location->rack_unit_start;
Returns a boolean whether the device under validation has been assigned a location.
The Conch::DB::Result::HardwareProduct object to be used for validation. Note that this might not be the same hardware as what the report sku says.
Any additional data related to hardware_products may be read as normal using DBIx::Class interfaces. The result object is built using a read-only database handle, so attempts to alter the data will not be permitted.
Get the name of the hardware product used for validation.
if ($self->hardware_product_name eq 'Joyent-123') {...}
Get the expected hardware legacy product name used for validation.
if ($self->hardware_legacy_product_name eq 'Joyent-123') {...}
Get the expected hardware product generation used for validation.
if ($self->hardware_product_generation eq 'Joyent-123') {...}
Get the hardware product SKU used for validation.
if ($self->hardware_product_sku eq 'Joyent-123') {...}
Get the hardware product specification used for validation. Returns a JSON string (for now).
Get the expected hardware product vendor name used for validation.
if ($self->hardware_product_vendor eq 'Dell') {...}
A key-value unblessed hashref of device settings stored for the device being validated.
Get the list of all validation results.
Get a validation result by (0-based) index.
Get the list of validation results that were failures
Get the list of validation results that were successful
Get the list of validation results that have error status (halted execution).
NOTE: Unless “run” is called multiple times on the same validation object without calling “clear_results” between, there should be at most 1 error validation because execution is halted.
Clear the stored validation results.
Run the Validation with the specified input data.
$validation->run($validation_data);
Contains the validation logic for validations.
This method must be re-defined in sub-classes of Conch::Validation or it will raise an exception.
package MyValidation;
use Mojo::Base 'Conch::Validation';
sub validate {
my ($self, $data) = @_;
$self->register_result({ expected => 1, got => $data->{pass} });
}
Register a Validation Result in the validation logic. “register_result” may be called as many times as desired in a “validate” method.
Instead of calculating whether a result should pass or fail in the validation logic, provide an ‘expected’ value, the ‘got’ value, and a comparison operator. This declarative syntax allows for result deduplication and consistent messages.
## direct comparison
$self->register_result(expected => 'hello', got => 'hello');
$self->register_result(expected => 42, got => 42);
## specified comparison operator
$self->register_result(expected => 1, got => 2, cmp => '>=');
$self->register_result(expected => 'second', got => 'first', cmp => 'lt');
## using 'like' to match with a regex
$self->register_result(expected => qr/.+bar.+/, got => 'foobarbaz', cmpself => 'like');
## using 'oneOf' to select one of multiple values
$self->register_result(expected => ['a', 'b', 'c' ], got => 'b', cmp => 'oneOf');
The default operator is ‘eq’. The available comparison operators are:
'==', '!=', '>', '>=', '<', '<=', '<=',
'eq', 'ne', 'lt', 'le', 'gt', 'ge',
'like' (regex comparison), 'oneOf' (list membership comparison)
You may also provide the following attributes to override validation results
name
By default, the validation result logs the name
attribute of the
Validation class. You may override the validation result name with this
attribute.
This value is not stored in the database. To disambiguate multiple results in the database, use
component
.
$self->register_result(
expected => 'hello',
got => 'hello',
name => 'hello_validation'
);
message
The default message stored in the validation result has the form, “Expected
$operator ‘$expected_value’. Got ‘$got_value’.”. You may override this message
by specifying the message
attribute.
$self->register_result(
expected => 'hello',
got => 'hello',
message => 'Hello world!'
);
category
By default, the validation result stores the category
attribute of the
Validation class. You may override the validation result category with this
attribute.
$self->register_result(
expected => 'hello',
got => 'hello',
category => 'BIOS'
);
component
You may specify the optional string attribute component
to set an
identifier to help identify a specific component under test.
$self->register_result(
expected => 'OK',
got => $disk->{health},
component => $disk->{serial_number}
);
hint
You may specify the optional string attribute hint
to be stored if
the validation fails. This string should help identify to a user how to fix the
validation failure. If the validation succeeds, the hint string is not stored
in the validation result.
$self->register_result(
expected => 'hello',
got => 'bye',
hint => "Try saying 'hello' instead"
);
EXPERIMENTAL. A new way of registering validation results. Pass arguments as you would to “cmp_deeply” in Test::Deep, and a validation result is registered with the result and diagnostics as appropriate.
Stop execution of the Validation immediately and record an error. The attributes ‘level’ and ‘hint’ may be specified.
$self->die('This validation cannot continue!') if $bad_condition;
$self->die('This validation cannot continue!', hint => 'Here's how to fix it');
$self->die('This exception happend 3 frames up', level => 3);
Record a failing validation result with a message and continues execution. This may be useful if you cannot validate some part of the input data but want to continue validating other parts of the data.
$self->fail('This validation fails but validation evaluation will continue')
unless defined($data->{required_value});
The attributes name
, category
, component
, and hint
may be
specified like with “register_result”.
$self->fail('I fail!',
name => 'some_component_validation',
hint => 'How to fix this failure...'
);
Copyright Joyent, Inc.
This Source Code Form is subject to the terms of the Mozilla Public License, v.2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://www.mozilla.org/en-US/MPL/2.0/.