From d35727dbb7f0515a287b71b8e35f503f007eae53 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Mon, 15 Dec 2025 01:27:58 +0300 Subject: [PATCH] Add test_level_placement and fix it with the 2.2.0+ PG "folding" system --- .gitea/workflows/test.yml | 18 ++++++++++++++++ mon/osd_tree.js | 2 +- mon/pg_gen.js | 2 +- tests/run_tests.sh | 2 ++ tests/test_level_placement.sh | 39 +++++++++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 2 deletions(-) create mode 100755 tests/test_level_placement.sh diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index b9f8074e..ed26a905 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -414,6 +414,24 @@ jobs: echo "" done + test_level_placement: + runs-on: ubuntu-latest + needs: build + container: ${{env.TEST_IMAGE}}:${{github.sha}} + steps: + - name: Run test + id: test + timeout-minutes: 3 + run: /root/vitastor/tests/test_level_placement.sh + - name: Print logs + if: always() && steps.test.outcome == 'failure' + run: | + for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do + echo "-------- $i --------" + cat $i + echo "" + done + test_snapshot: runs-on: ubuntu-latest needs: build diff --git a/mon/osd_tree.js b/mon/osd_tree.js index 5ce6d0dd..13c31334 100644 --- a/mon/osd_tree.js +++ b/mon/osd_tree.js @@ -87,7 +87,7 @@ function make_hier_tree(global_config, tree) tree[''] = { children: [] }; for (const node_id in tree) { - if (node_id === '' || !(tree[node_id].children||[]).length && (tree[node_id].size||0) <= 0) + if (node_id === '') { continue; } diff --git a/mon/pg_gen.js b/mon/pg_gen.js index 3924a054..6647132d 100644 --- a/mon/pg_gen.js +++ b/mon/pg_gen.js @@ -178,7 +178,7 @@ async function generate_pool_pgs(state, global_config, pool_id, osd_tree, levels const rules = use_rules ? get_pg_rules(pool_id, pool_cfg, global_config.placement_levels) : null; const folded = fold_failure_domains(Object.values(pool_tree), use_rules ? rules : [ [ [ pool_cfg.failure_domain ] ] ]); // FIXME: Remove/merge make_hier_tree() step somewhere, however it's needed to remove empty nodes - const folded_tree = make_hier_tree(global_config, folded.nodes); + const folded_tree = make_hier_tree(global_config, folded.nodes.reduce((a, c) => { a[c.id] = c; return a; }, {})); const old_pg_count = prev_pgs.length; const optimize_cfg = { osd_weights: folded.nodes.reduce((a, c) => { if (Number(c.id)) { a[c.id] = c.size; } return a; }, {}), diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 8a76a572..26056604 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -33,6 +33,8 @@ OLD=1 SCHEME=ec IMMEDIATE_COMMIT=1 ./test_interrupted_rebalance.sh ./test_failure_domain.sh +./test_level_placement.sh + ./test_snapshot.sh SCHEME=ec ./test_snapshot.sh OLD=1 ./test_snapshot.sh diff --git a/tests/test_level_placement.sh b/tests/test_level_placement.sh new file mode 100755 index 00000000..2de292c3 --- /dev/null +++ b/tests/test_level_placement.sh @@ -0,0 +1,39 @@ +#!/bin/bash -ex + +. `dirname $0`/common.sh + +node mon/mon-main.js $MON_PARAMS --etcd_address $ETCD_URL --etcd_prefix "/vitastor" >>./testdata/mon.log 2>&1 & +MON_PID=$! +wait_etcd + +TIME=$(date '+%s') +$ETCDCTL put /vitastor/config/global '{"placement_levels":{"rack":1,"host":2,"osd":3},"immediate_commit":"none"}' +$ETCDCTL put /vitastor/config/node_placement '{"rack1":{"level":"rack"},"rack2":{"level":"rack"},"rack3":{"level":"rack"},"rack4":{"level":"rack"}, + "host1":{"level":"host","parent":"rack1"},"host2":{"level":"host","parent":"rack1"}, + "host3":{"level":"host","parent":"rack2"},"host4":{"level":"host","parent":"rack2"}, + "host5":{"level":"host","parent":"rack3"},"host6":{"level":"host","parent":"rack3"}, + "host7":{"level":"host","parent":"rack4"},"host8":{"level":"host","parent":"rack4"}}' +$ETCDCTL put /vitastor/osd/stats/1 '{"host":"host1","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/2 '{"host":"host1","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/3 '{"host":"host2","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/4 '{"host":"host2","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/5 '{"host":"host3","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/6 '{"host":"host3","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/7 '{"host":"host4","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/8 '{"host":"host4","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/9 '{"host":"host5","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/10 '{"host":"host5","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/11 '{"host":"host6","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/12 '{"host":"host6","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/13 '{"host":"host7","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/14 '{"host":"host7","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/15 '{"host":"host8","size":1073741824,"time":"'$TIME'"}' +$ETCDCTL put /vitastor/osd/stats/16 '{"host":"host8","size":1073741824,"time":"'$TIME'"}' +build/src/cmd/vitastor-cli --etcd_address $ETCD_URL create-pool testpool --failure_domain host --level_placement rack=112233 --ec 4+2 -n 32 +sleep 2 +$ETCDCTL get --prefix /vitastor/pg/config --print-value-only | \ + jq -s -e '([ .[0].items["1"] | .[].osd_set | map_values(. | tonumber) | select( + (. | map_values((. - 1) / 2 | floor) | unique | length) == 6 and + (. | map_values((. - 1) / 4 | floor) | unique | length) == 3) ] | length) == 32' + +format_green OK