- pgmock, birim testleri ve E2E testleri için bellek içi bir PostgreSQL mock sunucusudur; dış bağımlılık olmadan Node.js ve tarayıcıda WebAssembly üzerinde çalışır
node-postgres kullanıcıları, port açmayan bir yapılandırma nesnesi alarak bağlanabilir; bu yöntem tarayıcıda da çalışır
- Tarayıcıda web uygulamaları TCP portu açamaz, ancak
PostgresMock.createSocket ve node-postgres yapılandırması kullanılabilir; bundler statik import’ları analiz ederse isteğe bağlı Node.js modülleri için uyarı verebilir
- Uygulama şu anda PostgreSQL sunucusunu bir x86 emülatörü içinde çalıştırma yaklaşımını kullanıyor; test ve prodüksiyon arasındaki davranış farklarını önlemeyi performansa göre önceliklendiriyor
- Uzun vadede, yerel PostgreSQL WASM fork’u olgunlaştığında iki yaklaşımı da sunma ve sonrasında varsayılanı yerel WASM’e çevirme planı var
pgmock’un sundukları
- pgmock, birim testleri ve E2E testleri için bellek içi bir PostgreSQL mock sunucusudur
- Dış bağımlılık gerektirmez; hem Node.js hem de tarayıcı tarafında WebAssembly içinde çalışır
- npm ile kurulabilir
npm install pgmock
Temel kullanım akışı
- Bellek içi sunucu
PostgresMock.create() ile oluşturulur ve listen(5432) ile bağlantı dizesi alınabilir
import { PostgresMock } from "pgmock";
const mock = await PostgresMock.create();
const connectionString = await mock.listen(5432);
node-postgres kullanılıyorsa mock.getNodePostgresConfig(), port dinlemeden bağlanmayı sağlayan bir yapılandırma nesnesi sunar
- İş bitince kaynakları serbest bırakmak için
mock.destroy() çağrılması önerilir
mock.destroy();
Tarayıcı desteği ve pglite ile farkı
pgmock, tarayıcı ortamını tam olarak destekler
- Web uygulamaları TCP portu açamaz, ancak
PostgresMock.createSocket ve node-postgres yapılandırması kullanılabilir
- Bundler import’ları statik olarak analiz ederse, isteğe bağlı Node.js modüllerinin bulunmadığına dair uyarı verebilir; Webpack yapılandırma örneği
examples/web-demo/next.config.mjs içinde yer alır
- Tarayıcıda yalnızca veritabanı çalıştırmak istiyorsanız pglite değerlendirilebilir
- pglite daha hızlı ve hafiftir, ancak özellik kümesi sınırlıdır
pgmock, test ortamında istenen prodüksiyon PostgreSQL ile özellik eşdeğerliğini hedefleyecek şekilde tasarlanmıştır
PostgreSQL’i WebAssembly’de çalıştırma yöntemleri
- PostgreSQL’i WebAssembly’de çalıştırmanın iki yolu vardır
- Yerel WASM fork’u yaklaşımı daha hızlıdır ve çok daha az bellek kullanır, ancak yalnızca tek kullanıcı modunu destekler; bağlantıları ve eklentileri desteklemez
pgmock şu anda x86 emülatörü yaklaşımını kullanıyor
- Amaç, test ve prodüksiyon arasındaki uyumsuzluğu önlemektir
- Çünkü testlerde performans genellikle büyük bir sorun değildir
- Orta vadede yerel PostgreSQL WASM fork’u olgunlaştığında iki seçeneği de sunma planı var
- Sonrasında varsayılanı yerel WASM’e çevirme planlanıyor;
PostgresMock.subtle iç API’si dışında çok fazla büyük breaking change beklenmiyor
Mevcut tarayıcı PostgreSQL projeleriyle farkı
pgmock, JavaScript runtime’ı içinde tam özellik uyumluluğu sağlar ve iletişim için ağ proxy’sine bağımlı değildir
- Ağ yığınını JavaScript ile simüle ederek gerçek ağ gibi davranmasını sağlar ve raw socket erişimine izin vermeyen platformlarda da TCP bağlantısını simüle edebilir
Genişletilebilirlik ve ilgili projeler
- Diğer Docker imajlarını veya veritabanlarını çalıştırmak teorik olarak mümkündür, ancak test edilmemiştir
- İlgili uygulamalar ve temel projeler olarak şunlar belirtilmiştir
- v86: x86 emülatörü
- Supabase & Snaplet: PostgreSQL’i WebAssembly içinde çalıştırma yaklaşımının temeli
- Stackframe:
pgmock geliştirilirken maaş sağlayan şirket olarak anılır
1 yorum
Hacker News yorumları
Birkaç aydır şirkette bellek içi Postgres sürümü üzerinde çalışıyorduk ve üretim veritabanıyla özellik eşdeğerliğine sahip
Avantajı, harici bir süreç ya da proxy gerektirmemesi. Platform WASM çalıştırabiliyorsa pgmock’u Node.js’te veya tarayıcıda da çalıştırabilirsiniz; sahte verilerle dolu yeni bir veritabanı oluşturmak da bir JavaScript nesnesi oluşturmak kadar basit
pgmock’u açık kaynak yapmamızı sağlayan pglite’tan biraz farklı. pgmock, özgün Postgres’i bir x86 emülatörü içinde çalıştırıyor; pglite ise bir Postgres fork’unu doğrudan native WASM’e derlediği için daha hızlı ve hafif
Ancak pglite tek kullanıcı modunu ve yalnızca bazı eklentileri desteklediğinden normal Postgres istemcileriyle bağlanılamıyor; bu da E2E testlerinde oldukça önemli
Teorik olarak WebAssembly platformunda herhangi bir Docker imajını çalıştıracak şekilde değiştirilebilir; görmek istediğiniz belirli bir hedef var mı merak ediyorum
Çoklu bağlantı modu eklemek için birkaç yol düşünüyoruz ama biraz zaman alacak gibi. PGlite’ta tek kullanıcı moduyla ilgili başka sınırlamalar da var; örneğin pg_notify’ı henüz desteklemiyor, bunu da düzeltmeyi planlıyoruz
Öte yandan bu proje gerçek Postgres’e çok daha yakın, bu yüzden doğrudan çalışması daha olası. Bu tür bellek içi Postgres projeleri test çalışma sürelerini dörtte birin altına indirebilecek gibi görünüyor ve test alanında büyük potansiyele sahip
PGlite üzerinde çalışan biri olarak düşüncelerim bunlar
Yakın zamanda istemcide FFMPEG/SoX hattı çalıştırmak istemiştim; bağımlılıkları o kadar fazlaydı ki Emscripten ile kolayca yeniden derlemek zordu. Bu yaklaşımın böyle durumlarda da yardımcı olup olamayacağını merak ediyorum
İlişkisel özellikler sayesinde, normalde ilişkisel veritabanlarında bulunan zengin alana özgü metaverileri ekleyip birlikte sorgulayabilirsiniz
select foo();çalıştırıncaError.captureStackTrace is not a functionçıkıyor; Linux’ta Firefox 124.0.2’de oluyorPostgres dosyalarını basitçe ramdisk üzerine koyup çalıştırmak olmaz mı diye merak ediyorum
Güncelleme: Tarayıcı/Node ortamında çalışabildiği için testler oluşturup güncelleyip silebiliyor gibi. Fazlasıyla backend geliştiricisi olduğumdan, sıradan geliştirme ortamına göre avantajını pek kavrayamıyorum. Nerede, ne zaman ve nasıl daha iyi olduğunu açıklayabilirseniz iyi olur
WebAssembly ile yapılmasının nedeni; platformlar, mimariler, tarayıcı veya edge ortamları arasında davranışı daha taşınabilir biçimde eşleyebilmek ve Docker’a bile ihtiyaç duymayan, harici bağımlılıksız bir kurulum elde etmek
Emülatör zaten çalışır durumdayken doğrudan önyükleme yapabildiği için emüle edilen veritabanı, gerçek bir veritabanı ya da Docker konteyneri başlatmaktan daha hızlı açılıyor. Ancak bu, tasarım hedefinden çok şans eseri elde edilmiş bir etki
https://testcontainers.com/ gibi bir şey kullanılamaz mı diye merak ediyorum. Konteyner motorunun harici bağımlılık olması gerçekten o kadar kötü mü?
İçine mock soktuğunuz anda bu birim testine dönüşür. Etkilidir ama aynı şey değildir. E2E’nin kilit noktalarından biri, mock olmadığı için testin doğru olduğunu bilebilmenizdir. Bu, Postgres’i test etmek değil; her seferinde bu sistemi test etmek demektir
Gömülü, hafif, düşük performanslı sistemler için PG yapıyorsanız, yavaş gerçek E2E testlerinden önce doğrulama testi olarak mantıklı. Benim de böyle bir kullanımım var
Bunun dışında güzel bir proje ve PG shim gerektiğinde kullanılabilecek bir araç gibi görünüyor
Postgres’te savepoint kullanıyoruz ama ramdisk üzerinde bile pek hızlı değil
Eskiden testlerde her türden özel sahte bellek içi sunucu çalıştırırdık. Bugünlerde https://testcontainers.com ile gerçek hedefleri çalıştırıyoruz
Prisma/Node.js geliştiricisi yerel geliştirme için yalnızca “kutuda Postgres” istiyorsa, PGlite’ın yakın zamanda çıkan sunuculaştırılmış sürümü pglite-server daha iyi olabilir: https://github.com/kamilogorek/pglite-server
Daha hızlı ve verileri dosya sisteminde tutabiliyor; ancak yoğun kullanımda tam x86 emülatörü tabanlı E2E test sunucusundan daha az kararlı. pglite-server yalnızca 150MB bellek kullanırken pgmock-server 830MB kullandı
dotenv ile yeni bir
.env.localcheckout edip tüm nextjs/prismapackage.jsonçalıştırma betiklerindeDATABASE_URL’yi değiştirmeniz yeterliDATABASE_URL="postgresql://postgres@localhost:5432/awesomeproject""db:pushlocal": "dotenv -e .env.local -- pnpm prisma db push"Her projeye çok kolayca eklenebilir; Neon’un bu alanı desteklemesini de anlayabiliyorum
Heves kırmak istemem ama ben bunu kullanmayı düşünmem
Basit bir uygulamada işe yarayabilir; ancak kilitlenme riski olması veya veritabanı biçimine bağımlılık gibi karmaşıklık arttığında, davranıştaki küçük farklar bile ölümcül sorunlara dönüşebilir ve değeri azalır
Bu aralar kaynak kısıtlı E2E ortamlarını tercih ediyorum. Çünkü yerel test çalıştırıcısına, biri aşırı verimsiz kod yazdığında bozulma fırsatı veriyor
Ayrıca veritabanını birkaç saniye sonra anlık görüntüye dönüştürüp bu snapshot’ı test bölümlerine dağıtmak çok hızlı; test paketlerinden çoğu kez dakikalar kazandırdı
İlginç bir fikir ve iyi bir öğrenme deneyimi, ancak hedef kullanıcı kitlesinin sınırlı olduğunu düşünüyorum
Başlık biraz kafa karıştırıcı. “Şirkette yaptı” deniyorsa, şirket kaynaklarının kullanıldığı varsayımıyla bu projenin fikri mülkiyet haklarının işverene ait olması gerekmez mi diye düşünüyorum
Öyleyse teknik olarak açık kaynak yayımlanıp yayımlanamayacağını merak ediyorum
Copyright 2024 Stackframe.yazıyor. Görünüşe göre yazar Stackframe’de çalışıyorBunun H2’nin Postgres uyumluluk modu ile karşılaştırıldığında nasıl olduğunu merak ediyorum
Oldukça havalı. Cevaplayabiliyorsanız birkaç şeyi merak ediyorum
Şirkette bu projeyi yapmaya neyin yol açtığını, Docker container’ında Postgres çalıştırmanın çok mu yavaş olduğunu merak ediyorum
pgmock’u akışa entegre etmeden önce ve sonra E2E testleri için CI yapılandırmasının nasıl değiştiğini de bilmek isterim
Bu çözüme geçiş sürecinin zor olup olmadığını da merak ediyorum
Üretim verilerini dump edip tüm hassas verileri kaldırdıktan sonra, log tabloları gibi gereksiz tabloları truncate ederseniz geliştirme için iyi bir kopya elde edersiniz
Bunu geliştirme, QA, E2E vb. ortamlara çoğaltabilirsiniz. E2E için gereken şey tam olarak o extension’lar, trigger’lar, fonksiyonlar, view’lar, indeksler ve verilerdir
Neden sadece Docker kullanıp ayrı bir test veritabanı tutmuyoruz, merak ediyorum
Elixir bunu böyle yapıyor; test framework’ü her testi bir transaction içine sarıyor ve izolasyon için rollback yapıyor. Bu yaklaşımın avantajının ne olduğunu öğrenmek ilginç olurdu