lambci / docker-lambda

Docker images and test runners that replicate the live AWS Lambda environment
MIT License
5.84k stars 431 forks source link

Runtime.ImportModuleError jest #320

Closed mattvb91 closed 3 years ago

mattvb91 commented 3 years ago

Im trying to get jest tests running with github actions. Locally it works fine but on github it errors. My github action file looks like this:

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run. 
on:
  push:
  pull_request:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    container: 
      image: lambci/lambda:build-nodejs12.x

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Runs a set of commands using the runners shell
      - name: Build
        run: |
          curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo
          curl --silent --location https://rpm.nodesource.com/setup_12.x | bash -
          yum install yarn -y
          for d in $GITHUB_WORKSPACE/lambda/*; do (cd "$d" && yarn --frozen-lockfile); done
          cd $GITHUB_WORKSPACE
          yarn --frozen-lockfile
          yarn build
          ls -la $GITHUB_WORKSPACE/lambda/hooks
          yarn test
    env:
      AWS_DEFAULT_REGION: "us-east-1"
$ tsc
Done in 10.06s.
total 72
drwxr-xr-x  3 root root  4096 Nov 28 11:51 .
drwxr-xr-x  6 root root  4096 Nov 28 11:50 ..
-rw-r--r--  1 root root    11 Nov 28 11:51 hookHandler.d.ts
-rw-r--r--  1 root root  4172 Nov 28 11:51 hookHandler.js
-rw-r--r--  1 root root  1087 Nov 28 11:50 hookHandler.ts
drwxr-xr-x 93 root root  4096 Nov 28 11:51 node_modules
-rw-r--r--  1 root root   281 Nov 28 11:50 package.json
-rw-r--r--  1 root root 40128 Nov 28 11:50 yarn.lock
yarn run v1.22.5
$ jest
FAIL test/lambda.test.ts (18.96 s)
  ✕ Test Empty event results in 500 (8621 ms)

  ● Test Empty event results in 500

    {"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'hookHandler'\nRequire stack:\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js"}

      3 | 
      4 | test('Test Empty event results in 500', () => {
    > 5 |     var lambdaCallbackResult = dockerLambda({
        |                                ^
      6 |         taskDir: path.resolve(__dirname + "/../lambda/hooks/"),
      7 |         handler: "hookHandler.handler",
      8 |         dockerImage: 'lambci/lambda:nodejs12.x'

      at runSync (node_modules/docker-lambda/index.js:49:13)
      at Object.<anonymous> (test/lambda.test.ts:5:32)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        19.635 s

My test code:

var dockerLambda = require('docker-lambda')
import path from "path"

test('Test Empty event results in 500', () => {
    var lambdaCallbackResult = dockerLambda({
        taskDir: path.resolve(__dirname + "/../lambda/hooks/"),
        handler: "hookHandler.handler",
        dockerImage: 'lambci/lambda:nodejs12.x'
    })

    expect(lambdaCallbackResult.statusCode).toEqual(500);
});

Not really sure how to replicate as its working fine locally. I am probably missing some dependancy on the github runner image?

mhart commented 3 years ago

Are you sure the ../lambda/hooks/ directory exists when you're running it in GitHub Actions?

mattvb91 commented 3 years ago

Are you sure the ../lambda/hooks/ directory exists when you're running it in GitHub Actions?

@mhart Thats actually why I have the ls -la $GITHUB_WORKSPACE/lambda/hooks up above to validate in the output that it exists in the action as I was suspecting the same thing.

my directory structure is:

 - lambda
    - hooks <!--- this is the ls -la dir from above
- test
   - lambda.test.ts
mhart commented 3 years ago

Not sure then I'm afraid. You could try outputting more debugging info from the Jest test – like ensuring that path.resolve(__dirname + "/../lambda/hooks/") is the directory you think it is, and listing that directory from your Jest test.

If that all still looks fine, then I can't really understand why the Lambda runtime can't find the file – possibly a permissions issue? All of the module-loading code is native to the runtime, not written/managed by docker-lambda

mattvb91 commented 3 years ago

Thanks for the suggestion. Have verified inside jest test that the path does indeed contain the files and also chmod 777 everything inside of it to test if its a permission issue with no luck.

Will report back if I make any progress.

mhart commented 3 years ago

You could also just try executing the docker run command manually. That's all that dockerLambda does:

https://github.com/lambci/docker-lambda/blob/4e1b563f26ec90e83d54af776924fb0fd0752c21/index.js#L33-L40

That might give you an indication as to where the problem is.

It might be actually that GitHub Action's volume mounting is causing problems:

https://github.community/t/how-to-bind-repository-to-docker-container/17869

I wonder if you use:

taskDir: "/github/workflow/lambda/hooks", 

Whether that will work (I realize that won't work locally, but you can create a conditional to check if you're in CI or not)

mattvb91 commented 3 years ago

I think your suspicion about volume mounting seems to be the right direction. Even when I manually directly run

docker run --rm -v "/github/workflow/lambda/hooks":/var/task:ro,delegated lambci/lambda:nodejs12.x hookHandler.handler

or

docker run --rm -v "$GITHUB_WORKSPACE/lambda/hooks":/var/task:ro,delegated lambci/lambda:nodejs12.x hookHandler.handler

in the action I get the same error. so its nothing to do with the node side of things but the docker side / mounting

mattvb91 commented 3 years ago

Going to close this issue as it has nothing to do with lambci but rather its a volume mounting issue in github actions as suggested above. Even with docker run -v /any_path:/var/task bash ls -lah /var/task I cant see anything I put into any_path.

I have opened a discussion here: https://github.community/t/docker-run-v-inside-container/145921

Will edit this post if I manage to solve it.

Edit: Got it working! Managed to get the contents: https://github.community/t/docker-run-v-inside-container/145921/5?u=mattvb91

For anyone else looking into the same issue here is my complete workflow:

name: CI

on:
  push:
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    container: 
      image: lambci/lambda:build-nodejs12.x
      options: -v /volume_mount:/volume_mount

    steps:
      - uses: actions/checkout@v2

      - name: Build
        run: |
          export MOUNT_PATH=/volume_mount/platform
          cp -R /__w/platform/platform /volume_mount
          curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo
          curl --silent --location https://rpm.nodesource.com/setup_12.x | bash -
          yum install yarn -y
          for d in $MOUNT_PATH/lambda/*; do (cd "$d" && yarn --frozen-lockfile); done
          cd $MOUNT_PATH
          yarn --frozen-lockfile
          yarn build
          yarn test
        env:
          MOUNT_DIR: "/volume_mount/platform/"

the important parts i was missing:

      options: -v /volume_mount:/volume_mount

and then copying the files into that directory. Still a bit rough around the edges but I just needed it green once to work off!

and in my tests:

var dockerLambda = require('docker-lambda')
import path from "path"

//If we are inside Github Action we need to go to the mounted directory
const taskDir = path.resolve((process.env.MOUNT_DIR ?? __dirname + "/..") + "/lambda/hooks")

test('Test Empty event results in 404', () => {
    var lambdaCallbackResult = dockerLambda({
        taskDir,
        handler: "hookHandler.handler",
        dockerImage: 'lambci/lambda:nodejs12.x'
    })

    expect(lambdaCallbackResult.statusCode).toEqual(404);
});

thank you for the help @mhart appreciated!