Всё, что ниже рантайма Битрикса, тестами не закрыть: установка, права, левое меню, раскладка компонентов, агенты, таблица импорта, поведение при обновлении. Проверять это приходится руками — и лучше по списку, потому что забытый шаг находит не разработчик, а клиент.
В статье:
Всё, что ниже рантайма Битрикса, тестами не закрыть: установка, права, левое меню, раскладка компонентов, агенты, таблица импорта, поведение при обновлении. Проверять это приходится руками — и лучше по списку, потому что забытый шаг находит не разработчик, а клиент.
Процедура рассчитана на отдельный стенд, а не на боевой портал. Шаги «удалить модуль» и «поставить на CP1251» на рабочем портале делать нельзя: удаление стирает таблицу импорта.
Раскладка репозитория — в module-structure.md, сборка — в build-and-install.md.
Для сценария «обновление» нужен стенд, где уже стоит 1.2.x — на нём проверяется то, ради чего 2.0.0 сделана мажорной.
Снимите копию каталога модуля, настроек, таблицы импорта и компонентов 1.x в
/local — шаги с удалением необратимы, а установщик удаляет
/local/components/shef.insync без проверки содержимого (в 1.x там мог
править проект):
cp -a /var/www/portal/bitrix/modules/shef.insync /tmp/shef.insync.before 2>/dev/null
cp -a /var/www/portal/local/components/shef.insync /tmp/local-components.before 2>/dev/null
mysqldump -u… portal b_option --where="MODULE_ID='shef.insync'" > /tmp/opt.before.sql
mysqldump -u… portal shef_insync_model > /tmp/model.before.sql
ls /var/www/portal/local/components/ /var/www/portal/bitrix/components/ /var/www/portal/bitrix/js/ | sort > /tmp/public.before
Архив собирается побайтово одинаково у всех, кто взял тот же коммит:
git clone https://github.com/bx-shef/insync.git
cd insync && git checkout <тег проверяемой версии>
./build.sh # последняя строка напечатает sha256
sha256sum /путь/к/скачанному/shef.insync.zip
Хеши обязаны совпасть. Первым уровнем внутри архива — ровно shef.insync/:
unzip -Z1 shef.insync.zip | cut -d/ -f1 | sort -u
shef.options 3.0.0+ и shef.problems 2.0.0+ стоят.bitrix/modules/, чтобы получилось bitrix/modules/shef.insync/.Ожидается: «Модуль успешно установлен»; появились
/bitrix/components/shef.insync/ (два компонента) и
/bitrix/js/shef-insync/ui-anchors/; в /local/components/ каталога
shef.insync нет; в БД появилась таблица shef_insync_model; в левом меню
появился раздел «SH Импорт» со страницами «Статистика» и «Записи импорта».
Отдельно: на стенде без shef.options 3.x или без shef.problems 2.x
установка обязана отказать с текстом про модуль и версию — а не поставиться и
упасть на первой странице.
Делается на стенде, где стоит 1.2.x, есть строки в таблице импорта и хотя бы один агент импорта.
ls /var/www/portal/local/components/shef.insync/ # в 1.x есть
mysql -e "SELECT COUNT(*) FROM shef_insync_model" portal
/bitrix/admin/agent_list.php, модули
импорта) и дождаться, пока текущий запуск закончится. Модели 2.0.0 знают
колонку ID, которой в таблице 1.x нет: между заменой файлов и
SyncTable::init() каждый запрос агента к таблице упадёт.shef.options до 3.x и shef.problems до 2.x./local/components/shef.insync останутся и
перекроют новые. Разложите файлы установщиком, не удаляя модуль (удаление
стёрло бы таблицу импорта) — в «Командной PHP-строке» администратора:require $_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/shef.insync/install/index.php';
(new shef_insync())->InstallFiles();
\Bitrix\Main\Loader::includeModule('shef.insync');
\Shef\InSync\Sync\Model\SyncTable::init(); // ключ таблицы 1.x -> 2.x
До перевода проверьте, что внешние коды не совпадают в первых 191 символе —
иначе уникальный индекс не встанет и init() откажет (строки не тронет):
SELECT ORIGINATOR_ID, LEFT(ORIGIN_ID, 191) AS K, COUNT(*) FROM shef_insync_model
GROUP BY ORIGINATOR_ID, K HAVING COUNT(*) > 1;
Пусто — переводите. Нет — лишние строки (обычно давно упавшие) удалить или разобрать до перевода.
init() переводит таблицу импорта 1.x на ключ 2.x: первичный ключ — новая
колонка ID, внешний код уникален в пределах кода импорта, индексы 1.x
(_origs, _orig_id, _originator_id) снимаются. Строки остаются;
повторный вызов ничего не делает. Перевод — один ALTER TABLE, MySQL
перестраивает таблицу и на это время не пускает запись: большую таблицу
(SELECT COUNT(*) из п. 1) переводите в окно без импорта. Ключ таблицы не
1.x и не 2.x — init() отказывает и ничего не меняет.
Ожидается:
/local/components/shef.insync/ удалён, /bitrix/components/shef.insync/ на месте;shef_insync_model то же;SHOW KEYS FROM shef_insync_model — ровно два ключа: PRIMARY на ID и
уникальный shef_insync_model_origin на ORIGINATOR_ID, ORIGIN_ID;
индексы, которые проект завёл на таблице сам, — на месте;Undefined array key, Class "Shef\UiClear\..." not found,
Call to undefined function _showError().Ожидается: файлы из /upload/import/ лежат в <каталог импорта>/,
/upload/import удалён, обмен кладёт новый файл в <каталог импорта>/<код>/,
агент его забирает.
Настройки → Настройки модулей → SH InSync.
Ожидается: вкладка «Общие», в ней «Сколько дней хранится файл в результате импорта» со значениями 1, 2, 3, 5, 15, 30; по умолчанию — 3. Сохранить 15 — значение сохранилось.
Если модуль-импорт выводит на своей странице настроек опции
Options\Agent\Option или Options\Import\FromFile\Option: у администратора
кнопки запуска/остановки агента и импорта работают; у пользователя с правом
«Чтение» на тот модуль кнопки агента не видны.
Под пользователем без прав (не администратор, прав на модули нет):
/page/shinsync/statimportlocal/ — «Недостаточно прав».BX.ajax.runComponentAction('shef.insync:import.stat.local', 'stopAgent', {mode: 'class', data: {id: 1}})
Ожидается: ошибка, агент с ID 1 (агент ядра) не выключен —
проверить на /bitrix/admin/agent_list.php.
/bitrix/services/main/ajax.php?action=…stopAgent&…),
открыть его под пользователем без прав, подставив agentId=1&moduleId=main
и его sessid (BX.bitrix_sessid()) — ошибка, агент не тронут.sale (или другой модуль ядра со своими
агентами), повторить п. 3 с ID агента sale и moduleId=sale — ошибка
«Agent not found», агент не тронут: модуль трогает только агенты импорта.Под администратором: страница статистики открывается, агент модуля-импорта выключается и включается кнопкой, «Очистить» у строки грида удаляет только строки этой загрузки.
На странице импорта из файла модуля-импорта (левое меню «SH Импорт»):
test.php (переименуйте любой текстовый) — отказ «Wrong
file type», в <каталог импорта>/<код>/ файла нет.<b>жирный</b> и ошибка разбора, — в блоке
ошибок текст виден как текст, а не жирным.Ожидается: каталог импорта — вне корня сайта (/home/bitrix/sh_import на
BitrixVM, если не задан свой); в <каталог импорта>/copy/<код>/ архив с именем
done_<код>_<дата>_<16 символов>.<расш> — хвост случайный.
\Bitrix\Main\Loader::includeModule('shef.insync');
echo (new ReflectionClass(\SbWereWolf\XmlNavigator\Extraction\HierarchyComposer::class))->getFileName();
Ожидается: проект без Composer — путь в …/shef.insync/vendor/sbwerewolf/…;
проект с Composer, где стоит sbwerewolf/xml-navigator, — путь в vendor
проекта. Во втором случае версия там обязана быть 7.2.x: ветки 8+ требуют
PHP 8.4 и разбирают XML в тот же формат, но модуль на них не проверялся.
Агент модуля-импорта (наследник Sync\FromFile\AAgent) после загрузки файла:
Ожидается: строки из shef_insync_model уходят пачками, успешные
удаляются, ошибочные остаются со статусом F и сообщением; в журнале событий
проблемы с типом SH_PROBLEMS_SYNC; страница статистики обновляется сама
(pull), без ошибок в консоли браузера.
Из PHP-консоли на товаре торгового каталога (ID и тип цены — свои):
\Bitrix\Main\Loader::includeModule('shef.insync');
$price = new \Shef\InSync\Sync\Model\Catalog\Driver\Price();
var_dump($price->save(['PRODUCT_ID' => 1, 'CATALOG_GROUP_ID' => 1], ['PRICE' => 10, 'CURRENCY' => 'BYN'])->isSuccess());
var_dump($price->save(['PRODUCT_ID' => 1, 'CATALOG_GROUP_ID' => 1], ['PRICE' => 12.5, 'CURRENCY' => 'BYN'])->isSuccess());
var_dump((new \Shef\InSync\Sync\Model\Catalog\Driver\Product())->save(['ID' => 1], ['WEIGHT' => 250])->isSuccess());
var_dump((new \Shef\InSync\Sync\Model\Catalog\Driver\Amount())->save(['PRODUCT_ID' => 1], ['STORE_ID' => 1, 'AMOUNT' => 7])->isSuccess());
Ожидается: четыре true, ни одного Warning; у товара одна цена
этого типа — 12.50, PRICE_SCALE заполнен; вес 250; остаток на складе 1 — 7
(при включённом складском учёте ядро остаток так не примет — это верно).
Ожидается:
/bitrix/components/shef.insync/, /bitrix/js/shef-insync/ и
/local/components/shef.insync/ (если был) удалены, чужие компоненты на месте;shef_insync_model нет, настроек модуля в b_option нет,
настройки shef.options — на месте;Формы «сохранить данные?» у модуля нет: удаление из админки стирает таблицу
импорта всегда. Оставить данные — только из PHP-консоли:
(new shef_insync())->UnInstallDB(['savedata' => 'Y']) после подключения
/bitrix/modules/shef.insync/install/index.php.
Если модуль зависит от других (shef.* с shef.insync в requireModules),
удаление обязано отказать и назвать их.
Установка обязана отказать с текстом про UTF-8. На современных ядрах ветка
недостижима — Application::isUtfMode() возвращает true без условий, — тогда
в бланке отмечается «пропущено», и это верный ответ.
for e in agent xml; do DOCUMENT_ROOT=/var/www/portal php examples/$e.php || echo "FAIL $e"; done
Ожидается: два раза ГОТОВО: …, ни одного FAIL, Warning,
Deprecated.
Версия: ____ Коммит: ____ sha256 архива сошёлся: да / нет
Ядро main: ____ PHP: ____ shef.options: ____ shef.problems: ____
Composer в проекте: да / нет intranet: да / нет
0. Архив .................................. ок / не ок
A. Чистая установка ....................... ок / не ок
без shef.options 3 / shef.problems 2 — отказ .. ок / не ок
B. Обновление с 1.2.x ..................... ок / не ок / нет стенда
C. Страница настроек ...................... ок / не ок
D. Права: без прав — отказ ................ ок / не ок
агент ядра не тронут ................... ок / не ок
«W» на sale — агенты sale не тронуты ... ок / не ок
E. Импорт файла ........................... ок / не ок
.php отклонён .......................... ок / не ок
F. Библиотеки XML взяты из ................ модуль / Composer
G. Агент импорта .......................... ок / не ок
G2. Драйверы каталога ..................... ок / не ок
H. Удаление ............................... ок / не ок
I. CP1251 ................................. ок / пропущено
J. Примеры на живом ядре .................. ок / не ок
Замечания: