From 47ab066d110be48027bf8cd95b1c78ece975fe1e Mon Sep 17 00:00:00 2001 From: Drew Bollinger Date: Thu, 25 Jun 2020 16:37:29 -0400 Subject: [PATCH 1/2] print test cli output to artifacts --- .circleci/config.yml | 2 ++ .gitignore | 3 ++- test/artifacts/.gitkeep | 0 test/integration/test_classification_labels.py | 6 +++++- test/integration/test_classification_labels_geojson.py | 6 +++++- .../test_classification_labels_linestring_geojson.py | 6 +++++- test/integration/test_classification_labels_sparse.py | 6 +++++- 7 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 test/artifacts/.gitkeep diff --git a/.circleci/config.yml b/.circleci/config.yml index 95b4a93..88ece28 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -52,6 +52,8 @@ jobs: - run: name: run tox command: ~/.local/bin/tox + - store_artifacts: + path: test/artifacts - add_ssh_keys: fingerprints: - "79:16:39:74:e9:b3:39:52:87:2c:90:aa:ee:3c:09:13" diff --git a/.gitignore b/.gitignore index dd3307f..8d74172 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ stdout* /integration* .idea/ docs/_build/ - +test/artifacts/* +!test/artifacts/.gitkeep .tox \ No newline at end of file diff --git a/test/artifacts/.gitkeep b/test/artifacts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/integration/test_classification_labels.py b/test/integration/test_classification_labels.py index 4ea1cef..89a85ce 100644 --- a/test/integration/test_classification_labels.py +++ b/test/integration/test_classification_labels.py @@ -2,6 +2,7 @@ label-maker labels --dest integration-cl --config test/fixtures/integration/config.integration.json""" import unittest import json +import os from os import makedirs from shutil import copyfile, rmtree import subprocess @@ -37,7 +38,10 @@ def test_cli(self): cmd = 'label-maker labels --dest integration-cl --config test/fixtures/integration/config.integration.json' cmd = cmd.split(' ') with subprocess.Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE) as p: - self.assertEqual(expected_output, p.stdout.read()) + with open(os.path.join('test' ,'artifacts', type(self).__name__), 'w') as w: + output = p.stdout.read() + w.write(output) + self.assertEqual(expected_output, output) # our labels should look like this expected_labels = { diff --git a/test/integration/test_classification_labels_geojson.py b/test/integration/test_classification_labels_geojson.py index ef192af..aae47a8 100644 --- a/test/integration/test_classification_labels_geojson.py +++ b/test/integration/test_classification_labels_geojson.py @@ -2,6 +2,7 @@ label-maker labels --dest integration-cl --config test/fixtures/integration/config.geojson.json""" import unittest import json +import os from os import makedirs from shutil import copyfile, rmtree import subprocess @@ -37,7 +38,10 @@ def test_cli(self): cmd = 'label-maker labels --dest integration-cl --config test/fixtures/integration/config.geojson.json' cmd = cmd.split(' ') with subprocess.Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE) as p: - self.assertEqual(expected_output, p.stdout.read()) + with open(os.path.join('test' ,'artifacts', type(self).__name__), 'w') as w: + output = p.stdout.read() + w.write(output) + self.assertEqual(expected_output, output) # our labels should look like this expected_labels = { diff --git a/test/integration/test_classification_labels_linestring_geojson.py b/test/integration/test_classification_labels_linestring_geojson.py index 359150d..be29a4c 100644 --- a/test/integration/test_classification_labels_linestring_geojson.py +++ b/test/integration/test_classification_labels_linestring_geojson.py @@ -2,6 +2,7 @@ label-maker labels --dest integration-cl --config test/fixtures/integration/config.geojson.json""" import unittest import json +import os from os import makedirs from shutil import copyfile, rmtree import subprocess @@ -37,7 +38,10 @@ def test_cli(self): cmd = 'label-maker labels --dest integration-cl --config test/fixtures/integration/config-linestring.geojson.json' cmd = cmd.split(' ') with subprocess.Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE) as p: - self.assertEqual(expected_output, p.stdout.read()) + with open(os.path.join('test' ,'artifacts', type(self).__name__), 'w') as w: + output = p.stdout.read() + w.write(output) + self.assertEqual(expected_output, output) # our labels should look like this diff --git a/test/integration/test_classification_labels_sparse.py b/test/integration/test_classification_labels_sparse.py index 00ff208..d813dbd 100644 --- a/test/integration/test_classification_labels_sparse.py +++ b/test/integration/test_classification_labels_sparse.py @@ -2,6 +2,7 @@ label-maker labels --dest integration-cl --config test/fixtures/integration/config.integration_sparse.json --sparse""" import unittest import json +import os from os import makedirs from shutil import copyfile, rmtree import subprocess @@ -38,7 +39,10 @@ def test_cli(self): cmd = 'label-maker labels --dest integration-cl --config test/fixtures/integration/config.integration_sparse.json --sparse' cmd = cmd.split(' ') with subprocess.Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE) as p: - self.assertEqual(expected_output, p.stdout.read()) + with open(os.path.join('test' ,'artifacts', type(self).__name__), 'w') as w: + output = p.stdout.read() + w.write(output) + self.assertEqual(expected_output, output) # our labels should look like this expected_labels = { From af94e2cd341d33575767331058c36de33cce6ce3 Mon Sep 17 00:00:00 2001 From: Drew Bollinger Date: Thu, 25 Jun 2020 17:17:45 -0400 Subject: [PATCH 2/2] Rename test, test fixture name, and remove @martham93's home folder from config path --- .../integration/config-linestring.geojson.json | 2 +- ..._classification_labels_linestring_geojson.py | 4 ++-- test/tiles/1087767-1046604-21.jpg | Bin 0 -> 14654 bytes test/tiles/146-195-9.jpeg | Bin 0 -> 11832 bytes 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 test/tiles/1087767-1046604-21.jpg create mode 100644 test/tiles/146-195-9.jpeg diff --git a/test/fixtures/integration/config-linestring.geojson.json b/test/fixtures/integration/config-linestring.geojson.json index 17d8a36..b9a9026 100644 --- a/test/fixtures/integration/config-linestring.geojson.json +++ b/test/fixtures/integration/config-linestring.geojson.json @@ -8,7 +8,7 @@ {"name": "residential", "filter": ["in", "highway", "residential"]}, {"name": "unclassified", "filter": ["in", "highway", "unclassified"]} ], - "geojson": "/Users/marthamorrissey/repos/label-maker/test/fixtures/integration/labels-linestring.geojson", + "geojson": "integration-cl/labels-linestring.geojson", "imagery": "https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.jpg?access_token=ACCESS_TOKEN", "background_ratio": 1, "split_vals": [1.0, 0.0, 0.0], diff --git a/test/integration/test_classification_labels_linestring_geojson.py b/test/integration/test_classification_labels_linestring_geojson.py index be29a4c..0d4001c 100644 --- a/test/integration/test_classification_labels_linestring_geojson.py +++ b/test/integration/test_classification_labels_linestring_geojson.py @@ -9,12 +9,12 @@ import numpy as np -class TestClassificationLabelGeoJSON(unittest.TestCase): +class TestClassificationLabelLineStringGeoJSON(unittest.TestCase): """Tests for classification label creation""" @classmethod def setUpClass(cls): makedirs('integration-cl') - copyfile('test/fixtures/integration/labels-linestring.geojson', 'integration-cl/labels.geojson') + copyfile('test/fixtures/integration/labels-linestring.geojson', 'integration-cl/labels-linestring.geojson') @classmethod def tearDownClass(cls): diff --git a/test/tiles/1087767-1046604-21.jpg b/test/tiles/1087767-1046604-21.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a6d3a113735005befd4b787e88e71e4a0a42f63 GIT binary patch literal 14654 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

#+x1f1KT;gI6k8>?QFl57Q6=JN-w^UO@q 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 Nh^}<(I{ml&zX5R(J9_{C literal 0 HcmV?d00001 diff --git a/test/tiles/146-195-9.jpeg b/test/tiles/146-195-9.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..3130abb13a9803228be369cbeff5e8c5e3b67ab2 GIT binary patch literal 11832 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