প্রকল্প সম্পর্কে

# go-docker-testsuite একটি Go লাইব্রেরি যা ডকার কন্টেইনারে তৃতীয়-পক্ষের ডিপেন্ডেন্সি চালিয়ে ইন্টিগ্রেশন টেস্টিং করে। এটি যেকোনো ডকার ইমেজ—ডেটাবেস, কিউ, ক্যাশ বা অবজেক্ট স্টোরেজ—চালু করতে এবং আপনার Go টেস্ট থেকে সেগুলোর সাথে সংযোগ করতে দেয়। ## বৈশিষ্ট্য - **Container** — যেকোনো ডকার ইমেজ তৈরি, চালানো, আউটপুট অপেক্ষা এবং পরিষ্কার করার জন্য নিম্ন-স্তরের র্যাপার - **Group** — আইপি-স্তরের সংযোগসহ একটি বিচ্ছিন্ন ডকার নেটওয়ার্কে একাধিক কন্টেইনার চালানো - **Applications** — জনপ্রিয় সার্ভিসের জন্য রেডি-টু-ইউজ র্যাপার (MySQL, PostgreSQL, Redis, Kafka ইত্যাদি) - **Hooks** — প্রতি কন্টেইনারের জন্য লাইফসাইকেল কলব্যাক (BeforeRun, AfterRun, BeforeClose, AfterClose) - **Exec** — চলমান কন্টেইনারের ভিতরে কমান্ড চালানো এবং stdout, stderr এবং এক্সিট কোড ক্যাপচার করা - **লাইফসাইকেল কমান্ড** — exec এর মাধ্যমে স্টার্টআপ / রেডি-পরবর্তী কমান্ড চালানো - **কন্টেইনারে ফাইল কপি** — `WithFiles` দিয়ে শুরু করার আগে ফাইল সিড করা - **কন্টেইনার থেকে ফাইল কপি** — চলমান কন্টেইনার থেকে tar স্ট্রিম হিসেবে ফাইল পড়া - **রিসোর্স সীমা** — হোস্ট এবং CI রক্ষার জন্য CPU/মেমরি/pids সীমিত করা - **Matchers** — সাবস্ট্রিং, এক্সাক্ট বা regexp ম্যাচার দিয়ে কন্টেইনার লগ অপেক্ষা করা - **Wait কৌশল** — কম্পোজেবল রেডিনেস প্রোব (ForLog, ForHTTPGet, ForCommand, ForTCPConnection) - **এনভায়রনমেন্ট বিল্ডার** — টাইপড এনভায়রনমেন্ট ভেরিয়েবলের জন্য ফ্লুয়েন্ট DSL - **পোর্ট বাইন্ডিং** — র্যান্ডম বা এক-থেকে-এক বরাদ্দসহ DNAT পোর্ট ম্যাপিং - **নেটওয়ার্ক মোড** — হোস্ট বা কাস্টম নেটওয়ার্ক সাপোর্ট - **IMAGE_PREFIX** — প্রক্সি/মিররের মাধ্যমে ইমেজ রুট করা - **`*testing.T` বাইন্ডিং** — নিরাপদ `t.Parallel()` সহ স্বয়ংক্রিয় টিয়ারডাউন এবং লগিং ## প্রয়োজনীয়তা - Go 1.26+ - একটি চলমান ডকার ডেমন (`DOCKER_HOST` এর মাধ্যমে রিমোট হোস্টে কাজ করে) ## ইনস্টলেশন মাল্টি-মডিউল ওয়ার্কস্পেস: রুট হল কোর মডিউল, এবং `applications/<name>` এর অধীনে প্রতিটি অ্যাপ্লিকেশন তার নিজস্ব Go মডিউল। শুধু যা প্রয়োজন তা টানুন: ```sh go get github.com/teran/go-docker-testsuite # নির্দিষ্ট অ্যাপ্লিকেশন র্যাপার: go get github.com/teran/go-docker-testsuite/applications/redis go get github.com/teran/go-docker-testsuite/applications/postgres ``` ## অ্যাপ্লিকেশন রেডি-টু-ইউজ র্যাপার (প্রতিটি একটি টাইপড ক্লায়েন্ট ইন্টারফেস রিটার্ন করে এবং স্টার্টআপ, হেলথ চেক এবং ক্লিনআপ পরিচালনা করে): - AWS SDK v2 সহ Ceph (RGW) - clickhouse-go সহ ClickHouse - SQLite সহ Forgejo - vtysh সহ FRR রাউটিং স্যুট - client-go সহ K3s - Sarama সহ Kafka - gomemcache সহ Memcache - MinIO (S3-সামঞ্জস্যপূর্ণ) - mongo-driver সহ MongoDB - MySQL / MariaDB / Percona Server - PostgreSQL + Redis সহ NetBox - Nginx - opensearch-go সহ OpenSearch - PostgreSQL + Valkey সহ Paperless-ngx - pgx সহ PostgreSQL - prometheus/client_golang সহ Prometheus - RabbitMQ (AMQP + ম্যানেজমেন্ট API) - go-redis সহ Redis - gocql সহ ScyllaDB - Vault - Libvirtd (KVM/QEMU) অনেক প্যাকেজে pkg.go.dev-এ টেস্টেবল উদাহরণ রয়েছে। ## ব্যবহার ### দ্রুত শুরু — MySQL ```go package main import ( "context" "database/sql" "time" _ "github.com/go-sql-driver/mysql" "github.com/teran/go-docker-testsuite/applications/mysql" ) func main() { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() app, err := mysql.New(ctx, "index.docker.io/library/mysql:8.0.4") if err != nil { panic(err) } defer app.Close(ctx) if err := app.CreateDB(ctx, "important_database"); err != nil { panic(err) } db, err := sql.Open("mysql", app.MustDSN("important_database")) if err != nil { panic(err) } defer db.Close() if _, err := db.ExecContext(ctx, "SELECT 1"); err != nil { panic(err) } } ``` ### মাল্টি-কন্টেইনার গ্রুপ ```go package main import ( "context" "time" "github.com/teran/go-docker-testsuite" "github.com/teran/go-docker-testsuite/wait" ) func main() { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() app := docker.NewApplication( c, docker.HookFunc(func(ctx context.Context, ht docker.HookType, c docker.Container) error { return wait.Wait(ctx, c, wait.ForLog(docker.NewSubstringMatcher("ready"))) }), ) g, err := docker.NewGroup("my-services", app1, app2) if err != nil { panic(err) } if err := g.Run(ctx); err != nil { panic(err) } defer g.Close(ctx) } ``` ### Wait কৌশল ```go if err := wait.Wait(ctx, c, wait.ForHTTPGet(8080, wait.WithPath("/health"), wait.WithResponseStatuses(200), )); err != nil { panic(err) } ``` অন্যান্য কৌশল: `ForLog`, `ForCommand`, `ForTCPConnection`। `ForAll` / `ForAny` / `ForAtLeast` দিয়ে একত্রিত করুন। ### `*testing.T` বাইন্ডিং ```go func TestRedis(t *testing.T) { t.Parallel() c, err := docker.NewContainerWithT( t, "redis", images.Redis, nil, docker.NewEnvironment(), docker.NewPortBindings().PortDNAT(docker.ProtoTCP, 6379), ) if err != nil { t.Fatal(err) } c.RunT(ctx) // fail-fast; registers t.Cleanup } ``` ### লাইফসাইকেল হুক ```go docker.HookTypeBeforeRun // কন্টেইনার শুরুর আগে docker.HookTypeAfterRun // কন্টেইনার শুরুর পরে docker.HookTypeBeforeClose // কন্টেইনার বন্ধের আগে docker.HookTypeAfterClose // কন্টেইনার বন্ধের পরে ``` ### Exec এবং লাইফসাইকেল কমান্ড ```go res, err := c.Exec(ctx, []string{"echo", "hello"}) if err != nil { panic(err) } if err := res.Error(); err != nil { panic(err) } fmt.Printf("exit code: %d\n", res.ExitCode) fmt.Printf("stdout: %s", res.Stdout) ``` ### কন্টেইনারে/থেকে ফাইল কপি করা ছোট কন্টেন্টের জন্য `FileFromBytes` সহ `WithFiles` ব্যবহার করুন বা বড় ফাইলের জন্য `io.Reader` + `Size`। `docker.CopyFromContainer` দিয়ে ফাইল ফিরে পড়ুন। ### ইমেজ প্রিফিক্স / প্রক্সি ```sh export IMAGE_PREFIX=registry-mirror.example.com ``` ## মডিউল ও রিলিজ একক ভার্সন নম্বরসহ মাল্টি-মডিউল ওয়ার্কস্পেস, আলাদাভাবে ট্যাগ করা (যেমন, কোর `v1.6.0`, অ্যাপ্লিকেশন `applications/redis/v1.6.0`)। রিলিজ অর্ডার: প্রথমে কোর, তারপর অ্যাপ্লিকেশন। ট্যাগ করতে Makefile ব্যবহার করুন। ## লাইসেন্স Apache License, Version 2.0