#PHP SDK Integration tests
1 messages ยท Page 1 of 1 (latest)
I'm turning this into a thread so I can keep help in one place:
This will sound silly but, how do I run the module_php_test.go independently?
or as close to as possible?
Okay I think I got that part... I just ran go test --run ./module_php_test.go
so, i do this: dagger call test specific --race --pkg="./core/integration" --run="<regex for my test>"
this spins up the dev engine alongside
and manages all that
you can also do ./hack/with-dev go test --run ...
which is slightly different, because it starts a dev engine in-docker, and keeps it around afterwards
the go test --run flag takes a regex for your test name
e.g. Module/ModuleDevelopVersion will run this test: https://github.com/dagger/dagger/blob/cf5a8847e252c64432d2a701ccc9365e258106ef/core/integration/module_test.go#L4990-L4990
Right so..
dagger call test specific --race --pkg="./core/integration/module_php_test.go" --run="TestInit"
would work?
Right now I just ran a test on integration full stop
uh, i don't actually know about putting file names in there, mayyyybe it works
i would make a new TestPHP function (copying the suite logic that we do in other test files)
then it should just be --run=TestPHP
Oh I see!
ye, a file isn't a package in go, so you can't do this
I think that already exists
I'm quite new to Go, so thank you.
It's quite a nice language, I can read it, write it with references. but the intricacies escape me currently
I'm trying to make a simple "The local branch doesn't explode when initialized" test:
t.Run("from local", func(ctx context.Context, t *testctx.T) {
c := connect(ctx, t)
sdkSrc, err := filepath.Abs("../../sdk/php/")
require.NoError(t, err)
out, err := daggerCliBase(t, c).
WithDirectory("/sdk/php", c.Host().Directory(sdkSrc)).
With(daggerExec(
"init",
"--name=bare",
"--sdk=/sdk/php/")).
With(daggerCall("container-echo", "--string-arg", "hello", "stdout")).
Stdout(ctx)
require.NoError(t, err)
require.Equal(t, "hello\n", out)
})
Right now that is what I'm trying but I get this:
Error: failed to generate code: input: moduleSource.withName.withSDK failed to loa
dule source: local module dep source path "/sdk/php" is absolute: unknown builtin
The "/sdk/php" SDK does not exist. The available SDKs are:
- go
- python
- typescript
- php
- elixir
- java
- any non-bundled SDK from its git ref (e.g. github.com/dagger/dagger/sdk/elixir@m
I see the Java one does this for modules (Which you helped me find before, thank you):
func javaModule(t *testctx.T, c *dagger.Client, moduleName string) *dagger.Container {
t.Helper()
modSrc, err := filepath.Abs(filepath.Join("./testdata/modules/java", moduleName))
require.NoError(t, err)
sdkSrc, err := filepath.Abs("../../sdk/java")
require.NoError(t, err)
return goGitBase(t, c).
WithDirectory("modules/"+moduleName, c.Host().Directory(modSrc)).
WithDirectory("sdk/java", c.Host().Directory(sdkSrc)).
WithWorkdir("/work/modules/" + moduleName)
}
But I'm not testing a module just yet, I literally just want to check that TestInit doesn't explode from current changes
Is that possible? As I can't find any tests like that for other SDKs
huh
local module dep source path "/sdk/php" is absolute is a bit sus
technically. this is true.
oohhh lol
(use goGitBase instead of daggerCliBase)
the reason for this is that .git is a magical directory that sets the root (yes, this is painful)
I still seem to be struggling with it. Absolute, relative. It isn't happy
t.Run("from local", func(ctx context.Context, t *testctx.T) {
c := connect(ctx, t)
sdkSrc, err := filepath.Abs("../../sdk/php/")
require.NoError(t, err)
out, err := goGitBase(t, c).
WithDirectory("work/sdk/php", c.Host().Directory(sdkSrc)).
With(daggerExec(
"init",
"--name=bare",
"--sdk=./sdk/php")).
With(daggerCall("container-echo", "--string-arg", "hello", "stdout")).
Stdout(ctx)
require.NoError(t, err)
require.Equal(t, "hello\n", out)
what error do you get?
failed to load sdk for module source: failed to load local dep: select: local path "/work/sdk/php" does not exist: unknown builtin sdk
It wasn't happy when it was in /sdk/php because it was outside of scope
if you put the sdk in /work/sdk/php
and then set workdir to /work
then --sdk=./sdk/php should work
if not, i'll take a look
But this should be the case already:
func goGitBase(t testing.TB, c *dagger.Client) *dagger.Container {
t.Helper()
return c.Container().From(golangImage).
WithExec([]string{"apk", "add", "git"}).
WithExec([]string{"git", "config", "--global", "user.email", "dagger@example.com"}).
WithExec([]string{"git", "config", "--global", "user.name", "Dagger Tests"}).
WithMountedFile(testCLIBinPath, daggerCliFile(t, c)).
WithWorkdir("/work").
WithExec([]string{"git", "init"})
goGitBase sets the work dir to "/work"
I'll update the withDirectory to have that forward slash at the front. Giving it a whirl now.
yeah that's worked for me
t.Run("from local", func(ctx context.Context, t *testctx.T) {
c := connect(ctx, t)
sdkSrc, err := filepath.Abs("../../sdk/php/")
require.NoError(t, err)
out, err := goGitBase(t, c).
WithDirectory("/work/sdk/php", c.Host().Directory(sdkSrc)).
With(daggerExec(
"init",
"--name=bare",
"--sdk=./sdk/php")).
With(daggerCall("container-echo", "--string-arg", "hello", "stdout")).
Stdout(ctx)
require.NoError(t, err)
require.Equal(t, "hello\n", out)
})
Yeah I'm getting somewhere with it, I had a slight error but it did make a difference
I didn't want to send out the fireworks before it ran XD
Okay. Success Protocol has begun
๐ ๐ ๐ ๐ฆ exit code 0
Thank you very much! I will tidy it up and put in a small PR shortly
I've made a PR https://github.com/dagger/dagger/pull/9710 for that addition plus a couple tidy ups @gray escarp
Adds a test which takes the local ./sdk/php to test if the current changes work.
This is to help avoid issues like this.
Next I will add in some actual module tests like the Java one does
I'm doing something wrong here:
func (PHPSuite) TestPhpSignatures(ctx context.Context, t *testctx.T) {
bla bla bla t.Run yadayada
call test specific --race --pkg="./core/integration" --run="TestPhpSignatures"
.withExec(
args:
[
"go",
"test",
"-ldflags",
"-X github.com/dagger/dagger/engine.Version=v0.17.0-250320123519-05ec7d865ca2 -X github.com/dagger/dagger/engine.Tag=05ec7d865ca261b2aee920144937757514e74607",
"-timeout=30m",
"-race",
"-count=1",
"-run",
"TestPhpSignatures",
"./core/integration"
]
)
29ms
ok github.com/dagger/dagger/core/integration 1.218s [no tests to run]
it should be --run=TestPHP/TestPhpSignatures
I plan to rename it to TestSignatures later, but for now, I just want to run it quick
Riiight.
Nice! I have failing tests. One more question... should returning null actually give back an empty string?
/go/pkg/mod/github.com/dagger/testctx@v0.0.4/tes
295
/go/pkg/mod/github.com/dagger/testctx/oteltest@v
g.go:37
/go/pkg/mod/github.com/dagger/testctx/oteltest@v
ace.go:83
/go/pkg/mod/github.com/dagger/testctx@v0.0.4/mid
go:25
/go/pkg/mod/github.com/dagger/testctx@v0.0.4/tes
149
Error: Not equal:
expected: <nil>(<nil>)
actual : string("")
Test: TestPHP/TestSignatures/null
! test failed
This is the function it calls:
#[DaggerFunction]
public function getNull(): null
{
return null;
}
Rather basic, but it's worth covering the basics
what does your test look like ๐
func (PHPSuite) TestSignatures(ctx context.Context, t *testctx.T) {
c := connect(ctx, t)
module := phpModule(t, c, "signatures")
t.Run("null", func(ctx context.Context, t *testctx.T) {
out, err := module. With(daggerCall("get-null")). Stdout(ctx)
require.NoError(t, err)
require.Equal(t, nil, out)
})
// ...
ah yeah, that makes sense. the stdout is going to be the empty string
you should just be able to do require.Equal(t, "", out)
you can also do require.Empty sometimes?
I'll stick to Equal since Empty looks like it's less strict
But that's fine. I just wanted to make sure I hadn't found a bug with PHP nulls
@gray escarp I threw a PR at you, it's got 19 files but DW there's only actually 4 files to check:
module_php_test.go
ListKind.php
ScalarKind.php
VoidKind.php
Everything else is just, generated stuff required to run the test modules
Oh nice ๐ถ๏ธ
Tom reviewed it so it's been merged but we've got a few more tests ๐
I'm adding some built-in object ones as well.
Genuine relief ๐
It removes so much worry of "Okay, have I broken anything?"
I'm hoping you may be able to save me on this one: I want to test that I can pass a custom object as an argument.
#[DaggerObject] class Custom
{
#[DaggerFunction] public function daggerOrganization(): Organization
{
// ...
}
#[DaggerFunction, ReturnsListOfType('string')]
public function getUrlsOfMembers(Organization $arg): array
{
// ...
}
}
So I need to call dagger-organization and then pass that object to the get-urls-of-members function.
But I have no idea how to write that bit in Go.
t.Run("Custom Object", func(ctx context.Context, t *testctx.T) {
c := connect(ctx, t)
module := phpModule(t, c, "object-kind/custom")
// org := module.With(daggerCall("dagger-organization"))
// out, err := module.
// Call("get-urls-of-members", org).
// Stdout(ctx)
require.NoError(t, err)
require.Equal(t, "https://github.com/jane\nhttps://github.com/john\n", out)
})
I've put some pseudo code in there atm. But I only know how to get the stdout. I'm just not sure how I should go about testing this.
ah, you can't pass objects on the cli using call
Yeah sorry, pseudocode
you can either:
- create the php module as a depdency (scan for
./depusage), and then call it
- or, use shell, which can use a subshell
$()to create the object
there should be a pattern of the first somewhere
Is the shell option something I can do inline?
like daggerCall("get-urls-of-members", "--arg=$(dagger-organization)"
uhhh using daggerShell as a helper i think works
(not daggerCall)
as an example of a bit of both: https://github.com/dagger/dagger/blob/755e57b5e9eb20fcf180577cea57bc3090cbb0ef/core/integration/module_shell_test.go#L61-L61
