diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Option.php b/app/code/Magento/Bundle/Model/ResourceModel/Option.php index 2ad7e57f522d6..46fd8b910f6f1 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Option.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Option.php @@ -81,31 +81,39 @@ protected function _afterSave(\Magento\Framework\Model\AbstractModel $object) { parent::_afterSave($object); - $condition = [ + $conditions = [ 'option_id = ?' => $object->getId(), 'store_id = ? OR store_id = 0' => $object->getStoreId(), 'parent_product_id = ?' => $object->getParentId() ]; $connection = $this->getConnection(); - $connection->delete($this->getTable('catalog_product_bundle_option_value'), $condition); - $data = new \Magento\Framework\DataObject(); - $data->setOptionId($object->getId()) - ->setStoreId($object->getStoreId()) - ->setParentProductId($object->getParentId()) - ->setTitle($object->getTitle()); - - $connection->insert($this->getTable('catalog_product_bundle_option_value'), $data->getData()); - - /** - * also saving default value if this store view scope - */ + if ($this->isOptionPresent($conditions)) { + $connection->update( + $this->getTable('catalog_product_bundle_option_value'), + [ + 'title' => $object->getTitle() + ], + $conditions + ); + } else { + $data = new \Magento\Framework\DataObject(); + $data->setOptionId($object->getId()) + ->setStoreId($object->getStoreId()) + ->setParentProductId($object->getParentId()) + ->setTitle($object->getTitle()); - if ($object->getStoreId()) { - $data->setStoreId(0); - $data->setTitle($object->getDefaultTitle()); $connection->insert($this->getTable('catalog_product_bundle_option_value'), $data->getData()); + + /** + * also saving default value if this store view scope + */ + if ($object->getStoreId()) { + $data->setStoreId(0); + $data->setTitle($object->getDefaultTitle()); + $connection->insert($this->getTable('catalog_product_bundle_option_value'), $data->getData()); + } } return $this; @@ -210,4 +218,26 @@ public function save(\Magento\Framework\Model\AbstractModel $object) return $this; } + + /** + * Is Bundle option present in the database + * + * @param array $conditions + * + * @return bool + */ + private function isOptionPresent($conditions) + { + $connection = $this->getConnection(); + + $select = $connection->select()->from($this->getTable('catalog_product_bundle_option_value')); + foreach ($conditions as $condition => $conditionValue) { + $select->where($condition, $conditionValue); + } + $select->limit(1); + + $rowSelect = $connection->fetchRow($select); + + return (is_array($rowSelect) && !empty($rowSelect)); + } } diff --git a/app/code/Magento/Catalog/Block/Product/View.php b/app/code/Magento/Catalog/Block/Product/View.php index b3b5dea9602f6..8055d17a64a84 100644 --- a/app/code/Magento/Catalog/Block/Product/View.php +++ b/app/code/Magento/Catalog/Block/Product/View.php @@ -120,51 +120,6 @@ public function getWishlistOptions() return ['productType' => $this->getProduct()->getTypeId()]; } - /** - * Add meta information from product to head block - * - * @return \Magento\Catalog\Block\Product\View - */ - protected function _prepareLayout() - { - $this->getLayout()->createBlock(\Magento\Catalog\Block\Breadcrumbs::class); - $product = $this->getProduct(); - if (!$product) { - return parent::_prepareLayout(); - } - - $title = $product->getMetaTitle(); - if ($title) { - $this->pageConfig->getTitle()->set($title); - } - $keyword = $product->getMetaKeyword(); - $currentCategory = $this->_coreRegistry->registry('current_category'); - if ($keyword) { - $this->pageConfig->setKeywords($keyword); - } elseif ($currentCategory) { - $this->pageConfig->setKeywords($product->getName()); - } - $description = $product->getMetaDescription(); - if ($description) { - $this->pageConfig->setDescription($description); - } else { - $this->pageConfig->setDescription($this->string->substr($product->getDescription(), 0, 255)); - } - if ($this->_productHelper->canUseCanonicalTag()) { - $this->pageConfig->addRemotePageAsset( - $product->getUrlModel()->getUrl($product, ['_ignore_category' => true]), - 'canonical', - ['attributes' => ['rel' => 'canonical']] - ); - } - - $pageMainTitle = $this->getLayout()->getBlock('page.main.title'); - if ($pageMainTitle) { - $pageMainTitle->setPageTitle($product->getName()); - } - return parent::_prepareLayout(); - } - /** * Retrieve current product model * diff --git a/app/code/Magento/Catalog/Helper/Product/View.php b/app/code/Magento/Catalog/Helper/Product/View.php index 2558fa2d85af6..11c61df4af64b 100644 --- a/app/code/Magento/Catalog/Helper/Product/View.php +++ b/app/code/Magento/Catalog/Helper/Product/View.php @@ -59,6 +59,11 @@ class View extends \Magento\Framework\App\Helper\AbstractHelper */ protected $categoryUrlPathGenerator; + /** + * @var \Magento\Framework\Stdlib\StringUtils + */ + private $string; + /** * Constructor * @@ -70,6 +75,7 @@ class View extends \Magento\Framework\App\Helper\AbstractHelper * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator * @param array $messageGroups + * @param \Magento\Framework\Stdlib\StringUtils|null $string */ public function __construct( \Magento\Framework\App\Helper\Context $context, @@ -79,7 +85,8 @@ public function __construct( \Magento\Framework\Registry $coreRegistry, \Magento\Framework\Message\ManagerInterface $messageManager, \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator $categoryUrlPathGenerator, - array $messageGroups = [] + array $messageGroups = [], + \Magento\Framework\Stdlib\StringUtils $string = null ) { $this->_catalogSession = $catalogSession; $this->_catalogDesign = $catalogDesign; @@ -88,9 +95,61 @@ public function __construct( $this->messageGroups = $messageGroups; $this->messageManager = $messageManager; $this->categoryUrlPathGenerator = $categoryUrlPathGenerator; + $this->string = $string ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Stdlib\StringUtils::class); parent::__construct($context); } + /** + * Add meta information from product to layout + * + * @param \Magento\Framework\View\Result\Page $resultPage + * @param \Magento\Catalog\Model\Product $product + * @return \Magento\Framework\View\Result\Page + */ + private function preparePageMetadata(ResultPage $resultPage, $product) + { + $pageLayout = $resultPage->getLayout(); + $pageLayout->createBlock(\Magento\Catalog\Block\Breadcrumbs::class); + + $pageConfig = $resultPage->getConfig(); + + $title = $product->getMetaTitle(); + if ($title) { + $pageConfig->getTitle()->set($title); + } + + $keyword = $product->getMetaKeyword(); + $currentCategory = $this->_coreRegistry->registry('current_category'); + if ($keyword) { + $pageConfig->setKeywords($keyword); + } elseif ($currentCategory) { + $pageConfig->setKeywords($product->getName()); + } + + $description = $product->getMetaDescription(); + if ($description) { + $pageConfig->setDescription($description); + } else { + $pageConfig->setDescription($this->string->substr($product->getDescription(), 0, 255)); + } + + if ($this->_catalogProduct->canUseCanonicalTag()) { + $pageConfig->addRemotePageAsset( + $product->getUrlModel()->getUrl($product, ['_ignore_category' => true]), + 'canonical', + ['attributes' => ['rel' => 'canonical']] + ); + } + + $pageMainTitle = $pageLayout->getBlock('page.main.title'); + if ($pageMainTitle) { + $pageMainTitle->setPageTitle($product->getName()); + } + + return $this; + } + /** * Init layout for viewing product page * @@ -225,6 +284,7 @@ public function prepareAndRender(ResultPage $resultPage, $productId, $controller } $this->initProductLayout($resultPage, $product, $params); + $this->preparePageMetadata($resultPage, $product); return $this; } } diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php index 03d418f3ba0d9..bd28b65bb7982 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php @@ -245,12 +245,13 @@ protected function processNewAndExistingImages($product, array &$images) if (empty($image['removed'])) { $data = $this->processNewImage($product, $image); - $this->resourceModel->deleteGalleryValueInStore( - $image['value_id'], - $product->getData($this->metadata->getLinkField()), - $product->getStoreId() - ); - + if (!$product->isObjectNew()) { + $this->resourceModel->deleteGalleryValueInStore( + $image['value_id'], + $product->getData($this->metadata->getLinkField()), + $product->getStoreId() + ); + } // Add per store labels, position, disabled $data['value_id'] = $image['value_id']; $data['label'] = isset($image['label']) ? $image['label'] : ''; diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index 91f589f9b5bd7..971f34e02f9e5 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -9,6 +9,7 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; use Magento\Framework\Image as MagentoImage; +use Magento\Framework\Serialize\SerializerInterface; /** * @method string getFile() @@ -172,6 +173,16 @@ class Image extends \Magento\Framework\Model\AbstractModel */ private $imageAsset; + /** + * @var string + */ + private $cachePrefix = 'IMG_INFO'; + + /** + * @var SerializerInterface + */ + private $serializer; + /** * Constructor * @@ -190,6 +201,7 @@ class Image extends \Magento\Framework\Model\AbstractModel * @param array $data * @param \Magento\Catalog\Model\View\Asset\ImageFactory|null $viewAssetImageFactory * @param \Magento\Catalog\Model\View\Asset\PlaceholderFactory|null $viewAssetPlaceholderFactory + * @param SerializerInterface|null $serializer * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ @@ -208,7 +220,8 @@ public function __construct( \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], \Magento\Catalog\Model\View\Asset\ImageFactory $viewAssetImageFactory = null, - \Magento\Catalog\Model\View\Asset\PlaceholderFactory $viewAssetPlaceholderFactory = null + \Magento\Catalog\Model\View\Asset\PlaceholderFactory $viewAssetPlaceholderFactory = null, + SerializerInterface $serializer = null ) { $this->_storeManager = $storeManager; $this->_catalogProductMediaConfig = $catalogProductMediaConfig; @@ -223,6 +236,7 @@ public function __construct( ->get(\Magento\Catalog\Model\View\Asset\ImageFactory::class); $this->viewAssetPlaceholderFactory = $viewAssetPlaceholderFactory ?: ObjectManager::getInstance() ->get(\Magento\Catalog\Model\View\Asset\PlaceholderFactory::class); + $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class); } /** @@ -356,86 +370,6 @@ public function setSize($size) return $this; } - /** - * @param string|null $file - * @return bool - */ - protected function _checkMemory($file = null) - { - return $this->_getMemoryLimit() > $this->_getMemoryUsage() + $this->_getNeedMemoryForFile( - $file - ) - || $this->_getMemoryLimit() == -1; - } - - /** - * @return string - */ - protected function _getMemoryLimit() - { - $memoryLimit = trim(strtoupper(ini_get('memory_limit'))); - - if (!isset($memoryLimit[0])) { - $memoryLimit = "128M"; - } - - if (substr($memoryLimit, -1) == 'K') { - return substr($memoryLimit, 0, -1) * 1024; - } - if (substr($memoryLimit, -1) == 'M') { - return substr($memoryLimit, 0, -1) * 1024 * 1024; - } - if (substr($memoryLimit, -1) == 'G') { - return substr($memoryLimit, 0, -1) * 1024 * 1024 * 1024; - } - return $memoryLimit; - } - - /** - * @return int - */ - protected function _getMemoryUsage() - { - if (function_exists('memory_get_usage')) { - return memory_get_usage(); - } - return 0; - } - - /** - * @param string|null $file - * @return float|int - * @SuppressWarnings(PHPMD.NPathComplexity) - */ - protected function _getNeedMemoryForFile($file = null) - { - $file = $file === null ? $this->getBaseFile() : $file; - if (!$file) { - return 0; - } - - if (!$this->_mediaDirectory->isExist($file)) { - return 0; - } - - $imageInfo = getimagesize($this->_mediaDirectory->getAbsolutePath($file)); - - if (!isset($imageInfo[0]) || !isset($imageInfo[1])) { - return 0; - } - if (!isset($imageInfo['channels'])) { - // if there is no info about this parameter lets set it for maximum - $imageInfo['channels'] = 4; - } - if (!isset($imageInfo['bits'])) { - // if there is no info about this parameter lets set it for maximum - $imageInfo['bits'] = 8; - } - return round( - ($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $imageInfo['channels'] / 8 + Pow(2, 16)) * 1.65 - ); - } - /** * Convert array of 3 items (decimal r, g, b) to string of their hex values * @@ -472,9 +406,7 @@ public function setBaseFile($file) 'filePath' => $file, ] ); - if ($file == 'no_selection' || !$this->_fileExists($this->imageAsset->getSourceFile()) - || !$this->_checkMemory($this->imageAsset->getSourceFile()) - ) { + if ($file == 'no_selection' || !$this->_fileExists($this->imageAsset->getSourceFile())) { $this->_isBaseFilePlaceholder = true; $this->imageAsset = $this->viewAssetPlaceholderFactory->create( [ @@ -682,11 +614,14 @@ public function getDestinationSubdir() } /** - * @return bool|void + * @return bool */ public function isCached() { - return file_exists($this->imageAsset->getPath()); + return ( + is_array($this->loadImageInfoFromCache($this->imageAsset->getPath())) || + file_exists($this->imageAsset->getPath()) + ); } /** @@ -856,6 +791,7 @@ public function clearCache() $this->_mediaDirectory->delete($directory); $this->_coreFileStorageDatabase->deleteFolder($this->_mediaDirectory->getAbsolutePath($directory)); + $this->clearImageInfoFromCache(); } /** @@ -890,7 +826,7 @@ public function getResizedImageInfo() $image = $this->imageAsset->getPath(); } - $imageProperties = getimagesize($image); + $imageProperties = $this->getimagesize($image); return $imageProperties; } finally { @@ -932,4 +868,66 @@ private function getMiscParams() return $miscParams; } + + /** + * Get image size + * + * @param string $imagePath + * @return array + */ + private function getImageSize($imagePath) + { + $imageInfo = $this->loadImageInfoFromCache($imagePath); + if (!isset($imageInfo['size'])) { + $imageSize = getimagesize($imagePath); + $this->saveImageInfoToCache(['size' => $imageSize], $imagePath); + return $imageSize; + } else { + return $imageInfo['size']; + } + } + + /** + * Save image data to cache + * + * @param array $imageInfo + * @param string $imagePath + * @return void + */ + private function saveImageInfoToCache(array $imageInfo, string $imagePath) + { + $imagePath = $this->cachePrefix . $imagePath; + $this->_cacheManager->save( + $this->serializer->serialize($imageInfo), + $imagePath, + [$this->cachePrefix] + ); + } + + /** + * Load image data from cache + * + * @param string $imagePath + * @return array|false + */ + private function loadImageInfoFromCache(string $imagePath) + { + $imagePath = $this->cachePrefix . $imagePath; + $cacheData = $this->_cacheManager->load($imagePath); + if (!$cacheData) { + return false; + } else { + return $this->serializer->unserialize($cacheData); + } + } + + /** + * Clear image data from cache + * + * @return void + */ + private function clearImageInfoFromCache() + { + $this->_cacheManager->clean([$this->cachePrefix]); + } } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php index 3cf342cbbd990..2e5b4ca538ffe 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php @@ -180,7 +180,10 @@ protected function _prepareLoadSelect(array $selects) protected function _saveAttributeValue($object, $attribute, $value) { $connection = $this->getConnection(); - $storeId = (int) $this->_storeManager->getStore($object->getStoreId())->getId(); + $hasSingleStore = $this->_storeManager->hasSingleStore(); + $storeId = $hasSingleStore + ? $this->getDefaultStoreId() + : (int) $this->_storeManager->getStore($object->getStoreId())->getId(); $table = $attribute->getBackend()->getTable(); /** @@ -189,15 +192,18 @@ protected function _saveAttributeValue($object, $attribute, $value) * In this case we clear all not default values */ $entityIdField = $this->getLinkField(); - if ($this->_storeManager->hasSingleStore()) { - $storeId = $this->getDefaultStoreId(); + $conditions = [ + 'attribute_id = ?' => $attribute->getAttributeId(), + "{$entityIdField} = ?" => $object->getData($entityIdField), + 'store_id <> ?' => $storeId + ]; + if ($hasSingleStore + && !$object->isObjectNew() + && $this->isAttributePresentForNonDefaultStore($attribute, $conditions) + ) { $connection->delete( $table, - [ - 'attribute_id = ?' => $attribute->getAttributeId(), - "{$entityIdField} = ?" => $object->getData($entityIdField), - 'store_id <> ?' => $storeId - ] + $conditions ); } @@ -236,6 +242,27 @@ protected function _saveAttributeValue($object, $attribute, $value) return $this; } + /** + * Check if attribute present for non default Store View. + * Prevent "delete" query locking in a case when nothing to delete + * + * @param AbstractAttribute $attribute + * @param array $conditions + * + * @return boolean + */ + private function isAttributePresentForNonDefaultStore($attribute, $conditions) + { + $connection = $this->getConnection(); + $select = $connection->select()->from($attribute->getBackend()->getTable()); + foreach ($conditions as $condition => $conditionValue) { + $select->where($condition, $conditionValue); + } + $select->limit(1); + + return !empty($connection->fetchRow($select)); + } + /** * Insert entity attribute value * diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/CategoryLink.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/CategoryLink.php index 6e2642d09910a..b54c19a111508 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/CategoryLink.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/CategoryLink.php @@ -83,11 +83,12 @@ public function saveCategoryLinks(ProductInterface $product, array $categoryLink $insertUpdate = $this->processCategoryLinks($categoryLinks, $oldCategoryLinks); $deleteUpdate = $this->processCategoryLinks($oldCategoryLinks, $categoryLinks); - list($delete, $insert) = $this->analyseUpdatedLinks($deleteUpdate, $insertUpdate); + list($delete, $insert, $update) = $this->analyseUpdatedLinks($deleteUpdate, $insertUpdate); return array_merge( - $this->updateCategoryLinks($product, $insert), - $this->deleteCategoryLinks($product, $delete) + $this->deleteCategoryLinks($product, $delete), + $this->updateCategoryLinks($product, $insert, true), + $this->updateCategoryLinks($product, $update) ); } @@ -133,16 +134,15 @@ private function processCategoryLinks($newCategoryPositions, &$oldCategoryPositi /** * @param ProductInterface $product * @param array $insertLinks + * @param bool $insert * @return array */ - private function updateCategoryLinks(ProductInterface $product, array $insertLinks) + private function updateCategoryLinks(ProductInterface $product, array $insertLinks, $insert = false) { if (empty($insertLinks)) { return []; } - $connection = $this->resourceConnection->getConnection(); - $data = []; foreach ($insertLinks as $categoryLink) { $data[] = [ @@ -153,11 +153,22 @@ private function updateCategoryLinks(ProductInterface $product, array $insertLin } if ($data) { - $connection->insertOnDuplicate( - $this->getCategoryLinkMetadata()->getEntityTable(), - $data, - ['position'] - ); + $connection = $this->resourceConnection->getConnection(); + if ($insert) { + $connection->insertArray( + $this->getCategoryLinkMetadata()->getEntityTable(), + array_keys($data[0]), + $data, + \Magento\Framework\DB\Adapter\AdapterInterface::INSERT_IGNORE + ); + } else { + // for mass update category links with constraint by unique key use insert on duplicate statement + $connection->insertOnDuplicate( + $this->getCategoryLinkMetadata()->getEntityTable(), + $data, + ['position'] + ); + } } return array_column($insertLinks, 'category_id'); @@ -215,7 +226,7 @@ private function verifyCategoryLinks(array $links) } /** - * Analyse category links for update or/and delete + * Analyse category links for update or/and delete. Return array of links for delete, insert and update * * @param array $deleteUpdate * @param array $insertUpdate @@ -226,8 +237,7 @@ private function analyseUpdatedLinks($deleteUpdate, $insertUpdate) $delete = $deleteUpdate['changed'] ?: []; $insert = $insertUpdate['changed'] ?: []; $insert = array_merge_recursive($insert, $deleteUpdate['updated']); - $insert = array_merge_recursive($insert, $insertUpdate['updated']); - return [$delete, $insert]; + return [$delete, $insert, $insertUpdate['updated']]; } } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Link.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Link.php index 4b420329eef99..ef3f83e5ffa7e 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Link.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Link.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Model\ResourceModel\Product; +use Magento\Framework\DB\Adapter\AdapterInterface; + /** * Catalog product link resource model * @@ -136,7 +138,6 @@ public function saveProductLinks($parentId, $data, $typeId) $data = []; } - $attributes = $this->getAttributesByType($typeId); $connection = $this->getConnection(); $bind = [':product_id' => (int)$parentId, ':link_type_id' => (int)$typeId]; @@ -151,42 +152,38 @@ public function saveProductLinks($parentId, $data, $typeId) $links = $connection->fetchPairs($select, $bind); - foreach ($data as $linkedProductId => $linkInfo) { - $linkId = null; - if (isset($links[$linkedProductId])) { - $linkId = $links[$linkedProductId]; - unset($links[$linkedProductId]); - } else { - $bind = [ - 'product_id' => $parentId, - 'linked_product_id' => $linkedProductId, - 'link_type_id' => $typeId, - ]; - $connection->insert($this->getMainTable(), $bind); - $linkId = $connection->lastInsertId($this->getMainTable()); - } + list($insertData, $updateData, $deleteConditions) = $this->prepareProductLinksData( + $parentId, + $data, + $typeId, + $links + ); - foreach ($attributes as $attributeInfo) { - $attributeTable = $this->getAttributeTypeTable($attributeInfo['type']); - if ($attributeTable) { - if (isset($linkInfo[$attributeInfo['code']])) { - $value = $this->_prepareAttributeValue( - $attributeInfo['type'], - $linkInfo[$attributeInfo['code']] - ); - $bind = [ - 'product_link_attribute_id' => $attributeInfo['id'], - 'link_id' => $linkId, - 'value' => $value, - ]; - $connection->insertOnDuplicate($attributeTable, $bind, ['value']); - } else { - $connection->delete( - $attributeTable, - ['link_id = ?' => $linkId, 'product_link_attribute_id = ?' => $attributeInfo['id']] - ); - } - } + if ($insertData) { + $insertColumns = [ + 'product_link_attribute_id', + 'link_id', + 'value', + ]; + foreach ($insertData as $table => $values) { + $connection->insertArray($table, $insertColumns, $values, AdapterInterface::INSERT_IGNORE); + } + } + if ($updateData) { + // for mass update product links with constraint by unique key use insert on duplicate statement + foreach ($updateData as $table => $values) { + $connection->insertOnDuplicate($table, $values, ['value']); + } + } + if ($deleteConditions) { + foreach ($deleteConditions as $table => $deleteCondition) { + $connection->delete( + $table, + [ + 'link_id = ?' => $deleteCondition['link_id'], + 'product_link_attribute_id = ?' => $deleteCondition['product_link_attribute_id'] + ] + ); } } @@ -302,4 +299,69 @@ public function getParentIdsByChild($childId, $typeId) return $parentIds; } + + /** + * Prepare data for insert, update or delete product link attributes + * + * @param int $parentId + * @param array $data + * @param int $typeId + * @param array $links + * @return array + */ + private function prepareProductLinksData($parentId, $data, $typeId, $links) + { + $connection = $this->getConnection(); + $attributes = $this->getAttributesByType($typeId); + + $insertData = []; + $updateData = []; + $deleteConditions = []; + + foreach ($data as $linkedProductId => $linkInfo) { + $linkId = null; + if (isset($links[$linkedProductId])) { + $linkId = $links[$linkedProductId]; + } else { + $bind = [ + 'product_id' => $parentId, + 'linked_product_id' => $linkedProductId, + 'link_type_id' => $typeId, + ]; + $connection->insert($this->getMainTable(), $bind); + $linkId = $connection->lastInsertId($this->getMainTable()); + } + + foreach ($attributes as $attributeInfo) { + $attributeTable = $this->getAttributeTypeTable($attributeInfo['type']); + if (!$attributeTable) { + continue; + } + if (isset($linkInfo[$attributeInfo['code']])) { + $value = $this->_prepareAttributeValue( + $attributeInfo['type'], + $linkInfo[$attributeInfo['code']] + ); + if (isset($links[$linkedProductId])) { + $updateData[$attributeTable][] = [ + 'product_link_attribute_id' => $attributeInfo['id'], + 'link_id' => $linkId, + 'value' => $value, + ]; + } else { + $insertData[$attributeTable][] = [ + 'product_link_attribute_id' => $attributeInfo['id'], + 'link_id' => $linkId, + 'value' => $value, + ]; + } + } else { + $deleteConditions[$attributeTable]['link_id'][] = $linkId; + $deleteConditions[$attributeTable]['product_link_attribute_id'][] = $attributeInfo['id']; + } + } + } + + return [$insertData, $updateData, $deleteConditions]; + } } diff --git a/app/code/Magento/Catalog/Observer/UnsetSpecialPrice.php b/app/code/Magento/Catalog/Observer/UnsetSpecialPrice.php deleted file mode 100644 index 0ba1251edc7d6..0000000000000 --- a/app/code/Magento/Catalog/Observer/UnsetSpecialPrice.php +++ /dev/null @@ -1,31 +0,0 @@ -getEvent()->getProduct(); - if ($product->getSpecialPrice() === null) { - $product->setData('special_price', ''); - } - - return $this; - } -} diff --git a/app/code/Magento/Catalog/Plugin/Model/ResourceModel/ReadSnapshotPlugin.php b/app/code/Magento/Catalog/Plugin/Model/ResourceModel/ReadSnapshotPlugin.php new file mode 100644 index 0000000000000..4dae4ec68efa8 --- /dev/null +++ b/app/code/Magento/Catalog/Plugin/Model/ResourceModel/ReadSnapshotPlugin.php @@ -0,0 +1,95 @@ +metadataPool = $metadataPool; + $this->config = $config; + } + + /** + * @param ReadSnapshot $subject + * @param array $entityData + * @param string $entityType + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterExecute(ReadSnapshot $subject, array $entityData, $entityType) + { + if (!in_array($entityType, [ProductInterface::class, CategoryInterface::class], true)) { + return $entityData; + } + + $metadata = $this->metadataPool->getMetadata($entityType); + $connection = $metadata->getEntityConnection(); + $globalAttributes = []; + $attributesMap = []; + $eavEntityType = $metadata->getEavEntityType(); + $attributes = (null === $eavEntityType) ? [] : $this->config->getEntityAttributes($eavEntityType); + + /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */ + foreach ($attributes as $attribute) { + if (!$attribute->isStatic() && $attribute->isScopeGlobal()) { + $globalAttributes[$attribute->getBackend()->getTable()][] = $attribute->getAttributeId(); + $attributesMap[$attribute->getAttributeId()] = $attribute->getAttributeCode(); + } + } + + if ($globalAttributes) { + $selects = []; + foreach ($globalAttributes as $table => $attributeIds) { + $select = $connection->select() + ->from( + ['t' => $table], + ['value' => 't.value', 'attribute_id' => 't.attribute_id'] + ) + ->where($metadata->getLinkField() . ' = ?', $entityData[$metadata->getLinkField()]) + ->where('attribute_id' . ' in (?)', $attributeIds) + ->where('store_id = ?', \Magento\Store\Model\Store::DEFAULT_STORE_ID); + $selects[] = $select; + } + $unionSelect = new \Magento\Framework\DB\Sql\UnionExpression( + $selects, + \Magento\Framework\DB\Select::SQL_UNION_ALL + ); + foreach ($connection->fetchAll($unionSelect) as $attributeValue) { + $entityData[$attributesMap[$attributeValue['attribute_id']]] = $attributeValue['value']; + } + } + + return $entityData; + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php index f918692cb2753..627aa1848506e 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php @@ -5,12 +5,10 @@ */ namespace Magento\Catalog\Test\Unit\Model\Product; -use Magento\Catalog\Model\View\Asset\Image\ContextFactory; use Magento\Catalog\Model\View\Asset\ImageFactory; use Magento\Catalog\Model\View\Asset\PlaceholderFactory; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\View\Asset\ContextInterface; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -73,10 +71,24 @@ class ImageTest extends \PHPUnit\Framework\TestCase */ private $viewAssetPlaceholderFactory; + /** + * @var \Magento\Framework\Serialize\SerializerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $serializer; + + /** + * @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $cacheManager; + protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->context = $this->createMock(\Magento\Framework\Model\Context::class); + $this->cacheManager = $this->getMockBuilder(\Magento\Framework\App\CacheInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->context->expects($this->any())->method('getCacheManager')->will($this->returnValue($this->cacheManager)); $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManager::class) ->disableOriginalConstructor() @@ -112,17 +124,36 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); + $this->serializer = $this->getMockBuilder( + \Magento\Framework\Serialize\SerializerInterface::class + )->getMockForAbstractClass(); + $this->serializer->expects($this->any()) + ->method('serialize') + ->willReturnCallback( + function ($value) { + return json_encode($value); + } + ); + $this->serializer->expects($this->any()) + ->method('unserialize') + ->willReturnCallback( + function ($value) { + return json_decode($value, true); + } + ); $this->image = $objectManager->getObject( \Magento\Catalog\Model\Product\Image::class, [ + 'context' => $this->context, 'storeManager' => $this->storeManager, 'catalogProductMediaConfig' => $this->config, 'coreFileStorageDatabase' => $this->coreFileHelper, 'filesystem' => $this->filesystem, 'imageFactory' => $this->factory, 'viewAssetImageFactory' => $this->viewAssetImageFactory, - 'viewAssetPlaceholderFactory' => $this->viewAssetPlaceholderFactory + 'viewAssetPlaceholderFactory' => $this->viewAssetPlaceholderFactory, + 'serializer' => $this->serializer ] ); @@ -354,12 +385,16 @@ public function testIsCached() $this->testSetGetBaseFile(); $absolutePath = dirname(dirname(__DIR__)) . '/_files/catalog/product/watermark/somefile.png'; $this->imageAsset->expects($this->any())->method('getPath')->willReturn($absolutePath); + $this->cacheManager->expects($this->once())->method('load')->willReturn( + json_encode(['size' => ['image data']]) + ); $this->assertTrue($this->image->isCached()); } public function testClearCache() { $this->coreFileHelper->expects($this->once())->method('deleteFolder')->will($this->returnValue(true)); + $this->cacheManager->expects($this->once())->method('clean'); $this->image->clearCache(); } @@ -383,4 +418,24 @@ public function testIsBaseFilePlaceholder() { $this->assertFalse($this->image->isBaseFilePlaceholder()); } + + public function testGetResizedImageInfoWithCache() + { + $absolutePath = dirname(dirname(__DIR__)) . '/_files/catalog/product/watermark/somefile.png'; + $this->imageAsset->expects($this->any())->method('getPath')->willReturn($absolutePath); + $this->cacheManager->expects($this->once())->method('load')->willReturn( + json_encode(['size' => ['image data']]) + ); + $this->cacheManager->expects($this->never())->method('save'); + $this->assertEquals(['image data'], $this->image->getResizedImageInfo()); + } + + public function testGetResizedImageInfoEmptyCache() + { + $absolutePath = dirname(dirname(__DIR__)) . '/_files/catalog/product/watermark/somefile.png'; + $this->imageAsset->expects($this->any())->method('getPath')->willReturn($absolutePath); + $this->cacheManager->expects($this->once())->method('load')->willReturn(false); + $this->cacheManager->expects($this->once())->method('save'); + $this->assertTrue(is_array($this->image->getResizedImageInfo())); + } } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/ProductCollection.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/ProductCollection.php new file mode 100644 index 0000000000000..f4334bc25efd8 --- /dev/null +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/ProductCollection.php @@ -0,0 +1,28 @@ +_productLimitationFilters->setUsePriceIndex(false); + return $this->_productLimitationPrice(true); + } +} diff --git a/app/code/Magento/Catalog/etc/adminhtml/di.xml b/app/code/Magento/Catalog/etc/adminhtml/di.xml index 34d089580906f..9739ee28a6dae 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/di.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/di.xml @@ -78,6 +78,11 @@ + + + \Magento\Catalog\Ui\DataProvider\Product\ProductCollection + + @@ -86,6 +91,7 @@ Magento\Catalog\Ui\DataProvider\Product\AddStoreFieldToCollection + \Magento\Catalog\Ui\DataProvider\Product\ProductCollectionFactory diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index f28d2cbcdff3e..29b1cdfc7d15a 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -816,6 +816,9 @@ Magento\Catalog\Model\ResourceModel\AttributePersistor + + + diff --git a/app/code/Magento/Catalog/etc/events.xml b/app/code/Magento/Catalog/etc/events.xml index 3fdb554e65b62..63bd574894339 100644 --- a/app/code/Magento/Catalog/etc/events.xml +++ b/app/code/Magento/Catalog/etc/events.xml @@ -56,7 +56,6 @@ - diff --git a/app/code/Magento/CatalogRule/etc/mview.xml b/app/code/Magento/CatalogRule/etc/mview.xml index 2990c03ae0159..4b1166941bdc8 100644 --- a/app/code/Magento/CatalogRule/etc/mview.xml +++ b/app/code/Magento/CatalogRule/etc/mview.xml @@ -18,7 +18,6 @@
-
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php index e4ccd0b869db7..c4d67f447e2cf 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/ProductProcessUrlRewriteSavingObserver.php @@ -50,13 +50,6 @@ public function execute(\Magento\Framework\Event\Observer $observer) || $product->getIsChangedWebsites() || $product->dataHasChangedFor('visibility') ) { - $this->urlPersist->deleteByData([ - UrlRewrite::ENTITY_ID => $product->getId(), - UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, - UrlRewrite::REDIRECT_TYPE => 0, - UrlRewrite::STORE_ID => $product->getStoreId() - ]); - if ($product->isVisibleInSiteVisibility()) { $this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product)); } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductProcessUrlRewriteSavingObserverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductProcessUrlRewriteSavingObserverTest.php index d294f6d022ef3..39317b42af989 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductProcessUrlRewriteSavingObserverTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/ProductProcessUrlRewriteSavingObserverTest.php @@ -103,7 +103,6 @@ public function urlKeyDataProvider() 'isChangedWebsites' => false, 'isChangedCategories' => false, 'visibilityResult' => true, - 'expectedDeleteCount' => 1, 'expectedReplaceCount' => 1, ], @@ -113,7 +112,6 @@ public function urlKeyDataProvider() 'isChangedWebsites' => false, 'isChangedCategories' => false, 'visibilityResult' => true, - 'expectedDeleteCount' => 0, 'expectedReplaceCount' => 0 ], 'visibility changed' => [ @@ -122,7 +120,6 @@ public function urlKeyDataProvider() 'isChangedWebsites' => false, 'isChangedCategories' => false, 'visibilityResult' => true, - 'expectedDeleteCount' => 1, 'expectedReplaceCount' => 1 ], 'websites changed' => [ @@ -131,7 +128,6 @@ public function urlKeyDataProvider() 'isChangedWebsites' => true, 'isChangedCategories' => false, 'visibilityResult' => true, - 'expectedDeleteCount' => 1, 'expectedReplaceCount' => 1 ], 'categories changed' => [ @@ -140,7 +136,6 @@ public function urlKeyDataProvider() 'isChangedWebsites' => false, 'isChangedCategories' => true, 'visibilityResult' => true, - 'expectedDeleteCount' => 1, 'expectedReplaceCount' => 1 ], 'url changed invisible' => [ @@ -149,7 +144,6 @@ public function urlKeyDataProvider() 'isChangedWebsites' => false, 'isChangedCategories' => false, 'visibilityResult' => false, - 'expectedDeleteCount' => 1, 'expectedReplaceCount' => 0 ], ]; @@ -161,7 +155,6 @@ public function urlKeyDataProvider() * @param bool $isChangedWebsites * @param bool $isChangedCategories * @param bool $visibilityResult - * @param int $expectedDeleteCount * @param int $expectedReplaceCount * * @dataProvider urlKeyDataProvider @@ -172,7 +165,6 @@ public function testExecuteUrlKey( $isChangedWebsites, $isChangedCategories, $visibilityResult, - $expectedDeleteCount, $expectedReplaceCount ) { $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(12)); @@ -194,13 +186,6 @@ public function testExecuteUrlKey( ->method('getIsChangedCategories') ->will($this->returnValue($isChangedCategories)); - $this->urlPersist->expects($this->exactly($expectedDeleteCount))->method('deleteByData')->with([ - UrlRewrite::ENTITY_ID => $this->product->getId(), - UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, - UrlRewrite::REDIRECT_TYPE => 0, - UrlRewrite::STORE_ID => $this->product->getStoreId() - ]); - $this->product->expects($this->any()) ->method('isVisibleInSiteVisibility') ->will($this->returnValue($visibilityResult)); diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php index 3c9689a1c4eb9..95afba984d57d 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable.php @@ -17,6 +17,7 @@ use Magento\ConfigurableProduct\Model\ResourceModel\Attribute\OptionProvider; use Magento\Framework\App\ScopeResolverInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\DB\Adapter\AdapterInterface; class Configurable extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { @@ -109,27 +110,34 @@ public function saveProducts($mainProduct, array $productIds) } $productId = $mainProduct->getData($this->optionProvider->getProductEntityLinkField()); + $select = $this->getConnection()->select()->from( + ['t' => $this->getMainTable()], + ['product_id'] + )->where( + 't.parent_id = ?', + $productId + ); - $data = []; - foreach ($productIds as $id) { - $data[] = ['product_id' => (int) $id, 'parent_id' => (int) $productId]; - } + $existingProductIds = $this->getConnection()->fetchCol($select); + $insertProductIds = array_diff($productIds, $existingProductIds); + $deleteProductIds = array_diff($existingProductIds, $productIds); - if (!empty($data)) { - $this->getConnection()->insertOnDuplicate( + if (!empty($insertProductIds)) { + $insertData = []; + foreach ($insertProductIds as $id) { + $insertData[] = ['product_id' => (int) $id, 'parent_id' => (int) $productId]; + } + $this->getConnection()->insertMultiple( $this->getMainTable(), - $data, - ['product_id', 'parent_id'] + $insertData ); } - $where = ['parent_id = ?' => $productId]; - if (!empty($productIds)) { - $where['product_id NOT IN(?)'] = $productIds; + if (!empty($deleteProductIds)) { + $where = ['parent_id = ?' => $productId, 'product_id IN (?)' => $deleteProductIds]; + $this->getConnection()->delete($this->getMainTable(), $where); } - $this->getConnection()->delete($this->getMainTable(), $where); - // configurable product relations should be added to relation table $this->catalogProductRelation->processRelations($productId, $productIds); diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute.php index 7ea83099f2589..e93c44893bf58 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Type/Configurable/Attribute.php @@ -8,8 +8,8 @@ namespace Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable; use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute as ConfigurableAttribute; +use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Store\Model\Store; -use Magento\Store\Model\StoreManagerInterface; class Attribute extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { @@ -85,22 +85,30 @@ public function saveLabel($attribute) 'store_id' => \Magento\Store\Model\Store::DEFAULT_STORE_ID, ]; $valueId = $connection->fetchOne($select, $bind); + if ($valueId) { - $storeId = (int)$attribute->getStoreId() ?: $this->_storeManager->getStore()->getId(); + $connection->insertOnDuplicate( + $this->_labelTable, + [ + 'product_super_attribute_id' => (int)$attribute->getId(), + 'store_id' => (int)$attribute->getStoreId() ?: $this->_storeManager->getStore()->getId(), + 'use_default' => (int)$attribute->getUseDefault(), + 'value' => $attribute->getLabel(), + ], + ['value', 'use_default'] + ); } else { // if attribute label not exists, always store on default store (0) - $storeId = Store::DEFAULT_STORE_ID; + $connection->insert( + $this->_labelTable, + [ + 'product_super_attribute_id' => (int)$attribute->getId(), + 'store_id' => Store::DEFAULT_STORE_ID, + 'use_default' => (int)$attribute->getUseDefault(), + 'value' => $attribute->getLabel(), + ] + ); } - $connection->insertOnDuplicate( - $this->_labelTable, - [ - 'product_super_attribute_id' => (int)$attribute->getId(), - 'use_default' => (int)$attribute->getUseDefault(), - 'store_id' => $storeId, - 'value' => $attribute->getLabel(), - ], - ['value', 'use_default'] - ); return $this; } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Product/Type/Configurable/AttributeTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Product/Type/Configurable/AttributeTest.php index a6c7f00c2dfbe..e7b033ff84fd0 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Product/Type/Configurable/AttributeTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Product/Type/Configurable/AttributeTest.php @@ -53,7 +53,7 @@ protected function setUp() ); } - public function testSaveLabel() + public function testSaveNewLabel() { $attributeId = 4354; @@ -70,7 +70,7 @@ public function testSaveLabel() ] )->willReturn(0); - $this->connection->expects($this->once())->method('insertOnDuplicate')->with( + $this->connection->expects($this->once())->method('insert')->with( 'catalog_product_super_attribute_label', [ 'product_super_attribute_id' => $attributeId, @@ -79,12 +79,48 @@ public function testSaveLabel() 'value' => 'test', ] ); - $attributeMode = $this->getMockBuilder(AttributeModel::class)->setMethods( + $attributeMock = $this->getMockBuilder(AttributeModel::class)->setMethods( ['getId', 'getUseDefault', 'getLabel'] )->disableOriginalConstructor()->getMock(); - $attributeMode->expects($this->any())->method('getId')->willReturn($attributeId); - $attributeMode->expects($this->any())->method('getUseDefault')->willReturn(0); - $attributeMode->expects($this->any())->method('getLabel')->willReturn('test'); - $this->assertEquals($this->attribute, $this->attribute->saveLabel($attributeMode)); + $attributeMock->expects($this->atLeastOnce())->method('getId')->willReturn($attributeId); + $attributeMock->expects($this->atLeastOnce())->method('getUseDefault')->willReturn(0); + $attributeMock->expects($this->atLeastOnce())->method('getLabel')->willReturn('test'); + $this->assertEquals($this->attribute, $this->attribute->saveLabel($attributeMock)); + } + + public function testSaveExistingLabel() + { + $attributeId = 4354; + + $select = $this->getMockBuilder(Select::class)->disableOriginalConstructor()->getMock(); + $this->connection->expects($this->once())->method('select')->willReturn($select); + $select->expects($this->once())->method('from')->willReturnSelf(); + $select->expects($this->at(1))->method('where')->willReturnSelf(); + $select->expects($this->at(2))->method('where')->willReturnSelf(); + $this->connection->expects($this->once())->method('fetchOne')->with( + $select, + [ + 'product_super_attribute_id' => $attributeId, + 'store_id' => \Magento\Store\Model\Store::DEFAULT_STORE_ID, + ] + )->willReturn(1); + + $this->connection->expects($this->once())->method('insertOnDuplicate')->with( + 'catalog_product_super_attribute_label', + [ + 'product_super_attribute_id' => $attributeId, + 'use_default' => 0, + 'store_id' => 1, + 'value' => 'test', + ] + ); + $attributeMock = $this->getMockBuilder(AttributeModel::class)->setMethods( + ['getId', 'getUseDefault', 'getLabel', 'getStoreId'] + )->disableOriginalConstructor()->getMock(); + $attributeMock->expects($this->atLeastOnce())->method('getId')->willReturn($attributeId); + $attributeMock->expects($this->atLeastOnce())->method('getStoreId')->willReturn(1); + $attributeMock->expects($this->atLeastOnce())->method('getUseDefault')->willReturn(0); + $attributeMock->expects($this->atLeastOnce())->method('getLabel')->willReturn('test'); + $this->assertEquals($this->attribute, $this->attribute->saveLabel($attributeMock)); } } diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Product/Type/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Product/Type/ConfigurableTest.php index 5a494d1c7a19b..cda9c300cd1d9 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Product/Type/ConfigurableTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/ResourceModel/Product/Type/ConfigurableTest.php @@ -142,19 +142,48 @@ public function testSaveProducts() $this->optionProvider->expects($this->once()) ->method('getProductEntityLinkField') ->willReturnSelf(); - $this->connectionMock->expects($this->once()) - ->method('insertOnDuplicate') - ->willReturnSelf(); - $this->resource->expects($this->any())->method('getConnection')->willReturn($this->connectionMock); $this->resource->expects($this->any())->method('getTableName')->willReturn('table name'); - $statement = $this->getMockBuilder(\Zend_Db_Statement::class)->disableOriginalConstructor()->getMock(); - $statement->method('fetchAll')->willReturn([1]); + $select = $this->getMockBuilder(\Magento\Framework\DB\Select::class) + ->setMethods(['from', 'where']) + ->disableOriginalConstructor() + ->getMock(); + $select->expects($this->exactly(1))->method('from')->willReturnSelf(); + $select->expects($this->exactly(1))->method('where')->willReturnSelf(); + + $this->connectionMock->expects($this->atLeastOnce()) + ->method('select') + ->willReturn($select); + + $existingProductIds = [1, 2]; + $this->connectionMock->expects($this->once()) + ->method('fetchCol') + ->with($select) + ->willReturn($existingProductIds); + + $this->connectionMock->expects($this->once()) + ->method('insertMultiple') + ->with( + 'table name', + [ + ['product_id' => 3, 'parent_id' => 3], + ['product_id' => 4, 'parent_id' => 3], + ] + ) + ->willReturnSelf(); + + $this->connectionMock->expects($this->once()) + ->method('delete') + ->with( + 'table name', + ['parent_id = ?' => 3, 'product_id IN (?)' => [1]] + ) + ->willReturnSelf(); $this->assertSame( $this->configurable, - $this->configurable->saveProducts($this->product, [1, 2, 3]) + $this->configurable->saveProducts($this->product, [2, 3, 4]) ); } diff --git a/app/code/Magento/Eav/Model/ResourceModel/AttributePersistor.php b/app/code/Magento/Eav/Model/ResourceModel/AttributePersistor.php index f3b2e0ba3e618..9c6adc0354f8d 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/AttributePersistor.php +++ b/app/code/Magento/Eav/Model/ResourceModel/AttributePersistor.php @@ -144,6 +144,31 @@ public function processInserts($entityType, $context) return; } $metadata = $this->metadataPool->getMetadata($entityType); + $insertData = $this->prepareInsertDataForMultipleSave($entityType, $context); + + foreach ($insertData as $table => $tableData) { + foreach ($tableData as $data) { + $metadata->getEntityConnection()->insertArray( + $table, + $data['columns'], + $data['data'], + \Magento\Framework\DB\Adapter\AdapterInterface::INSERT_IGNORE + ); + } + } + } + + /** + * Prepare data for insert multiple rows + * + * @param string $entityType + * @param \Magento\Framework\Model\Entity\ScopeInterface[] $context + * @return array + */ + private function prepareInsertDataForMultipleSave($entityType, $context) + { + $metadata = $this->metadataPool->getMetadata($entityType); + $insertData = []; foreach ($this->insert[$entityType] as $link => $data) { foreach ($data as $attributeCode => $attributeValue) { /** @var AbstractAttribute $attribute */ @@ -151,19 +176,21 @@ public function processInserts($entityType, $context) $metadata->getEavEntityType(), $attributeCode ); - + $attributeTable = $attribute->getBackend()->getTable(); $conditions = $this->buildInsertConditions($attribute, $metadata, $context, $link); $value = $this->prepareValue($entityType, $attributeValue, $attribute); foreach ($conditions as $condition) { $condition['value'] = $value; - $metadata->getEntityConnection()->insertOnDuplicate( - $attribute->getBackend()->getTable(), - $condition - ); + $columns = array_keys($condition); + $columnsHash = implode('', $columns); + $insertData[$attributeTable][$columnsHash]['columns'] = $columns; + $insertData[$attributeTable][$columnsHash]['data'][] = array_values($condition); } } } + + return $insertData; } /** diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Collection.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Collection.php index f55c4db31efdc..492da0b72c122 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Collection.php +++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Collection.php @@ -210,17 +210,19 @@ public function setAttributeSetsFilter(array $setIds) */ public function setInAllAttributeSetsFilter(array $setIds) { - foreach ($setIds as $setId) { - $setId = (int)$setId; - if (!$setId) { - continue; - } - $alias = sprintf('entity_attribute_%d', $setId); - $joinCondition = $this->getConnection()->quoteInto( - "{$alias}.attribute_id = main_table.attribute_id AND {$alias}.attribute_set_id =?", - $setId - ); - $this->join([$alias => 'eav_entity_attribute'], $joinCondition, 'attribute_id'); + if (!empty($setIds)) { + $this->getSelect() + ->join( + ['entity_attribute' => $this->getTable('eav_entity_attribute')], + 'entity_attribute.attribute_id = main_table.attribute_id', + ['count' => new \Zend_Db_Expr('COUNT(*)')] + ) + ->where( + 'entity_attribute.attribute_set_id IN (?)', + $setIds + ) + ->group('entity_attribute.attribute_id') + ->having('count = ' . count($setIds)); } //$this->getSelect()->distinct(true); diff --git a/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/Attribute/CollectionTest.php b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/Attribute/CollectionTest.php new file mode 100644 index 0000000000000..138e1363bb6dd --- /dev/null +++ b/app/code/Magento/Eav/Test/Unit/Model/ResourceModel/Entity/Attribute/CollectionTest.php @@ -0,0 +1,158 @@ +entityFactoryMock = $this->getMockBuilder(\Magento\Framework\Data\Collection\EntityFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->loggerMock = $this->getMockBuilder(\Psr\Log\LoggerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->fetchStrategyMock = $this->getMockBuilder(FetchStrategyInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->eavConfigMock = $this->getMockBuilder(\Magento\Eav\Model\Config::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\Pdo\Mysql::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->resourceMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class) + ->setMethods(['__wakeup', 'getConnection', 'getMainTable', 'getTable']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $this->resourceMock->expects($this->any())->method('getConnection')->willReturn($this->connectionMock); + $this->resourceMock->expects($this->any())->method('getMainTable')->willReturn('eav_entity_attribute'); + + $this->selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->connectionMock->expects($this->any())->method('select')->willReturn($this->selectMock); + + $objectManager = new ObjectManager($this); + $this->model = $objectManager->getObject( + \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection::class, + [ + 'entityFactory' => $this->entityFactoryMock, + 'logger' => $this->loggerMock, + 'fetchStrategy' => $this->fetchStrategyMock, + 'eventManager' => $this->eventManagerMock, + 'eavConfig' => $this->eavConfigMock, + 'connection' => $this->connectionMock, + 'resource' => $this->resourceMock, + ] + ); + } + + /** + * Test method \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection::setInAllAttributeSetsFilter + * + * @return void + */ + public function testSetInAllAttributeSetsFilter() + { + $setIds = [1, 2, 3]; + + $this->selectMock->expects($this->atLeastOnce()) + ->method('where') + ->with('entity_attribute.attribute_set_id IN (?)', $setIds) + ->willReturnSelf(); + $this->selectMock->expects($this->atLeastOnce())->method('join')->with( + ['entity_attribute' => $this->model->getTable('eav_entity_attribute')], + 'entity_attribute.attribute_id = main_table.attribute_id', + ['count' => new \Zend_Db_Expr('COUNT(*)')] + )->willReturnSelf(); + + $this->selectMock->expects($this->atLeastOnce())->method('group')->with('entity_attribute.attribute_id') + ->willReturnSelf(); + + $this->selectMock->expects($this->atLeastOnce())->method('having')->with('count = ' . count($setIds)) + ->willReturnSelf(); + + $this->model->setInAllAttributeSetsFilter($setIds); + } +} diff --git a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php index 376b07a17fe6a..f418ffe4a1ad9 100644 --- a/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php +++ b/app/code/Magento/UrlRewrite/Model/Storage/DbStorage.php @@ -147,7 +147,10 @@ protected function doReplace(array $urls) { foreach ($this->createFilterDataBasedOnUrls($urls) as $type => $urlData) { $urlData[UrlRewrite::ENTITY_TYPE] = $type; - $this->deleteByData($urlData); + // prevent query locking in a case when nothing to delete + if ($this->connection->fetchRow($this->prepareSelect($urlData))) { + $this->deleteByData($urlData); + } } $data = []; foreach ($urls as $url) { diff --git a/app/code/Magento/UrlRewrite/Test/Unit/Model/Storage/DbStorageTest.php b/app/code/Magento/UrlRewrite/Test/Unit/Model/Storage/DbStorageTest.php index 261894dc8fe33..41fd5b48ecca9 100644 --- a/app/code/Magento/UrlRewrite/Test/Unit/Model/Storage/DbStorageTest.php +++ b/app/code/Magento/UrlRewrite/Test/Unit/Model/Storage/DbStorageTest.php @@ -436,6 +436,9 @@ public function testFindOneByDataWithRequestPathTwoResults() $this->assertEquals(['urlRewrite1'], $this->storage->findOneByData($data)); } + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ public function testReplace() { $urlFirst = $this->createMock(\Magento\UrlRewrite\Service\V1\Data\UrlRewrite::class); @@ -476,24 +479,52 @@ public function testReplace() ->method('where') ->with('entity_type IN (?)', 'product'); - $this->select->expects($this->at(4)) + $this->select->expects($this->at(5)) + ->method('where') + ->with('entity_id IN (?)', ['entity_1']); + + $this->select->expects($this->at(6)) + ->method('where') + ->with('store_id IN (?)', ['store_id_1']); + + $this->select->expects($this->at(7)) + ->method('where') + ->with('entity_type IN (?)', 'product'); + + $this->connectionMock->expects($this->any()) + ->method('fetchRow') + ->willReturn(['some-data']); + + $this->select->expects($this->at(8)) ->method('deleteFromSelect') ->with('table_name') ->will($this->returnValue('sql delete query')); - $this->select->expects($this->at(6)) + $this->select->expects($this->at(10)) ->method('where') ->with('entity_id IN (?)', ['entity_2']); - $this->select->expects($this->at(7)) + $this->select->expects($this->at(11)) ->method('where') ->with('store_id IN (?)', ['store_id_2']); - $this->select->expects($this->at(8)) + $this->select->expects($this->at(12)) + ->method('where') + ->with('entity_type IN (?)', 'category'); + + $this->select->expects($this->at(14)) + ->method('where') + ->with('entity_id IN (?)', ['entity_2']); + + $this->select->expects($this->at(15)) + ->method('where') + ->with('store_id IN (?)', ['store_id_2']); + + $this->select->expects($this->at(16)) ->method('where') ->with('entity_type IN (?)', 'category'); - $this->select->expects($this->at(9)) + $this->select->expects($this->at(17)) ->method('deleteFromSelect') ->with('table_name') ->will($this->returnValue('sql delete query')); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ViewTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ViewTest.php index f2534ea7156ed..01398213b854a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ViewTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/ViewTest.php @@ -41,15 +41,10 @@ public function testSetLayout() /** @var $layout \Magento\Framework\View\Layout */ $layout = $objectManager->get(\Magento\Framework\View\LayoutInterface::class); - /** @var $pageConfig \Magento\Framework\View\Page\Config */ - $pageConfig = $objectManager->get(\Magento\Framework\View\Page\Config::class); - $layout->createBlock(\Magento\Catalog\Block\Product\View::class); + $productView = $layout->createBlock(\Magento\Catalog\Block\Product\View::class); - $this->assertNotEmpty($pageConfig->getTitle()->get()); - $this->assertEquals($this->_product->getMetaTitle(), $pageConfig->getTitle()->get()); - $this->assertEquals($this->_product->getMetaKeyword(), $pageConfig->getKeywords()); - $this->assertEquals($this->_product->getMetaDescription(), $pageConfig->getDescription()); + $this->assertInstanceOf(\Magento\Framework\View\LayoutInterface::class, $productView->getLayout()); } public function testGetProduct() diff --git a/dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/FactoryTest.php b/dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/FactoryTest.php new file mode 100644 index 0000000000000..e6ee5297e4532 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/FactoryTest.php @@ -0,0 +1,83 @@ +objectManager = Bootstrap::getObjectManager(); + $this->factory = $this->objectManager->create( + \Magento\Framework\App\Cache\Frontend\Factory::class + ); + } + + /** + * Check RemoteSynchronizedCache + * Removing any cache item in the RemoteSynchronizedCache must invalidate all cache items + * + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + */ + public function testRemoteSynchronizedCache() + { + $data = 'data'; + $identifier = 'identifier'; + $secondIdentifier = 'secondIdentifier'; + $secondData = 'secondData'; + + $frontendOptions = ['backend' => 'remote_synchronized_cache']; + $this->model = $this->factory->create($frontendOptions); + + //Saving data + $this->assertTrue($this->model->save($data, $identifier)); + $this->assertTrue($this->model->save($secondData, $secondIdentifier)); + + //Checking data + $this->assertEquals($this->model->load($identifier), $data); + $this->assertEquals($this->model->load($secondIdentifier), $secondData); + + //Removing data + sleep(2); + $this->assertTrue($this->model->remove($secondIdentifier)); + $this->assertEquals($this->model->load($identifier), false); + $this->assertEquals($this->model->load($secondIdentifier), false); + + //Saving data + $this->assertTrue($this->model->save($data, $identifier)); + $this->assertTrue($this->model->save($secondData, $secondIdentifier)); + + //Checking data + $this->assertEquals($this->model->load($identifier), $data); + $this->assertEquals($this->model->load($secondIdentifier), $secondData); + + //Removing data + sleep(2); + $this->assertTrue($this->model->remove($identifier)); + $this->assertEquals($this->model->load($identifier), false); + $this->assertEquals($this->model->load($secondIdentifier), false); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/GenerateFixturesCommandTest.php b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/GenerateFixturesCommandTest.php new file mode 100644 index 0000000000000..eaa8b2f6fdbbf --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/GenerateFixturesCommandTest.php @@ -0,0 +1,151 @@ +objectManager = Bootstrap::getObjectManager(); + + $this->objectManager->get(\Magento\TestFramework\App\Config::class)->clean(); + + $this->fixtureModelMock = $this->getMockBuilder(FixtureModel::class) + ->setMethods(['getObjectManager']) + ->setConstructorArgs([$this->objectManager->get(IndexerReindexCommand::class)]) + ->getMock(); + $this->fixtureModelMock + ->method('getObjectManager') + ->willReturn($this->objectManager); + + $this->command = $this->objectManager->create( + GenerateFixturesCommand::class, + [ + 'fixtureModel' => $this->fixtureModelMock + ] + ); + + $objectFactoryMock = $this->getMockBuilder(ObjectManagerFactory::class) + ->setMethods(['create']) + ->disableOriginalConstructor() + ->getMock(); + $objectFactoryMock + ->method('create') + ->willReturn($this->objectManager); + + $this->indexerCommand = new CommandTester($this->objectManager->create( + IndexerReindexCommand::class, + ['objectManagerFactory' => $objectFactoryMock] + )); + + $this->commandTester = new CommandTester($this->command); + + $this->setIncrement(3); + + parent::setUp(); + } + + /** + * @return string + */ + private function getEdition() + { + return trim(file_get_contents(__DIR__ . '/_files/edition')); + } + + /** + * teardown + */ + public function tearDown() + { + $this->setIncrement(1); + + parent::tearDown(); + } + + public static function setUpBeforeClass() + { + $db = Bootstrap::getInstance()->getBootstrap() + ->getApplication() + ->getDbInstance(); + if (!$db->isDbDumpExists()) { + throw new \LogicException('DB dump does not exist.'); + } + $db->restoreFromDbDump(); + + parent::setUpBeforeClass(); + } + + /** + * @magentoAppArea adminhtml + * @magentoAppIsolation enabled + */ + public function testExecute() + { + $profile = BP . "/setup/performance-toolkit/profiles/{$this->getEdition()}/small.xml"; + $this->commandTester->execute( + [ + GenerateFixturesCommand::PROFILE_ARGUMENT => $profile, + '--' . GenerateFixturesCommand::SKIP_REINDEX_OPTION => true + ] + ); + $this->indexerCommand->execute([]); + + static::assertEquals( + Cli::RETURN_SUCCESS, + $this->indexerCommand->getStatusCode(), + $this->indexerCommand->getDisplay(true) + ); + + static::assertEquals( + Cli::RETURN_SUCCESS, + $this->commandTester->getStatusCode(), + $this->commandTester->getDisplay(true) + ); + } + + /** + * @param $value + */ + private function setIncrement($value) + { + /** @var \Magento\Framework\DB\Adapter\AdapterInterface $db */ + $db = Bootstrap::getObjectManager()->get(ResourceConnection::class)->getConnection(); + $db->query("SET @@session.auto_increment_increment=$value"); + $db->query("SET @@session.auto_increment_offset=$value"); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/edition b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/edition new file mode 100644 index 0000000000000..a2a77c324b740 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/edition @@ -0,0 +1 @@ +ce diff --git a/lib/internal/Magento/Framework/App/Cache/Frontend/Factory.php b/lib/internal/Magento/Framework/App/Cache/Frontend/Factory.php index 4c539da0960ea..0e7ac7527ccba 100644 --- a/lib/internal/Magento/Framework/App/Cache/Frontend/Factory.php +++ b/lib/internal/Magento/Framework/App/Cache/Frontend/Factory.php @@ -266,6 +266,15 @@ protected function _getBackendOptions(array $cacheOptions) $backendType = \Magento\Framework\Cache\Backend\Database::class; $options = $this->_getDbAdapterOptions(); break; + case 'remote_synchronized_cache': + $backendType = \Magento\Framework\Cache\Backend\RemoteSynchronizedCache::class; + $options['remote_backend'] = \Magento\Framework\Cache\Backend\Database::class; + $options['remote_backend_options'] = $this->_getDbAdapterOptions(); + $options['local_backend'] = \Cm_Cache_Backend_File::class; + $cacheDir = $this->_filesystem->getDirectoryWrite(DirectoryList::CACHE); + $options['local_backend_options']['cache_dir'] = $cacheDir->getAbsolutePath(); + $cacheDir->create(); + break; default: if ($type != $this->_defaultBackend) { try { diff --git a/lib/internal/Magento/Framework/Cache/Backend/Database.php b/lib/internal/Magento/Framework/Cache/Backend/Database.php index 8bb786e335f74..291078383014a 100644 --- a/lib/internal/Magento/Framework/Cache/Backend/Database.php +++ b/lib/internal/Magento/Framework/Cache/Backend/Database.php @@ -216,16 +216,15 @@ public function save($data, $id, $tags = [], $specificLifetime = false) $time = time(); $expire = $lifetime === 0 || $lifetime === null ? 0 : $time + $lifetime; + $idCol = $connection->quoteIdentifier('id'); $dataCol = $connection->quoteIdentifier('data'); + $createCol = $connection->quoteIdentifier('create_time'); + $updateCol = $connection->quoteIdentifier('update_time'); $expireCol = $connection->quoteIdentifier('expire_time'); - $query = "INSERT INTO {$dataTable} (\n {$connection->quoteIdentifier( - 'id' - )},\n {$dataCol},\n {$connection->quoteIdentifier( - 'create_time' - )},\n {$connection->quoteIdentifier( - 'update_time' - )},\n {$expireCol})\n VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE\n - {$dataCol}=VALUES({$dataCol}),\n {$expireCol}=VALUES({$expireCol})"; + + $query = "INSERT INTO {$dataTable} ({$idCol}, {$dataCol}, {$createCol}, {$updateCol}, {$expireCol}) " . + "VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE {$dataCol}=VALUES({$dataCol}), " . + "{$updateCol}=VALUES({$updateCol}), {$expireCol}=VALUES({$expireCol})"; $result = $connection->query($query, [$id, $data, $time, $time, $expire])->rowCount(); } diff --git a/lib/internal/Magento/Framework/Cache/Backend/RemoteSynchronizedCache.php b/lib/internal/Magento/Framework/Cache/Backend/RemoteSynchronizedCache.php new file mode 100644 index 0000000000000..007f921259bed --- /dev/null +++ b/lib/internal/Magento/Framework/Cache/Backend/RemoteSynchronizedCache.php @@ -0,0 +1,239 @@ + '', + 'remote_backend_invalidation_time_id' => 'default_remote_backend_invalidation_time', + 'remote_backend_custom_naming' => true, + 'remote_backend_autoload' => true, + 'remote_backend_options' => [], + 'local_backend' => '', + 'local_backend_options' => [], + 'local_backend_custom_naming' => true, + 'local_backend_autoload' => true + ]; + + /** + * @param array $options + */ + public function __construct(array $options = []) + { + parent::__construct($options); + + $universalOptions = array_diff_key($options, $this->_options); + + if ($this->_options['remote_backend'] === null) { + \Zend_Cache::throwException('remote_backend option must be set'); + } elseif ($this->_options['remote_backend'] instanceof \Zend_Cache_Backend_ExtendedInterface) { + $this->remote = $this->_options['remote_backend']; + } else { + $this->remote = \Zend_Cache::_makeBackend( + $this->_options['remote_backend'], + array_merge($universalOptions, $this->_options['remote_backend_options']), + $this->_options['remote_backend_custom_naming'], + $this->_options['remote_backend_autoload'] + ); + if (!($this->remote instanceof \Zend_Cache_Backend_ExtendedInterface)) { + \Zend_Cache::throwException( + 'remote_backend must implement the Zend_Cache_Backend_ExtendedInterface interface' + ); + } + } + + if ($this->_options['local_backend'] === null) { + \Zend_Cache::throwException('local_backend option must be set'); + } elseif ($this->_options['local_backend'] instanceof \Zend_Cache_Backend_ExtendedInterface) { + $this->local = $this->_options['local_backend']; + } else { + $this->local = \Zend_Cache::_makeBackend( + $this->_options['local_backend'], + array_merge($universalOptions, $this->_options['local_backend_options']), + $this->_options['local_backend_custom_naming'], + $this->_options['local_backend_autoload'] + ); + if (!($this->local instanceof \Zend_Cache_Backend_ExtendedInterface)) { + \Zend_Cache::throwException( + 'local_backend must implement the Zend_Cache_Backend_ExtendedInterface interface' + ); + } + } + } + + /** + * Update remote cache status info + * + * @return void + */ + private function updateRemoteCacheStatusInfo() + { + $this->remote->save(time(), $this->_options['remote_backend_invalidation_time_id'], [], null); + $this->cacheInvalidationTime = null; + } + + /** + * {@inheritdoc} + */ + public function setDirectives($directives) + { + return $this->local->setDirectives($directives); + } + + /** + * {@inheritdoc} + */ + public function load($id, $doNotTestCacheValidity = false) + { + $dataModificationTime = $this->local->test($id); + if ($this->cacheInvalidationTime === null) { + $this->cacheInvalidationTime = $this->remote->load($this->_options['remote_backend_invalidation_time_id']); + } + if ($dataModificationTime >= $this->cacheInvalidationTime) { + return $this->local->load($id, $doNotTestCacheValidity); + } else { + return false; + } + } + + /** + * {@inheritdoc} + */ + public function test($id) + { + return $this->local->test($id); + } + + /** + * {@inheritdoc} + */ + public function save($data, $id, $tags = [], $specificLifetime = false) + { + return $this->local->save($data, $id, $tags, $specificLifetime); + } + + /** + * {@inheritdoc} + */ + public function remove($id) + { + $this->updateRemoteCacheStatusInfo(); + return $this->local->remove($id); + } + + /** + * {@inheritdoc} + */ + public function clean($mode = \Zend_Cache::CLEANING_MODE_ALL, $tags = []) + { + $this->updateRemoteCacheStatusInfo(); + return $this->local->clean($mode, $tags); + } + + /** + * {@inheritdoc} + */ + public function getIds() + { + return $this->local->getIds(); + } + + /** + * {@inheritdoc} + */ + public function getTags() + { + return $this->local->getTags(); + } + + /** + * {@inheritdoc} + */ + public function getIdsMatchingTags($tags = []) + { + return $this->local->getIdsMatchingTags($tags); + } + + /** + * {@inheritdoc} + */ + public function getIdsNotMatchingTags($tags = []) + { + return $this->local->getIdsNotMatchingTags($tags); + } + + /** + * {@inheritdoc} + */ + public function getIdsMatchingAnyTags($tags = []) + { + return $this->local->getIdsMatchingAnyTags($tags); + } + + /** + * {@inheritdoc} + */ + public function getFillingPercentage() + { + return $this->local->getFillingPercentage(); + } + + /** + * {@inheritdoc} + */ + public function getMetadatas($id) + { + return $this->local->getMetadatas($id); + } + + /** + * {@inheritdoc} + */ + public function touch($id, $extraLifetime) + { + return $this->local->touch($id, $extraLifetime); + } + + /** + * {@inheritdoc} + */ + public function getCapabilities() + { + return $this->local->getCapabilities(); + } +} diff --git a/lib/internal/Magento/Framework/Cache/Test/Unit/Backend/RemoteSynchronizedCacheTest.php b/lib/internal/Magento/Framework/Cache/Test/Unit/Backend/RemoteSynchronizedCacheTest.php new file mode 100644 index 0000000000000..6aca2bedd4989 --- /dev/null +++ b/lib/internal/Magento/Framework/Cache/Test/Unit/Backend/RemoteSynchronizedCacheTest.php @@ -0,0 +1,260 @@ +objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + } + + /** + * @param array $options + * + * @expectedException \Zend_Cache_Exception + * @dataProvider initializeWithExceptionDataProvider + */ + public function testInitializeWithException($options) + { + $this->objectManager->getObject( + \Magento\Framework\Cache\Backend\RemoteSynchronizedCache::class, + [ + 'options' => $options, + ] + ); + } + + /** + * @return array + */ + public function initializeWithExceptionDataProvider() + { + return [ + 'empty_backend_option' => [ + 'options' => [ + 'remote_backend' => null, + 'local_backend' => null, + ], + ], + 'empty_remote_backend_option' => [ + 'options' => [ + 'remote_backend' => \Magento\Framework\Cache\Backend\Database::class, + 'local_backend' => null, + ], + ], + 'empty_local_backend_option' => [ + 'options' => [ + 'remote_backend' => null, + 'local_backend' => \Cm_Cache_Backend_File::class, + ], + ], + ]; + } + + /** + * @param array $options + * + * @dataProvider initializeWithOutExceptionDataProvider + */ + public function testInitializeWithOutException($options) + { + $result = $this->objectManager->getObject( + \Magento\Framework\Cache\Backend\RemoteSynchronizedCache::class, + [ + 'options' => $options, + ] + ); + $this->assertInstanceOf(\Magento\Framework\Cache\Backend\RemoteSynchronizedCache::class, $result); + } + + /** + * @return array + */ + public function initializeWithOutExceptionDataProvider() + { + $connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\Pdo\Mysql::class) + ->disableOriginalConstructor() + ->getMock(); + + return [ + 'not_empty_backend_option' => [ + 'options' => [ + 'remote_backend' => \Magento\Framework\Cache\Backend\Database::class, + 'remote_backend_options' => [ + 'adapter_callback' => '', + 'data_table' => 'data_table', + 'data_table_callback' => 'data_table_callback', + 'tags_table' => 'tags_table', + 'tags_table_callback' => 'tags_table_callback', + 'store_data' => '', + 'adapter' => $connectionMock, + ], + 'local_backend' => \Cm_Cache_Backend_File::class, + 'local_backend_options' => [ + 'cache_dir' => '/tmp', + ], + ], + ], + ]; + } + + /** + * @param array $options + * @param bool|string $expected + * + * @dataProvider loadDataProvider + */ + public function testLoad($options, $expected) + { + /** @var \Magento\Framework\Cache\Backend\Database $database */ + $database = $this->objectManager->getObject( + \Magento\Framework\Cache\Backend\RemoteSynchronizedCache::class, + [ + 'options' => $options, + ] + ); + + $this->assertEquals($expected, $database->load(5)); + } + + /** + * @return array + */ + public function loadDataProvider() + { + return [ + 'cacheInvalidationTime_is_less_than_that_dataModificationTime' => [ + 'options' => [ + 'remote_backend' => $this->getDatabaseMock(444), + 'local_backend' => $this->getFileMock(555, 'loaded_value'), + ], + 'expected' => 'loaded_value', + ], + 'cacheInvalidationTime_is_greater_than_that_dataModificationTime' => [ + 'options' => [ + 'remote_backend' => $this->getDatabaseMock(444), + 'local_backend' => $this->getFileMock(333, 'loaded_value'), + ], + 'expected' => false, + ], + 'cacheInvalidationTime_is_equal_to_the_dataModificationTime' => [ + 'options' => [ + 'remote_backend' => $this->getDatabaseMock(444), + 'local_backend' => $this->getFileMock(444, 'loaded_value'), + ], + 'expected' => 'loaded_value', + ], + ]; + } + + /** + * @param integer $cacheInvalidationTime + * @return \Magento\Framework\Cache\Backend\Database|\PHPUnit_Framework_MockObject_MockObject + */ + public function getDatabaseMock($cacheInvalidationTime) + { + $databaseMock = $this->getMockBuilder(\Magento\Framework\Cache\Backend\Database::class) + ->setMethods(['load']) + ->disableOriginalConstructor() + ->getMock(); + $databaseMock->expects($this->once()) + ->method('load') + ->will($this->returnValue($cacheInvalidationTime)); + + return $databaseMock; + } + + /** + * @param integer $dataModificationTime + * @return \Cm_Cache_Backend_File|\PHPUnit_Framework_MockObject_MockObject + */ + public function getFileMock($dataModificationTime, $cacheResult) + { + $fileMock = $this->getMockBuilder(\Cm_Cache_Backend_File::class) + ->setMethods(['test', 'load']) + ->disableOriginalConstructor() + ->getMock(); + $fileMock->expects($this->once()) + ->method('test') + ->will($this->returnValue($dataModificationTime)); + $fileMock->expects($this->any()) + ->method('load') + ->will($this->returnValue($cacheResult)); + + return $fileMock; + } + + public function testRemove() + { + $databaseMock = $this->getMockBuilder(\Magento\Framework\Cache\Backend\Database::class) + ->setMethods(['save']) + ->disableOriginalConstructor() + ->getMock(); + $databaseMock->expects($this->once()) + ->method('save') + ->will($this->returnValue(true)); + + $fileMock = $this->getMockBuilder(\Cm_Cache_Backend_File::class) + ->setMethods(['remove']) + ->disableOriginalConstructor() + ->getMock(); + $fileMock->expects($this->once()) + ->method('remove') + ->will($this->returnValue(true)); + + /** @var \Magento\Framework\Cache\Backend\Database $database */ + $database = $this->objectManager->getObject( + \Magento\Framework\Cache\Backend\RemoteSynchronizedCache::class, + [ + 'options' => [ + 'remote_backend' => $databaseMock, + 'local_backend' => $fileMock, + ] + ] + ); + + $this->assertEquals(true, $database->remove(5)); + } + + public function testClean() + { + $databaseMock = $this->getMockBuilder(\Magento\Framework\Cache\Backend\Database::class) + ->setMethods(['save']) + ->disableOriginalConstructor() + ->getMock(); + $databaseMock->expects($this->once()) + ->method('save') + ->will($this->returnValue(true)); + + $fileMock = $this->getMockBuilder(\Cm_Cache_Backend_File::class) + ->setMethods(['clean']) + ->disableOriginalConstructor() + ->getMock(); + $fileMock->expects($this->once()) + ->method('clean') + ->will($this->returnValue(true)); + + /** @var \Magento\Framework\Cache\Backend\Database $database */ + $database = $this->objectManager->getObject( + \Magento\Framework\Cache\Backend\RemoteSynchronizedCache::class, + [ + 'options' => [ + 'remote_backend' => $databaseMock, + 'local_backend' => $fileMock, + ] + ] + ); + + $this->assertEquals(true, $database->clean()); + } +} diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php index 61631e94d6dd6..7dc88c4369858 100644 --- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php +++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php @@ -2017,11 +2017,11 @@ public function insertArray($table, array $columns, array $data, $strategy = 0) } switch ($strategy) { - case self::INSERT_ON_DUPLICATE: + case self::REPLACE: $query = $this->_getReplaceSqlQuery($table, $columns, $values); break; default: - $query = $this->_getInsertSqlQuery($table, $columns, $values); + $query = $this->_getInsertSqlQuery($table, $columns, $values, $strategy); } // execute the statement and return the number of affected rows @@ -3688,16 +3688,18 @@ protected function _prepareInsertData($row, &$bind) * @param string $tableName * @param array $columns * @param array $values + * @param null|int $strategy * @return string */ - protected function _getInsertSqlQuery($tableName, array $columns, array $values) + protected function _getInsertSqlQuery($tableName, array $columns, array $values, $strategy = null) { $tableName = $this->quoteIdentifier($tableName, true); $columns = array_map([$this, 'quoteIdentifier'], $columns); $columns = implode(',', $columns); $values = implode(', ', $values); + $strategy = $strategy === self::INSERT_IGNORE ? 'IGNORE' : ''; - $insertSql = sprintf('INSERT INTO %s (%s) VALUES %s', $tableName, $columns, $values); + $insertSql = sprintf('INSERT %s INTO %s (%s) VALUES %s', $strategy, $tableName, $columns, $values); return $insertSql; } diff --git a/lib/internal/Magento/Framework/DB/Test/Unit/Adapter/Pdo/MysqlTest.php b/lib/internal/Magento/Framework/DB/Test/Unit/Adapter/Pdo/MysqlTest.php index 2085018e8fe7a..c86f097520462 100644 --- a/lib/internal/Magento/Framework/DB/Test/Unit/Adapter/Pdo/MysqlTest.php +++ b/lib/internal/Magento/Framework/DB/Test/Unit/Adapter/Pdo/MysqlTest.php @@ -464,7 +464,7 @@ public function testInsertOnDuplicateWithQuotedColumnName() 'insert' => 'insertValue', ]; $fields = ['select', 'insert']; - $sqlQuery = "INSERT INTO `some_table` (`index`,`row`,`select`,`insert`) VALUES (?, ?, ?, ?) " + $sqlQuery = "INSERT INTO `some_table` (`index`,`row`,`select`,`insert`) VALUES (?, ?, ?, ?) " . "ON DUPLICATE KEY UPDATE `select` = VALUES(`select`), `insert` = VALUES(`insert`)"; $stmtMock = $this->createMock(\Zend_Db_Statement_Pdo::class); diff --git a/lib/internal/Magento/Framework/Stdlib/StringUtils.php b/lib/internal/Magento/Framework/Stdlib/StringUtils.php index 2ef7f3e79cd05..35decd7dab0a0 100644 --- a/lib/internal/Magento/Framework/Stdlib/StringUtils.php +++ b/lib/internal/Magento/Framework/Stdlib/StringUtils.php @@ -148,7 +148,7 @@ public function split($value, $length = 1, $keepWords = false, $trim = false, $w */ public function strlen($string) { - return iconv_strlen($string, self::ICONV_CHARSET); + return mb_strlen($string, self::ICONV_CHARSET); } /** @@ -159,15 +159,11 @@ public function strlen($string) */ public function cleanString($string) { - if ('"libiconv"' == ICONV_IMPL) { - return iconv(self::ICONV_CHARSET, self::ICONV_CHARSET . '//IGNORE', $string); - } else { - return $string; - } + return mb_convert_encoding($string, self::ICONV_CHARSET); } /** - * Pass through to iconv_substr() + * Pass through to mb_substr() * * @param string $string * @param int $offset @@ -180,7 +176,7 @@ public function substr($string, $offset, $length = null) if ($length === null) { $length = $this->strlen($string) - $offset; } - return iconv_substr($string, $offset, $length, self::ICONV_CHARSET); + return mb_substr($string, $offset, $length, self::ICONV_CHARSET); } /** @@ -212,6 +208,6 @@ public function strrev($str) */ public function strpos($haystack, $needle, $offset = null) { - return iconv_strpos($haystack, $needle, $offset, self::ICONV_CHARSET); + return mb_strpos($haystack, $needle, $offset, self::ICONV_CHARSET); } } diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index b09ee3dc0b331..06f41bc36ad9f 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -12421,29 +12421,12 @@ adminUserList.add(vars.get("admin_user")); - - - - - continue - - false - ${loops} - - ${csrPoolUsers} - ${ramp_period} - 1505803944000 - 1505803944000 - false - - - mpaf/tool/fragments/_system/thread_group.jmx - - + + 1 false 1 - ${adminReturnsManagementPercentage} + ${adminProductCreationPercentage} mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx @@ -12464,7 +12447,7 @@ if (testLabel - vars.put("testLabel", "Admin Returns Management"); + vars.put("testLabel", "Admin Create Product"); true @@ -12669,8530 +12652,352 @@ vars.put("admin_user", adminUser); - + + mpaf/tool/fragments/ce/once_only_controller.jmx + + + + mpaf/tool/fragments/ce/admin_create_product/get_related_product_id.jmx + import org.apache.jmeter.samplers.SampleResult; +import java.util.Random; +Random random = new Random(); +if (${seedForRandom} > 0) { + random.setSeed(${seedForRandom}); +} +relatedIndex = random.nextInt(props.get("simple_products_list").size()); +vars.put("related_product_id", props.get("simple_products_list").get(relatedIndex).get("id")); + + + true + + + + mpaf/tool/fragments/ce/simple_controller.jmx - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_process_returns/orders_page.jmx - - - - Create New Order - - Assertion.response_data - false - 2 - - - - - - - - - true - sales_order_grid - = - true - namespace - - - true - - = - true - search - - - true - true - = - true - filters[placeholder] - - - true - 200 - = - true - paging[pageSize] - - - true - 1 - = - true - paging[current] - - - true - increment_id - = - true - sorting[field] - - - true - desc - = - true - sorting[direction] - - - true - true - = - true - isAjax - - - true - ${admin_form_key} - = - true - form_key - false - - - true - pending - = - true - filters[status] - true + + + + Content-Type + application/json - - true - ${__time()}${__Random(1,1000000)} - = - true - _ + + Accept + */* - - - - - - ${request_protocol} - - ${base_path}${admin_path}/mui/index/render/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_process_returns/open_orders.jmx - - - - totalRecords + mpaf/tool/fragments/ce/api/header_manager_before_token.jmx + + + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/integration/admin/token + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/admin_token_retrieval.jmx + + + admin_token + $ + + + BODY + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + admin_token + + + + + + + + Authorization + Bearer ${admin_token} + - Assertion.response_data - false - 2 - + mpaf/tool/fragments/ce/api/header_manager.jmx - - - - - - - true - ${admin_form_key} - = - true - form_key - - - true - sales_order_grid - = - true - namespace - true - - - true - - = - true - search - true - - - true - true - = - true - filters[placeholder] - true - - - true - 200 - = - true - paging[pageSize] - true - - - true - 1 - = - true - paging[current] - true - - - true - increment_id - = - true - sorting[field] - true - - - true - asc - = - true - sorting[direction] - true - - - true - true - = - true - isAjax - true - - - true - pending - = - true - filters[status] - - - true - ${__time()}${__Random(1,1000000)} - = - true - _ - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/mui/index/render/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_process_returns/search_orders.jmx - - - - totalRecords + + + + + + false + mycolor + = + true + searchCriteria[filterGroups][0][filters][0][value] + + + false + attribute_code + = + true + searchCriteria[filterGroups][0][filters][0][field] + + + false + mysize + = + true + searchCriteria[filterGroups][0][filters][1][value] + + + false + attribute_code + = + true + searchCriteria[filterGroups][0][filters][1][field] + - Assertion.response_data - false - 2 - + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products/attributes + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_product/get_product_attributes.jmx + + + product_attributes + $.items + + + BODY + - - false - order_numbers - \"increment_id\":\"(\d+)\"\, - $1$ - - -1 - simple_products - + + javascript + + + + +var attributesData = JSON.parse(vars.get("product_attributes")), +maxOptions = 2; + +attributes = []; +for (i in attributesData) { + if (i >= 2) { + break; + } + var data = attributesData[i], + attribute = { + "id": data.attribute_id, + "code": data.attribute_code, + "label": data.default_frontend_label, + "options": [] + }; + + var processedOptions = 0; + for (optionN in data.options) { + var option = data.options[optionN]; + if (parseInt(option.value) > 0 && processedOptions < maxOptions) { + processedOptions++; + attribute.options.push(option); + } + } + attributes.push(attribute); +} + +vars.putObject("product_attributes", attributes); + + - + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/catalog/product_set/index/filter/${attribute_set_filter} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_product/configurable_setup_attribute_set.jmx + + + false - order_ids - \"entity_id\":\"(\d+)\"\, + attribute_set_id + catalog\/product_set\/edit\/id\/([\d]+)\/"[\D\d]*Attribute Set 1 $1$ - -1 - simple_products + 1 - - - - mpaf/tool/fragments/ce/admin_create_process_returns/setup.jmx - - import java.util.ArrayList; - import java.util.HashMap; - import org.apache.jmeter.protocol.http.util.Base64Encoder; - import java.util.Random; + + false + + + import org.apache.commons.codec.binary.Base64; - // get count of "order_numbers" variable defined in "Search Pending Orders Limit" - int ordersCount = Integer.parseInt(vars.get("order_numbers_matchNr")); - - - int clusterLength; - int threadsNumber = ctx.getThreadGroup().getNumThreads(); - if (threadsNumber == 0) { - //Number of orders for one thread - clusterLength = ordersCount; - } else { - clusterLength = Math.round(ordersCount / threadsNumber); - if (clusterLength == 0) { - clusterLength = 1; - } - } - - //Current thread number starts from 0 - int currentThreadNum = ctx.getThreadNum(); - - //Index of the current product from the cluster - Random random = new Random(); - if (${seedForRandom} > 0) { - random.setSeed(${seedForRandom} + ${__threadNum}); - } - int iterator = random.nextInt(clusterLength); - if (iterator == 0) { - iterator = 1; - } +byte[] encodedBytes = Base64.encodeBase64("set_name=Attribute Set 1".getBytes()); +vars.put("attribute_set_filter", new String(encodedBytes)); + + + + + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + import org.apache.jmeter.samplers.SampleResult; +import java.util.Random; +Random random = new Random(); +if (${seedForRandom} > 0) { + random.setSeed(${seedForRandom}); +} +number = random.nextInt(props.get("simple_products_list").size()); +simpleList = props.get("simple_products_list").get(number); +vars.put("simple_product_1_id", simpleList.get("id")); +vars.put("simple_product_1_name", simpleList.get("title")); - int i = clusterLength * currentThreadNum + iterator; +do { + number1 = random.nextInt(props.get("simple_products_list").size()); +} while(number == number1); +simpleList = props.get("simple_products_list").get(number1); +vars.put("simple_product_2_id", simpleList.get("id")); +vars.put("simple_product_2_name", simpleList.get("title")); - orderNumber = vars.get("order_numbers_" + i.toString()); - orderId = vars.get("order_ids_" + i.toString()); - vars.put("order_number", orderNumber); - vars.put("order_id", orderId); +number2 = random.nextInt(props.get("configurable_products_list").size()); +configurableList = props.get("configurable_products_list").get(number2); +vars.put("configurable_product_1_id", configurableList.get("id")); +vars.put("configurable_product_1_url_key", configurableList.get("url_key")); +vars.put("configurable_product_1_name", configurableList.get("title")); - - - - false - - +//Additional category to be added +//int categoryId = Integer.parseInt(vars.get("simple_product_category_id")); +//vars.put("category_additional", (categoryId+1).toString()); +//New price +vars.put("price_new", "9999"); +//New special price +vars.put("special_price_new", "8888"); +//New quantity +vars.put("quantity_new", "100600"); +vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNum}-${__Random(1,1000000)}"); - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order/view/order_id/${order_id}/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_process_returns/open_order.jmx - - - - #${order_number} - - Assertion.response_data - false - 2 - - - - false - order_status - <span id="order_status">([^<]+)</span> - $1$ - - 1 - simple_products - + + + + true + mpaf/tool/fragments/ce/admin_create_product/setup.jmx - - - - "${order_status}" == "Pending" - false - mpaf/tool/fragments/ce/admin_edit_order/if_controller.jmx + + + mpaf/tool/fragments/ce/admin_create_product/create_bundle_product.jmx + - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order_invoice/start/order_id/${order_id}/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_process_returns/invoice_start.jmx - - - - Invoice Totals - - Assertion.response_data - false - 2 - - - - false - item_ids - <div id="order_item_(\d+)_title"\s*class="product-title"> - $1$ - - -1 - simple_products - - - - - - - - - true - ${admin_form_key} - = - true - form_key - false - - - true - 1 - = - true - invoice[items][${item_ids_1}] - - - true - 1 - = - true - invoice[items][${item_ids_2}] + + + - - true - Invoiced - = - true - invoice[comment_text] + + + + + ${request_protocol} + + ${base_path}${admin_path}/catalog/product/ + GET + true + false + true + false + false + + + + + + records found + + Assertion.response_data + false + 2 + + + + + + - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order_invoice/save/order_id/${order_id}/ - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_process_returns/invoice_submit.jmx - - - - The invoice has been created - - Assertion.response_data - false - 2 - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order_creditmemo/start/order_id/${order_id}/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_process_returns/credit_memo_start.jmx - - - - New Memo - - Assertion.response_data - false - 2 - - - - - - - - - true - ${admin_form_key} - = - true - form_key - false - - - true - 1 - = - true - creditmemo[items][${item_ids_1}][qty] - - - true - 1 - = - true - creditmemo[items][${item_ids_2}][qty] - - - true - 1 - = - true - creditmemo[do_offline] - - - true - Credit Memo added - = - true - creditmemo[comment_text] - - - true - 10 - = - true - creditmemo[shipping_amount] - - - true - 0 - = - true - creditmemo[adjustment_positive] - - - true - 0 - = - true - creditmemo[adjustment_negative] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order_creditmemo/save/order_id/${order_id}/ - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_process_returns/credit_memo_full_refund.jmx - - - - You created the credit memo - - Assertion.response_data - false - 2 - - - - - - 1 - 0 - ${__javaScript(Math.round(${adminCreateProcessReturnsDelay}*1000))} - mpaf/tool/fragments/ce/admin_create_process_returns/pause.jmx - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/auth/logout/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/setup/admin_logout.jmx - - - - false - - - -adminUserList = props.get("adminUserList"); -adminUserList.add(vars.get("admin_user")); - - mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx - - - - - - - 1 - false - 1 - ${browseCustomerGridPercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "Browse Customer Grid"); - - true - - - - - - function getFormKeyFromResponse() - { - var url = prev.getUrlAsString(), - responseCode = prev.getResponseCode(), - formKey = null; - searchPattern = /var FORM_KEY = '(.+)'/; - if (responseCode == "200" && url) { - response = prev.getResponseDataAsString(); - formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; - } - return formKey; - } - - formKey = vars.get("form_key_storage"); - - currentFormKey = getFormKeyFromResponse(); - - if (currentFormKey != null && currentFormKey != formKey) { - vars.put("form_key_storage", currentFormKey); - } - - javascript - mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx - - - - formKey = vars.get("form_key_storage"); - if (formKey - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' - && sampler.getMethod() == "POST") - { - arguments = sampler.getArguments(); - for (i=0; i<arguments.getArgumentCount(); i++) - { - argument = arguments.getArgument(i); - if (argument.getName() == 'form_key' && argument.getValue() != formKey) { - log.info("admin form key updated: " + argument.getValue() + " => " + formKey); - argument.setValue(formKey); - } - } - } - - javascript - - - - - - false - mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - get-admin-email - mpaf/tool/fragments/ce/lock_controller.jmx - - - - mpaf/tool/fragments/ce/get_admin_email.jmx - -adminUserList = props.get("adminUserList"); -adminUser = adminUserList.poll(); -if (adminUser == null) { - SampleResult.setResponseMessage("adminUser list is empty"); - SampleResult.setResponseData("adminUser list is empty","UTF-8"); - IsSuccess=false; - SampleResult.setSuccessful(false); - SampleResult.setStopThread(true); -} -vars.put("admin_user", adminUser); - - - - true - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_login/admin_login.jmx - - - - Welcome - <title>Magento Admin</title> - - Assertion.response_data - false - 2 - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - admin_form_key - - - - - - - - - true - - = - true - dummy - - - true - ${admin_form_key} - = - true - form_key - - - true - ${admin_password} - = - true - login[password] - - - true - ${admin_user} - = - true - login[username] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/dashboard/ - POST - true - false - true - false - Java - false - - mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx - - - - - - - vars.put("gridEntityType" , "Customer"); - - pagesCount = parseInt(vars.get("customers_page_size")) || 20; - vars.put("grid_entity_page_size" , pagesCount); - vars.put("grid_namespace" , "customer_listing"); - vars.put("grid_admin_browse_filter_text" , vars.get("admin_browse_customer_filter_text")); - vars.put("grid_filter_field", "name"); - - // set sort fields and sort directions - vars.put("grid_sort_field_1", "name"); - vars.put("grid_sort_field_2", "group_id"); - vars.put("grid_sort_field_3", "billing_country_id"); - vars.put("grid_sort_order_1", "asc"); - vars.put("grid_sort_order_2", "desc"); - - javascript - mpaf/tool/fragments/ce/admin_browse_customers_grid/setup.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - - - - true - ${grid_namespace} - = - true - namespace - true - - - true - - = - true - search - true - - - true - true - = - true - filters[placeholder] - true - - - true - ${grid_entity_page_size} - = - true - paging[pageSize] - true - - - true - 1 - = - true - paging[current] - true - - - true - entity_id - = - true - sorting[field] - true - - - true - asc - = - true - sorting[direction] - true - - - true - true - = - true - isAjax - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/mui/index/render/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_grid_browsing/set_pages_count.jmx - - - $.totalRecords - 0 - true - false - true - - - - entity_total_records - $.totalRecords - - - BODY - - - - - - - - var pageSize = parseInt(vars.get("grid_entity_page_size")) || 20; - var totalsRecord = parseInt(vars.get("entity_total_records")); - var pageCount = Math.round(totalsRecord/pageSize); - - vars.put("grid_pages_count", pageCount); - - javascript - - - - - - - - - true - ${grid_namespace} - = - true - namespace - true - - - true - - = - true - search - true - - - true - ${grid_admin_browse_filter_text} - = - true - filters[placeholder] - true - - - true - ${grid_entity_page_size} - = - true - paging[pageSize] - true - - - true - 1 - = - true - paging[current] - true - - - true - entity_id - = - true - sorting[field] - true - - - true - asc - = - true - sorting[direction] - true - - - true - true - = - true - isAjax - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/mui/index/render/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_grid_browsing/set_filtered_pages_count.jmx - - - $.totalRecords - 0 - true - false - true - true - - - - entity_total_records - $.totalRecords - - - BODY - - - - - - - var pageSize = parseInt(vars.get("grid_entity_page_size")) || 20; -var totalsRecord = parseInt(vars.get("entity_total_records")); -var pageCount = Math.round(totalsRecord/pageSize); - -vars.put("grid_pages_count_filtered", pageCount); - - javascript - - - - - - 1 - ${grid_pages_count} - 1 - page_number - - true - false - mpaf/tool/fragments/ce/admin_grid_browsing/select_page_number.jmx - - - - - - - true - ${grid_namespace} - = - true - namespace - true - - - true - - = - true - search - true - - - true - true - = - true - filters[placeholder] - true - - - true - ${grid_entity_page_size} - = - true - paging[pageSize] - true - - - true - ${page_number} - = - true - paging[current] - true - - - true - entity_id - = - true - sorting[field] - true - - - true - asc - = - true - sorting[direction] - true - - - true - true - = - true - isAjax - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/mui/index/render/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_grid_browsing/admin_browse_grid.jmx - - - - \"totalRecords\":[^0]\d* - - Assertion.response_data - false - 2 - - - - - - 1 - ${grid_pages_count_filtered} - 1 - page_number - - true - false - mpaf/tool/fragments/ce/admin_grid_browsing/select_filtered_page_number.jmx - - - - mpaf/tool/fragments/ce/admin_grid_browsing/admin_browse_grid_sort_and_filter.jmx - - - - grid_sort_field - grid_sort_field - true - 0 - 3 - - - - grid_sort_order - grid_sort_order - true - 0 - 2 - - - - - - - true - ${grid_namespace} - = - true - namespace - false - - - true - ${grid_admin_browse_filter_text} - = - true - filters[${grid_filter_field}] - false - - - true - true - = - true - filters[placeholder] - false - - - true - ${grid_entity_page_size} - = - true - paging[pageSize] - false - - - true - ${page_number} - = - true - paging[current] - false - - - true - ${grid_sort_field} - = - true - sorting[field] - false - - - true - ${grid_sort_order} - = - true - sorting[direction] - false - - - true - true - = - true - isAjax - false - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/mui/index/render/ - GET - true - false - true - false - false - - - - - - \"totalRecords\":[^0]\d* - - Assertion.response_data - false - 2 - - - - - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/auth/logout/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/setup/admin_logout.jmx - - - - false - - - -adminUserList = props.get("adminUserList"); -adminUserList.add(vars.get("admin_user")); - - mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx - - - - - - - 1 - false - 1 - ${adminCreateOrderPercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "Admin Create Order"); - - true - - - - - - function getFormKeyFromResponse() - { - var url = prev.getUrlAsString(), - responseCode = prev.getResponseCode(), - formKey = null; - searchPattern = /var FORM_KEY = '(.+)'/; - if (responseCode == "200" && url) { - response = prev.getResponseDataAsString(); - formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; - } - return formKey; - } - - formKey = vars.get("form_key_storage"); - - currentFormKey = getFormKeyFromResponse(); - - if (currentFormKey != null && currentFormKey != formKey) { - vars.put("form_key_storage", currentFormKey); - } - - javascript - mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx - - - - formKey = vars.get("form_key_storage"); - if (formKey - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' - && sampler.getMethod() == "POST") - { - arguments = sampler.getArguments(); - for (i=0; i<arguments.getArgumentCount(); i++) - { - argument = arguments.getArgument(i); - if (argument.getName() == 'form_key' && argument.getValue() != formKey) { - log.info("admin form key updated: " + argument.getValue() + " => " + formKey); - argument.setValue(formKey); - } - } - } - - javascript - - - - - - false - mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - get-admin-email - mpaf/tool/fragments/ce/lock_controller.jmx - - - - mpaf/tool/fragments/ce/get_admin_email.jmx - -adminUserList = props.get("adminUserList"); -adminUser = adminUserList.poll(); -if (adminUser == null) { - SampleResult.setResponseMessage("adminUser list is empty"); - SampleResult.setResponseData("adminUser list is empty","UTF-8"); - IsSuccess=false; - SampleResult.setSuccessful(false); - SampleResult.setStopThread(true); -} -vars.put("admin_user", adminUser); - - - - true - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_login/admin_login.jmx - - - - Welcome - <title>Magento Admin</title> - - Assertion.response_data - false - 2 - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - admin_form_key - - - - - - - - - true - - = - true - dummy - - - true - ${admin_form_key} - = - true - form_key - - - true - ${admin_password} - = - true - login[password] - - - true - ${admin_user} - = - true - login[username] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/dashboard/ - POST - true - false - true - false - Java - false - - mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx - - - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - - - mpaf/tool/fragments/ce/admin_create_order/admin_create_order.jmx - import org.apache.jmeter.samplers.SampleResult; -import java.util.Random; -Random random = new Random(); -if (${seedForRandom} > 0) { - random.setSeed(${seedForRandom}); -} -number = random.nextInt(props.get("simple_products_list").size()); -simpleList = props.get("simple_products_list").get(number); -vars.put("simple_product_1_url_key", simpleList.get("url_key")); -vars.put("simple_product_1_name", simpleList.get("title")); -vars.put("simple_product_1_id", simpleList.get("id")); - -do { - number1 = random.nextInt(props.get("simple_products_list").size()); -} while(number == number1); -simpleList = props.get("simple_products_list").get(number1); -vars.put("simple_product_2_url_key", simpleList.get("url_key")); -vars.put("simple_product_2_name", simpleList.get("title")); -vars.put("simple_product_2_id", simpleList.get("id")); - -number = random.nextInt(props.get("configurable_products_list").size()); -configurableList = props.get("configurable_products_list").get(number); -vars.put("configurable_product_1_url_key", configurableList.get("url_key")); -vars.put("configurable_product_1_name", configurableList.get("title")); -vars.put("configurable_product_1_id", configurableList.get("id")); -vars.put("configurable_product_1_sku", configurableList.get("sku")); -vars.put("configurable_attribute_id", configurableList.get("attribute_id")); -vars.put("configurable_option_id", configurableList.get("attribute_option_id")); - - -customers_index = 0; -if (!props.containsKey("customer_ids_index")) { - props.put("customer_ids_index", customers_index); -} - -try { - customers_index = props.get("customer_ids_index"); - customers_list = props.get("customer_ids_list"); - - if (customers_index == customers_list.size()) { - customers_index=0; - } - vars.put("customer_id", customers_list.get(customers_index)); - props.put("customer_ids_index", ++customers_index); -} -catch (java.lang.Exception e) { - log.error("Caught Exception in 'Admin Create Order' thread."); - SampleResult.setStopThread(true); -} - - - true - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order_create/start/ - GET - true - false - true - false - false - - Detected the start of a redirect chain - - - - - - - - Content-Type - application/json - - - Accept - */* - - - - - - true - - - - false - {"username":"${admin_user}","password":"${admin_password}"} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/V1/integration/admin/token - POST - true - false - true - false - false - - - - - admin_token - $ - - - BODY - - - - - ^[a-z0-9-]+$ - - Assertion.response_data - false - 1 - variable - admin_token - - - - - - - Authorization - Bearer ${admin_token} - - - - - - - - - - - - - ${request_protocol} - - ${base_path}rest/V1/configurable-products/${configurable_product_1_sku}/options/all - GET - true - false - true - false - false - - - - - attribute_ids - $.[*].attribute_id - NO_VALUE - - BODY - - - - option_values - $.[*].values[0].value_index - NO_VALUE - - BODY - - - - - - - - - true - item[${simple_product_1_id}][qty] - 1 - = - true - - - true - item[${simple_product_2_id}][qty] - 1 - = - true - - - true - item[${configurable_product_1_id}][qty] - 1 - = - true - - - true - customer_id - ${customer_id} - = - true - - - true - store_id - 1 - = - true - - - true - currency_id - - = - true - - - true - form_key - ${admin_form_key} - = - true - - - true - payment[method] - checkmo - = - true - - - true - reset_shipping - 1 - = - true - - - true - json - 1 - = - true - - - true - as_js_varname - iFrameResponse - = - true - - - true - form_key - ${admin_form_key} - = - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order_create/loadBlock/block/search,items,shipping_method,totals,giftmessage,billing_method?isAjax=true - POST - true - false - true - false - false - - Detected the start of a redirect chain - - - - false - - - try { - attribute_ids = vars.get("attribute_ids"); - option_values = vars.get("option_values"); - attribute_ids = attribute_ids.replace("[","").replace("]","").replace("\"", ""); - option_values = option_values.replace("[","").replace("]","").replace("\"", ""); - attribute_ids_array = attribute_ids.split(","); - option_values_array = option_values.split(","); - args = ctx.getCurrentSampler().getArguments(); - it = args.iterator(); - while (it.hasNext()) { - argument = it.next(); - if (argument.getStringValue().contains("${")) { - args.removeArgument(argument.getName()); - } - } - for (int i = 0; i < attribute_ids_array.length; i++) { - - ctx.getCurrentSampler().addArgument("item[" + vars.get("configurable_product_1_id") + "][super_attribute][" + attribute_ids_array[i] + "]", option_values_array[i]); - } -} catch (Exception e) { - log.error("error???", e); -} - - - - - - - - true - collect_shipping_rates - 1 - = - true - - - true - customer_id - ${customer_id} - = - true - - - true - store_id - 1 - = - true - - - true - currency_id - false - = - true - - - true - form_key - ${admin_form_key} - = - true - - - true - payment[method] - checkmo - = - true - - - true - json - true - = - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order_create/loadBlock/block/shipping_method,totals?isAjax=true - POST - true - false - true - false - false - - - - - - shipping_method - Flat Rate - - Assertion.response_data - false - 2 - - - - - - - - true - form_key - ${admin_form_key} - = - true - - - true - limit - 20 - = - true - - - true - entity_id - - = - true - - - true - name - - = - true - - - true - email - - = - true - - - true - Telephone - - = - true - - - true - billing_postcode - - = - true - - - true - billing_country_id - - = - true - - - true - billing_regione - - = - true - - - true - store_name - - = - true - - - true - page - 1 - = - true - - - true - order[currency] - USD - = - true - - - true - sku - - = - true - - - true - qty - - = - true - - - true - limit - 20 - = - true - - - true - entity_id - - = - true - - - true - name - - = - true - - - true - sku - - = - true - - - true - price[from] - - = - true - - - true - price[to] - - = - true - - - true - in_products - - = - true - - - true - page - 1 - = - true - - - true - coupon_code - - = - true - - - true - order[account][group_id] - 1 - = - true - - - true - order[account][email] - user_${customer_id}@example.com - = - true - - - true - order[billing_address][customer_address_id] - - = - true - - - true - order[billing_address][prefix] - - = - true - - - true - order[billing_address][firstname] - Anthony - = - true - - - true - order[billing_address][middlename] - - = - true - - - true - order[billing_address][lastname] - Nealy - = - true - - - true - order[billing_address][suffix] - - = - true - - - true - order[billing_address][company] - - = - true - - - true - order[billing_address][street][0] - 123 Freedom Blvd. #123 - = - true - - - true - order[billing_address][street][1] - - = - true - - - true - order[billing_address][city] - Fayetteville - = - true - - - true - order[billing_address][country_id] - US - = - true - - - true - order[billing_address][region] - - = - true - - - true - order[billing_address][region_id] - 5 - = - true - - - true - order[billing_address][postcode] - 123123 - = - true - - - true - order[billing_address][telephone] - 022-333-4455 - = - true - - - true - order[billing_address][fax] - - = - true - - - true - order[billing_address][vat_id] - - = - true - - - true - shipping_same_as_billing - on - = - true - - - true - payment[method] - checkmo - = - true - - - true - order[shipping_method] - flatrate_flatrate - = - true - - - true - order[comment][customer_note] - - = - true - - - true - order[comment][customer_note_notify] - 1 - = - true - - - true - order[send_confirmation] - 1 - = - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order_create/save/ - POST - true - false - true - true - false - - Detected the start of a redirect chain - - - - false - order_id - ${host}${base_path}${admin_path}/sales/order/index/order_id/(\d+)/ - $1$ - - 1 - - - - false - order_item_1 - order_item_(\d+)_title - $1$ - - 1 - - - - false - order_item_2 - order_item_(\d+)_title - $1$ - - 2 - - - - false - order_item_3 - order_item_(\d+)_title - $1$ - - 3 - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - order_id - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - order_item_1 - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - order_item_2 - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - order_item_3 - - - - - You created the order. - - Assertion.response_data - false - 2 - - - - - - - - true - form_key - ${admin_form_key} - = - true - - - true - invoice[items][${order_item_1}] - 1 - = - true - - - true - invoice[items][${order_item_2}] - 1 - = - true - - - true - invoice[items][${order_item_3}] - 1 - = - true - - - true - invoice[comment_text] - - = - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/sales/order_invoice/save/order_id/${order_id}/ - POST - true - false - true - false - false - - Detected the start of a redirect chain - - - - - The invoice has been created. - - Assertion.response_data - false - 2 - - - - - - - - true - form_key - ${admin_form_key} - = - true - - - true - shipment[items][${order_item_1}] - 1 - = - true - - - true - shipment[items][${order_item_2}] - 1 - = - true - - - true - shipment[items][${order_item_3}] - 1 - = - true - - - true - shipment[comment_text] - - = - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/order_shipment/save/order_id/${order_id}/ - POST - true - false - true - false - false - - Detected the start of a redirect chain - - - - - The shipment has been created. - - Assertion.response_data - false - 2 - - - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/auth/logout/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/setup/admin_logout.jmx - - - - false - - - -adminUserList = props.get("adminUserList"); -adminUserList.add(vars.get("admin_user")); - - mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx - - - - - - - - - continue - - false - ${loops} - - ${apiPoolUsers} - ${ramp_period} - 1505803944000 - 1505803944000 - false - - - mpaf/tool/fragments/_system/thread_group.jmx - - - 1 - false - 1 - ${apiBasePercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "API"); - - true - - - - - - - Content-Type - application/json - - - Accept - */* - - - mpaf/tool/fragments/ce/api/header_manager_before_token.jmx - - - - true - - - - false - {"username":"${admin_user}","password":"${admin_password}"} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/V1/integration/admin/token - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/admin_token_retrieval.jmx - - - admin_token - $ - - - BODY - - - - - ^[a-z0-9-]+$ - - Assertion.response_data - false - 1 - variable - admin_token - - - - - - - - Authorization - Bearer ${admin_token} - - - mpaf/tool/fragments/ce/api/header_manager.jmx - - - - 1 - false - 1 - 100 - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "API Create Customer"); - - true - - - - - true - - - - false - { - "customer": { - - "email": "customer_${__time()}-${__threadNum}-${__Random(1,1000000)}@example.com", - "firstname": "test_${__time()}-${__threadNum}-${__Random(1,1000000)}", - "lastname": "Doe" - }, - "password": "test@123" -} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/customers - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/create_customer.jmx - - - customer_id - $.id - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - customer_id - - - - - - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/customers/${customer_id} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/api/check_customer.jmx - - - $.id - ${customer_id} - true - false - false - - - - - - - - 1 - false - 1 - 100 - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "API Catalog Browsing"); - - true - - - - - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/categories - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/api/get_categories.jmx - - - - errors - - Assertion.response_data - false - 6 - variable - - - - - search_category_id - $.id - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - search_category_id - - - - - - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/categories/${search_category_id} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/api/get_category.jmx - - - - errors - - Assertion.response_data - false - 6 - variable - - - - - - - - - - true - 20 - = - true - searchCriteria[page_size] - true - - - true - 1 - = - true - searchCriteria[current_page] - true - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/api/get_products.jmx - - - - errors - - Assertion.response_data - false - 6 - variable - - - - - - - - - 1 - false - 1 - 100 - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "API Search"); - - true - - - - - - - - true - quick_search_container - = - true - searchCriteria[request_name] - - - true - search_term - = - true - searchCriteria[filter_groups][0][filters][0][field] - - - true - Simple - = - true - searchCriteria[filter_groups][0][filters][0][value] - - - true - 20 - = - true - searchCriteria[page_size] - - - true - 1 - = - true - searchCriteria[current_page] - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/search - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/api/search_for_product_frontend.jmx - - - $.total_count - 0 - true - false - true - - - - search_product_id - $.items[0].id - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - search_product_id - - - - - - - - 1 - false - 1 - 100 - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "API Checkout"); - - true - - - - - mpaf/tool/fragments/ce/common/init_random_generator_setup.jmx - -import java.util.Random; - -Random random = new Random(); -if (${seedForRandom} > 0) { - random.setSeed(${seedForRandom} + ${__threadNum}); -} - -vars.putObject("randomIntGenerator", random); - - - - true - - - - - -import java.util.Random; - -Random random = vars.getObject("randomIntGenerator"); -number = random.nextInt(props.get("simple_products_list").size()); -product = props.get("simple_products_list").get(number); - -vars.put("product_url_key", product.get("url_key")); -vars.put("product_id", product.get("id")); -vars.put("product_name", product.get("title")); -vars.put("product_uenc", product.get("uenc")); -vars.put("product_sku", product.get("sku")); - - - - true - mpaf/tool/fragments/ce/product_browsing_and_adding_items_to_the_cart/simple_products_setup.jmx - - - - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/carts - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/create_quote.jmx - - - quote_id - $ - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - quote_id - - - - - - true - - - - false - { - "cartItem": { - "sku": "${product_sku}", - "qty":"1", - "quote_id":"${quote_id}" - } -} - - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/carts/${quote_id}/items - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/add_product_to_quote_hardwired_sku.jmx - - - - $.sku - ${product_sku} - true - false - false - - - - - - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/carts/${quote_id}/items - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/api/check_product_in_quote_hardwired_sku.jmx - - - $[0].sku - ${product_sku} - true - false - false - - - - - - true - - - - false - { - "storeId": 1 -} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/guest-carts/ - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/create_guest_cart.jmx - - - cart_id - $ - - - BODY - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - cart_id - - - - - - true - - - - false - { - "cartItem": { - "sku": "${product_sku}", - "qty":"1", - "quote_id":"${cart_id}" - } -} - - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/guest-carts/${cart_id}/items - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/add_product_to_guest_cart_hardwired_sku.jmx - - - $.quote_id - ^[a-z0-9-]+$ - true - false - false - - - - - - true - - - - false - { - "sender": "John Doe", - "recipient": "Jane Roe", - "giftMessage": "Gift Message Text" -} - - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/guest-carts/${cart_id}/gift-message - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/add_gift_message_to_guest_cart.jmx - - - $ - true - true - false - false - - - - - - true - - - - false - {"address":{"country_id":"US","postcode":"95630"}} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/guest-carts/${cart_id}/estimate-shipping-methods - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/guest_checkout/checkout_estimate_shipping_methods_with_postal_code.jmx - - - - - Referer - ${base_path}checkout/onepage/ - - - Content-Type - application/json; charset=UTF-8 - - - X-Requested-With - XMLHttpRequest - - - Accept - application/json - - - - - - - "available":true - - Assertion.response_data - false - 2 - - - - - - true - - - - false - {"addressInformation":{"shipping_address":{"countryId":"US","regionId":"12","regionCode":"CA","region":"California","street":["10441 Jefferson Blvd ste 200"],"company":"","telephone":"3109450345","fax":"","postcode":"90232","city":"Culver City","firstname":"Name","lastname":"Lastname"},"shipping_method_code":"flatrate","shipping_carrier_code":"flatrate"}} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/guest-carts/${cart_id}/shipping-information - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/guest_checkout/checkout_billing_shipping_information.jmx - - - - - Referer - ${base_path}checkout/onepage/ - - - Content-Type - application/json; charset=UTF-8 - - - X-Requested-With - XMLHttpRequest - - - Accept - application/json - - - - - - - {"payment_methods": - - Assertion.response_data - false - 2 - - - - - - true - - - - false - {"cartId":"${cart_id}","email":"test@example.com","paymentMethod":{"method":"checkmo","po_number":null,"additional_data":null},"billingAddress":{"countryId":"US","regionId":"12","regionCode":"CA","region":"California","street":["10441 Jefferson Blvd ste 200"],"company":"","telephone":"3109450345","fax":"","postcode":"90232","city":"Culver City","firstname":"Name","lastname":"Lastname","save_in_address_book":0}} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/guest-carts/${cart_id}/payment-information - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/checkout_payment_info_place_order.jmx - - - - - Referer - ${base_path}checkout/onepage/ - - - Content-Type - application/json; charset=UTF-8 - - - X-Requested-With - XMLHttpRequest - - - Accept - application/json - - - - - - - "[0-9]+" - - Assertion.response_data - false - 2 - - - - order_id - $ - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - order_id - - - - - - - - - - - - continue - - false - ${loops} - - ${deadLocksPoolUsers} - ${ramp_period} - 1505803944000 - 1505803944000 - false - - - mpaf/tool/fragments/_system/thread_group.jmx - - - 1 - false - 1 - ${productGridMassActionPercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "Product Grid Mass Actions"); - - true - - - - - - function getFormKeyFromResponse() - { - var url = prev.getUrlAsString(), - responseCode = prev.getResponseCode(), - formKey = null; - searchPattern = /var FORM_KEY = '(.+)'/; - if (responseCode == "200" && url) { - response = prev.getResponseDataAsString(); - formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; - } - return formKey; - } - - formKey = vars.get("form_key_storage"); - - currentFormKey = getFormKeyFromResponse(); - - if (currentFormKey != null && currentFormKey != formKey) { - vars.put("form_key_storage", currentFormKey); - } - - javascript - mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx - - - - formKey = vars.get("form_key_storage"); - if (formKey - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' - && sampler.getMethod() == "POST") - { - arguments = sampler.getArguments(); - for (i=0; i<arguments.getArgumentCount(); i++) - { - argument = arguments.getArgument(i); - if (argument.getName() == 'form_key' && argument.getValue() != formKey) { - log.info("admin form key updated: " + argument.getValue() + " => " + formKey); - argument.setValue(formKey); - } - } - } - - javascript - - - - - - false - mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - get-admin-email - mpaf/tool/fragments/ce/lock_controller.jmx - - - - mpaf/tool/fragments/ce/get_admin_email.jmx - -adminUserList = props.get("adminUserList"); -adminUser = adminUserList.poll(); -if (adminUser == null) { - SampleResult.setResponseMessage("adminUser list is empty"); - SampleResult.setResponseData("adminUser list is empty","UTF-8"); - IsSuccess=false; - SampleResult.setSuccessful(false); - SampleResult.setStopThread(true); -} -vars.put("admin_user", adminUser); - - - - true - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_login/admin_login.jmx - - - - Welcome - <title>Magento Admin</title> - - Assertion.response_data - false - 2 - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - admin_form_key - - - - - - - - - true - - = - true - dummy - - - true - ${admin_form_key} - = - true - form_key - - - true - ${admin_password} - = - true - login[password] - - - true - ${admin_user} - = - true - login[username] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/dashboard/ - POST - true - false - true - false - Java - false - - mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx - - - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - - - - true - ${admin_form_key} - = - true - form_key - - - true - product_listing - = - true - namespace - true - - - true - - = - true - search - true - - - true - true - = - true - filters[placeholder] - true - - - true - 20 - = - true - paging[pageSize] - true - - - true - 1 - = - true - paging[current] - true - - - true - entity_id - = - true - sorting[field] - true - - - true - asc - = - true - sorting[direction] - true - - - true - true - = - true - isAjax - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/mui/index/render/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_browse_products_grid/get_product_pages_count.jmx - - - $.totalRecords - 0 - true - false - true - - - - products_number - $.totalRecords - - - BODY - - - - false - - - var productsPageSize = Integer.parseInt(vars.get("products_page_size")); -var productsTotal = Integer.parseInt(vars.get("products_number")); -var pageCountProducts = Math.round(productsTotal/productsPageSize); - -vars.put("pages_count_product", String.valueOf(pageCountProducts)); - - - - - - -import java.util.Random; -Random random = new Random(); -if (${seedForRandom} > 0) { -random.setSeed(${seedForRandom}); -} -var productsPageSize = Integer.parseInt(vars.get("products_page_size")); -var totalNumberOfPages = Integer.parseInt(vars.get("pages_count_product")); - -// Randomly select a page. -var randomProductsPage = random.nextInt(totalNumberOfPages) + 1; - -// Get the first and last product id on that page. -var lastProductIdOnPage = randomProductsPage * productsPageSize; -var firstProductIdOnPage = lastProductIdOnPage - productsPageSize + 1; - -var randomProductId1 = Math.floor(random.nextInt(productsPageSize)) + firstProductIdOnPage; -var randomProductId2 = Math.floor(random.nextInt(productsPageSize)) + firstProductIdOnPage; -var randomProductId3 = Math.floor(random.nextInt(productsPageSize)) + firstProductIdOnPage; - -vars.put("page_number", String.valueOf(randomProductsPage)); -vars.put("productId1", String.valueOf(randomProductId1)); -vars.put("productId2", String.valueOf(randomProductId2)); -vars.put("productId3", String.valueOf(randomProductId3)); - -var randomQuantity = random.nextInt(1000) + 1; -var randomPrice = random.nextInt(500) + 10; -var randomVisibility = random.nextInt(4) + 1; - -vars.put("quantity", String.valueOf(randomQuantity)); -vars.put("price", String.valueOf(randomPrice)); -vars.put("visibility", String.valueOf(randomVisibility)); - - - - false - mpaf/tool/fragments/ce/admin_browse_products_grid/products_grid_mass_actions/setup.jmx - - - - - - - true - ${admin_form_key} - = - true - form_key - true - - - true - product_listing - = - true - namespace - true - - - true - - = - true - search - true - - - true - true - = - true - filters[placeholder] - true - - - true - ${products_page_size} - = - true - paging[pageSize] - true - - - true - ${page_number} - = - true - paging[current] - true - - - true - entity_id - = - true - sorting[field] - true - - - true - asc - = - true - sorting[direction] - true - - - true - true - = - true - isAjax - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/mui/index/render/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_browse_products_grid/products_grid_mass_actions/display_grid.jmx - - - - totalRecords - - Assertion.response_data - false - 2 - - - - - - - - - true - ${productId1} - = - true - selected[0] - - - true - ${productId2} - = - true - selected[1] - - - true - ${productId3} - = - true - selected[2] - true - - - true - true - = - true - filters[placeholder] - false - - - true - ${admin_form_key} - = - true - form_key - false - - - true - product_listing - = - true - namespace - false - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/catalog/product_action_attribute/edit - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_browse_products_grid/products_grid_mass_actions/display_update_attributes.jmx - - - - Update Attributes - - Assertion.response_data - false - 2 - - - - - - - - - true - true - = - true - isAjax - true - - - true - ${admin_form_key} - = - true - form_key - true - - - true - 1 - = - true - product[product_has_weight] - true - - - true - 1 - = - true - product[use_config_gift_message_available] - true - - - true - 1 - = - true - product[use_config_gift_wrapping_available] - true - - - true - ${quantity} - = - true - inventory[qty] - true - - - true - ${price} - = - true - attributes[price] - - - true - ${visibility} - = - true - attributes[visibility] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/catalog/product_action_attribute/validate - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_browse_products_grid/products_grid_mass_actions/change_attributes.jmx - - - - {"error":false} - - Assertion.response_data - false - 2 - - - - - - - - true - true - = - true - isAjax - false - - - true - ${admin_form_key} - = - true - form_key - false - - - true - 1 - = - true - product[product_has_weight] - true - - - true - 1 - = - true - product[use_config_gift_message_available] - - - true - 1 - = - true - product[use_config_gift_wrapping_available] - true - - - true - ${quantity} - = - true - inventory[qty] - - - true - on - = - true - toggle_price - true - - - true - ${price} - = - true - attributes[price] - - - true - on - = - true - toggle_price - true - - - true - ${visibility} - = - true - attributes[visibility] - - - true - on - = - true - toggle_visibility - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/catalog/product_action_attribute/save/store/0/active_tab/attributes - POST - true - false - true - true - false - - - - - - were updated. - - Assertion.response_data - false - 2 - - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/auth/logout/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/setup/admin_logout.jmx - - - - false - - - -adminUserList = props.get("adminUserList"); -adminUserList.add(vars.get("admin_user")); - - mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx - - - - - - - 1 - false - 1 - ${importProductsPercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "Import Products"); - - true - - - - - - function getFormKeyFromResponse() - { - var url = prev.getUrlAsString(), - responseCode = prev.getResponseCode(), - formKey = null; - searchPattern = /var FORM_KEY = '(.+)'/; - if (responseCode == "200" && url) { - response = prev.getResponseDataAsString(); - formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; - } - return formKey; - } - - formKey = vars.get("form_key_storage"); - - currentFormKey = getFormKeyFromResponse(); - - if (currentFormKey != null && currentFormKey != formKey) { - vars.put("form_key_storage", currentFormKey); - } - - javascript - mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx - - - - formKey = vars.get("form_key_storage"); - if (formKey - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' - && sampler.getMethod() == "POST") - { - arguments = sampler.getArguments(); - for (i=0; i<arguments.getArgumentCount(); i++) - { - argument = arguments.getArgument(i); - if (argument.getName() == 'form_key' && argument.getValue() != formKey) { - log.info("admin form key updated: " + argument.getValue() + " => " + formKey); - argument.setValue(formKey); - } - } - } - - javascript - - - - - - false - mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - get-admin-email - mpaf/tool/fragments/ce/lock_controller.jmx - - - - mpaf/tool/fragments/ce/get_admin_email.jmx - -adminUserList = props.get("adminUserList"); -adminUser = adminUserList.poll(); -if (adminUser == null) { - SampleResult.setResponseMessage("adminUser list is empty"); - SampleResult.setResponseData("adminUser list is empty","UTF-8"); - IsSuccess=false; - SampleResult.setSuccessful(false); - SampleResult.setStopThread(true); -} -vars.put("admin_user", adminUser); - - - - true - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_login/admin_login.jmx - - - - Welcome - <title>Magento Admin</title> - - Assertion.response_data - false - 2 - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - admin_form_key - - - - - - - - - true - - = - true - dummy - - - true - ${admin_form_key} - = - true - form_key - - - true - ${admin_password} - = - true - login[password] - - - true - ${admin_user} - = - true - login[username] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/dashboard/ - POST - true - false - true - false - Java - false - - mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx - - - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - vars.put("entity", "catalog_product"); -String behavior = "${adminImportProductBehavior}"; -vars.put("adminImportBehavior", behavior); -String filepath = "${files_folder}${adminImportProductFilePath}"; -vars.put("adminImportFilePath", filepath); - - - true - mpaf/tool/fragments/ce/import_products/setup.jmx - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/import/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/common/import.jmx - - - - Import Settings - - Assertion.response_data - false - 2 - - - - - - - - - true - ${admin_form_key} - = - true - form_key - false - - - true - ${entity} - = - true - entity - - - true - ${adminImportBehavior} - = - true - behavior - - - true - validation-stop-on-errors - = - true - validation_strategy - - - true - 10 - = - true - allowed_error_count - - - true - , - = - true - _import_field_separator - - - true - , - = - true - _import_multiple_value_separator - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/import/validate - POST - true - false - true - false - HttpClient4 - - - - ${adminImportFilePath} - import_file - application/vnd.ms-excel - - - - false - - mpaf/tool/fragments/ce/common/import_validate.jmx - - - - File is valid! To start import process - - Assertion.response_data - false - 16 - - - - - - - - - true - ${admin_form_key} - = - true - form_key - false - - - true - ${entity} - = - true - entity - - - true - ${adminImportBehavior} - = - true - behavior - - - true - validation-stop-on-errors - = - true - validation_strategy - false - - - true - 10 - = - true - allowed_error_count - false - - - true - , - = - true - _import_field_separator - false - - - true - , - = - true - _import_multiple_value_separator - false - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/import/start - POST - true - false - true - false - HttpClient4 - - - - ${adminImportFilePath} - import_file - application/vnd.ms-excel - - - - false - - mpaf/tool/fragments/ce/common/import_save.jmx - - - - Import successfully done - - Assertion.response_data - false - 16 - - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/auth/logout/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/setup/admin_logout.jmx - - - - false - - - -adminUserList = props.get("adminUserList"); -adminUserList.add(vars.get("admin_user")); - - mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx - - - - - - - 1 - false - 1 - ${importCustomersPercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "Import Customers"); - - true - - - - - - function getFormKeyFromResponse() - { - var url = prev.getUrlAsString(), - responseCode = prev.getResponseCode(), - formKey = null; - searchPattern = /var FORM_KEY = '(.+)'/; - if (responseCode == "200" && url) { - response = prev.getResponseDataAsString(); - formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; - } - return formKey; - } - - formKey = vars.get("form_key_storage"); - - currentFormKey = getFormKeyFromResponse(); - - if (currentFormKey != null && currentFormKey != formKey) { - vars.put("form_key_storage", currentFormKey); - } - - javascript - mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx - - - - formKey = vars.get("form_key_storage"); - if (formKey - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' - && sampler.getMethod() == "POST") - { - arguments = sampler.getArguments(); - for (i=0; i<arguments.getArgumentCount(); i++) - { - argument = arguments.getArgument(i); - if (argument.getName() == 'form_key' && argument.getValue() != formKey) { - log.info("admin form key updated: " + argument.getValue() + " => " + formKey); - argument.setValue(formKey); - } - } - } - - javascript - - - - - - false - mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - get-admin-email - mpaf/tool/fragments/ce/lock_controller.jmx - - - - mpaf/tool/fragments/ce/get_admin_email.jmx - -adminUserList = props.get("adminUserList"); -adminUser = adminUserList.poll(); -if (adminUser == null) { - SampleResult.setResponseMessage("adminUser list is empty"); - SampleResult.setResponseData("adminUser list is empty","UTF-8"); - IsSuccess=false; - SampleResult.setSuccessful(false); - SampleResult.setStopThread(true); -} -vars.put("admin_user", adminUser); - - - - true - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_login/admin_login.jmx - - - - Welcome - <title>Magento Admin</title> - - Assertion.response_data - false - 2 - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - admin_form_key - - - - - - - - - true - - = - true - dummy - - - true - ${admin_form_key} - = - true - form_key - - - true - ${admin_password} - = - true - login[password] - - - true - ${admin_user} - = - true - login[username] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/dashboard/ - POST - true - false - true - false - Java - false - - mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx - - - - - - vars.put("entity", "customer"); -String behavior = "${adminImportCustomerBehavior}"; -vars.put("adminImportBehavior", behavior); -String filepath = "${files_folder}${adminImportCustomerFilePath}"; -vars.put("adminImportFilePath", filepath); - - - true - mpaf/tool/fragments/ce/import_customers/setup.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/import/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/common/import.jmx - - - - Import Settings - - Assertion.response_data - false - 2 - - - - - - - - - true - ${admin_form_key} - = - true - form_key - false - - - true - ${entity} - = - true - entity - - - true - ${adminImportBehavior} - = - true - behavior - - - true - validation-stop-on-errors - = - true - validation_strategy - - - true - 10 - = - true - allowed_error_count - - - true - , - = - true - _import_field_separator - - - true - , - = - true - _import_multiple_value_separator - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/import/validate - POST - true - false - true - false - HttpClient4 - - - - ${adminImportFilePath} - import_file - application/vnd.ms-excel - - - - false - - mpaf/tool/fragments/ce/common/import_validate.jmx - - - - File is valid! To start import process - - Assertion.response_data - false - 16 - - - - - - - - - true - ${admin_form_key} - = - true - form_key - false - - - true - ${entity} - = - true - entity - - - true - ${adminImportBehavior} - = - true - behavior - - - true - validation-stop-on-errors - = - true - validation_strategy - false - - - true - 10 - = - true - allowed_error_count - false - - - true - , - = - true - _import_field_separator - false - - - true - , - = - true - _import_multiple_value_separator - false - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/import/start - POST - true - false - true - false - HttpClient4 - - - - ${adminImportFilePath} - import_file - application/vnd.ms-excel - - - - false - - mpaf/tool/fragments/ce/common/import_save.jmx - - - - Import successfully done - - Assertion.response_data - false - 16 - - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/auth/logout/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/setup/admin_logout.jmx - - - - false - - - -adminUserList = props.get("adminUserList"); -adminUserList.add(vars.get("admin_user")); - - mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx - - - - - - - 1 - false - 1 - ${exportProductsPercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "Export Products"); - - true - - - - - - function getFormKeyFromResponse() - { - var url = prev.getUrlAsString(), - responseCode = prev.getResponseCode(), - formKey = null; - searchPattern = /var FORM_KEY = '(.+)'/; - if (responseCode == "200" && url) { - response = prev.getResponseDataAsString(); - formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; - } - return formKey; - } - - formKey = vars.get("form_key_storage"); - - currentFormKey = getFormKeyFromResponse(); - - if (currentFormKey != null && currentFormKey != formKey) { - vars.put("form_key_storage", currentFormKey); - } - - javascript - mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx - - - - formKey = vars.get("form_key_storage"); - if (formKey - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' - && sampler.getMethod() == "POST") - { - arguments = sampler.getArguments(); - for (i=0; i<arguments.getArgumentCount(); i++) - { - argument = arguments.getArgument(i); - if (argument.getName() == 'form_key' && argument.getValue() != formKey) { - log.info("admin form key updated: " + argument.getValue() + " => " + formKey); - argument.setValue(formKey); - } - } - } - - javascript - - - - - - false - mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - get-admin-email - mpaf/tool/fragments/ce/lock_controller.jmx - - - - mpaf/tool/fragments/ce/get_admin_email.jmx - -adminUserList = props.get("adminUserList"); -adminUser = adminUserList.poll(); -if (adminUser == null) { - SampleResult.setResponseMessage("adminUser list is empty"); - SampleResult.setResponseData("adminUser list is empty","UTF-8"); - IsSuccess=false; - SampleResult.setSuccessful(false); - SampleResult.setStopThread(true); -} -vars.put("admin_user", adminUser); - - - - true - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_login/admin_login.jmx - - - - Welcome - <title>Magento Admin</title> - - Assertion.response_data - false - 2 - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - admin_form_key - - - - - - - - - true - - = - true - dummy - - - true - ${admin_form_key} - = - true - form_key - - - true - ${admin_password} - = - true - login[password] - - - true - ${admin_user} - = - true - login[username] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/dashboard/ - POST - true - false - true - false - Java - false - - mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx - - - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/export/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/common/export.jmx - - - - Export Settings - - Assertion.response_data - false - 2 - - - - - - - - - true - form_key - ${admin_form_key} - = - true - - - true - attribute_code - - = - true - - - true - export_filter[allow_message][] - , - = - true - - - true - export_filter[allow_open_amount] - - = - true - - - true - export_filter[category_ids] - 24,25,26,27,28,29,30 - = - true - - - true - export_filter[configurable_variations] - - = - true - - - true - export_filter[cost][] - , - = - true - - - true - export_filter[country_of_manufacture] - - = - true - - - true - export_filter[created_at] - - = - true - - - true - export_filter[custom_design] - - = - true - - - true - export_filter[custom_design_from][] - , - = - true - - - true - export_filter[custom_design_to][] - , - = - true - - - true - export_filter[custom_layout_update] - - = - true - - - true - export_filter[description] - - = - true - - - true - export_filter[email_template] - - = - true - - - true - export_filter[gallery] - - = - true - - - true - export_filter[gift_message_available] - - = - true - - - true - export_filter[gift_wrapping_available] - - = - true - - - true - export_filter[gift_wrapping_price][] - , - = - true - - - true - export_filter[group_price][] - , - = - true - - - true - export_filter[has_options] - - = - true - - - true - export_filter[image] - - = - true - - - true - export_filter[image_label] - - = - true - - - true - export_filter[is_redeemable][] - , - = - true - - - true - export_filter[is_returnable] - - = - true - - - true - export_filter[lifetime][] - , - = - true - - - true - export_filter[links_exist][] - , - = - true - - - true - export_filter[links_purchased_separately][] - , - = - true - - - true - export_filter[links_title] - - = - true - - - true - export_filter[media_gallery] - - = - true - - - true - export_filter[meta_description] - - = - true - - - true - export_filter[meta_keyword] - - = - true - - - true - export_filter[meta_title] - - = - true - - - true - export_filter[minimal_price][] - , - = - true - - - true - export_filter[msrp][] - , - = - true - - - true - export_filter[msrp_display_actual_price_type] - - = - true - - - true - export_filter[name] - - = - true - - - true - export_filter[news_from_date][] - , - = - true - - - true - export_filter[news_to_date][] - , - = - true - - - true - export_filter[old_id][] - , - = - true - - - true - export_filter[open_amount_max][] - , - = - true - - - true - export_filter[open_amount_min][] - , - = - true - - - true - export_filter[options_container] - - = - true - - - true - export_filter[page_layout] - - = - true - - - true - export_filter[price][] - , - = - true - - - true - export_filter[price_type][] - , - = - true - - - true - export_filter[price_view] - - = - true - - - true - export_filter[quantity_and_stock_status] - - = - true - - - true - export_filter[related_tgtr_position_behavior][] - , - = - true - - - true - export_filter[related_tgtr_position_limit][] - , - = - true - - - true - export_filter[required_options] - - = - true - - - true - export_filter[samples_title] - - = - true - - - true - export_filter[shipment_type][] - , - = - true - - - true - export_filter[short_description] - - = - true - - - true - export_filter[sku] - - = - true - - - true - export_filter[sku_type][] - , - = - true - - - true - export_filter[small_image] - - = - true - - - true - export_filter[small_image_label] - - = - true - - - true - export_filter[special_from_date][] - , - = - true - - - true - export_filter[special_price][] - , - = - true - - - true - export_filter[special_to_date][] - , - = - true - - - true - export_filter[status] - - = - true - - - true - export_filter[tax_class_id] - - = - true - - - true - export_filter[thumbnail] - - = - true - - - true - export_filter[thumbnail_label] - - = - true - - - true - export_filter[tier_price][] - , - = - true - - - true - export_filter[updated_at] - - = - true - - - true - export_filter[upsell_tgtr_position_behavior][] - , - = - true - - - true - export_filter[upsell_tgtr_position_limit][] - , - = - true - - - true - export_filter[url_key] - - = - true - - - true - export_filter[url_path] - - = - true - - - true - export_filter[use_config_allow_message][] - , - = - true - - - true - export_filter[use_config_email_template][] - , - = - true - - - true - export_filter[use_config_is_redeemable][] - , - = - true - - - true - export_filter[use_config_lifetime][] - , - = - true - - - true - export_filter[visibility] - - = - true - - - true - export_filter[weight][] - , - = - true - - - true - export_filter[weight_type][] - , - = - true - - - true - frontend_label - - = - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/export/export/entity/catalog_product/file_format/csv - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/export_products/export_products.jmx - - - - Simple Product 1 - - Assertion.response_data - false - 16 - - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/auth/logout/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/setup/admin_logout.jmx - - - - false - - - -adminUserList = props.get("adminUserList"); -adminUserList.add(vars.get("admin_user")); - - mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx - - - - - - - 1 - false - 1 - ${exportCustomersPercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "Export Customers"); - - true - - - - - - function getFormKeyFromResponse() - { - var url = prev.getUrlAsString(), - responseCode = prev.getResponseCode(), - formKey = null; - searchPattern = /var FORM_KEY = '(.+)'/; - if (responseCode == "200" && url) { - response = prev.getResponseDataAsString(); - formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; - } - return formKey; - } - - formKey = vars.get("form_key_storage"); - - currentFormKey = getFormKeyFromResponse(); - - if (currentFormKey != null && currentFormKey != formKey) { - vars.put("form_key_storage", currentFormKey); - } - - javascript - mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx - - - - formKey = vars.get("form_key_storage"); - if (formKey - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' - && sampler.getMethod() == "POST") - { - arguments = sampler.getArguments(); - for (i=0; i<arguments.getArgumentCount(); i++) - { - argument = arguments.getArgument(i); - if (argument.getName() == 'form_key' && argument.getValue() != formKey) { - log.info("admin form key updated: " + argument.getValue() + " => " + formKey); - argument.setValue(formKey); - } - } - } - - javascript - - - - - - false - mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - get-admin-email - mpaf/tool/fragments/ce/lock_controller.jmx - - - - mpaf/tool/fragments/ce/get_admin_email.jmx - -adminUserList = props.get("adminUserList"); -adminUser = adminUserList.poll(); -if (adminUser == null) { - SampleResult.setResponseMessage("adminUser list is empty"); - SampleResult.setResponseData("adminUser list is empty","UTF-8"); - IsSuccess=false; - SampleResult.setSuccessful(false); - SampleResult.setStopThread(true); -} -vars.put("admin_user", adminUser); - - - - true - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_login/admin_login.jmx - - - - Welcome - <title>Magento Admin</title> - - Assertion.response_data - false - 2 - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - admin_form_key - - - - - - - - - true - - = - true - dummy - - - true - ${admin_form_key} - = - true - form_key - - - true - ${admin_password} - = - true - login[password] - - - true - ${admin_user} - = - true - login[username] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/dashboard/ - POST - true - false - true - false - Java - false - - mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx - - - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/export/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/common/export.jmx - - - - Export Settings - - Assertion.response_data - false - 2 - - - - - - - - - true - ${admin_form_key} - = - true - form_key - false - - - true - - = - true - attribute_code - true - - - true - - = - true - export_filter[confirmation] - true - - - true - - = - true - export_filter[created_at] - true - - - true - - = - true - export_filter[created_in] - true - - - true - , - = - true - export_filter[default_billing][] - true - - - true - , - = - true - export_filter[default_shipping][] - true - - - true - - = - true - export_filter[disable_auto_group_change] - true - - - true - , - = - true - export_filter[dob][] - true - - - true - - = - true - export_filter[email] - true - - - true - - = - true - export_filter[firstname] - true - - - true - - = - true - export_filter[gender] - true - - - true - - = - true - export_filter[group_id] - true - - - true - - = - true - export_filter[lastname] - true - - - true - - = - true - export_filter[middlename] - true - - - true - - = - true - export_filter[password_hash] - true - - - true - - = - true - export_filter[prefix] - true - - - true - , - = - true - export_filter[reward_update_notification][] - true - - - true - , - = - true - export_filter[reward_warning_notification][] - true - - - true - - = - true - export_filter[rp_token] - true - - - true - , - = - true - export_filter[rp_token_created_at][] - true - - - true - - = - true - export_filter[store_id] - true - - - true - - = - true - export_filter[suffix] - true - - - true - - = - true - export_filter[taxvat] - true - - - true - - = - true - export_filter[website_id] - true - - - true - - = - true - frontend_label - true - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/export/export/entity/customer/file_format/csv - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/export_customers/export_customers.jmx - - - - user_1@example.com - - Assertion.response_data - false - 16 - - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/auth/logout/ - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/setup/admin_logout.jmx - - - - false - - - -adminUserList = props.get("adminUserList"); -adminUserList.add(vars.get("admin_user")); - - mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx - - - - - - - 1 - false - 1 - ${apiBasePercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "API"); - - true - - - - - - - Content-Type - application/json - - - Accept - */* - - - mpaf/tool/fragments/ce/api/header_manager_before_token.jmx - - - - true - - - - false - {"username":"${admin_user}","password":"${admin_password}"} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/V1/integration/admin/token - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/admin_token_retrieval.jmx - - - admin_token - $ - - - BODY - - - - - ^[a-z0-9-]+$ - - Assertion.response_data - false - 1 - variable - admin_token - - - - - - - - Authorization - Bearer ${admin_token} - - - mpaf/tool/fragments/ce/api/header_manager.jmx - - - - 1 - false - 1 - 100 - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "API Process Orders"); - - true - - - - - // Each thread gets an equal number of orders, based on how many orders are available. - - int apiProcessOrders = Integer.parseInt("${apiProcessOrders}"); - if (apiProcessOrders > 0) { - ordersPerThread = apiProcessOrders; - } else { - ordersPerThread = 1; - } - - - threadNum = ${__threadNum}; - vars.put("ordersPerThread", String.valueOf(ordersPerThread)); - vars.put("threadNum", String.valueOf(threadNum)); - - - - - false - mpaf/tool/fragments/ce/api/process_orders/setup.jmx - - - - - - - true - status - = - true - searchCriteria[filterGroups][0][filters][0][field] - - - true - Pending - = - true - searchCriteria[filterGroups][0][filters][0][value] - - - true - ${ordersPerThread} - = - true - searchCriteria[pageSize] - - - true - ${threadNum} - = - true - searchCriteria[current_page] - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/orders - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/api/process_orders/get_orders.jmx - - - entity_ids - $.items[*].entity_id - - - BODY - - - - - - entity_ids - order_id - true - mpaf/tool/fragments/ce/api/process_orders/for_each_order.jmx - - - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/order/${order_id}/invoice - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/process_orders/create_invoice.jmx - - - - "\d+" - - Assertion.response_data - false - 2 - - - - - - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/order/${order_id}/ship - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/process_orders/create_shipment.jmx - - - - "\d+" - - Assertion.response_data - false - 2 - - - - - - - - - 1 - false - 1 - 100 - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "API Product Management"); - - true - - - - - true - - - - false - { - "product": { - "sku": "psku-test-${__time()}-${__threadNum}-${__Random(1,1000000)}", - "name": "Product_${__time()}-${__threadNum}-${__Random(1,1000000)}", - "attributeSetId": 4 - } -} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/create_product_no_custom_attributes.jmx - - - simple_product_id - $.id - - - BODY - - - - simple_product_sku - $.sku - - - BODY - - - - simple_stock_item_id - $.extension_attributes.stock_item.item_id - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - simple_product_id - - - - - ^[a-z0-9-]+$ - - Assertion.response_data - false - 1 - variable - simple_product_sku - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - simple_stock_item_id - - - - - - true - - - - false - { - "stock_item": { - "manage_stock": true, - "is_in_stock": true, - "qty": ${simple_product_id} - } - } - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products/${simple_product_sku}/stockItems/${simple_stock_item_id} - PUT - true - false - true - false - false - - mpaf/tool/fragments/ce/api/update_product_stock_info.jmx - - - $ - ${simple_stock_item_id} - true - false - false - - - - - - true - - - - true - - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products/${simple_product_sku} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/api/check_product.jmx - - - $.sku - ${simple_product_sku} - true - false - false - - - - $.id - ${simple_product_id} - true - false - false - - - - $.extension_attributes.stock_item.item_id - ${simple_stock_item_id} - true - false - false - - - - $.extension_attributes.stock_item.qty - ${simple_product_id} - true - false - false - - - - - - true - - - - false - { - "product": { - "sku": "apsku-test-${__time()}-${__threadNum}-${__Random(1,1000000)}", - "name": "Extensible_Product_${__time()}-${__threadNum}-${__Random(1,1000000)}", - "visibility": "4", - "type_id": "simple", - "price": "3.62", - "status": "1", - "attribute_set_id": "4", - "custom_attributes": [ - { - "attribute_code": "cost", - "value": "" - }, - { - "attribute_code": "description", - "value": "Description" - } - ], - "extension_attributes":{ - "stock_item":{ - "manage_stock": true, - "is_in_stock": true, - "qty":"100" - } - } , - "media_gallery_entries": - [{ - "id": null, - "label":"test_label_${__time()}-${__threadNum}-${__Random(1,1000000)}", - "position":1, - "disabled":false, - "media_type":"image", - "types":["image"], - "content":{ - "base64_encoded_data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABgAGADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iioLy8t9Ps5bu7lWKCIZd26KKaTbshpX0RPRXN/8J/4V/6DVv8Ak3+FH/Cf+Ff+g1b/AJN/hXR9SxP/AD7l9zNPYVf5X9x0lFc3/wAJ/wCFf+g1b/k3+FH/AAn/AIV/6DVv+Tf4UfUsT/z7l9zD2FX+V/cdJRXN/wDCf+Ff+g1b/k3+FH/Cf+Ff+g1b/k3+FH1LE/8APuX3MPYVf5X9x0lFc3/wn/hX/oNW/wCTf4Uf8J/4V/6DVv8Ak3+FH1LE/wDPuX3MPYVf5X9x0lFVdP1G01WyS8sZ1nt3JCyL0ODg/qKtVzyi4u0lZmbTTswrm/H3/Iiav/1x/wDZhXSVzfj7/kRNX/64/wDswrowf+80/wDEvzNKH8WPqj5voorB1zS7OLT7m7SHE5YNu3HqWGeM471+kYutOhSdSEU7Jt3dtF20f6H1FacqcHJK9vO36M3qKzTa6foqPdxwlWxswrFi2T0AJ9aRdVmjkT7XYSW8TsFEm8MAT0yB0qfrcafu1tJeV2l2u7K3zsL2yjpPR+V3+NjTorPn1GVbt7a1s2uJIwDJ84ULnpyaik1SWTTrp47Z0uIQRJGzAFOPvZ70Sx1GLau9L9H03SdrNrsgdeCuu3k+hq0VR0ma4msImuIih2LtYvuLjA+b2zV6uijUVWmprqaQkpxUl1PoP4Xf8iBYf78v/oxq7GuO+F3/ACIFh/vy/wDoxq7GvzTMf98q/wCJ/mfLYn+NP1YVzfj7/kRNX/64/wDswrpK5vx9/wAiJq//AFx/9mFRg/8Aeaf+JfmTQ/ix9UfN9ZniD/kB3H/Af/QhWnTZI45kKSIroeqsMg1+l4mk61GdNfaTX3o+pqw54Sj3Rma/GXsI3BcLFMruU+8F5yR+dUZ4tOeNFOq3tx5jACNZg5J+mK6PrUMdrbxPvjgiR/7yoAa48TgPa1HNW1STvfp2s1+JjVw/PJy017mbe/YTqTB7iWzuQgPmhtocfjwajiupbjTtTieUXCxRsqTKMb8qePwrYlghnAE0UcgHQOoP86ckaRoERFVR/CowKbwU3UclJJO+19brqr203vvoHsJczd7J3/H8PmVNJnhm063WOVHZIkDhTkqcd/yNXajighg3eTFHHu67FAz+VSV2UIShTjGe67G9NOMUpbn0H8Lv+RAsP9+X/wBGNXY1x3wu/wCRAsP9+X/0Y1djX5tmP++Vf8T/ADPl8T/Gn6sK5vx9/wAiJq//AFx/9mFdJXN+Pv8AkRNX/wCuP/swqMH/ALzT/wAS/Mmh/Fj6o+b6KKK/Uj60KKKKACiiigAooooA+g/hd/yIFh/vy/8Aoxq7GuO+F3/IgWH+/L/6Mauxr8wzH/fKv+J/mfKYn+NP1YVzfj7/AJETV/8Arj/7MK6Sub8ff8iJq/8A1x/9mFRg/wDeaf8AiX5k0P4sfVHzfRRRX6kfWhRRRQAUUUUAFFFFAH0H8Lv+RAsP9+X/ANGNXY1x3wu/5ECw/wB+X/0Y1djX5hmP++Vf8T/M+UxP8afqwqC8s7fULOW0u4llglGHRujCp6K5E2ndGKdtUc3/AMIB4V/6Atv+bf40f8IB4V/6Atv+bf410lFdH13E/wDPyX3s09vV/mf3nN/8IB4V/wCgLb/m3+NH/CAeFf8AoC2/5t/jXSUUfXcT/wA/Jfew9vV/mf3nN/8ACAeFf+gLb/m3+NH/AAgHhX/oC2/5t/jXSUUfXcT/AM/Jfew9vV/mf3nN/wDCAeFf+gLb/m3+NH/CAeFf+gLb/m3+NdJRR9dxP/PyX3sPb1f5n95V0/TrTSrJLOxgWC3QkrGvQZOT+pq1RRXPKTk7yd2Zttu7P//Z", - "type": "image/jpeg", - "name": "test_image_${__time(YMDHMS)}-${__threadNum}-${__Random(1,1000000)}.jpeg" - } - } - ] - } -} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/create_product_with_extensible_data_objects.jmx - - - simple_product_id - $.id - - - BODY - - - - simple_product_sku - $.sku - - - BODY - - - - simple_stock_item_id - $.extension_attributes.stock_item.item_id - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - simple_product_id - - - - - ^[a-z0-9-]+$ - - Assertion.response_data - false - 1 - variable - simple_product_sku - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - simple_stock_item_id - - - - - - true - - - - true - - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products/${simple_product_sku} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/api/check_product_with_extensible_data_objects.jmx - - - $.sku - ${simple_product_sku} - true - false - false - - - - $.id - ${simple_product_id} - true - false - false - - - - $.extension_attributes.stock_item.item_id - ${simple_stock_item_id} - true - false - false - - - - $.extension_attributes.stock_item.qty - 100 - true - false - false - - - - - - - - 1 - false - 1 - 100 - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "API Product Attribute Management"); - - true - - - - - true - - - - false - { - "attributeSet": { - "attribute_set_name": "new_attribute_set_${__time()}-${__threadNum}-${__Random(1,1000000)}", - "sort_order": 500 - }, - "skeletonId": "4" -} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products/attribute-sets/ - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/create_attribute_set.jmx - - - attribute_set_id - $.attribute_set_id - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - attribute_set_id - - - - - - true - - - - false - { - "group": { - "attribute_group_name": "empty_attribute_group_${__time()}-${__threadNum}-${__Random(1,1000000)}", - "attribute_set_id": ${attribute_set_id} - } -} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products/attribute-sets/groups - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/create_attribute_group.jmx - - - attribute_group_id - $.attribute_group_id - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - attribute_set_id - - - - - - true - - - - false - { - "attribute": { - "attribute_code": "attr_code_${__time()}", - "frontend_labels": [ - { - "store_id": 0, - "label": "front_lbl_${__time(YMDHMS)}-${__threadNum}-${__Random(1,1000000)}" - } - ], - "default_value": "default value", - "frontend_input": "textarea", - "is_required": true - } -} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products/attributes/ - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/create_attribute.jmx - - - attribute_id - $.attribute_id - - - BODY - - - - attribute_code - $.attribute_code - - - BODY - - - - - ^\d+$ - - Assertion.response_data - false - 1 - variable - attribute_id - - - - - ^[a-z0-9-_]+$ - - Assertion.response_data - false - 1 - variable - attribute_code - - - - - - true - - - - false - { - "attributeSetId": "${attribute_set_id}", - "attributeGroupId": "${attribute_group_id}", - "attributeCode": "${attribute_code}", - "sortOrder": 3 -} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products/attribute-sets/attributes - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/add_attribute_to_attribute_set.jmx - - - $ - (\d+) - true - false - false - - - - - - - - - - 1 - false - 1 - ${adminProductCreationPercentage} - mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx - - - -var testLabel = "${testLabel}" ? " (${testLabel})" : ""; -if (testLabel - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' -) { - if (sampler.getName().indexOf(testLabel) == -1) { - sampler.setName(sampler.getName() + testLabel); - } -} else if (sampler.getName().indexOf("SetUp - ") == -1) { - sampler.setName("SetUp - " + sampler.getName()); -} - - javascript - mpaf/tool/fragments/_system/setup_label.jmx - - - - vars.put("testLabel", "Admin Create Product"); - - true - - - - - - function getFormKeyFromResponse() - { - var url = prev.getUrlAsString(), - responseCode = prev.getResponseCode(), - formKey = null; - searchPattern = /var FORM_KEY = '(.+)'/; - if (responseCode == "200" && url) { - response = prev.getResponseDataAsString(); - formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; - } - return formKey; - } - - formKey = vars.get("form_key_storage"); - - currentFormKey = getFormKeyFromResponse(); - - if (currentFormKey != null && currentFormKey != formKey) { - vars.put("form_key_storage", currentFormKey); - } - - javascript - mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx - - - - formKey = vars.get("form_key_storage"); - if (formKey - && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' - && sampler.getMethod() == "POST") - { - arguments = sampler.getArguments(); - for (i=0; i<arguments.getArgumentCount(); i++) - { - argument = arguments.getArgument(i); - if (argument.getName() == 'form_key' && argument.getValue() != formKey) { - log.info("admin form key updated: " + argument.getValue() + " => " + formKey); - argument.setValue(formKey); - } - } - } - - javascript - - - - - - false - mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - get-admin-email - mpaf/tool/fragments/ce/lock_controller.jmx - - - - mpaf/tool/fragments/ce/get_admin_email.jmx - -adminUserList = props.get("adminUserList"); -adminUser = adminUserList.poll(); -if (adminUser == null) { - SampleResult.setResponseMessage("adminUser list is empty"); - SampleResult.setResponseData("adminUser list is empty","UTF-8"); - IsSuccess=false; - SampleResult.setSuccessful(false); - SampleResult.setStopThread(true); -} -vars.put("admin_user", adminUser); - - - - true - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_login/admin_login.jmx - - - - Welcome - <title>Magento Admin</title> - - Assertion.response_data - false - 2 - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - - - - - ^.+$ - - Assertion.response_data - false - 1 - variable - admin_form_key - - - - - - - - - true - - = - true - dummy - - - true - ${admin_form_key} - = - true - form_key - - - true - ${admin_password} - = - true - login[password] - - - true - ${admin_user} - = - true - login[username] - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/admin/dashboard/ - POST - true - false - true - false - Java - false - - mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx - - - - false - admin_form_key - <input name="form_key" type="hidden" value="([^'"]+)" /> - $1$ - - 1 - mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx - - - - - - mpaf/tool/fragments/ce/once_only_controller.jmx - - - - mpaf/tool/fragments/ce/admin_create_product/get_related_product_id.jmx - import org.apache.jmeter.samplers.SampleResult; -import java.util.Random; -Random random = new Random(); -if (${seedForRandom} > 0) { - random.setSeed(${seedForRandom}); -} -relatedIndex = random.nextInt(props.get("simple_products_list").size()); -vars.put("related_product_id", props.get("simple_products_list").get(relatedIndex).get("id")); - - - true - - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - - - Content-Type - application/json - - - Accept - */* - - - mpaf/tool/fragments/ce/api/header_manager_before_token.jmx - - - - true - - - - false - {"username":"${admin_user}","password":"${admin_password}"} - = - - - - - - - - ${request_protocol} - - ${base_path}rest/V1/integration/admin/token - POST - true - false - true - false - false - - mpaf/tool/fragments/ce/api/admin_token_retrieval.jmx - - - admin_token - $ - - - BODY - - - - - ^[a-z0-9-]+$ - - Assertion.response_data - false - 1 - variable - admin_token - - - - - - - - Authorization - Bearer ${admin_token} - - - mpaf/tool/fragments/ce/api/header_manager.jmx - - - - - - - false - mycolor - = - true - searchCriteria[filterGroups][0][filters][0][value] - - - false - attribute_code - = - true - searchCriteria[filterGroups][0][filters][0][field] - - - false - mysize - = - true - searchCriteria[filterGroups][0][filters][1][value] - - - false - attribute_code - = - true - searchCriteria[filterGroups][0][filters][1][field] - - - - - - - - ${request_protocol} - - ${base_path}rest/default/V1/products/attributes - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_product/get_product_attributes.jmx - - - product_attributes - $.items - - - BODY - - - - javascript - - - - -var attributesData = JSON.parse(vars.get("product_attributes")), -maxOptions = 2; - -attributes = []; -for (i in attributesData) { - if (i >= 2) { - break; - } - var data = attributesData[i], - attribute = { - "id": data.attribute_id, - "code": data.attribute_code, - "label": data.default_frontend_label, - "options": [] - }; - - var processedOptions = 0; - for (optionN in data.options) { - var option = data.options[optionN]; - if (parseInt(option.value) > 0 && processedOptions < maxOptions) { - processedOptions++; - attribute.options.push(option); - } - } - attributes.push(attribute); -} - -vars.putObject("product_attributes", attributes); - - - - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/catalog/product_set/index/filter/${attribute_set_filter} - GET - true - false - true - false - false - - mpaf/tool/fragments/ce/admin_create_product/configurable_setup_attribute_set.jmx - - - - false - attribute_set_id - catalog\/product_set\/edit\/id\/([\d]+)\/"[\D\d]*Attribute Set 1 - $1$ - - 1 - - - - false - - - import org.apache.commons.codec.binary.Base64; - -byte[] encodedBytes = Base64.encodeBase64("set_name=Attribute Set 1".getBytes()); -vars.put("attribute_set_filter", new String(encodedBytes)); - - - - - - - - mpaf/tool/fragments/ce/simple_controller.jmx - - - - import org.apache.jmeter.samplers.SampleResult; -import java.util.Random; -Random random = new Random(); -if (${seedForRandom} > 0) { - random.setSeed(${seedForRandom}); -} -number = random.nextInt(props.get("simple_products_list").size()); -simpleList = props.get("simple_products_list").get(number); -vars.put("simple_product_1_id", simpleList.get("id")); -vars.put("simple_product_1_name", simpleList.get("title")); - -do { - number1 = random.nextInt(props.get("simple_products_list").size()); -} while(number == number1); -simpleList = props.get("simple_products_list").get(number1); -vars.put("simple_product_2_id", simpleList.get("id")); -vars.put("simple_product_2_name", simpleList.get("title")); - -number2 = random.nextInt(props.get("configurable_products_list").size()); -configurableList = props.get("configurable_products_list").get(number2); -vars.put("configurable_product_1_id", configurableList.get("id")); -vars.put("configurable_product_1_url_key", configurableList.get("url_key")); -vars.put("configurable_product_1_name", configurableList.get("title")); - -//Additional category to be added -//int categoryId = Integer.parseInt(vars.get("simple_product_category_id")); -//vars.put("category_additional", (categoryId+1).toString()); -//New price -vars.put("price_new", "9999"); -//New special price -vars.put("special_price_new", "8888"); -//New quantity -vars.put("quantity_new", "100600"); -vars.put("configurable_sku", "Configurable Product - ${__time(YMD)}-${__threadNum}-${__Random(1,1000000)}"); - - - - - true - mpaf/tool/fragments/ce/admin_create_product/setup.jmx - - - - mpaf/tool/fragments/ce/admin_create_product/create_bundle_product.jmx - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/catalog/product/ - GET - true - false - true - false - false - - - - - - records found - - Assertion.response_data - false - 2 - - - - - - - - - - - - ${request_protocol} - - ${base_path}${admin_path}/catalog/product/new/set/4/type/bundle/ - GET - true - false - true - false - false - - - - - - New Product - - Assertion.response_data - false - 2 - + + + + + ${request_protocol} + + ${base_path}${admin_path}/catalog/product/new/set/4/type/bundle/ + GET + true + false + true + false + false + + + + + + New Product + + Assertion.response_data + false + 2 + @@ -29924,42 +21729,8105 @@ vars.put("admin_user", adminUser); ctx.getCurrentSampler().addArgument("product[configurable_attributes_data][" + attributeId + "][code]", attributeCode); ctx.getCurrentSampler().addArgument("product[configurable_attributes_data][" + attributeId + "][label]", attributeLabel); - int valuesCount = Integer.parseInt(vars.get("attribute_" + attributeId + "_values_matchNr")); - for (int j = 1; j <= valuesCount; j++) { - attributeValue = vars.get("attribute_" + attributeId + "_values_" + j.toString()); - ctx.getCurrentSampler().addArgument( - "product[configurable_attributes_data][" + attributeId + "][values][" + attributeValue + "][include]", - "1" - ); - ctx.getCurrentSampler().addArgument( - "product[configurable_attributes_data][" + attributeId + "][values][" + attributeValue + "][value_index]", - attributeValue - ); - } - } - ctx.getCurrentSampler().addArgument("associated_product_ids_serialized", vars.get("associated_products_ids").toString()); - } catch (Exception e) { - log.error("error???", e); - } - - - - - You saved the product - - Assertion.response_data - false - 2 - if have trouble see messages-message-error - + int valuesCount = Integer.parseInt(vars.get("attribute_" + attributeId + "_values_matchNr")); + for (int j = 1; j <= valuesCount; j++) { + attributeValue = vars.get("attribute_" + attributeId + "_values_" + j.toString()); + ctx.getCurrentSampler().addArgument( + "product[configurable_attributes_data][" + attributeId + "][values][" + attributeValue + "][include]", + "1" + ); + ctx.getCurrentSampler().addArgument( + "product[configurable_attributes_data][" + attributeId + "][values][" + attributeValue + "][value_index]", + attributeValue + ); + } + } + ctx.getCurrentSampler().addArgument("associated_product_ids_serialized", vars.get("associated_products_ids").toString()); + } catch (Exception e) { + log.error("error???", e); + } + + + + + You saved the product + + Assertion.response_data + false + 2 + if have trouble see messages-message-error + + + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/auth/logout/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/setup/admin_logout.jmx + + + + false + + + +adminUserList = props.get("adminUserList"); +adminUserList.add(vars.get("admin_user")); + + mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx + + + + + + + + + continue + + false + ${loops} + + ${csrPoolUsers} + ${ramp_period} + 1505803944000 + 1505803944000 + false + + + mpaf/tool/fragments/_system/thread_group.jmx + + + 1 + false + 1 + ${adminReturnsManagementPercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "Admin Returns Management"); + + true + + + + + + function getFormKeyFromResponse() + { + var url = prev.getUrlAsString(), + responseCode = prev.getResponseCode(), + formKey = null; + searchPattern = /var FORM_KEY = '(.+)'/; + if (responseCode == "200" && url) { + response = prev.getResponseDataAsString(); + formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; + } + return formKey; + } + + formKey = vars.get("form_key_storage"); + + currentFormKey = getFormKeyFromResponse(); + + if (currentFormKey != null && currentFormKey != formKey) { + vars.put("form_key_storage", currentFormKey); + } + + javascript + mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx + + + + formKey = vars.get("form_key_storage"); + if (formKey + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' + && sampler.getMethod() == "POST") + { + arguments = sampler.getArguments(); + for (i=0; i<arguments.getArgumentCount(); i++) + { + argument = arguments.getArgument(i); + if (argument.getName() == 'form_key' && argument.getValue() != formKey) { + log.info("admin form key updated: " + argument.getValue() + " => " + formKey); + argument.setValue(formKey); + } + } + } + + javascript + + + + + + false + mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + get-admin-email + mpaf/tool/fragments/ce/lock_controller.jmx + + + + mpaf/tool/fragments/ce/get_admin_email.jmx + +adminUserList = props.get("adminUserList"); +adminUser = adminUserList.poll(); +if (adminUser == null) { + SampleResult.setResponseMessage("adminUser list is empty"); + SampleResult.setResponseData("adminUser list is empty","UTF-8"); + IsSuccess=false; + SampleResult.setSuccessful(false); + SampleResult.setStopThread(true); +} +vars.put("admin_user", adminUser); + + + + true + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_login/admin_login.jmx + + + + Welcome + <title>Magento Admin</title> + + Assertion.response_data + false + 2 + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + + + + + ^.+$ + + Assertion.response_data + false + 1 + variable + admin_form_key + + + + + + + + + true + + = + true + dummy + + + true + ${admin_form_key} + = + true + form_key + + + true + ${admin_password} + = + true + login[password] + + + true + ${admin_user} + = + true + login[username] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/dashboard/ + POST + true + false + true + false + Java + false + + mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx + + + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_process_returns/orders_page.jmx + + + + Create New Order + + Assertion.response_data + false + 2 + + + + + + + + + true + sales_order_grid + = + true + namespace + + + true + + = + true + search + + + true + true + = + true + filters[placeholder] + + + true + 200 + = + true + paging[pageSize] + + + true + 1 + = + true + paging[current] + + + true + increment_id + = + true + sorting[field] + + + true + desc + = + true + sorting[direction] + + + true + true + = + true + isAjax + + + true + ${admin_form_key} + = + true + form_key + false + + + true + pending + = + true + filters[status] + true + + + true + ${__time()}${__Random(1,1000000)} + = + true + _ + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/mui/index/render/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_process_returns/open_orders.jmx + + + + totalRecords + + Assertion.response_data + false + 2 + + + + + + + + + true + ${admin_form_key} + = + true + form_key + + + true + sales_order_grid + = + true + namespace + true + + + true + + = + true + search + true + + + true + true + = + true + filters[placeholder] + true + + + true + 200 + = + true + paging[pageSize] + true + + + true + 1 + = + true + paging[current] + true + + + true + increment_id + = + true + sorting[field] + true + + + true + asc + = + true + sorting[direction] + true + + + true + true + = + true + isAjax + true + + + true + pending + = + true + filters[status] + + + true + ${__time()}${__Random(1,1000000)} + = + true + _ + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/mui/index/render/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_process_returns/search_orders.jmx + + + + totalRecords + + Assertion.response_data + false + 2 + + + + false + order_numbers + \"increment_id\":\"(\d+)\"\, + $1$ + + -1 + simple_products + + + + false + order_ids + \"entity_id\":\"(\d+)\"\, + $1$ + + -1 + simple_products + + + + + + mpaf/tool/fragments/ce/admin_create_process_returns/setup.jmx + + import java.util.ArrayList; + import java.util.HashMap; + import org.apache.jmeter.protocol.http.util.Base64Encoder; + import java.util.Random; + + // get count of "order_numbers" variable defined in "Search Pending Orders Limit" + int ordersCount = Integer.parseInt(vars.get("order_numbers_matchNr")); + + + int clusterLength; + int threadsNumber = ctx.getThreadGroup().getNumThreads(); + if (threadsNumber == 0) { + //Number of orders for one thread + clusterLength = ordersCount; + } else { + clusterLength = Math.round(ordersCount / threadsNumber); + if (clusterLength == 0) { + clusterLength = 1; + } + } + + //Current thread number starts from 0 + int currentThreadNum = ctx.getThreadNum(); + + //Index of the current product from the cluster + Random random = new Random(); + if (${seedForRandom} > 0) { + random.setSeed(${seedForRandom} + ${__threadNum}); + } + int iterator = random.nextInt(clusterLength); + if (iterator == 0) { + iterator = 1; + } + + int i = clusterLength * currentThreadNum + iterator; + + orderNumber = vars.get("order_numbers_" + i.toString()); + orderId = vars.get("order_ids_" + i.toString()); + vars.put("order_number", orderNumber); + vars.put("order_id", orderId); + + + + + false + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order/view/order_id/${order_id}/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_process_returns/open_order.jmx + + + + #${order_number} + + Assertion.response_data + false + 2 + + + + false + order_status + <span id="order_status">([^<]+)</span> + $1$ + + 1 + simple_products + + + + + + "${order_status}" == "Pending" + false + mpaf/tool/fragments/ce/admin_edit_order/if_controller.jmx + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order_invoice/start/order_id/${order_id}/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_process_returns/invoice_start.jmx + + + + Invoice Totals + + Assertion.response_data + false + 2 + + + + false + item_ids + <div id="order_item_(\d+)_title"\s*class="product-title"> + $1$ + + -1 + simple_products + + + + + + + + + true + ${admin_form_key} + = + true + form_key + false + + + true + 1 + = + true + invoice[items][${item_ids_1}] + + + true + 1 + = + true + invoice[items][${item_ids_2}] + + + true + Invoiced + = + true + invoice[comment_text] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order_invoice/save/order_id/${order_id}/ + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_process_returns/invoice_submit.jmx + + + + The invoice has been created + + Assertion.response_data + false + 2 + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order_creditmemo/start/order_id/${order_id}/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_process_returns/credit_memo_start.jmx + + + + New Memo + + Assertion.response_data + false + 2 + + + + + + + + + true + ${admin_form_key} + = + true + form_key + false + + + true + 1 + = + true + creditmemo[items][${item_ids_1}][qty] + + + true + 1 + = + true + creditmemo[items][${item_ids_2}][qty] + + + true + 1 + = + true + creditmemo[do_offline] + + + true + Credit Memo added + = + true + creditmemo[comment_text] + + + true + 10 + = + true + creditmemo[shipping_amount] + + + true + 0 + = + true + creditmemo[adjustment_positive] + + + true + 0 + = + true + creditmemo[adjustment_negative] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order_creditmemo/save/order_id/${order_id}/ + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_create_process_returns/credit_memo_full_refund.jmx + + + + You created the credit memo + + Assertion.response_data + false + 2 + + + + + + 1 + 0 + ${__javaScript(Math.round(${adminCreateProcessReturnsDelay}*1000))} + mpaf/tool/fragments/ce/admin_create_process_returns/pause.jmx + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/auth/logout/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/setup/admin_logout.jmx + + + + false + + + +adminUserList = props.get("adminUserList"); +adminUserList.add(vars.get("admin_user")); + + mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx + + + + + + + 1 + false + 1 + ${browseCustomerGridPercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "Browse Customer Grid"); + + true + + + + + + function getFormKeyFromResponse() + { + var url = prev.getUrlAsString(), + responseCode = prev.getResponseCode(), + formKey = null; + searchPattern = /var FORM_KEY = '(.+)'/; + if (responseCode == "200" && url) { + response = prev.getResponseDataAsString(); + formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; + } + return formKey; + } + + formKey = vars.get("form_key_storage"); + + currentFormKey = getFormKeyFromResponse(); + + if (currentFormKey != null && currentFormKey != formKey) { + vars.put("form_key_storage", currentFormKey); + } + + javascript + mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx + + + + formKey = vars.get("form_key_storage"); + if (formKey + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' + && sampler.getMethod() == "POST") + { + arguments = sampler.getArguments(); + for (i=0; i<arguments.getArgumentCount(); i++) + { + argument = arguments.getArgument(i); + if (argument.getName() == 'form_key' && argument.getValue() != formKey) { + log.info("admin form key updated: " + argument.getValue() + " => " + formKey); + argument.setValue(formKey); + } + } + } + + javascript + + + + + + false + mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + get-admin-email + mpaf/tool/fragments/ce/lock_controller.jmx + + + + mpaf/tool/fragments/ce/get_admin_email.jmx + +adminUserList = props.get("adminUserList"); +adminUser = adminUserList.poll(); +if (adminUser == null) { + SampleResult.setResponseMessage("adminUser list is empty"); + SampleResult.setResponseData("adminUser list is empty","UTF-8"); + IsSuccess=false; + SampleResult.setSuccessful(false); + SampleResult.setStopThread(true); +} +vars.put("admin_user", adminUser); + + + + true + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_login/admin_login.jmx + + + + Welcome + <title>Magento Admin</title> + + Assertion.response_data + false + 2 + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + + + + + ^.+$ + + Assertion.response_data + false + 1 + variable + admin_form_key + + + + + + + + + true + + = + true + dummy + + + true + ${admin_form_key} + = + true + form_key + + + true + ${admin_password} + = + true + login[password] + + + true + ${admin_user} + = + true + login[username] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/dashboard/ + POST + true + false + true + false + Java + false + + mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx + + + + + + + vars.put("gridEntityType" , "Customer"); + + pagesCount = parseInt(vars.get("customers_page_size")) || 20; + vars.put("grid_entity_page_size" , pagesCount); + vars.put("grid_namespace" , "customer_listing"); + vars.put("grid_admin_browse_filter_text" , vars.get("admin_browse_customer_filter_text")); + vars.put("grid_filter_field", "name"); + + // set sort fields and sort directions + vars.put("grid_sort_field_1", "name"); + vars.put("grid_sort_field_2", "group_id"); + vars.put("grid_sort_field_3", "billing_country_id"); + vars.put("grid_sort_order_1", "asc"); + vars.put("grid_sort_order_2", "desc"); + + javascript + mpaf/tool/fragments/ce/admin_browse_customers_grid/setup.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + + + + true + ${grid_namespace} + = + true + namespace + true + + + true + + = + true + search + true + + + true + true + = + true + filters[placeholder] + true + + + true + ${grid_entity_page_size} + = + true + paging[pageSize] + true + + + true + 1 + = + true + paging[current] + true + + + true + entity_id + = + true + sorting[field] + true + + + true + asc + = + true + sorting[direction] + true + + + true + true + = + true + isAjax + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/mui/index/render/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_grid_browsing/set_pages_count.jmx + + + $.totalRecords + 0 + true + false + true + + + + entity_total_records + $.totalRecords + + + BODY + + + + + + + + var pageSize = parseInt(vars.get("grid_entity_page_size")) || 20; + var totalsRecord = parseInt(vars.get("entity_total_records")); + var pageCount = Math.round(totalsRecord/pageSize); + + vars.put("grid_pages_count", pageCount); + + javascript + + + + + + + + + true + ${grid_namespace} + = + true + namespace + true + + + true + + = + true + search + true + + + true + ${grid_admin_browse_filter_text} + = + true + filters[placeholder] + true + + + true + ${grid_entity_page_size} + = + true + paging[pageSize] + true + + + true + 1 + = + true + paging[current] + true + + + true + entity_id + = + true + sorting[field] + true + + + true + asc + = + true + sorting[direction] + true + + + true + true + = + true + isAjax + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/mui/index/render/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_grid_browsing/set_filtered_pages_count.jmx + + + $.totalRecords + 0 + true + false + true + true + + + + entity_total_records + $.totalRecords + + + BODY + + + + + + + var pageSize = parseInt(vars.get("grid_entity_page_size")) || 20; +var totalsRecord = parseInt(vars.get("entity_total_records")); +var pageCount = Math.round(totalsRecord/pageSize); + +vars.put("grid_pages_count_filtered", pageCount); + + javascript + + + + + + 1 + ${grid_pages_count} + 1 + page_number + + true + false + mpaf/tool/fragments/ce/admin_grid_browsing/select_page_number.jmx + + + + + + + true + ${grid_namespace} + = + true + namespace + true + + + true + + = + true + search + true + + + true + true + = + true + filters[placeholder] + true + + + true + ${grid_entity_page_size} + = + true + paging[pageSize] + true + + + true + ${page_number} + = + true + paging[current] + true + + + true + entity_id + = + true + sorting[field] + true + + + true + asc + = + true + sorting[direction] + true + + + true + true + = + true + isAjax + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/mui/index/render/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_grid_browsing/admin_browse_grid.jmx + + + + \"totalRecords\":[^0]\d* + + Assertion.response_data + false + 2 + + + + + + 1 + ${grid_pages_count_filtered} + 1 + page_number + + true + false + mpaf/tool/fragments/ce/admin_grid_browsing/select_filtered_page_number.jmx + + + + mpaf/tool/fragments/ce/admin_grid_browsing/admin_browse_grid_sort_and_filter.jmx + + + + grid_sort_field + grid_sort_field + true + 0 + 3 + + + + grid_sort_order + grid_sort_order + true + 0 + 2 + + + + + + + true + ${grid_namespace} + = + true + namespace + false + + + true + ${grid_admin_browse_filter_text} + = + true + filters[${grid_filter_field}] + false + + + true + true + = + true + filters[placeholder] + false + + + true + ${grid_entity_page_size} + = + true + paging[pageSize] + false + + + true + ${page_number} + = + true + paging[current] + false + + + true + ${grid_sort_field} + = + true + sorting[field] + false + + + true + ${grid_sort_order} + = + true + sorting[direction] + false + + + true + true + = + true + isAjax + false + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/mui/index/render/ + GET + true + false + true + false + false + + + + + + \"totalRecords\":[^0]\d* + + Assertion.response_data + false + 2 + + + + + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/auth/logout/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/setup/admin_logout.jmx + + + + false + + + +adminUserList = props.get("adminUserList"); +adminUserList.add(vars.get("admin_user")); + + mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx + + + + + + + 1 + false + 1 + ${adminCreateOrderPercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "Admin Create Order"); + + true + + + + + + function getFormKeyFromResponse() + { + var url = prev.getUrlAsString(), + responseCode = prev.getResponseCode(), + formKey = null; + searchPattern = /var FORM_KEY = '(.+)'/; + if (responseCode == "200" && url) { + response = prev.getResponseDataAsString(); + formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; + } + return formKey; + } + + formKey = vars.get("form_key_storage"); + + currentFormKey = getFormKeyFromResponse(); + + if (currentFormKey != null && currentFormKey != formKey) { + vars.put("form_key_storage", currentFormKey); + } + + javascript + mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx + + + + formKey = vars.get("form_key_storage"); + if (formKey + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' + && sampler.getMethod() == "POST") + { + arguments = sampler.getArguments(); + for (i=0; i<arguments.getArgumentCount(); i++) + { + argument = arguments.getArgument(i); + if (argument.getName() == 'form_key' && argument.getValue() != formKey) { + log.info("admin form key updated: " + argument.getValue() + " => " + formKey); + argument.setValue(formKey); + } + } + } + + javascript + + + + + + false + mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + get-admin-email + mpaf/tool/fragments/ce/lock_controller.jmx + + + + mpaf/tool/fragments/ce/get_admin_email.jmx + +adminUserList = props.get("adminUserList"); +adminUser = adminUserList.poll(); +if (adminUser == null) { + SampleResult.setResponseMessage("adminUser list is empty"); + SampleResult.setResponseData("adminUser list is empty","UTF-8"); + IsSuccess=false; + SampleResult.setSuccessful(false); + SampleResult.setStopThread(true); +} +vars.put("admin_user", adminUser); + + + + true + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_login/admin_login.jmx + + + + Welcome + <title>Magento Admin</title> + + Assertion.response_data + false + 2 + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + + + + + ^.+$ + + Assertion.response_data + false + 1 + variable + admin_form_key + + + + + + + + + true + + = + true + dummy + + + true + ${admin_form_key} + = + true + form_key + + + true + ${admin_password} + = + true + login[password] + + + true + ${admin_user} + = + true + login[username] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/dashboard/ + POST + true + false + true + false + Java + false + + mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx + + + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + + + mpaf/tool/fragments/ce/admin_create_order/admin_create_order.jmx + import org.apache.jmeter.samplers.SampleResult; +import java.util.Random; +Random random = new Random(); +if (${seedForRandom} > 0) { + random.setSeed(${seedForRandom}); +} +number = random.nextInt(props.get("simple_products_list").size()); +simpleList = props.get("simple_products_list").get(number); +vars.put("simple_product_1_url_key", simpleList.get("url_key")); +vars.put("simple_product_1_name", simpleList.get("title")); +vars.put("simple_product_1_id", simpleList.get("id")); + +do { + number1 = random.nextInt(props.get("simple_products_list").size()); +} while(number == number1); +simpleList = props.get("simple_products_list").get(number1); +vars.put("simple_product_2_url_key", simpleList.get("url_key")); +vars.put("simple_product_2_name", simpleList.get("title")); +vars.put("simple_product_2_id", simpleList.get("id")); + +number = random.nextInt(props.get("configurable_products_list").size()); +configurableList = props.get("configurable_products_list").get(number); +vars.put("configurable_product_1_url_key", configurableList.get("url_key")); +vars.put("configurable_product_1_name", configurableList.get("title")); +vars.put("configurable_product_1_id", configurableList.get("id")); +vars.put("configurable_product_1_sku", configurableList.get("sku")); +vars.put("configurable_attribute_id", configurableList.get("attribute_id")); +vars.put("configurable_option_id", configurableList.get("attribute_option_id")); + + +customers_index = 0; +if (!props.containsKey("customer_ids_index")) { + props.put("customer_ids_index", customers_index); +} + +try { + customers_index = props.get("customer_ids_index"); + customers_list = props.get("customer_ids_list"); + + if (customers_index == customers_list.size()) { + customers_index=0; + } + vars.put("customer_id", customers_list.get(customers_index)); + props.put("customer_ids_index", ++customers_index); +} +catch (java.lang.Exception e) { + log.error("Caught Exception in 'Admin Create Order' thread."); + SampleResult.setStopThread(true); +} + + + true + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order_create/start/ + GET + true + false + true + false + false + + Detected the start of a redirect chain + + + + + + + + Content-Type + application/json + + + Accept + */* + + + + + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/integration/admin/token + POST + true + false + true + false + false + + + + + admin_token + $ + + + BODY + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + admin_token + + + + + + + Authorization + Bearer ${admin_token} + + + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/configurable-products/${configurable_product_1_sku}/options/all + GET + true + false + true + false + false + + + + + attribute_ids + $.[*].attribute_id + NO_VALUE + + BODY + + + + option_values + $.[*].values[0].value_index + NO_VALUE + + BODY + + + + + + + + + true + item[${simple_product_1_id}][qty] + 1 + = + true + + + true + item[${simple_product_2_id}][qty] + 1 + = + true + + + true + item[${configurable_product_1_id}][qty] + 1 + = + true + + + true + customer_id + ${customer_id} + = + true + + + true + store_id + 1 + = + true + + + true + currency_id + + = + true + + + true + form_key + ${admin_form_key} + = + true + + + true + payment[method] + checkmo + = + true + + + true + reset_shipping + 1 + = + true + + + true + json + 1 + = + true + + + true + as_js_varname + iFrameResponse + = + true + + + true + form_key + ${admin_form_key} + = + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order_create/loadBlock/block/search,items,shipping_method,totals,giftmessage,billing_method?isAjax=true + POST + true + false + true + false + false + + Detected the start of a redirect chain + + + + false + + + try { + attribute_ids = vars.get("attribute_ids"); + option_values = vars.get("option_values"); + attribute_ids = attribute_ids.replace("[","").replace("]","").replace("\"", ""); + option_values = option_values.replace("[","").replace("]","").replace("\"", ""); + attribute_ids_array = attribute_ids.split(","); + option_values_array = option_values.split(","); + args = ctx.getCurrentSampler().getArguments(); + it = args.iterator(); + while (it.hasNext()) { + argument = it.next(); + if (argument.getStringValue().contains("${")) { + args.removeArgument(argument.getName()); + } + } + for (int i = 0; i < attribute_ids_array.length; i++) { + + ctx.getCurrentSampler().addArgument("item[" + vars.get("configurable_product_1_id") + "][super_attribute][" + attribute_ids_array[i] + "]", option_values_array[i]); + } +} catch (Exception e) { + log.error("error???", e); +} + + + + + + + + true + collect_shipping_rates + 1 + = + true + + + true + customer_id + ${customer_id} + = + true + + + true + store_id + 1 + = + true + + + true + currency_id + false + = + true + + + true + form_key + ${admin_form_key} + = + true + + + true + payment[method] + checkmo + = + true + + + true + json + true + = + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order_create/loadBlock/block/shipping_method,totals?isAjax=true + POST + true + false + true + false + false + + + + + + shipping_method + Flat Rate + + Assertion.response_data + false + 2 + + + + + + + + true + form_key + ${admin_form_key} + = + true + + + true + limit + 20 + = + true + + + true + entity_id + + = + true + + + true + name + + = + true + + + true + email + + = + true + + + true + Telephone + + = + true + + + true + billing_postcode + + = + true + + + true + billing_country_id + + = + true + + + true + billing_regione + + = + true + + + true + store_name + + = + true + + + true + page + 1 + = + true + + + true + order[currency] + USD + = + true + + + true + sku + + = + true + + + true + qty + + = + true + + + true + limit + 20 + = + true + + + true + entity_id + + = + true + + + true + name + + = + true + + + true + sku + + = + true + + + true + price[from] + + = + true + + + true + price[to] + + = + true + + + true + in_products + + = + true + + + true + page + 1 + = + true + + + true + coupon_code + + = + true + + + true + order[account][group_id] + 1 + = + true + + + true + order[account][email] + user_${customer_id}@example.com + = + true + + + true + order[billing_address][customer_address_id] + + = + true + + + true + order[billing_address][prefix] + + = + true + + + true + order[billing_address][firstname] + Anthony + = + true + + + true + order[billing_address][middlename] + + = + true + + + true + order[billing_address][lastname] + Nealy + = + true + + + true + order[billing_address][suffix] + + = + true + + + true + order[billing_address][company] + + = + true + + + true + order[billing_address][street][0] + 123 Freedom Blvd. #123 + = + true + + + true + order[billing_address][street][1] + + = + true + + + true + order[billing_address][city] + Fayetteville + = + true + + + true + order[billing_address][country_id] + US + = + true + + + true + order[billing_address][region] + + = + true + + + true + order[billing_address][region_id] + 5 + = + true + + + true + order[billing_address][postcode] + 123123 + = + true + + + true + order[billing_address][telephone] + 022-333-4455 + = + true + + + true + order[billing_address][fax] + + = + true + + + true + order[billing_address][vat_id] + + = + true + + + true + shipping_same_as_billing + on + = + true + + + true + payment[method] + checkmo + = + true + + + true + order[shipping_method] + flatrate_flatrate + = + true + + + true + order[comment][customer_note] + + = + true + + + true + order[comment][customer_note_notify] + 1 + = + true + + + true + order[send_confirmation] + 1 + = + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order_create/save/ + POST + true + false + true + true + false + + Detected the start of a redirect chain + + + + false + order_id + ${host}${base_path}${admin_path}/sales/order/index/order_id/(\d+)/ + $1$ + + 1 + + + + false + order_item_1 + order_item_(\d+)_title + $1$ + + 1 + + + + false + order_item_2 + order_item_(\d+)_title + $1$ + + 2 + + + + false + order_item_3 + order_item_(\d+)_title + $1$ + + 3 + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + order_id + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + order_item_1 + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + order_item_2 + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + order_item_3 + + + + + You created the order. + + Assertion.response_data + false + 2 + + + + + + + + true + form_key + ${admin_form_key} + = + true + + + true + invoice[items][${order_item_1}] + 1 + = + true + + + true + invoice[items][${order_item_2}] + 1 + = + true + + + true + invoice[items][${order_item_3}] + 1 + = + true + + + true + invoice[comment_text] + + = + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/sales/order_invoice/save/order_id/${order_id}/ + POST + true + false + true + false + false + + Detected the start of a redirect chain + + + + + The invoice has been created. + + Assertion.response_data + false + 2 + + + + + + + + true + form_key + ${admin_form_key} + = + true + + + true + shipment[items][${order_item_1}] + 1 + = + true + + + true + shipment[items][${order_item_2}] + 1 + = + true + + + true + shipment[items][${order_item_3}] + 1 + = + true + + + true + shipment[comment_text] + + = + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/order_shipment/save/order_id/${order_id}/ + POST + true + false + true + false + false + + Detected the start of a redirect chain + + + + + The shipment has been created. + + Assertion.response_data + false + 2 + + + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/auth/logout/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/setup/admin_logout.jmx + + + + false + + + +adminUserList = props.get("adminUserList"); +adminUserList.add(vars.get("admin_user")); + + mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx + + + + + + + + + continue + + false + ${loops} + + ${apiPoolUsers} + ${ramp_period} + 1505803944000 + 1505803944000 + false + + + mpaf/tool/fragments/_system/thread_group.jmx + + + 1 + false + 1 + ${apiBasePercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "API"); + + true + + + + + + + Content-Type + application/json + + + Accept + */* + + + mpaf/tool/fragments/ce/api/header_manager_before_token.jmx + + + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/integration/admin/token + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/admin_token_retrieval.jmx + + + admin_token + $ + + + BODY + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + admin_token + + + + + + + + Authorization + Bearer ${admin_token} + + + mpaf/tool/fragments/ce/api/header_manager.jmx + + + + 1 + false + 1 + 100 + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "API Create Customer"); + + true + + + + + true + + + + false + { + "customer": { + + "email": "customer_${__time()}-${__threadNum}-${__Random(1,1000000)}@example.com", + "firstname": "test_${__time()}-${__threadNum}-${__Random(1,1000000)}", + "lastname": "Doe" + }, + "password": "test@123" +} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/customers + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/create_customer.jmx + + + customer_id + $.id + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + customer_id + + + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/customers/${customer_id} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/api/check_customer.jmx + + + $.id + ${customer_id} + true + false + false + + + + + + + + 1 + false + 1 + 100 + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "API Catalog Browsing"); + + true + + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/categories + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/api/get_categories.jmx + + + + errors + + Assertion.response_data + false + 6 + variable + + + + + search_category_id + $.id + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + search_category_id + + + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/categories/${search_category_id} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/api/get_category.jmx + + + + errors + + Assertion.response_data + false + 6 + variable + + + + + + + + + + true + 20 + = + true + searchCriteria[page_size] + true + + + true + 1 + = + true + searchCriteria[current_page] + true + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/api/get_products.jmx + + + + errors + + Assertion.response_data + false + 6 + variable + + + + + + + + + 1 + false + 1 + 100 + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "API Search"); + + true + + + + + + + + true + quick_search_container + = + true + searchCriteria[request_name] + + + true + search_term + = + true + searchCriteria[filter_groups][0][filters][0][field] + + + true + Simple + = + true + searchCriteria[filter_groups][0][filters][0][value] + + + true + 20 + = + true + searchCriteria[page_size] + + + true + 1 + = + true + searchCriteria[current_page] + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/search + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/api/search_for_product_frontend.jmx + + + $.total_count + 0 + true + false + true + + + + search_product_id + $.items[0].id + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + search_product_id + + + + + + + + 1 + false + 1 + 100 + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "API Checkout"); + + true + + + + + mpaf/tool/fragments/ce/common/init_random_generator_setup.jmx + +import java.util.Random; + +Random random = new Random(); +if (${seedForRandom} > 0) { + random.setSeed(${seedForRandom} + ${__threadNum}); +} + +vars.putObject("randomIntGenerator", random); + + + + true + + + + + +import java.util.Random; + +Random random = vars.getObject("randomIntGenerator"); +number = random.nextInt(props.get("simple_products_list").size()); +product = props.get("simple_products_list").get(number); + +vars.put("product_url_key", product.get("url_key")); +vars.put("product_id", product.get("id")); +vars.put("product_name", product.get("title")); +vars.put("product_uenc", product.get("uenc")); +vars.put("product_sku", product.get("sku")); + + + + true + mpaf/tool/fragments/ce/product_browsing_and_adding_items_to_the_cart/simple_products_setup.jmx + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/carts + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/create_quote.jmx + + + quote_id + $ + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + quote_id + + + + + + true + + + + false + { + "cartItem": { + "sku": "${product_sku}", + "qty":"1", + "quote_id":"${quote_id}" + } +} + + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/carts/${quote_id}/items + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/add_product_to_quote_hardwired_sku.jmx + + + + $.sku + ${product_sku} + true + false + false + + + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/carts/${quote_id}/items + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/api/check_product_in_quote_hardwired_sku.jmx + + + $[0].sku + ${product_sku} + true + false + false + + + + + + true + + + + false + { + "storeId": 1 +} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/guest-carts/ + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/create_guest_cart.jmx + + + cart_id + $ + + + BODY + + + + + ^.+$ + + Assertion.response_data + false + 1 + variable + cart_id + + + + + + true + + + + false + { + "cartItem": { + "sku": "${product_sku}", + "qty":"1", + "quote_id":"${cart_id}" + } +} + + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/guest-carts/${cart_id}/items + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/add_product_to_guest_cart_hardwired_sku.jmx + + + $.quote_id + ^[a-z0-9-]+$ + true + false + false + + + + + + true + + + + false + { + "sender": "John Doe", + "recipient": "Jane Roe", + "giftMessage": "Gift Message Text" +} + + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/guest-carts/${cart_id}/gift-message + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/add_gift_message_to_guest_cart.jmx + + + $ + true + true + false + false + + + + + + true + + + + false + {"address":{"country_id":"US","postcode":"95630"}} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/guest-carts/${cart_id}/estimate-shipping-methods + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/guest_checkout/checkout_estimate_shipping_methods_with_postal_code.jmx + + + + + Referer + ${base_path}checkout/onepage/ + + + Content-Type + application/json; charset=UTF-8 + + + X-Requested-With + XMLHttpRequest + + + Accept + application/json + + + + + + + "available":true + + Assertion.response_data + false + 2 + + + + + + true + + + + false + {"addressInformation":{"shipping_address":{"countryId":"US","regionId":"12","regionCode":"CA","region":"California","street":["10441 Jefferson Blvd ste 200"],"company":"","telephone":"3109450345","fax":"","postcode":"90232","city":"Culver City","firstname":"Name","lastname":"Lastname"},"shipping_method_code":"flatrate","shipping_carrier_code":"flatrate"}} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/guest-carts/${cart_id}/shipping-information + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/guest_checkout/checkout_billing_shipping_information.jmx + + + + + Referer + ${base_path}checkout/onepage/ + + + Content-Type + application/json; charset=UTF-8 + + + X-Requested-With + XMLHttpRequest + + + Accept + application/json + + + + + + + {"payment_methods": + + Assertion.response_data + false + 2 + + + + + + true + + + + false + {"cartId":"${cart_id}","email":"test@example.com","paymentMethod":{"method":"checkmo","po_number":null,"additional_data":null},"billingAddress":{"countryId":"US","regionId":"12","regionCode":"CA","region":"California","street":["10441 Jefferson Blvd ste 200"],"company":"","telephone":"3109450345","fax":"","postcode":"90232","city":"Culver City","firstname":"Name","lastname":"Lastname","save_in_address_book":0}} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/guest-carts/${cart_id}/payment-information + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/checkout_payment_info_place_order.jmx + + + + + Referer + ${base_path}checkout/onepage/ + + + Content-Type + application/json; charset=UTF-8 + + + X-Requested-With + XMLHttpRequest + + + Accept + application/json + + + + + + + "[0-9]+" + + Assertion.response_data + false + 2 + + + + order_id + $ + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + order_id + + + + + + + + 1 + false + 1 + 100 + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "API Product Management"); + + true + + + + + true + + + + false + { + "product": { + "sku": "psku-test-${__time()}-${__threadNum}-${__Random(1,1000000)}", + "name": "Product_${__time()}-${__threadNum}-${__Random(1,1000000)}", + "attributeSetId": 4 + } +} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/create_product_no_custom_attributes.jmx + + + simple_product_id + $.id + + + BODY + + + + simple_product_sku + $.sku + + + BODY + + + + simple_stock_item_id + $.extension_attributes.stock_item.item_id + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + simple_product_id + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + simple_product_sku + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + simple_stock_item_id + + + + + + true + + + + false + { + "stock_item": { + "manage_stock": true, + "is_in_stock": true, + "qty": ${simple_product_id} + } + } + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products/${simple_product_sku}/stockItems/${simple_stock_item_id} + PUT + true + false + true + false + false + + mpaf/tool/fragments/ce/api/update_product_stock_info.jmx + + + $ + ${simple_stock_item_id} + true + false + false + + + + + + true + + + + true + + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products/${simple_product_sku} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/api/check_product.jmx + + + $.sku + ${simple_product_sku} + true + false + false + + + + $.id + ${simple_product_id} + true + false + false + + + + $.extension_attributes.stock_item.item_id + ${simple_stock_item_id} + true + false + false + + + + $.extension_attributes.stock_item.qty + ${simple_product_id} + true + false + false + + + + + + true + + + + false + { + "product": { + "sku": "apsku-test-${__time()}-${__threadNum}-${__Random(1,1000000)}", + "name": "Extensible_Product_${__time()}-${__threadNum}-${__Random(1,1000000)}", + "visibility": "4", + "type_id": "simple", + "price": "3.62", + "status": "1", + "attribute_set_id": "4", + "custom_attributes": [ + { + "attribute_code": "cost", + "value": "" + }, + { + "attribute_code": "description", + "value": "Description" + } + ], + "extension_attributes":{ + "stock_item":{ + "manage_stock": true, + "is_in_stock": true, + "qty":"100" + } + } , + "media_gallery_entries": + [{ + "id": null, + "label":"test_label_${__time()}-${__threadNum}-${__Random(1,1000000)}", + "position":1, + "disabled":false, + "media_type":"image", + "types":["image"], + "content":{ + "base64_encoded_data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABgAGADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iioLy8t9Ps5bu7lWKCIZd26KKaTbshpX0RPRXN/8J/4V/6DVv8Ak3+FH/Cf+Ff+g1b/AJN/hXR9SxP/AD7l9zNPYVf5X9x0lFc3/wAJ/wCFf+g1b/k3+FH/AAn/AIV/6DVv+Tf4UfUsT/z7l9zD2FX+V/cdJRXN/wDCf+Ff+g1b/k3+FH/Cf+Ff+g1b/k3+FH1LE/8APuX3MPYVf5X9x0lFc3/wn/hX/oNW/wCTf4Uf8J/4V/6DVv8Ak3+FH1LE/wDPuX3MPYVf5X9x0lFVdP1G01WyS8sZ1nt3JCyL0ODg/qKtVzyi4u0lZmbTTswrm/H3/Iiav/1x/wDZhXSVzfj7/kRNX/64/wDswrowf+80/wDEvzNKH8WPqj5voorB1zS7OLT7m7SHE5YNu3HqWGeM471+kYutOhSdSEU7Jt3dtF20f6H1FacqcHJK9vO36M3qKzTa6foqPdxwlWxswrFi2T0AJ9aRdVmjkT7XYSW8TsFEm8MAT0yB0qfrcafu1tJeV2l2u7K3zsL2yjpPR+V3+NjTorPn1GVbt7a1s2uJIwDJ84ULnpyaik1SWTTrp47Z0uIQRJGzAFOPvZ70Sx1GLau9L9H03SdrNrsgdeCuu3k+hq0VR0ma4msImuIih2LtYvuLjA+b2zV6uijUVWmprqaQkpxUl1PoP4Xf8iBYf78v/oxq7GuO+F3/ACIFh/vy/wDoxq7GvzTMf98q/wCJ/mfLYn+NP1YVzfj7/kRNX/64/wDswrpK5vx9/wAiJq//AFx/9mFRg/8Aeaf+JfmTQ/ix9UfN9ZniD/kB3H/Af/QhWnTZI45kKSIroeqsMg1+l4mk61GdNfaTX3o+pqw54Sj3Rma/GXsI3BcLFMruU+8F5yR+dUZ4tOeNFOq3tx5jACNZg5J+mK6PrUMdrbxPvjgiR/7yoAa48TgPa1HNW1STvfp2s1+JjVw/PJy017mbe/YTqTB7iWzuQgPmhtocfjwajiupbjTtTieUXCxRsqTKMb8qePwrYlghnAE0UcgHQOoP86ckaRoERFVR/CowKbwU3UclJJO+19brqr203vvoHsJczd7J3/H8PmVNJnhm063WOVHZIkDhTkqcd/yNXajighg3eTFHHu67FAz+VSV2UIShTjGe67G9NOMUpbn0H8Lv+RAsP9+X/wBGNXY1x3wu/wCRAsP9+X/0Y1djX5tmP++Vf8T/ADPl8T/Gn6sK5vx9/wAiJq//AFx/9mFdJXN+Pv8AkRNX/wCuP/swqMH/ALzT/wAS/Mmh/Fj6o+b6KKK/Uj60KKKKACiiigAooooA+g/hd/yIFh/vy/8Aoxq7GuO+F3/IgWH+/L/6Mauxr8wzH/fKv+J/mfKYn+NP1YVzfj7/AJETV/8Arj/7MK6Sub8ff8iJq/8A1x/9mFRg/wDeaf8AiX5k0P4sfVHzfRRRX6kfWhRRRQAUUUUAFFFFAH0H8Lv+RAsP9+X/ANGNXY1x3wu/5ECw/wB+X/0Y1djX5hmP++Vf8T/M+UxP8afqwqC8s7fULOW0u4llglGHRujCp6K5E2ndGKdtUc3/AMIB4V/6Atv+bf40f8IB4V/6Atv+bf410lFdH13E/wDPyX3s09vV/mf3nN/8IB4V/wCgLb/m3+NH/CAeFf8AoC2/5t/jXSUUfXcT/wA/Jfew9vV/mf3nN/8ACAeFf+gLb/m3+NH/AAgHhX/oC2/5t/jXSUUfXcT/AM/Jfew9vV/mf3nN/wDCAeFf+gLb/m3+NH/CAeFf+gLb/m3+NdJRR9dxP/PyX3sPb1f5n95V0/TrTSrJLOxgWC3QkrGvQZOT+pq1RRXPKTk7yd2Zttu7P//Z", + "type": "image/jpeg", + "name": "test_image_${__time(YMDHMS)}-${__threadNum}-${__Random(1,1000000)}.jpeg" + } + } + ] + } +} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/create_product_with_extensible_data_objects.jmx + + + simple_product_id + $.id + + + BODY + + + + simple_product_sku + $.sku + + + BODY + + + + simple_stock_item_id + $.extension_attributes.stock_item.item_id + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + simple_product_id + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + simple_product_sku + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + simple_stock_item_id + + + + + + true + + + + true + + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products/${simple_product_sku} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/api/check_product_with_extensible_data_objects.jmx + + + $.sku + ${simple_product_sku} + true + false + false + + + + $.id + ${simple_product_id} + true + false + false + + + + $.extension_attributes.stock_item.item_id + ${simple_stock_item_id} + true + false + false + + + + $.extension_attributes.stock_item.qty + 100 + true + false + false + + + + + + + + + + + + continue + + false + ${loops} + + ${deadLocksPoolUsers} + ${ramp_period} + 1505803944000 + 1505803944000 + false + + + mpaf/tool/fragments/_system/thread_group.jmx + + + 1 + false + 1 + ${productGridMassActionPercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "Product Grid Mass Actions"); + + true + + + + + + function getFormKeyFromResponse() + { + var url = prev.getUrlAsString(), + responseCode = prev.getResponseCode(), + formKey = null; + searchPattern = /var FORM_KEY = '(.+)'/; + if (responseCode == "200" && url) { + response = prev.getResponseDataAsString(); + formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; + } + return formKey; + } + + formKey = vars.get("form_key_storage"); + + currentFormKey = getFormKeyFromResponse(); + + if (currentFormKey != null && currentFormKey != formKey) { + vars.put("form_key_storage", currentFormKey); + } + + javascript + mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx + + + + formKey = vars.get("form_key_storage"); + if (formKey + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' + && sampler.getMethod() == "POST") + { + arguments = sampler.getArguments(); + for (i=0; i<arguments.getArgumentCount(); i++) + { + argument = arguments.getArgument(i); + if (argument.getName() == 'form_key' && argument.getValue() != formKey) { + log.info("admin form key updated: " + argument.getValue() + " => " + formKey); + argument.setValue(formKey); + } + } + } + + javascript + + + + + + false + mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + get-admin-email + mpaf/tool/fragments/ce/lock_controller.jmx + + + + mpaf/tool/fragments/ce/get_admin_email.jmx + +adminUserList = props.get("adminUserList"); +adminUser = adminUserList.poll(); +if (adminUser == null) { + SampleResult.setResponseMessage("adminUser list is empty"); + SampleResult.setResponseData("adminUser list is empty","UTF-8"); + IsSuccess=false; + SampleResult.setSuccessful(false); + SampleResult.setStopThread(true); +} +vars.put("admin_user", adminUser); + + + + true + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_login/admin_login.jmx + + + + Welcome + <title>Magento Admin</title> + + Assertion.response_data + false + 2 + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + + + + + ^.+$ + + Assertion.response_data + false + 1 + variable + admin_form_key + + + + + + + + + true + + = + true + dummy + + + true + ${admin_form_key} + = + true + form_key + + + true + ${admin_password} + = + true + login[password] + + + true + ${admin_user} + = + true + login[username] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/dashboard/ + POST + true + false + true + false + Java + false + + mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx + + + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + + + + true + ${admin_form_key} + = + true + form_key + + + true + product_listing + = + true + namespace + true + + + true + + = + true + search + true + + + true + true + = + true + filters[placeholder] + true + + + true + 20 + = + true + paging[pageSize] + true + + + true + 1 + = + true + paging[current] + true + + + true + entity_id + = + true + sorting[field] + true + + + true + asc + = + true + sorting[direction] + true + + + true + true + = + true + isAjax + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/mui/index/render/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_browse_products_grid/get_product_pages_count.jmx + + + $.totalRecords + 0 + true + false + true + + + + products_number + $.totalRecords + + + BODY + + + + false + + + var productsPageSize = Integer.parseInt(vars.get("products_page_size")); +var productsTotal = Integer.parseInt(vars.get("products_number")); +var pageCountProducts = Math.round(productsTotal/productsPageSize); + +vars.put("pages_count_product", String.valueOf(pageCountProducts)); + + + + + + +import java.util.Random; +Random random = new Random(); +if (${seedForRandom} > 0) { +random.setSeed(${seedForRandom}); +} +var productsPageSize = Integer.parseInt(vars.get("products_page_size")); +var totalNumberOfPages = Integer.parseInt(vars.get("pages_count_product")); + +// Randomly select a page. +var randomProductsPage = random.nextInt(totalNumberOfPages) + 1; + +// Get the first and last product id on that page. +var lastProductIdOnPage = randomProductsPage * productsPageSize; +var firstProductIdOnPage = lastProductIdOnPage - productsPageSize + 1; + +var randomProductId1 = Math.floor(random.nextInt(productsPageSize)) + firstProductIdOnPage; +var randomProductId2 = Math.floor(random.nextInt(productsPageSize)) + firstProductIdOnPage; +var randomProductId3 = Math.floor(random.nextInt(productsPageSize)) + firstProductIdOnPage; + +vars.put("page_number", String.valueOf(randomProductsPage)); +vars.put("productId1", String.valueOf(randomProductId1)); +vars.put("productId2", String.valueOf(randomProductId2)); +vars.put("productId3", String.valueOf(randomProductId3)); + +var randomQuantity = random.nextInt(1000) + 1; +var randomPrice = random.nextInt(500) + 10; +var randomVisibility = random.nextInt(4) + 1; + +vars.put("quantity", String.valueOf(randomQuantity)); +vars.put("price", String.valueOf(randomPrice)); +vars.put("visibility", String.valueOf(randomVisibility)); + + + + false + mpaf/tool/fragments/ce/admin_browse_products_grid/products_grid_mass_actions/setup.jmx + + + + + + + true + ${admin_form_key} + = + true + form_key + true + + + true + product_listing + = + true + namespace + true + + + true + + = + true + search + true + + + true + true + = + true + filters[placeholder] + true + + + true + ${products_page_size} + = + true + paging[pageSize] + true + + + true + ${page_number} + = + true + paging[current] + true + + + true + entity_id + = + true + sorting[field] + true + + + true + asc + = + true + sorting[direction] + true + + + true + true + = + true + isAjax + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/mui/index/render/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_browse_products_grid/products_grid_mass_actions/display_grid.jmx + + + + totalRecords + + Assertion.response_data + false + 2 + + + + + + + + + true + ${productId1} + = + true + selected[0] + + + true + ${productId2} + = + true + selected[1] + + + true + ${productId3} + = + true + selected[2] + true + + + true + true + = + true + filters[placeholder] + false + + + true + ${admin_form_key} + = + true + form_key + false + + + true + product_listing + = + true + namespace + false + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/catalog/product_action_attribute/edit + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_browse_products_grid/products_grid_mass_actions/display_update_attributes.jmx + + + + Update Attributes + + Assertion.response_data + false + 2 + + + + + + + + + true + true + = + true + isAjax + true + + + true + ${admin_form_key} + = + true + form_key + true + + + true + 1 + = + true + product[product_has_weight] + true + + + true + 1 + = + true + product[use_config_gift_message_available] + true + + + true + 1 + = + true + product[use_config_gift_wrapping_available] + true + + + true + ${quantity} + = + true + inventory[qty] + true + + + true + ${price} + = + true + attributes[price] + + + true + ${visibility} + = + true + attributes[visibility] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/catalog/product_action_attribute/validate + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_browse_products_grid/products_grid_mass_actions/change_attributes.jmx + + + + {"error":false} + + Assertion.response_data + false + 2 + + + + + + + + true + true + = + true + isAjax + false + + + true + ${admin_form_key} + = + true + form_key + false + + + true + 1 + = + true + product[product_has_weight] + true + + + true + 1 + = + true + product[use_config_gift_message_available] + + + true + 1 + = + true + product[use_config_gift_wrapping_available] + true + + + true + ${quantity} + = + true + inventory[qty] + + + true + on + = + true + toggle_price + true + + + true + ${price} + = + true + attributes[price] + + + true + on + = + true + toggle_price + true + + + true + ${visibility} + = + true + attributes[visibility] + + + true + on + = + true + toggle_visibility + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/catalog/product_action_attribute/save/store/0/active_tab/attributes + POST + true + false + true + true + false + + + + + + were updated. + + Assertion.response_data + false + 2 + + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/auth/logout/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/setup/admin_logout.jmx + + + + false + + + +adminUserList = props.get("adminUserList"); +adminUserList.add(vars.get("admin_user")); + + mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx + + + + + + + 1 + false + 1 + ${importProductsPercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "Import Products"); + + true + + + + + + function getFormKeyFromResponse() + { + var url = prev.getUrlAsString(), + responseCode = prev.getResponseCode(), + formKey = null; + searchPattern = /var FORM_KEY = '(.+)'/; + if (responseCode == "200" && url) { + response = prev.getResponseDataAsString(); + formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; + } + return formKey; + } + + formKey = vars.get("form_key_storage"); + + currentFormKey = getFormKeyFromResponse(); + + if (currentFormKey != null && currentFormKey != formKey) { + vars.put("form_key_storage", currentFormKey); + } + + javascript + mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx + + + + formKey = vars.get("form_key_storage"); + if (formKey + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' + && sampler.getMethod() == "POST") + { + arguments = sampler.getArguments(); + for (i=0; i<arguments.getArgumentCount(); i++) + { + argument = arguments.getArgument(i); + if (argument.getName() == 'form_key' && argument.getValue() != formKey) { + log.info("admin form key updated: " + argument.getValue() + " => " + formKey); + argument.setValue(formKey); + } + } + } + + javascript + + + + + + false + mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + get-admin-email + mpaf/tool/fragments/ce/lock_controller.jmx + + + + mpaf/tool/fragments/ce/get_admin_email.jmx + +adminUserList = props.get("adminUserList"); +adminUser = adminUserList.poll(); +if (adminUser == null) { + SampleResult.setResponseMessage("adminUser list is empty"); + SampleResult.setResponseData("adminUser list is empty","UTF-8"); + IsSuccess=false; + SampleResult.setSuccessful(false); + SampleResult.setStopThread(true); +} +vars.put("admin_user", adminUser); + + + + true + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_login/admin_login.jmx + + + + Welcome + <title>Magento Admin</title> + + Assertion.response_data + false + 2 + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + + + + + ^.+$ + + Assertion.response_data + false + 1 + variable + admin_form_key + + + + + + + + + true + + = + true + dummy + + + true + ${admin_form_key} + = + true + form_key + + + true + ${admin_password} + = + true + login[password] + + + true + ${admin_user} + = + true + login[username] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/dashboard/ + POST + true + false + true + false + Java + false + + mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx + + + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + vars.put("entity", "catalog_product"); +String behavior = "${adminImportProductBehavior}"; +vars.put("adminImportBehavior", behavior); +String filepath = "${files_folder}${adminImportProductFilePath}"; +vars.put("adminImportFilePath", filepath); + + + true + mpaf/tool/fragments/ce/import_products/setup.jmx + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/import/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/common/import.jmx + + + + Import Settings + + Assertion.response_data + false + 2 + + + + + + + + + true + ${admin_form_key} + = + true + form_key + false + + + true + ${entity} + = + true + entity + + + true + ${adminImportBehavior} + = + true + behavior + + + true + validation-stop-on-errors + = + true + validation_strategy + + + true + 10 + = + true + allowed_error_count + + + true + , + = + true + _import_field_separator + + + true + , + = + true + _import_multiple_value_separator + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/import/validate + POST + true + false + true + false + HttpClient4 + + + + ${adminImportFilePath} + import_file + application/vnd.ms-excel + + + + false + + mpaf/tool/fragments/ce/common/import_validate.jmx + + + + File is valid! To start import process + + Assertion.response_data + false + 16 + + + + + + + + + true + ${admin_form_key} + = + true + form_key + false + + + true + ${entity} + = + true + entity + + + true + ${adminImportBehavior} + = + true + behavior + + + true + validation-stop-on-errors + = + true + validation_strategy + false + + + true + 10 + = + true + allowed_error_count + false + + + true + , + = + true + _import_field_separator + false + + + true + , + = + true + _import_multiple_value_separator + false + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/import/start + POST + true + false + true + false + HttpClient4 + + + + ${adminImportFilePath} + import_file + application/vnd.ms-excel + + + + false + + mpaf/tool/fragments/ce/common/import_save.jmx + + + + Import successfully done + + Assertion.response_data + false + 16 + + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/auth/logout/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/setup/admin_logout.jmx + + + + false + + + +adminUserList = props.get("adminUserList"); +adminUserList.add(vars.get("admin_user")); + + mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx + + + + + + + 1 + false + 1 + ${importCustomersPercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "Import Customers"); + + true + + + + + + function getFormKeyFromResponse() + { + var url = prev.getUrlAsString(), + responseCode = prev.getResponseCode(), + formKey = null; + searchPattern = /var FORM_KEY = '(.+)'/; + if (responseCode == "200" && url) { + response = prev.getResponseDataAsString(); + formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; + } + return formKey; + } + + formKey = vars.get("form_key_storage"); + + currentFormKey = getFormKeyFromResponse(); + + if (currentFormKey != null && currentFormKey != formKey) { + vars.put("form_key_storage", currentFormKey); + } + + javascript + mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx + + + + formKey = vars.get("form_key_storage"); + if (formKey + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' + && sampler.getMethod() == "POST") + { + arguments = sampler.getArguments(); + for (i=0; i<arguments.getArgumentCount(); i++) + { + argument = arguments.getArgument(i); + if (argument.getName() == 'form_key' && argument.getValue() != formKey) { + log.info("admin form key updated: " + argument.getValue() + " => " + formKey); + argument.setValue(formKey); + } + } + } + + javascript + + + + + + false + mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + get-admin-email + mpaf/tool/fragments/ce/lock_controller.jmx + + + + mpaf/tool/fragments/ce/get_admin_email.jmx + +adminUserList = props.get("adminUserList"); +adminUser = adminUserList.poll(); +if (adminUser == null) { + SampleResult.setResponseMessage("adminUser list is empty"); + SampleResult.setResponseData("adminUser list is empty","UTF-8"); + IsSuccess=false; + SampleResult.setSuccessful(false); + SampleResult.setStopThread(true); +} +vars.put("admin_user", adminUser); + + + + true + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_login/admin_login.jmx + + + + Welcome + <title>Magento Admin</title> + + Assertion.response_data + false + 2 + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + + + + + ^.+$ + + Assertion.response_data + false + 1 + variable + admin_form_key + + + + + + + + + true + + = + true + dummy + + + true + ${admin_form_key} + = + true + form_key + + + true + ${admin_password} + = + true + login[password] + + + true + ${admin_user} + = + true + login[username] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/dashboard/ + POST + true + false + true + false + Java + false + + mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx + + + + + + vars.put("entity", "customer"); +String behavior = "${adminImportCustomerBehavior}"; +vars.put("adminImportBehavior", behavior); +String filepath = "${files_folder}${adminImportCustomerFilePath}"; +vars.put("adminImportFilePath", filepath); + + + true + mpaf/tool/fragments/ce/import_customers/setup.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/import/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/common/import.jmx + + + + Import Settings + + Assertion.response_data + false + 2 + + + + + + + + + true + ${admin_form_key} + = + true + form_key + false + + + true + ${entity} + = + true + entity + + + true + ${adminImportBehavior} + = + true + behavior + + + true + validation-stop-on-errors + = + true + validation_strategy + + + true + 10 + = + true + allowed_error_count + + + true + , + = + true + _import_field_separator + + + true + , + = + true + _import_multiple_value_separator + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/import/validate + POST + true + false + true + false + HttpClient4 + + + + ${adminImportFilePath} + import_file + application/vnd.ms-excel + + + + false + + mpaf/tool/fragments/ce/common/import_validate.jmx + + + + File is valid! To start import process + + Assertion.response_data + false + 16 + + + + + + + + + true + ${admin_form_key} + = + true + form_key + false + + + true + ${entity} + = + true + entity + + + true + ${adminImportBehavior} + = + true + behavior + + + true + validation-stop-on-errors + = + true + validation_strategy + false + + + true + 10 + = + true + allowed_error_count + false + + + true + , + = + true + _import_field_separator + false + + + true + , + = + true + _import_multiple_value_separator + false + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/import/start + POST + true + false + true + false + HttpClient4 + + + + ${adminImportFilePath} + import_file + application/vnd.ms-excel + + + + false + + mpaf/tool/fragments/ce/common/import_save.jmx + + + + Import successfully done + + Assertion.response_data + false + 16 + + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/auth/logout/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/setup/admin_logout.jmx + + + + false + + + +adminUserList = props.get("adminUserList"); +adminUserList.add(vars.get("admin_user")); + + mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx + + + + + + + 1 + false + 1 + ${exportProductsPercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "Export Products"); + + true + + + + + + function getFormKeyFromResponse() + { + var url = prev.getUrlAsString(), + responseCode = prev.getResponseCode(), + formKey = null; + searchPattern = /var FORM_KEY = '(.+)'/; + if (responseCode == "200" && url) { + response = prev.getResponseDataAsString(); + formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; + } + return formKey; + } + + formKey = vars.get("form_key_storage"); + + currentFormKey = getFormKeyFromResponse(); + + if (currentFormKey != null && currentFormKey != formKey) { + vars.put("form_key_storage", currentFormKey); + } + + javascript + mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx + + + + formKey = vars.get("form_key_storage"); + if (formKey + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' + && sampler.getMethod() == "POST") + { + arguments = sampler.getArguments(); + for (i=0; i<arguments.getArgumentCount(); i++) + { + argument = arguments.getArgument(i); + if (argument.getName() == 'form_key' && argument.getValue() != formKey) { + log.info("admin form key updated: " + argument.getValue() + " => " + formKey); + argument.setValue(formKey); + } + } + } + + javascript + + + + + + false + mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + get-admin-email + mpaf/tool/fragments/ce/lock_controller.jmx + + + + mpaf/tool/fragments/ce/get_admin_email.jmx + +adminUserList = props.get("adminUserList"); +adminUser = adminUserList.poll(); +if (adminUser == null) { + SampleResult.setResponseMessage("adminUser list is empty"); + SampleResult.setResponseData("adminUser list is empty","UTF-8"); + IsSuccess=false; + SampleResult.setSuccessful(false); + SampleResult.setStopThread(true); +} +vars.put("admin_user", adminUser); + + + + true + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_login/admin_login.jmx + + + + Welcome + <title>Magento Admin</title> + + Assertion.response_data + false + 2 + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + + + + + ^.+$ + + Assertion.response_data + false + 1 + variable + admin_form_key + + + + + + + + + true + + = + true + dummy + + + true + ${admin_form_key} + = + true + form_key + + + true + ${admin_password} + = + true + login[password] + + + true + ${admin_user} + = + true + login[username] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/dashboard/ + POST + true + false + true + false + Java + false + + mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx + + + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/export/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/common/export.jmx + + + + Export Settings + + Assertion.response_data + false + 2 + + + + + + + + + true + form_key + ${admin_form_key} + = + true + + + true + attribute_code + + = + true + + + true + export_filter[allow_message][] + , + = + true + + + true + export_filter[allow_open_amount] + + = + true + + + true + export_filter[category_ids] + 24,25,26,27,28,29,30 + = + true + + + true + export_filter[configurable_variations] + + = + true + + + true + export_filter[cost][] + , + = + true + + + true + export_filter[country_of_manufacture] + + = + true + + + true + export_filter[created_at] + + = + true + + + true + export_filter[custom_design] + + = + true + + + true + export_filter[custom_design_from][] + , + = + true + + + true + export_filter[custom_design_to][] + , + = + true + + + true + export_filter[custom_layout_update] + + = + true + + + true + export_filter[description] + + = + true + + + true + export_filter[email_template] + + = + true + + + true + export_filter[gallery] + + = + true + + + true + export_filter[gift_message_available] + + = + true + + + true + export_filter[gift_wrapping_available] + + = + true + + + true + export_filter[gift_wrapping_price][] + , + = + true + + + true + export_filter[group_price][] + , + = + true + + + true + export_filter[has_options] + + = + true + + + true + export_filter[image] + + = + true + + + true + export_filter[image_label] + + = + true + + + true + export_filter[is_redeemable][] + , + = + true + + + true + export_filter[is_returnable] + + = + true + + + true + export_filter[lifetime][] + , + = + true + + + true + export_filter[links_exist][] + , + = + true + + + true + export_filter[links_purchased_separately][] + , + = + true + + + true + export_filter[links_title] + + = + true + + + true + export_filter[media_gallery] + + = + true + + + true + export_filter[meta_description] + + = + true + + + true + export_filter[meta_keyword] + + = + true + + + true + export_filter[meta_title] + + = + true + + + true + export_filter[minimal_price][] + , + = + true + + + true + export_filter[msrp][] + , + = + true + + + true + export_filter[msrp_display_actual_price_type] + + = + true + + + true + export_filter[name] + + = + true + + + true + export_filter[news_from_date][] + , + = + true + + + true + export_filter[news_to_date][] + , + = + true + + + true + export_filter[old_id][] + , + = + true + + + true + export_filter[open_amount_max][] + , + = + true + + + true + export_filter[open_amount_min][] + , + = + true + + + true + export_filter[options_container] + + = + true + + + true + export_filter[page_layout] + + = + true + + + true + export_filter[price][] + , + = + true + + + true + export_filter[price_type][] + , + = + true + + + true + export_filter[price_view] + + = + true + + + true + export_filter[quantity_and_stock_status] + + = + true + + + true + export_filter[related_tgtr_position_behavior][] + , + = + true + + + true + export_filter[related_tgtr_position_limit][] + , + = + true + + + true + export_filter[required_options] + + = + true + + + true + export_filter[samples_title] + + = + true + + + true + export_filter[shipment_type][] + , + = + true + + + true + export_filter[short_description] + + = + true + + + true + export_filter[sku] + + = + true + + + true + export_filter[sku_type][] + , + = + true + + + true + export_filter[small_image] + + = + true + + + true + export_filter[small_image_label] + + = + true + + + true + export_filter[special_from_date][] + , + = + true + + + true + export_filter[special_price][] + , + = + true + + + true + export_filter[special_to_date][] + , + = + true + + + true + export_filter[status] + + = + true + + + true + export_filter[tax_class_id] + + = + true + + + true + export_filter[thumbnail] + + = + true + + + true + export_filter[thumbnail_label] + + = + true + + + true + export_filter[tier_price][] + , + = + true + + + true + export_filter[updated_at] + + = + true + + + true + export_filter[upsell_tgtr_position_behavior][] + , + = + true + + + true + export_filter[upsell_tgtr_position_limit][] + , + = + true + + + true + export_filter[url_key] + + = + true + + + true + export_filter[url_path] + + = + true + + + true + export_filter[use_config_allow_message][] + , + = + true + + + true + export_filter[use_config_email_template][] + , + = + true + + + true + export_filter[use_config_is_redeemable][] + , + = + true + + + true + export_filter[use_config_lifetime][] + , + = + true + + + true + export_filter[visibility] + + = + true + + + true + export_filter[weight][] + , + = + true + + + true + export_filter[weight_type][] + , + = + true + + + true + frontend_label + + = + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/export/export/entity/catalog_product/file_format/csv + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/export_products/export_products.jmx + + + + Simple Product 1 + + Assertion.response_data + false + 16 + + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/auth/logout/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/setup/admin_logout.jmx + + + + false + + + +adminUserList = props.get("adminUserList"); +adminUserList.add(vars.get("admin_user")); + + mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx + + + + + + + 1 + false + 1 + ${exportCustomersPercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "Export Customers"); + + true + + + + + + function getFormKeyFromResponse() + { + var url = prev.getUrlAsString(), + responseCode = prev.getResponseCode(), + formKey = null; + searchPattern = /var FORM_KEY = '(.+)'/; + if (responseCode == "200" && url) { + response = prev.getResponseDataAsString(); + formKey = response && response.match(searchPattern) ? response.match(searchPattern)[1] : null; + } + return formKey; + } + + formKey = vars.get("form_key_storage"); + + currentFormKey = getFormKeyFromResponse(); + + if (currentFormKey != null && currentFormKey != formKey) { + vars.put("form_key_storage", currentFormKey); + } + + javascript + mpaf/tool/fragments/ce/admin/handle_admin_form_key.jmx + + + + formKey = vars.get("form_key_storage"); + if (formKey + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' + && sampler.getMethod() == "POST") + { + arguments = sampler.getArguments(); + for (i=0; i<arguments.getArgumentCount(); i++) + { + argument = arguments.getArgument(i); + if (argument.getName() == 'form_key' && argument.getValue() != formKey) { + log.info("admin form key updated: " + argument.getValue() + " => " + formKey); + argument.setValue(formKey); + } + } + } + + javascript + + + + + + false + mpaf/tool/fragments/ce/http_cookie_manager_without_clear_each_iteration.jmx + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + get-admin-email + mpaf/tool/fragments/ce/lock_controller.jmx + + + + mpaf/tool/fragments/ce/get_admin_email.jmx + +adminUserList = props.get("adminUserList"); +adminUser = adminUserList.poll(); +if (adminUser == null) { + SampleResult.setResponseMessage("adminUser list is empty"); + SampleResult.setResponseData("adminUser list is empty","UTF-8"); + IsSuccess=false; + SampleResult.setSuccessful(false); + SampleResult.setStopThread(true); +} +vars.put("admin_user", adminUser); + + + + true + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path} + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/admin_login/admin_login.jmx + + + + Welcome + <title>Magento Admin</title> + + Assertion.response_data + false + 2 + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + + + + + ^.+$ + + Assertion.response_data + false + 1 + variable + admin_form_key + + + + + + + + + true + + = + true + dummy + + + true + ${admin_form_key} + = + true + form_key + + + true + ${admin_password} + = + true + login[password] + + + true + ${admin_user} + = + true + login[username] + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/dashboard/ + POST + true + false + true + false + Java + false + + mpaf/tool/fragments/ce/admin_login/admin_login_submit_form.jmx + + + + false + admin_form_key + <input name="form_key" type="hidden" value="([^'"]+)" /> + $1$ + + 1 + mpaf/tool/fragments/ce/admin_login/admin_retrieve_form_key.jmx + + + + + + mpaf/tool/fragments/ce/simple_controller.jmx + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/export/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/common/export.jmx + + + + Export Settings + + Assertion.response_data + false + 2 + + + + + + + + + true + ${admin_form_key} + = + true + form_key + false + + + true + + = + true + attribute_code + true + + + true + + = + true + export_filter[confirmation] + true + + + true + + = + true + export_filter[created_at] + true + + + true + + = + true + export_filter[created_in] + true + + + true + , + = + true + export_filter[default_billing][] + true + + + true + , + = + true + export_filter[default_shipping][] + true + + + true + + = + true + export_filter[disable_auto_group_change] + true + + + true + , + = + true + export_filter[dob][] + true + + + true + + = + true + export_filter[email] + true + + + true + + = + true + export_filter[firstname] + true + + + true + + = + true + export_filter[gender] + true + + + true + + = + true + export_filter[group_id] + true + + + true + + = + true + export_filter[lastname] + true + + + true + + = + true + export_filter[middlename] + true + + + true + + = + true + export_filter[password_hash] + true + + + true + + = + true + export_filter[prefix] + true + + + true + , + = + true + export_filter[reward_update_notification][] + true + + + true + , + = + true + export_filter[reward_warning_notification][] + true + + + true + + = + true + export_filter[rp_token] + true + + + true + , + = + true + export_filter[rp_token_created_at][] + true + + + true + + = + true + export_filter[store_id] + true + + + true + + = + true + export_filter[suffix] + true + + + true + + = + true + export_filter[taxvat] + true + + + true + + = + true + export_filter[website_id] + true + + + true + + = + true + frontend_label + true + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/export/export/entity/customer/file_format/csv + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/export_customers/export_customers.jmx + + + + user_1@example.com + + Assertion.response_data + false + 16 + + + + + + + + + + + + + + ${request_protocol} + + ${base_path}${admin_path}/admin/auth/logout/ + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/setup/admin_logout.jmx + + + + false + + + +adminUserList = props.get("adminUserList"); +adminUserList.add(vars.get("admin_user")); + + mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx + + + + + + + 1 + false + 1 + ${apiBasePercentage} + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "API"); + + true + + + + + + + Content-Type + application/json + + + Accept + */* + + + mpaf/tool/fragments/ce/api/header_manager_before_token.jmx + + + + true + + + + false + {"username":"${admin_user}","password":"${admin_password}"} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/V1/integration/admin/token + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/admin_token_retrieval.jmx + + + admin_token + $ + + + BODY + + + + + ^[a-z0-9-]+$ + + Assertion.response_data + false + 1 + variable + admin_token + + + + + + + + Authorization + Bearer ${admin_token} + + + mpaf/tool/fragments/ce/api/header_manager.jmx + + + + 1 + false + 1 + 100 + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx + + + + vars.put("testLabel", "API Process Orders"); + + true + + + + + // Each thread gets an equal number of orders, based on how many orders are available. + + int apiProcessOrders = Integer.parseInt("${apiProcessOrders}"); + if (apiProcessOrders > 0) { + ordersPerThread = apiProcessOrders; + } else { + ordersPerThread = 1; + } + + + threadNum = ${__threadNum}; + vars.put("ordersPerThread", String.valueOf(ordersPerThread)); + vars.put("threadNum", String.valueOf(threadNum)); + + + + + false + mpaf/tool/fragments/ce/api/process_orders/setup.jmx + + + + + + + true + status + = + true + searchCriteria[filterGroups][0][filters][0][field] + + + true + Pending + = + true + searchCriteria[filterGroups][0][filters][0][value] + + + true + ${ordersPerThread} + = + true + searchCriteria[pageSize] + + + true + ${threadNum} + = + true + searchCriteria[current_page] + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/orders + GET + true + false + true + false + false + + mpaf/tool/fragments/ce/api/process_orders/get_orders.jmx + + + entity_ids + $.items[*].entity_id + + + BODY + + + + + + entity_ids + order_id + true + mpaf/tool/fragments/ce/api/process_orders/for_each_order.jmx + + + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/order/${order_id}/invoice + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/process_orders/create_invoice.jmx + + + + "\d+" + + Assertion.response_data + false + 2 + + + + + + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/order/${order_id}/ship + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/process_orders/create_shipment.jmx + + + + "\d+" + + Assertion.response_data + false + 2 + + + + + + + + + 1 + false + 1 + 100 + mpaf/tool/fragments/_system/scenario_controller_tmpl.jmx + + + +var testLabel = "${testLabel}" ? " (${testLabel})" : ""; +if (testLabel + && sampler.getClass().getName() == 'org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy' +) { + if (sampler.getName().indexOf(testLabel) == -1) { + sampler.setName(sampler.getName() + testLabel); + } +} else if (sampler.getName().indexOf("SetUp - ") == -1) { + sampler.setName("SetUp - " + sampler.getName()); +} + + javascript + mpaf/tool/fragments/_system/setup_label.jmx - + + + vars.put("testLabel", "API Product Attribute Management"); + + true + + + + + true + + + + false + { + "attributeSet": { + "attribute_set_name": "new_attribute_set_${__time()}-${__threadNum}-${__Random(1,1000000)}", + "sort_order": 500 + }, + "skeletonId": "4" +} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products/attribute-sets/ + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/create_attribute_set.jmx + + + attribute_set_id + $.attribute_set_id + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + attribute_set_id + + - - - - + + true + + + + false + { + "group": { + "attribute_group_name": "empty_attribute_group_${__time()}-${__threadNum}-${__Random(1,1000000)}", + "attribute_set_id": ${attribute_set_id} + } +} + = + + @@ -29967,28 +29835,160 @@ vars.put("admin_user", adminUser); ${request_protocol} - ${base_path}${admin_path}/admin/auth/logout/ - GET + ${base_path}rest/default/V1/products/attribute-sets/groups + POST true false true false false - mpaf/tool/fragments/ce/setup/admin_logout.jmx + mpaf/tool/fragments/ce/api/create_attribute_group.jmx - - - false - - - -adminUserList = props.get("adminUserList"); -adminUserList.add(vars.get("admin_user")); - - mpaf/tool/fragments/ce/common/return_admin_email_to_pool.jmx - + + attribute_group_id + $.attribute_group_id + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + attribute_set_id + + + + + + true + + + + false + { + "attribute": { + "attribute_code": "attr_code_${__time()}", + "frontend_labels": [ + { + "store_id": 0, + "label": "front_lbl_${__time(YMDHMS)}-${__threadNum}-${__Random(1,1000000)}" + } + ], + "default_value": "default value", + "frontend_input": "textarea", + "is_required": true + } +} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products/attributes/ + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/create_attribute.jmx + + + attribute_id + $.attribute_id + + + BODY + + + + attribute_code + $.attribute_code + + + BODY + + + + + ^\d+$ + + Assertion.response_data + false + 1 + variable + attribute_id + + + + + ^[a-z0-9-_]+$ + + Assertion.response_data + false + 1 + variable + attribute_code + + + + + + true + + + + false + { + "attributeSetId": "${attribute_set_id}", + "attributeGroupId": "${attribute_group_id}", + "attributeCode": "${attribute_code}", + "sortOrder": 3 +} + = + + + + + + + + ${request_protocol} + + ${base_path}rest/default/V1/products/attribute-sets/attributes + POST + true + false + true + false + false + + mpaf/tool/fragments/ce/api/add_attribute_to_attribute_set.jmx + + + $ + (\d+) + true + false + false + + + + diff --git a/setup/src/Magento/Setup/Fixtures/OrdersFixture.php b/setup/src/Magento/Setup/Fixtures/OrdersFixture.php index 74ff84189f557..1acad6dbc1787 100644 --- a/setup/src/Magento/Setup/Fixtures/OrdersFixture.php +++ b/setup/src/Magento/Setup/Fixtures/OrdersFixture.php @@ -232,6 +232,12 @@ public function execute() return; } + $ruleId = $this->getMaxEntityId( + 'salesrule', + \Magento\SalesRule\Model\ResourceModel\Rule::class, + 'rule_id' + ); + $maxItemId = $this->getMaxEntityId( 'sales_order_item', \Magento\Sales\Model\ResourceModel\Order\Item::class, @@ -330,6 +336,7 @@ public function execute() '%productStoreId%' => $productStoreId($entityId), '%productStoreName%' => $productStoreName($entityId), '%entityId%' => $entityId, + '%ruleId%' => $ruleId, ]; $shippingAddress = ['%orderAddressId%' => $entityId * 2 - 1, '%addressType%' => 'shipping']; $billingAddress = ['%orderAddressId%' => $entityId * 2, '%addressType%' => 'billing']; diff --git a/setup/src/Magento/Setup/Fixtures/_files/orders_fixture_data.json b/setup/src/Magento/Setup/Fixtures/_files/orders_fixture_data.json index 864ad45533afe..d323246cf6d34 100644 --- a/setup/src/Magento/Setup/Fixtures/_files/orders_fixture_data.json +++ b/setup/src/Magento/Setup/Fixtures/_files/orders_fixture_data.json @@ -102,7 +102,7 @@ "weight": 2.0000, "customer_dob": "NULL", "increment_id": "'%orderNumber%'", - "applied_rule_ids": 1, + "applied_rule_ids": "%ruleId%", "base_currency_code": "'USD'", "customer_email": "'%email%'", "customer_firstname": "NULL", @@ -208,7 +208,7 @@ "sku": "'%sku%'", "name": "'%name%'", "description": "NULL", - "applied_rule_ids": "'1'", + "applied_rule_ids": "'%ruleId%'", "additional_data": "NULL", "is_qty_decimal": "'0'", "no_discount": "'0'", @@ -374,7 +374,7 @@ "customer_note_notify": 1, "customer_is_guest": 1, "remote_ip": "'127.0.0.1'", - "applied_rule_ids": "'1'", + "applied_rule_ids": "'%ruleId%'", "reserved_order_id": "NULL", "password_hash": "NULL", "coupon_code": "NULL", @@ -512,7 +512,7 @@ "sku": "'%sku%'", "name": "'%name%'", "description": "NULL", - "applied_rule_ids": "'1'", + "applied_rule_ids": "'%ruleId%'", "additional_data": "NULL", "is_qty_decimal": "0", "no_discount": "0", diff --git a/setup/src/Magento/Setup/Model/FixtureGenerator/SqlCollector.php b/setup/src/Magento/Setup/Model/FixtureGenerator/SqlCollector.php index 6101e475cd50e..5e34db4dfdfb5 100644 --- a/setup/src/Magento/Setup/Model/FixtureGenerator/SqlCollector.php +++ b/setup/src/Magento/Setup/Model/FixtureGenerator/SqlCollector.php @@ -44,7 +44,7 @@ public function __construct(ResourceConnection $resourceConnection) */ private function addSql($sql, $bind) { - preg_match('~INSERT INTO `(.*)` \((.*)\) VALUES (\(.*\))+~', $sql, $queryMatches); + preg_match('~(?:INSERT|REPLACE)\s+(?:IGNORE)?\s*INTO `(.*)` \((.*)\) VALUES (\(.*\))+~', $sql, $queryMatches); if ($queryMatches) { $table = $queryMatches[1]; $fields = preg_replace('~[\s+`]+~', '', $queryMatches[2]); @@ -121,12 +121,25 @@ public function disable() $this->getProfiler()->setEnabled(false); $queries = $this->getProfiler()->getQueryProfiles() ?: []; foreach ($queries as $query) { - if ($query->getQueryType() === Profiler::INSERT) { + if ($query->getQueryType() === Profiler::INSERT || $this->isReplaceQuery($query)) { + // For generator we do not care about REPLACE query and can use INSERT instead + // due to it's not support parallel execution $this->addSql($query->getQuery(), $query->getQueryParams()); } } } + /** + * Detect "REPLACE INTO ..." query. + * + * @param Profiler $query + * @return bool + */ + private function isReplaceQuery($query) + { + return $query->getQueryType() === Profiler::QUERY && 0 === stripos(ltrim($query->getQuery()), 'replace'); + } + /** * @return \Zend_Db_Profiler */ diff --git a/setup/src/Magento/Setup/Test/Unit/Model/FixtureGenerator/SqlCollectorTest.php b/setup/src/Magento/Setup/Test/Unit/Model/FixtureGenerator/SqlCollectorTest.php index 3898f1d76105c..167f774cbd7a0 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/FixtureGenerator/SqlCollectorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/FixtureGenerator/SqlCollectorTest.php @@ -65,7 +65,7 @@ public function testGetEmptySqlWhenSelectQueryProcessed() $this->resourceConnection->expects($this->once())->method('getConnection')->willReturn($connection); $query = $this->getMockBuilder(\Zend_Db_Profiler_Query::class)->disableOriginalConstructor()->getMock(); - $query->expects($this->once())->method('getQueryType')->willReturn(\Zend_Db_Profiler::SELECT); + $query->expects($this->exactly(2))->method('getQueryType')->willReturn(\Zend_Db_Profiler::SELECT); $profiler->expects($this->once())->method('getQueryProfiles')->willReturn([$query]); $this->unit->disable();