Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Build and Test

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

permissions:
contents: read

jobs:
php-integration-tests:
runs-on: ubuntu-latest
steps:
- name: Setup Helioviewer Docker environment
uses: Helioviewer-Project/helioviewer.org-docker/.github/actions/helioviewer-docker@main
with:
api-ref: ${{ github.ref }}

- name: Disable movie builder (required for tests)
working-directory: helioviewer.org-docker
run: docker compose down movies

# Run tests inside the api container
- name: Run phpunit tests
working-directory: helioviewer.org-docker
run: docker compose exec -T api composer run-script test

- name: Run python tests
uses: Helioviewer-Project/helioviewer.org-docker/.github/actions/pytest-api@main
with:
working-directory: helioviewer.org-docker

- name: Print container logs
if: always()
working-directory: helioviewer.org-docker
run: |
docker compose logs

- name: Print API error logs
if: always()
working-directory: helioviewer.org-docker
run: cat data/log/*

playwright-e2e-tests:
strategy:
matrix:
shardIndex: [1, 2, 3, 4, 5]
shardTotal: [5]
# If one of the shards fails, continue running the remaining tests
fail-fast: false

timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- name: Run Playwright tests
uses: Helioviewer-Project/helioviewer.org-tests/.github/actions/playwright-test@main
with:
api-ref: ${{ github.sha }}
shard-index: ${{ matrix.shardIndex }}
shard-total: ${{ matrix.shardTotal }}
merge-reports:
# Merge reports after playwright-tests, even if some shards have failed
if: ${{ !cancelled() }}
needs: [playwright-e2e-tests]

runs-on: ubuntu-latest
steps:
- name: Checkout test code
uses: actions/checkout@v4
with:
repository: 'Helioviewer-Project/helioviewer.org-tests'
path: 'helioviewer.org-tests'

- name: Merge Playwright reports
uses: Helioviewer-Project/helioviewer.org-tests/.github/actions/playwright-merge-reports@main
with:
test-repo-path: 'helioviewer.org-tests'
155 changes: 0 additions & 155 deletions .github/workflows/php.yml

This file was deleted.

82 changes: 42 additions & 40 deletions install/__test__/test_vso_sunpy_download.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
from unittest.mock import patch
import responses
import unittest
import requests
import os

class TestVsoDownload(unittest.TestCase):

@patch("sunpy.net.Fido.fetch")
@responses.activate
def test_getImageGroup(self, fido_fetch_response):
# Allow requests to localhost to go through.
responses.add_passthru("http://localhost")
URL = "http://localhost/?action=getSciDataScript&imageScale=4.84088176&sourceIds=[13,10]&startDate=2021-06-01T00:01:00Z&endDate=2021-06-01T00:01:15Z&lang=sunpy&provider=vso";

response = requests.get(URL)

self.assertEqual(200, response.status_code)
self.assertEqual("OK", response.reason)

script_with_paths = response.content.replace(b'os.path.expanduser(\'~/\')', bytes('\'/tmp/\'', encoding='utf-8'))

try:
script_for_compile = compile(script_with_paths, '', 'exec', flags=0, dont_inherit=True)
except SyntaxError:
self.fail("Test Fail: Could not compile downloaded sunpy vso script , possible error in script")

test_dir = os.path.dirname(os.path.abspath(__file__))
request_path = os.path.join(test_dir, 'mocked_requests', 'vso_sunpy_download.yaml')
responses._add_from_file(file_path=request_path)

fido_fetch_response.return_value = ['theoretical_file.fits']
locals = {};
exec(script_for_compile,globals(), locals)

self.assertEqual(len(locals['data_aia_304']), 1)
self.assertEqual(len(locals['data_aia_171']), 1)

if __name__ == '__main__':
unittest.main()
from unittest.mock import patch
import responses
import unittest
import requests
import os

class TestVsoDownload(unittest.TestCase):

@patch("sunpy.net.Fido.fetch")
@responses.activate
def test_getImageGroup(self, fido_fetch_response):
# Get API host from environment variable, default to localhost
host = os.environ.get('PYTEST_API_HOST', 'localhost')
# Allow requests to the configured host to go through.
responses.add_passthru(f"http://{host}")
URL = f"http://{host}/?action=getSciDataScript&imageScale=4.84088176&sourceIds=[13,10]&startDate=2021-06-01T00:01:00Z&endDate=2021-06-01T00:01:15Z&lang=sunpy&provider=vso"

response = requests.get(URL)

self.assertEqual(200, response.status_code)
self.assertEqual("OK", response.reason)

script_with_paths = response.content.replace(b'os.path.expanduser(\'~/\')', bytes('\'/tmp/\'', encoding='utf-8'))

try:
script_for_compile = compile(script_with_paths, '', 'exec', flags=0, dont_inherit=True)
except SyntaxError:
self.fail("Test Fail: Could not compile downloaded sunpy vso script , possible error in script")

test_dir = os.path.dirname(os.path.abspath(__file__))
request_path = os.path.join(test_dir, 'mocked_requests', 'vso_sunpy_download.yaml')
responses._add_from_file(file_path=request_path)

fido_fetch_response.return_value = ['theoretical_file.fits']
locals = {};
exec(script_for_compile,globals(), locals)

self.assertEqual(len(locals['data_aia_304']), 1)
self.assertEqual(len(locals['data_aia_171']), 1)

if __name__ == '__main__':
unittest.main()
20 changes: 14 additions & 6 deletions src/Movie/FFMPEGEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ public function __construct($directory, $filename, $frameRate, $width, $height,
$this->_log = fopen($directory . 'ffmpeg.log', 'a');
}

private function checkVideoOutput($outputFile) {
// If FFmpeg segfaults, an empty movie container may still be produced,
if (!file_exists($outputFile)) {
throw new Exception("FFMpeg error encountered - movie file $outputFile does not exist");
}
$fsize = filesize($outputFile);
if ($fsize < 1000) {
throw new Exception("FFmpeg error encountered - Expected movie to be at least 1000 bytes, got $fsize ($outputFile)", 43);
}
}

/**
* Creates a medium quality video
*/
Expand All @@ -72,9 +83,7 @@ public function createVideo($convertHQ = false)
$this->_createWebMVideo($outputFile);
}

