Skip to content

Commit 5950164

Browse files
committed
edit for clarity, remove unneeded sections
1 parent 82ac506 commit 5950164

8 files changed

Lines changed: 87 additions & 376 deletions

File tree

content/learning-paths/servers-and-cloud-computing/dotnet-migration-nopcommerce/2-environment-setup.md

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,17 @@ weight: 2
66
layout: learningpathall
77
---
88

9-
Create two VMs in the same Azure region with matching OS and tooling so differences are attributable to architecture, not configuration drift.
9+
# Environment setup
1010

11-
This path was validated with Ubuntu 24.04 LTS VMs in `westus2`:
11+
Set up an Arm Cobalt environment first, then keep your toolchain and runtime configuration stable across all test runs. This creates a reliable Arm baseline for migration and tuning work.
1212

13-
| | x86 | Arm |
14-
|---|---|---|
15-
| **VM size** | Standard_D2s_v6 | Standard_D2ps_v6 |
16-
| **vCPUs** | 2 | 2 |
13+
Start with the official [Azure Cobalt setup guide](https://learn.arm.com/learning-paths/servers-and-cloud-computing/cobalt/) and complete VM provisioning there first.
1714

18-
## Log in and create VMs
15+
This path was validated with Ubuntu 24.04 LTS on Azure Cobalt in `westus2` (example VM size: `Standard_D2ps_v6`, 2 vCPUs).
1916

20-
```bash
21-
az login --use-device-code
22-
az account set --subscription <your-subscription>
23-
```
24-
25-
Create both VMs in the same resource group and region.
17+
## Install tools on Cobalt VM
2618

27-
## Install tools on each VM
19+
Install the toolchain on the Cobalt VM before building and testing.
2820

2921
```bash
3022
sudo apt-get update -y
@@ -38,37 +30,31 @@ sudo apt-get install -y dotnet-sdk-9.0
3830

3931
Verify:
4032

33+
Confirm architecture and tool versions before proceeding.
34+
4135
```bash
4236
uname -m
4337
dotnet --version
4438
docker --version
4539
```
4640

47-
Expected output: `x86_64` on the x86 VM, `aarch64` on the Arm VM. Both should report the same .NET SDK version (9.0.x).
41+
Expected output: `Arm` (kernel strings may still show architecture-specific values). Ensure the .NET SDK version is 9.0.x.
4842

4943
## PostgreSQL prerequisite for nopCommerce install
5044

51-
nopCommerce migrations on PostgreSQL require the `citext` extension. Create it before running the installer:
45+
nopCommerce defaults to SQL Server, but this learning path uses PostgreSQL for Arm validation. For PostgreSQL installs, `citext` is required before migration/installation. Without it, installer migrations fail with `type "citext" does not exist` (captured in local test artifacts).
46+
47+
Create PostgreSQL and enable `citext` before running the installer:
5248

5349
```bash
50+
# Start PostgreSQL for local validation.
5451
docker run -d --name nop-postgres \
5552
-e POSTGRES_USER=nop \
5653
-e POSTGRES_PASSWORD=<password> \
5754
-e POSTGRES_DB=nopcommerce \
5855
-p 5432:5432 postgres:16
5956

57+
# Enable the extension required by nopCommerce migrations.
6058
docker exec nop-postgres psql -U nop -d nopcommerce \
6159
-c "CREATE EXTENSION IF NOT EXISTS citext;"
6260
```
63-
64-
## Optional: script-driven remote execution
65-
66-
```bash
67-
az vm run-command invoke \
68-
-g <resource-group> \
69-
-n <vm-name> \
70-
--command-id RunShellScript \
71-
--scripts @./your-test-script.sh
72-
```
73-
74-
This was used to run identical commands on both VMs.

content/learning-paths/servers-and-cloud-computing/dotnet-migration-nopcommerce/3-checkout-build-baseline.md

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ weight: 3
66
layout: learningpathall
77
---
88

9-
Pin nopCommerce to a reproducible release, build on both architectures, and capture a baseline that includes core storefront paths.
9+
# Build and baseline
10+
11+
Create a reproducible Arm baseline before optimization work. This page pins source, verifies a clean build, and captures a representative endpoint baseline so later changes can be measured against a known control.
1012

1113
## Clone and pin the source
1214

15+
Pinning the exact tag and commit avoids silent drift in dependencies and behavior.
16+
1317
```bash
1418
git clone https://github.com/nopSolutions/nopCommerce.git
1519
cd nopCommerce
@@ -18,74 +22,73 @@ git checkout release-4.90.3
1822
git rev-parse --short=10 HEAD # expect 9beda11c42
1923
```
2024

21-
## Restore and build
25+
## Restore and build on Arm
26+
27+
Run on the Arm VM to establish a native Arm baseline.
2228

2329
```bash
30+
# Restore dependencies first so build failures are easier to triage.
2431
dotnet restore src/Presentation/Nop.Web/Nop.Web.csproj
32+
33+
# Build release binaries without re-restoring packages.
2534
dotnet build src/Presentation/Nop.Web/Nop.Web.csproj -c Release --no-restore
2635
```
2736

28-
## Start the application
37+
## Start and install nopCommerce
38+
39+
Start the app locally and complete installer setup with PostgreSQL.
2940

3041
```bash
3142
cd src/Presentation/Nop.Web
3243
dotnet run -c Release --no-build --urls http://0.0.0.0:5000
3344
```
3445

35-
## Baseline methodology
36-
37-
Do not rely on `/install` alone. Baseline at least:
38-
39-
- Home page
40-
- Search
41-
- Product page
42-
- Cart
43-
- Checkout
44-
45-
Prerequisite: complete nopCommerce setup first (database configured and installer finished). Otherwise, storefront paths redirect to the install flow and do not represent real behavior.
46-
47-
Use a valid product URL from your seeded catalog (for example, `/apple-macbook-pro`), not a hard-coded slug that may not exist in your dataset.
48-
49-
Quick smoke probe (pre-install, useful as a connectivity check only):
46+
Complete installation with PostgreSQL (`citext` enabled), then verify:
5047

5148
```bash
52-
for p in / \
53-
'/search?q=book' \
54-
'/apple-macbook-pro' \
55-
'/cart' \
56-
'/checkout'; do
57-
echo "== $p =="
58-
for i in $(seq 1 20); do
59-
curl -sS -o /dev/null -w '%{time_total}\n' "http://127.0.0.1:5000$p"
60-
done
61-
done
49+
# Root should return storefront content.
50+
curl -s -o /dev/null -w 'root=%{http_code}\n' http://127.0.0.1:5000/
51+
52+
# Install route should redirect once installation is complete.
53+
curl -s -o /dev/null -w 'install=%{http_code}\n' http://127.0.0.1:5000/install
6254
```
6355

64-
Before installation is complete, all storefront paths redirect to setup (`302`). Those numbers confirm reachability but are not valid performance baselines.
56+
Expected after successful install: `root=200`, `install=302`.
6557

66-
## Installed-store endpoint baseline (validated)
58+
## Baseline methodology
6759

68-
After fixing PostgreSQL setup (`citext`) and completing installation on both machines, the same endpoint benchmark was executed with `wrk` (`-t2 -c32 -d20s`) across this set:
60+
Do not benchmark `/install`. Baseline real storefront paths:
6961

7062
- `/`
71-
- `/search?q=book`
72-
- `/electronics`
73-
- `/apple-macbook-pro`
74-
- `/cart`
75-
- `/checkout`
76-
77-
Storefront pages returned `200`; `/checkout` returned `302` (expected without an authenticated session).
63+
- `/search/`
64+
- `/catalog/searchtermautocomplete`
65+
- `/product/search`
66+
- `/category/products/`
67+
- `/addproducttocart/catalog/...`
68+
- `/addproducttocart/details/...`
69+
- `/shoppingcart/productdetails_attributechange/...`
70+
- `/product/combinations`
71+
- `/cart/estimateshipping`
72+
- `/cart/selectshippingoption`
73+
74+
Use the endpoint tester:
7875

79-
Requests/second comparison:
76+
```bash
77+
# Use fixed concurrency and iterations for a repeatable starting point.
78+
python3 test_nopcommerce_endpoints.py \
79+
--base-url http://127.0.0.1:5000 \
80+
--concurrency 8 \
81+
--iterations 20 \
82+
--json-out arm_before.json
83+
```
8084

81-
| Endpoint | x86 | Arm | Arm vs x86 |
82-
|---|---:|---:|---:|
83-
| `/apple-macbook-pro` | 35.40 | 32.28 | -8.8% |
84-
| `/electronics` | 99.52 | 76.07 | -23.6% |
85-
| `/search?q=book` | 28.18 | 27.40 | -2.8% |
85+
## Baseline quality rules
8686

87-
Different endpoints show different gaps. Avoid reducing migration performance to a single number — use per-endpoint baselines to guide architecture-specific optimizations.
87+
Use these rules before you compare any optimization result:
8888

89-
## Arm MCP accelerator (optional)
89+
- Run at least 3 baseline trials with identical parameters.
90+
- Keep endpoint order fixed per run (not randomized) when comparing before vs after.
91+
- Keep database state and seeded data identical across runs.
92+
- Capture raw JSON for every run and compare medians, not single outliers.
9093

91-
Use MCP to script repeated baseline runs and summarize deltas, but keep the manual baseline commands as your ground truth.
94+
This baseline process becomes the control for every later tuning or code-change decision.

content/learning-paths/servers-and-cloud-computing/dotnet-migration-nopcommerce/4-dependency-mapping-manifests.md

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,29 @@ weight: 4
66
layout: learningpathall
77
---
88

9-
Use a manual-first audit, then use the Arm MCP server to accelerate checks.
9+
# Audit dependencies
1010

11-
## Manual workflow (required)
11+
Run dependency discovery before migration changes so you understand direct references, transitive risk, and hidden native payloads. This avoids late surprises when deploying to Arm.
1212

1313
### 1. Map direct references
1414

15+
Start with project-level references to see what your app explicitly depends on.
16+
1517
```bash
1618
rg -n "<PackageReference|<ProjectReference" src
1719
```
1820

1921
### 2. List transitive dependencies
2022

23+
Enumerate the full dependency graph; transitive packages often carry architecture-sensitive constraints.
24+
2125
```bash
2226
dotnet list src/Presentation/Nop.Web/Nop.Web.csproj package --include-transitive
2327
```
2428

25-
### 3. Generate an SBOM (required)
29+
### 3. Generate an SBOM
30+
31+
Generate an SBOM so you can track all components, versions, and exposure surface as a first-class migration artifact. While not strictly necessary for migration purposes, this is a best practice that will save your team time down the road. You can also give this SBOM to an LLM to extract insights about your codebase for you.
2632

2733
```bash
2834
dotnet tool install --global CycloneDX
@@ -33,6 +39,8 @@ If tool installation is blocked, treat `dotnet list --include-transitive` plus `
3339

3440
### 4. Inspect package internals for native payloads
3541

42+
Inspect package contents directly to find architecture-specific native binaries.
43+
3644
```bash
3745
mkdir -p /tmp/nupkg-audit
3846
cp ~/.nuget/packages/<package>/<version>/<package>.<version>.nupkg /tmp/nupkg-audit/
@@ -50,14 +58,4 @@ Treat dependencies as a chain, not isolated items:
5058
- Library A depends on library B
5159
- Library B is architecture-sensitive
5260

53-
You must resolve B first, then validate A, then validate the app. In nopCommerce, `iTextSharp` and `System.Drawing` are an example of this chain.
54-
55-
## Arm MCP accelerator (optional)
56-
57-
After manual evidence is collected, use MCP tools to speed repetitive checks:
58-
59-
- `knowledge_base_search` for package compatibility
60-
- `skopeo` or `check_image` for container image architecture coverage
61-
- `migrate_ease_scan` where scanner support exists
62-
63-
Keep manual outputs as the source of truth. Use MCP to prioritize and scale, not to skip evidence.
61+
You must resolve B first, then validate A, then validate the app.

content/learning-paths/servers-and-cloud-computing/dotnet-migration-nopcommerce/5-platform-code-deps.md

Lines changed: 0 additions & 81 deletions
This file was deleted.

0 commit comments

Comments
 (0)