إنتقل إلى المحتوى الرئيسي

مجموعة_اختبار_نسخ_التداول_(حتمية_+_مباشرة)

مجموعة_اختبار_نسخ_التداول_الكاملة._مستويان:

  1. اختبارات_حتمية (xUnit،بدون_شبكة)—رياضيات_النسخ+منطق المحرك._سريع،_CI،_لا_أسرار.تغطي_كل_وضع_إدارة_الأموال_وكل فلتر/خيار_ومرونة_المحرك.
  2. اختبارات_E2E_مباشرة (حسابات_demo_حقيقية_لـ_cTrader)— CopyEngineHost الإنتاج_يضع_ويُنسخ_أوامر_حقيقية_بين_حسابات حقيقية.مؤتمتة_كلياً_و_قابلة_لإعادة_التشغيل_كاختبار_وحدة: تقرأ_الأسرار_المُخبأة_من_ملفات_gitignored_المحلية، تُجدد_رمز_الوصول_ذاتها،تتخطى_بشكل_رشيق_عندما_الأسرار_غائبة (CI_تبقى_خضراء).

لا_تشغل_أبداً_ضد_حساب_تمويلي_مباشر_—_كل_حساب demo، كل_اختبار_مباشر_يُغلق_المواقع_التي_فتحها.

التخطيط​

tests/UnitTests/CopyTrading/
CopySizingCalculatorTests.cs —_كل_وضع_حجم_+_التقريب_+_min/max_lot
CopyDecisionEngineTests.cs —_اتجاه/عكس/انزلاق/تأخير/فلتر_رمز/حجم_صفر
CopyEngineHostTests.cs —_منطق_النسخ_المضيف_مقابل_جلسة_أصلي_في_الذاكرة
FakeTradingSession.cs —_IOpenApiTradingSession_حتمي_(تسجل_أوامر/إقفالات/تعديلات)
OpenApiConnectionTests.cs —_اتصال_/_إعادة_اتصال_/_تراجع_/_عطل_نهائي_(مرونة)

tests/IntegrationTests/CopyLive/
LiveCopySecrets.cs —_يحمل_الأسرار_المُ gitignored،_يحفظ_الرموز_المُجددة
LiveTokenBootstrapTests.cs —_لمرة_واحدة:_فك_تشفير_الرموز_من_قاعدة_بيانات_التطبيق_
إلى_ذاكرة_التخزين_الرمزية
LiveCopyFixture.cs —_تدوّر_رمز_الوصول،_تعرض_قائمة_حسابات_demo
LiveCopyScenario.cs —_يشغل_سيناريو_نسخ_حقيقي_من_بداية_إلى_نهاية_
(فتح_→_نسخ_→_تأكيد_→_تنظيف)
CopyTradingLiveTests.cs —_السيناريوهات_المباشرة_(1:1،_1:many،_عكس،_…)

الأسرار_(محلية،gitignored—_لا_ارتكاب_أبداً)​

كل_الأسرار_تحت_<repo>/secrets/(في.gitignore_+_أصلا).المطور يكتب أول_ملفين_فقط؛الثالث(الرموز)_ينتج_تلقائياً_بواسطة_onboarding.

secrets/openapi-test-app.local.json —_تطبيق_Open_API:

{ "ClientId": "2175_…", "ClientSecret": "…" }

secrets/openapi-cids.local.json —اعتماد_تسجيل_الدخول_cID_للتفويض (واحد_أو_كثير):

{ "Cids": [
{ "Cid": "amusleh", "Username": "amusleh", "Password": "…" },
{ "Cid": "afhacker", "Username": "afhacker", "Password": "…" }
] }

secrets/openapi-tokens.local.json — كتبها_onboarding،_متعدد_cID، مُجددة_كل_تشغيل:

{ "Cids": [
{ "Cid": "amusleh", "RefreshToken": "…", "AccessToken": "…", "IsLive": false,
"Accounts": [ { "CtidTraderAccountId": 25172589, "TraderLogin": 3635817, "IsLive": false }, … ] }
] }

رمز_التحديث لا_ينتهي_أبداً،لذا_بعد_onboarding_لمرة_واحدة_اختبارات النسخ_المباشرة_تعمل_لأجل_غير_مسمى:كل_تشغيل_يتبادل_رمز_التحديث لكل_cID_برمز_وصول_حديث_(تدوير)_—_لا_متصفح،_لا_موجهات.