// If FFmpeg segfaults, an empty movie container may still be produced,
if (!file_exists($outputFile) || filesize($outputFile) < 1000)
throw new Exception("FFmpeg error encountered.", 43);
$this->checkVideoOutput($outputFile);

return $outputFile;
}
Expand All @@ -93,9 +102,8 @@ public function createHQVideo()
$this->_createWebMVideo($outputFile, 1);
}

// If FFmpeg segfaults, an empty movie container may still be produced
if (!file_exists($outputFile) || filesize($outputFile) < 1000)
throw new Exception("FFmpeg error encountered.", 43);
// If FFmpeg segfaults, an empty movie container may still be produced,
$this->checkVideoOutput($outputFile);

return $outputFile;
}
Expand Down
5 changes: 3 additions & 2 deletions src/Movie/HelioviewerMovie.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ public function build() {
}
catch (Exception $e) {
Sentry::capture($e);
$this->_abort('Error encountered during movie frame compilation: ' . $e->getFile() . ":" . $e->getLine() . " - " . $e->getMessage() );
$this->_abort('Error encountered during movie frame compilation: ' . $e->getFile() . ":" . $e->getLine() . " - " . $e->getMessage() . "\n" . $e->getTraceAsString());
}

$t3 = time();
Expand All @@ -289,7 +289,8 @@ public function build() {
$t4 = time();
$this->_abort('Error encountered during video encoding. ' .
'This may be caused by an FFmpeg configuration issue, ' .
'or by insufficient permissions in the cache.', $t4 - $t3);
'or by insufficient permissions in the cache.' . "\n" .
$e->getFile() . ":" . $e->getLine() . " - " . $e->getMessage() . "\n" . $e->getTraceAsString(), $t4 - $t3);
}

// Log buildMovie in statistics table
Expand Down