Child pages
  • Общие вопросы
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 11 Next »

Мануал по работе с фреймворком ABillS

Мануал разработчика

Форматирование кода

  • Для отступов не использовать табуляций, только двойные пробелы
  • Форматирование if else:

    if (expr) {
      ...
    }
    else {
      ...
    }

Однострочные или-выражения

Всегда выражения берутся в скобки

$result = ($total_users == 1) ? "Ok" : "Fail";

print "test" if ($test == 1);

Переменные

  • Переменные указываются строчными буками

      $test, @devices, %switch
  • Объекты указываются с заглавной

    $Test = Test->new();
  • Массивы указываются в множественном числе

    my @devices = ();
    my @users = ();
  • Хеши в единственном

    %status_list = ();
    $status_list{disable}=1;

Общий шаблон функций

#**********************************************************
=head2 test_function($attr) - Test function
 
  Arguments:
    $attr   - Extra attributes
       TEXT   - Some text
 
  Returns:
   TRUE or FALSE
 
  Example:
 
    test_function({ TEXT => 'Some text' });
 
=cut
#**********************************************************
sub test_function {
  my ($attr) = @_;
 
  print "Hello world!";
 
  return 1;
}

Рекомендации:

  1. Отделяйте шапки функций звёздочками (58 штук).
  2. Не игнорируйте создание комментариев перед началом функции.
  3. Называйте функции строчными буквами с разделением нижним подчёркиванием.
  4. По умолчанию, в случае успешного выполнения функция должна возвращать 1, в случае ошибки - 0.

  5. Минимизируйте использование глобальных переменных в функциях.

Дата обновления в шапке модуля

Дату обновления модуля следует указывать в шапке модуля (в начале файла) в формате YYYYMMDD.

Пример:

=head1 Cdata

  C-data
  MODEL:
    epon
      FD1104SN
  ...

  DATE: 20190704
  UPDATE: 20210324

=cut

DATE - дата создания модуля

UPDATE - дата обновления модуля

Указывать дату правильно важно для коммерческих модулей, так как скрипт обновления update.sh ожидает увидеть дату в этом формате.

Можно ли использовать HTML в коде?

Ни в коем случае не используйте HTML в коде управляющей модели, вместо этого используйте объекты Abills::HTML или шаблоны.

Дополнительные модули

Загрузка дополнительных модулей Perl осуществляется командой

load_pmodule('Simple::XML');

(Библиотека Misc.pm)

С проверкой ошибок код выглядит так:

my $loaded_imager_error = load_pmodule( "Imager", { RETURN => 1 } );
if ( $loaded_imager_error ) {
  print $loaded_imager_error;
  return 0;
}

Дополнительные модули с автоустановкой

Загрузка дополнительных модулей Perl с автоустановкой осуществляется командой

load_perl_module('SQL::Translator');
(Библиотека PModules.pm)

Поиск в полях

Для удобства поиска было разработано несколько разделителей.

Для цифровых полей

Разделитель запятая (,) обозначает AND.

Пример: искать значения поля 56 и 66

56,66

Разделитель точка с запятой (;) обозначает OR.

Пример: искать значения поля 56 или 66

56;66

Тестирование

Для тестирования системы существует каталог с тестами abills/t.

make

Жесткий тест работоспособности, никогда его не выполняйте на рабочей системе, чревато пропажей данных

perl web.t brutal

тестирование синтаксиса и стресс-тест веб-приложений

НЕ ИСПОЛЬЗОВАТЬ НА ПРОДАКШН СИСТЕМЕ

Тест проверки авторизации и аккаунтинга

t/Aaa.t

Проверка DHCP авторизации используя приготовленный RAD PAIRS пакет dhcp.discover

perl Aaa.t dhcp_test dhcp.discovery

Тестирование абон. платы тарифного плана

perl Tariffs.t FILENAME=tp_test1.tp

FILENAME - файл с описанием тарифного плана и параметров абонента.

Для задания логина и пароля авторизации используется файл t/.test

login:password

В системе также есть специальный скрипт запуска выделенных тестов, которые хранятся в отдельных каталогах: Запуск тестов для модуля или папки

Создание демона

use Abills::Base;
use Abills::Server;

my $ARGV = parse_arguments(\@ARGV);

# Демонизация и ведение лога
if (defined($ARGV->{'-d'})) {
  my $pid_file = daemonize();
  #ведение лога
  #$Log->log_print('LOG_EMERG', '', "$prog_name Daemonize... $pid_file");
}
# Остановка процесса
elsif (defined($ARGV->{stop})) {
  stop_server();
  exit;
}
# Проверка, не запущен ли уже
elsif (make_pid() == 1) {
  exit;
}

# Таймаут между запусками 100 секунд
my $UPDATE_TIME=100;

while (1) {
  check_activity({ ALL => ($ARGV->{RECONFIG_PERIOD}) ? undef : $all });
  sleep $UPDATE_TIME;

Языковые маркеры

Сохраняются в глобальном хеше %lang.

Пример:

$lang{LANG_MARKER} = 'Языковой маркер';

Названия маркеров обязательно писать заглавными буквами.

Отображение в шаблонах:

_{LANG_MARKER}_

Переменные внутри lang

$lang{LANG_MARKER_WITH_VARS} = 'У абонента минус %DEPOSIT%';

И использовать функцию:

use Abills::Base qw(vars2lang);

vars2lang($lang{LANG_MARKER_WITH_VARS}, { DEPOSIT => '5' });

Но, конечно, вы можете использовать любой string с такой разметкой.

JSON тестирование

Для того, чтобы протестировать функцию:

  1. Создайте тест в /usr/abills/t
  2. Подключите JSON.t

    require "./JSON.t";
  3. Создайте JSON, заполнив его. API_KEY - ключ API текущего администратора

    my @test_list = (
      {
        name       => 'InfoFields',
        params     => {
          qindex       => 96,
          API_KEY      => '1523615231263123',
          json         => 1
        },
        result     => '',
        valid_json => 1,
        schema     => {
     
        }
      }
      );
  4. Передайте данные в функцию json_test

    json_test(
      \@test_list, 
      { TEST_NAME => 'info_fields_new test' });
  5. Выполните ваш тест, запустив программу

    # prove -v <название теста>.t

String Eval

Когда нужно загрузить динамически модуль необходимо его загрузить следующим образом

my $module = 'Example';
eval "use $module";

Но настоятельно не рекомендуется это делать в Perl. Потому нужно использовать следующий вариант

my $module_name = 'Example';
eval {
  my $module = "$module_name.pm";
  require $module;
  $module->import();
  1;
};

Если модуль имеет назву с названием директории пример

Module::Example

Тогда нужно получить последнее слово модуля, это его название

my $module_full_name = 'Module::Example';
my ($module_name) = $module_full_name =~ /(\w+)$/;

eval {
  my $module = "$module_name.pm";
  require $module;
  $module->import();
  1;
};
  • No labels