onboarding_لمرة_واحدة_(مؤتمت_كلياً_—_لا_تفاعل_مطور_بعد_حفظ_الأسرار)​

Onboarding_يقود_تسجيل_الدخول_الحقيقي_لـ_cTrader_ID_في_متصفح_بدون_رأس_ من_اعتماد_cID_المُخفاة،يحبس_OAuth_callback_على_مستمع_HTTPS_محلي عند_إعادة_التوجيه_المُسجّلة_للتطبيق_(https://localhost:7080/openapi/callback)_، يتبادل_الرمز_برمز_ويحمّل_قائمة_الحسابات،يكتب_ذاكرة_التخزين الرمزية_متعددة_cID.شغّل_لمرة_واحدة_لكل_جهاز(أو_عند_إضافة_cID):

CMIND_ONBOARD=1 dotnet test tests/E2ETests --filter FullyQualifiedName~OnboardingTests

يُفوض_كل_cID_في_openapi-cids.local.json،يكتب openapi-tokens.local.json.بعد_ذلك_اختبارات_النسخ_المباشرة_لا_تحتاج شيئاً_آخر.(يجب_أن_لا_يكون_لحساب_cID_2FA/captcha_على_تسجيل_الدخول لإكمال_الأتمتة.)

Bootstrap_بديل (إذا_الحسابات_معتمدة_بالفعل_في_التطبيق_القائم): فك_تشفير_الرموز_المُخزنة_مباشرة_من_قاعدة_بيانات_التطبيق_'s_Postgres_ volume_بدلاً_من_إعادة_التفويض:

docker run -d --name cmind-pg-extract -e POSTGRES_PASSWORD=appdev \
-v app-pg-data:/var/lib/postgresql/data -p 5544:5432 postgres:17-alpine
CMIND_VOLUME_CONN="Host=127.0.0.1;Port=5544;Database=appdb;Username=postgres;Password=appdev" \
dotnet test tests/IntegrationTests --filter FullyQualifiedName~LiveTokenBootstrapTests
docker rm -f cmind-pg-extract

الأمان_—_demo_فقط​

اختبارات_مباشرة_تتاول_ حسابات_demo_فقط:الfixture_تُصفّي_ذاكرة التخزين_الرمزية_إلى_حسابات_IsLive_==_falseوتتصل_ببوابة_demo، لذا_الأمر_لا_يصل_أبداً_إلى_حساب_تمويلي_مباشر_حتى_لو_حساب_مباشر معتمد._كل_موضع_يفتحه_الاختبار_يُغلق_في_التنظيف.

التشغيل​

# اختبارات_النسخ_الحتمية_فقط_(سريع،_لا_أسرار،_CI-آمن)
dotnet test tests/UnitTests --filter FullyQualifiedName~CopyTrading

# اختبارات_النسخ_المباشرة_مقابل_حسابات_demo_الحقيقية_(تحتاج_الملفين_السريين)
dotnet test tests/IntegrationTests --filter FullyQualifiedName~CopyTradingLiveTests

# الكل
dotnet test

بدون_ملفات_أسرار_اختبارات_مباشرة_تطبع_سبب_التخطي_+_تنجح_كـ_no-ops، لذا_المجموعة_آمنة_للتشغيل_في_أي_مكان.

التغطية​

إدارة_الأموال_/تحديد_الحجم(حتمي_—_CopySizingCalculatorTests)​

FixedLot_·LotMultiplier·NotionalMultiplier(contract-size_/currency)·_ ProportionalBalance_·ProportionalEquity·ProportionalFreeMargin·AutoProportional ·FixedRiskPercent·FixedLeverage· توسع لأعلى و لأسفل لعد_التوازن/leverage/الطاقة_المتناسبين ("القاعدة_الذهبية")·تقريب_lot-step·تخطي_min-lot_مقابل_force-to-min·_ حد_max-lot_·حد_الأكثر_صرامة_من_الحد_الإيجابي_وmin&max_المواصفات·_ تخطي_ميزان_الماستر_صفر.

فلاتر_القرار_(حتمي_—_CopyDecisionEngineTests)​

قائمة_الرموز_السماح/المنع_/allow_·LongOnly/ShortOnly·عكس_يعكس الجانب_و يبدّل_SL/TP ·انزلاق_فوق_الحد_تخطي+بالضبط_عند_الحد مسموح·تخطي_إشارة_قديم(max_delay)·تخطي_حجم_صفر· مصادقة_إعادة_الاتصال(open-missing dedup،_close-orphaned).

محرك_النسخ_المضيف_(حتمي_—_CopyEngineHostTests،_جلسة_في_الذاكرة)​

مفتوح_يُنسخ_أمر_السوق_(جانب_/حجم/تسمية)·_ عكس يعكس_الجانب و يبدّل_SL/TP ·_ تخطيط_الرموز يحلل_الرمز_الوجهة·_ فشل_الأمر_على_عبد_واحد_لا_يزال_يُنسخ_إلى_الآخرين ·مصدر_إغلاق يُغلق_النسخة_المُنسوخة_·_إعادة_الاتصال_تُغلق_النسخ_اليتيمة.

مرونة_الاتصال_(حتمي_—_OpenApiConnectionTests)​

يصل_إلى_Connected_بعد_اعتماد_التطبيق_·اتصال_مُسقط_يعيد_الاتصال_ويُعيد Auth_·خطأ auth_فادح_يُعطب_·_تراجع_أسي.

مباشر،حسابات_demo_حقيقية_لـ_cTrader(CopyTradingLiveTests)​

تجديد_الرمز_وقائمة_الحسابات_·_ 1:1 نسخ_يُنفذ·_ 1:many يُنسخ إلى_كل_عبد_·_ عكس يحول_شراء_الماستر_إلى_بيع_العبد·_ cross-cID (الماستر_تحت_cID_واحد_يُنسخ_إلى_عبد_تحت_cID_آخر، لكل_يُصادق_بمعرفه_الخاص).كل_واحد_يفتح_موضع_min-lot_حقيقي_على الماستر،ينتظر_المحرك_ليُنسخه(مطابق_بواسطة_معرف_موقع_المصدر على_العبد)،يؤكد،_يُغلق_كل_شيء.السوق_المغلق_يُبلغ Inconclusive،_وليس_فشل.

التسجيل_والتدقيق​

كل_عملية_نسخ_تداول_مسجلة_عبر_أحداث_مُنشأة_من_المصدر_( Core/Logging/LogMessages.cs،معرفات_الأحداث_1043–1055)،_ مسار_كامل_قابل_للتدقيق:

الحدثIdالمعنى
CopyHostStarted1046محرك_ملف_انطلق_(مصدر_+_عدد_الوجهات)
CopySourceOpen1047الماستر_فتح_موضع_(رمز_/جانب/_عقود)
CopyOrderPlaced1048أمر_النسخ_أُرسل_إلى_عبد_(رمز_/جانب/حجم/_معرف_المصدر)
CopySkipped1049تم_تخطي_نسخ_والسبب_(انزلاق_/اتجاه/فلتر_رمز/حجم_صفر/_…)
CopyProtectionApplied1050SL/TP_طُبّق_على_نسخة_عبد
CopyOpenFailed1051فتح_نسخة_عبد_فشل_(معزول_—_العبد_الأخرى_تستمر)
CopySourceClose / CopyPositionClosed1052 / 1053ماستر_أغلق_→_نسخة_عبد_أُغلقت
CopyCloseFailed1054إغلاق_نسخة_عبد_فشل
CopyResync1055مصادقة_إعادة_الاتصال_(عدد_مفتوح_المصدر،_الأيتام_أُغلقوا)
CopyPartialClose1056إغلاق_جزئي_للاستنساخ_انعكس_—_شريحة_متناسبة_أُغلقت_على_عبد
CopyScaleIn1057scale-in_للاستنساخ_انعكس_(opt-in)_—_حجم_مضاف_أُنسخ_إلى_عبد
CopyPendingOrderPlaced1058أمر_معلق_limit/stop_انعكس_إلى_عبد_(opt-in)
CopyPendingOrderCancelled1059الأمر_المعلق_المصدر_أُلغي_→_الأمر_المعلق_العبد_أُلغي
CopyTrailingApplied1060stop_متتابع_طُبّق_على_نسخة_عبد_(opt-in)
CopyStopLossAmended1061نقل_SL_المصدر_أعاده_تُعدّل_نسخة_العبد
CopyHostTokenRotated1062المنشئ_أعاده_يد_أعاد_تشغيل_المضيف_بعد_تدوير_رمز_الوصول

تُصدر_السجلات_كتنسيق_JSON_مضغوط_Serilog_(خصائص_مُهيكلة:_ ProfileId،DestinationCtid،SourcePositionId،Symbol،Side، Volume،…)،تُشحن_إلى_OTLP_عند_ضبطOTEL_EXPORTER_OTLP_ENDPOINT. قابل_للتكوين_كلياً لكل_فئة_عبر_التكوين_القياسي—مثلاً_رفع/خفض تفضيل_محرك_النسخ_بدون_لمس_الكود:

// appsettings.json —_تجاوزات_مستوى_Serilog
"Serilog": { "MinimumLevel": { "Override": {
"CopyEngine": "Information", // مسار_التدقيق_في_CopyEngineHost
"Nodes.CopyTrading": "Information" // المنشئ_/_تجديد_الرمز
} } }

Audit_log_records_every_trading_operation اختبار_المضيف_يؤكد_المسار يُصدر_لفتح_وأمر_وحماية_وإغلاق.

حالات_الحد_(تم_التحقق_مقابل_كيف_تفشل_منصات_النسخ/MAM_الحقيقية)​

انزلاق_&latency،لاحقة_الرمز/عدم_التطابق،التداول_المكرر_عند إعادة_الاتصال،عدم_تطابق_الرافعة_و_تحديد_حجم_هامش_آمن،اختلاف عملة_الإيداع/حجم_العقد،min/max_lot&التقريب،الأوامر_المرفوضة، فلاتر_الاتجاه،تنظيف_الأيتام_بعد_قطع_الاتصال—كل_ذلك_مغطى أعلاه.المصادر: عدم_تطابق_الرافعة · النسخ_cross-broker · فخاخ_النسخ · انزلاق_&_latency_ ·_ لماذا_يفشل_نسخ_التداول_ ·_ معاملات_المخاطر.

تغطية_التنميط_المتقدم_(إغلاق_جزئي_·أوامر_معلة·_SL-trailing)​

المضيف_يُنسخ_أكثر_من_فتح_السوق/إغلاق.كل_سلوك=خيار opt-in_لكل_وجهة_ على_CopyDestination(MirrorPartialClose افتراضي_تشغيل،MirrorScaleIn/ CopyPendingOrders/CopyTrailingStop افتراضي_إيقاف)،محروس_بأساليب القصد_،مُ persistمُ كـ_jsonb(هجرة_ CopyAdvancedMirroringAndNodeAffinity).

السلوكالاختبار_الحتمي_(CopyEngineHostTests)الاختبار_المباشر
إغلاق_جزئي_→_شريحة_متناسبةPartial_close_mirrors_a_proportional_slice_on_the_slave(1.0→0.4_أغلق_60%)+_المسار_المعطلPartial_close_shrinks_the_slave_copy_proportionally ✅
scale-inScale_in_is_ignored_by_default_and_mirrored_when_enabled—
أمر_معلق_limit/stop_مُوضعPending_order_is_placed_on_the_slave_when_enabled(نظرية:Limit+Stop)+_المسار_المعطلPending_limit_order_is_mirrored_and_cancel_propagates ✅
إلغاء_معلقSource_pending_cancel_cancels_the_slave_pending(نفس_الاختبار_المباشر_—_يُلغي_على_الماستر،_يؤكد_العبد_يُلغي) ✅
ملء_معلق_لا_يفتح_مرتينFilled_pending_does_not_double_open(dedupe_بـ_معرف_الأمر→_معرف_الموضع)—
stop_متتابعTrailing_stop_is_applied_to_the_copy_when_enabledTrailing_stop_is_mirrored_onto_the_slave_copy ✅
نقل_SL_المصدر_يُعدّلSource_stop_loss_move_re_amends_the_copy—
أحداث_التدقيق_تُصدرAdvanced_mirroring_audit_events_fire_(1056/1058/1059)—

كل_الاختبارات_المباشرة_أعلاه تم_التحقق_من_اخضرارها مقابل حسابات_demo_الحقيقية_لـ_cTrader_(1:1،_1:many،_عكس،_cross-cID،_إغلاق_جزئي، معلق+إلغاء،_trailing).

إضافات_السلك_في_OpenApiTradingSession: SendPendingOrderAsync،CancelOrderAsync،ReconcilePendingOrdersAsync، علامة_trailing_على_AmendPositionSltpAsync،حقول_الأمر/المعلق_على ExecutionEvent،LoadSpotPriceAsync(اشتراك_الفورية_→bid/ask، تُستخدم_باختبارات_المعلق/المتتابع_الحية_لوضع_الأوامر_المعلنة_بعيداً عن_السوق)، StopLoss/TrailingStopLoss علىOpenPositionSnapshot(حالة_trailing للاستنساخ_قابلة_للماحظة_عبر_المصادقة).النسخ_تبقى_مُسماة_بـ **معرف موقع_المصدر**(النسخ_المعلنة_بـ معرف_الأمر_المصدر)لذا_المصادقة عند_إعادة_الاتصال_تظل_مبنية_على_المعرف،_لا_تُكرر_تداولاً.

gotcha_الحدث_cTrader_(تم_التحقق_مباشرة): حدث_تنفيذ_ ORDER_ACCEPTED/ORDER_CANCELLEDللأمر_المعلق_المُقام_يحمل غير_مفتوح_PositionPlaceholder بالإضافة_إلىOrder.التدفق_يجب أن_يُصنّفه_كـ حدث_أمر قبل فرع_الموضع(بوابة_على_الموضع_ليس_ OPEN)_،_وإلا_تموضع_المعلق_المُنسوخ_يُقرأ_خطأً_كـ_إغلاق_موضع. _ SourceExecutionsAsync _يفعل_هذا؛عدمه_يُسقط_صامتاً_كل_تنميط الأوامر_المعلنة.

تدوير_الرمز_+_انجذاب_العقدة​

  • التدوير_إلى_المضيفين_القيد_التشغيل.CopyEngineSupervisor يسجل توقيع_الرمز_على_كل_مضيف_قيد_التشغيل_و،كل_مصادقة،يعيد_بناء الخطة_من_قاعدة_البيانات(مدوّرة_حديثاً_بواسطة_OpenApiTokenRefreshService)._ التوقيع_المتغير_يعيد_تشغيل_المضيف_(CopyHostTokenRotated،1062)؛ المضيف_الجديد_ResyncAsync يعيد_بناء_الحالة_بدون_تكرار_التداول. تدوير_القوة_في_منتصف_التشغيل_عبر_IOpenApiTokenClient.RefreshAsync_ للتحقق_من_المضيف_الحية_يستمر_في_النسخ.
  • انجذاب_العقدة_(لا_نسخ_مزدوج).منشئ_الويب_المحلي_و_عاملCopyAgent_ كلاهما_يشغل_منشئاً.كل_ملف_قيد_التشغيل_مطال_بواسطة_عقدة_واحدة_فقط (CopyProfile.AssignedNode،ادعاءExecuteUpdate ذري_مفتاح_من CopyOptions.NodeName،_اسم_الجهاز_الافتراضي).المنشئ_يستضيف_فقط الملفات_التي_يمتلكها؛_إيقاف/إيقاف_يُصدر_ادعاء.التغطية:
    • المجال_(وحدة):_AssignToNode_makes_profile_hosted_by_only_that_node، Stopping_a_profile_releases_its_node_assignment، NodeIdentity_rejects_blank.
    • تكامل_(Postgres_حقيقي،_Testcontainers):CopyNodeAffinityTests يدفعClaimUnassignedProfilesAsync الفعلي_للمنشئ—يؤكد_أول_عقدة تدّعي_3_ملفات_قيد_التشغيل،الثانية_تدّعي 0 (لا_مضيف_مزدوج)، إيقاف→إعادة_تشغيل_يُصدر_الادعاء_لعقدة_أخرى.
    • كشف_التدوير_(TokenRotationSignatureTests):توقيع_الرمز_الخاص بالمنشئ_يتغير_عندما_تدور_رمز_المصدر_أو_الوجهة_،ثابت_بخلاف ذلك_(مضيف_قيد_التشغيل_يعيد_التشغيل_فقط_عند_التدوير_الحقيقي).

رموز_التحديث_ذات_الاستخدام_الواحد_(مهم)​

رموز_تحديث_cTrader ذات_استخدام_واحد —كل_تحديث_يُرجع_رمز_تحديث جديد_،_يُلغي_القديم.الfixture_تحديث_في_البداية،تُPersistence_الرمز المدوّر_إلىsecrets/openapi-tokens.local.json._النتائج:

  • إذا_التحديث_يعمل_لكن لا_يستطيع_الإلحاق الرمز_الجديد(مثلاً_ mount_قراءة_فقط)_،الرمز_المُخبأ_ميت،التشغيل_التالي_يفشلACCESS_DENIED. أعد_التوليد_بـ_onboarding_بدون_رأس: CMIND_ONBOARD=1_dotnet_test_tests/E2ETests_--filter_FullyQualifiedName~OnboardingTests.
  • LiveCopySecrets.SaveTokens يبتلع_أخطاء_الكتابة_لذا_ذاكرة_التخزين المقروءة_فقط_لا_تُعطّل_التشغيل،لكن المباشر في_المجموعة في_العنقود_لا_يزال_يحتاج ذاكرة_التخزين_القابلة_للكتابة(K8s_Job_ تنسخ_Secret_إلى_emptyDir_—_انظر_توثيق_النشر).

تشغيل_المجموعة_في_عنقود_Kubernetes​

المجموعة_الكاملة_تشغل_في_العنقود_مقابل_التطبيق_المنتشر_عبر_Helm_، لذا_الانحدار_يُلتقط_في_العنقود_مثل_المحلية.انظر docs/deployment/kubernetes.md.

scripts/k8s-e2e.sh # مجموعة_حتمية_(لا_أسرار)
TEST_FILTER='FullyQualifiedName~CopyTradingLiveTests' COPY_SECRET=cmind-copy-secrets scripts/k8s-e2e.sh # مباشر

Dockerfile.tests يبني_صورة_المُشغِّل؛Helmtests-job.yaml(بوابة_ tests.enabled=false)تشغله_مقابل_Postgres+Web+MCP_في_العنقود. الافتراضي_=_المجموعة_الحتمية(لا_أسرار،لا_رموز_مدوّرة). للمجموعة_المباشرة،اضبطtests.copySecret إلى_Secret_التي_تحمل openapi-*.local.json المُgitignored؛init-container_تنسخه_إلى emptyDir_قابل_للكتابة في/app/secrets(مطلوب_—رموز_التحديث ذات_الاستخدام_الواحد_يجب_أن_تكون_قابلة_للإلحاق).اختبارات_النسخ تحتاج_فقط_Web_+Postgres+ذاكرة_التخزين_الرمزية—لا_وكلاء_عقد مميزين.البرنامج_يؤكد_الوظيفة_تخرج_0_والسجلات_تحتويPassed!.

تم_التحقق_هنا_(Docker،_لا_عنقود): صورة_الاختبار_تشغل_المجموعة_ الحتمية_(101_نجح)و،مع mountsecrets/قابل_للكتابة،المجموعة المباشرة الكاملة_(8_نجح)—المسار_الفعلي_للوظيفة_ناقص Kubernetes.kind/kubectl/helm غير_متوفرة_في_بيئة_التأليف، لذا_تشغيل_العنقود_الكاملk8s-e2e.sh هو_الخطوة_الواحدة_غير المنفذة_هنا.

مصفوفة_الخيار_المباشر_+الفوضى(LiveCopyMatrix_/_LiveCopyChaos)​

مجموعتان_مباشرتان_مدارتان_بـ_LiveCopyScenario/LiveCopyFixture, النظير_المباشر_لمجموعة_DST_الإجهاد:

  • LiveCopyMatrix —[Theory]/[MemberData]مصفوفة_خيار:مفتوح ماستر_حقيقي_واحد_لكل_صف_مقابل_حسابات_demo، كل_واحد_بتجهيز_وجهة_مُكوَّن_مختلف، يؤكد_النتيجة_الذهبية.الصفوف:one_to_one،half_multiplier، reverse(الجانب_المعاكس)،manage_only(لا_يفتح_شيئاً)، trading_hours_closed(النافذة_استبعدت_الآن→لا_نسخ)، source_label_block(فلتر_التسمية→لا_نسخ)، lot_sanity_block(السقف→_لا_نسخ).
  • LiveCopyChaos —محرك_النسخ_مقابل_بداية_عدائية:الماستر_يمتلك موضع_قبل_بدء_المضيف،لذا_التقارب_لا_يستطيع_القدوم_إلا_من مصادقة_البدء_(Sync-Open-on-Start)،بالإضافة_إلى_الحالة السلبية_مع_التبديل_إيقاف.التغطية_الحتمية_لـ_socket-flap/ تدوير_الرمز_/رفض_الفوضى_مُغطاة_بشكل_شامل_بواسطة_مجموعة_DST؛ هذا_يؤكد_مسار_ resync_المباشر.

كلاهما يتخطى_بشكل_رشيق _بدون_أسرار،يُبلغ Inconclusive _ عند_السوق_المغلق،كل_صف_يُنظف_المواقع_التي_فتحها(حسابات_demo_فقط).

متانة_الfixture:LiveCopyFixture الآن_تتodegradate_إلى_تخطي_نظيف عندما_لا_تستطيع_ذاكرة_التخزين_المُخبأة_التحديث(رموز_التحديث_ ذات_الاستخدام_الواحد_—ذاكرة_تخزين_قديمية_أو_تشغيل_غير_متصل_لا_تُعطّل المجموعة_المباشرة_بعدين؛أعد_تشغيل_onboarding_OAuth_لتحديث ذاكرة_التخزين).

تشغيل_المجموعات_المباشرة_+العنقودية_بنفسك(لا_عذر_—كل_شيء​

ذاتي_الخدمة)

كل_ما_أدناه_متوفر_في_هذه_البيئة.لا_تدّعي"الأسرار_غير_ متوفرة" أو_"الرمز_قديم"أو"kind/helm_غير_مثبتة"_—اضبطها وشغّلها.

1.احصل_على_رمز_Open_API_حديث(OAuth_بدون_رأس،_لا_تفاعل_متصفح)​

رموز_تحديث_cTrader_ذات_الاستخدام_الواحد،لذا_الرمز_المُخبأ_سيصبح قديم.أعد_صنعه_ذاته_من_اسم_المستخدم_وكلمة_ال مرور_المُخفاة (secrets/openapi-cids.local.json+ secrets/openapi-test-app.local.json،أو_موحّد secrets/dev-credentials.local.json).اختبار_onboarding_يقود OAuth_بدون_رأس_عبر_Playwright،يكتب secrets/openapi-tokens.local.json:

CMIND_ONBOARD=1 dotnet test tests/E2ETests --filter FullyQualifiedName~OnboardingTests

~13_ثانية؛يُفوض_كل_cID،_يُخبئ_رموز_حديثة.أعد_التشغيل_كلما مجموعة_مباشرة_تُبلغ_عن_عدم_توفر_fixture_بسبب_فشل_التحديث.

2.شغّل_مجموعات_النسخ_المباشرة(حسابات_demo_حقيقية_لـ_cTrader)​

dotnet test tests/IntegrationTests --filter FullyQualifiedName~CopyTradingLiveTests # التنميط_الأساسي_(8)
dotnet test tests/IntegrationTests --filter FullyQualifiedName~LiveCopyMatrix # مصفوفة_الخيارات_(7)
dotnet test tests/IntegrationTests --filter FullyQualifiedName~LiveCopyChaos # فوضى_resync_(2)

ضع_ونظّف_أوامر_ DEMO_الحقيقية_(لا_حسابات_مباشرة)_،يُبلغ Inconclusive _عند_السوق_المغلق.تم_التحقق_من_اخضرارها_من_طرف إلى_طرف.

3.Bootstrap_الرموز_من_حجم_تطبيق_قائم(بديل)​

إذا_التطبيق_شغال_+cID_مرتبط_في_التطبيق،استخرج_أحدث_رمز_تحديث للمصدر_مباشرة_من_app-pg-data Postgres_volume_بدلاً_من_إعادة التفويض_—انظرLiveTokenBootstrapTests،اضبطCMIND_VOLUME_CONN.

4._E2E_عنقود_Kubernetes​

kind،helm،Docker_متوفرة(ثبّت kind/helm_عبر_go_install/إصدارات_ ثنائية_أو_choco_install_kind_kubernetes-helmإذا_لم_على_PATH). برنامج_لمرة_واحدة_يبني_ويحمّل_الصور_،ينشر_chart،يشغل_وظيفة الاختبار_في_العنقود_،_يؤكد_خروج_0:

scripts/k8s-e2e.sh # مجموعة_النسخ_الحتمية_(لا_أسرار)
TEST_FILTER='FullyQualifiedName~CopyTradingLiveTests' COPY_SECRET=cmind-copy-secrets scripts/k8s-e2e.sh # مباشر_في_العنقود

انظر_../deployment/kubernetes.md.