From 283dea13d9305a10cc309eb7b524b514012f4be7 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 8 Aug 2012 15:18:23 -0700 Subject: [PATCH] Add a new 'cli' subdirectory for higher-level testing of apitrace CLI. As described in the README, this new directory is for tests that perform higher-level testing of the apitrace command-line interface than either of the existing traces or apps directories. Compared to traces, these new tests can do higher-level things like dumping images from traces, comparing images, etc. Compared to apps, these tests are intended to be portable across multiple targets. (This isn't actually the case yet because commands like "apitrace dump-images" currently work only on OpenGL. Also, even when that is fixed, we will also need to then extend these tests to have traces for each supported target for testing.) In this commit, the only new test exercises "apitrace dump-images" and "apitrace diff-images" on a simple trace file with one frame, (tri.trace grabbed from apps/gl). --- CMakeLists.txt | 14 ++++++ cli/.gitignore | 2 + cli/CMakeLists.txt | 15 ++++++ cli/README.markdown | 31 ++++++++++++ cli/cli-diff-images.script | 4 ++ cli/tri-ref/tri0000000027.png | Bin 0 -> 11750 bytes cli/tri.trace | Bin 0 -> 37526 bytes cli_driver.py | 91 ++++++++++++++++++++++++++++++++++ 8 files changed, 157 insertions(+) create mode 100644 cli/.gitignore create mode 100644 cli/CMakeLists.txt create mode 100644 cli/README.markdown create mode 100644 cli/cli-diff-images.script create mode 100644 cli/tri-ref/tri0000000027.png create mode 100644 cli/tri.trace create mode 100644 cli_driver.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 47c38cb..1096158 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,3 +90,17 @@ enable_testing() add_subdirectory (apps) add_subdirectory (traces) +# FIXME: The tests in the cli directory are intended to be high-level +# tests of the apitrace command-line interface which would ideally be +# portable across all platforms. However, these tests all rely on +# doing image comparisons and the current implementation of the +# "apitrace dump-images" command relies on direct invocation of the +# glretrace command. +# +# Someday, we should have more unified commands for replaying traces, +# dumping images, etc. At that point these cli tests should be usable +# with all targets so that we can drop the "if (OPENGL_FOUND)" +# condition here. +if (OPENGL_FOUND) + add_subdirectory (cli) +endif () diff --git a/cli/.gitignore b/cli/.gitignore new file mode 100644 index 0000000..5e96abe --- /dev/null +++ b/cli/.gitignore @@ -0,0 +1,2 @@ +!*.trace +tri-out diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt new file mode 100644 index 0000000..283f56f --- /dev/null +++ b/cli/CMakeLists.txt @@ -0,0 +1,15 @@ +file (GLOB scripts RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.script) + +list (SORT scripts) + +foreach (script ${scripts}) + if (APITRACE_EXECUTABLE) + add_test( + NAME ${script} + COMMAND python ${CMAKE_SOURCE_DIR}/cli_driver.py + --apitrace ${APITRACE_EXECUTABLE} + --apitrace-source ${APITRACE_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/${script} + ) + endif () +endforeach (script) diff --git a/cli/README.markdown b/cli/README.markdown new file mode 100644 index 0000000..3d49c7c --- /dev/null +++ b/cli/README.markdown @@ -0,0 +1,31 @@ +This directory tests high-level functionality of apitrace command-line +interface (cli). See also the neighboring "traces" directory which +also tests the cli, but in ways that can only be verified by doing +comparisons of resulting dump files. + +For writing new tests, if the functionality can be exercised by a +sequence of apitrace command invocations, and then a final comparison +of "apitrace dump" output, then it's likely simplest to write a new +test in the traces directory. Otherwise, a new test program can be +written in this directory. + +The tests in this directory are found in files with names matching +*.script. The scripts are simple line-based commands with the +following meanings based on the first word of each line: + + apitrace: Execute the current apitrace executable being tested + with the given arguments. If apitrace returns a + non-zero status, the test will fail. + + expect: Compare the results of the previously-executed command + with the given (json-quoted) string. If the strings + are not identical, the test will fail. + + rm_and_mkdir: Remove any existing directory of the given name and + then create it. The directory name is always + interpreted locally. If this fails for any reason + other than "file does not exist" the test will fail. + +If none of the commands in the script cause the test to fail, then the +test will pass. + diff --git a/cli/cli-diff-images.script b/cli/cli-diff-images.script new file mode 100644 index 0000000..cb4630f --- /dev/null +++ b/cli/cli-diff-images.script @@ -0,0 +1,4 @@ +rm_and_mkdir ./tri-out +apitrace dump-images -o ./tri-out/tri tri.trace +apitrace diff-images -v ./tri-ref ./tri-out +expect "Comparing ./tri-ref/tri0000000027.png and ./tri-out/tri0000000027.png ... MATCH\n" diff --git a/cli/tri-ref/tri0000000027.png b/cli/tri-ref/tri0000000027.png new file mode 100644 index 0000000000000000000000000000000000000000..b7840bd8647a61e9d9ec9c959b3901b6aa475332 GIT binary patch literal 11750 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 COU$qU literal 0 HcmV?d00001 diff --git a/cli/tri.trace b/cli/tri.trace new file mode 100644 index 0000000000000000000000000000000000000000..f900d52331e3c8033d354250cdc05baca457aa7b GIT binary patch literal 37526 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 literal 0 HcmV?d00001 diff --git a/cli_driver.py b/cli_driver.py new file mode 100644 index 0000000..6906b73 --- /dev/null +++ b/cli_driver.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python + +# Copyright 2012 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +'''Test driver for scripts in the cli directory.''' + +import json, errno, shutil, subprocess + +from base_driver import * + +class CliDriver(Driver): + + def do_apitrace(self, args): + cmd = [self.options.apitrace] + args[1:] + + self.output = subprocess.check_output(cmd) + + def do_expect(self, args): + expected = json.loads(" ".join(args[1:])) + if (self.output != expected): + fail("Unexpected output:\n Expected: %s\n Received: %s\n" % (expected, self.output)) + + def do_rm_and_mkdir(self, args): + + # Operate only on local directories + dir = './' + args[1] + + # Failing to delete a directory that doesn't exist is no failure + def rmtree_onerror(function, path, excinfo): + if excinfo[0] == OSError and excinfo[1].errno != errno.ENOENT: + raise + + shutil.rmtree(dir, onerror = rmtree_onerror) + os.makedirs(dir) + + def unknown_command(self, args): + fail('Broken test script: Unknown command: %s' % (args[0])) + + def run_script(self, cli_script): + "Execute the commands in the given cli script." + + commands = { + 'apitrace': self.do_apitrace, + 'expect': self.do_expect, + 'rm_and_mkdir': self.do_rm_and_mkdir + } + + script = open(cli_script, 'rt') + + while True: + line = script.readline() + + if (line == ''): + break + + cmd = line.split() + + if (len(cmd) == 0): + continue + + commands.get(cmd[0], self.unknown_command)(cmd) + + def run(self): + self.parseOptions() + + self.run_script(self.args[0]) + + pass_() + +if __name__ == '__main__': + CliDriver().run() -- 2.43.0