Skip to content
Snippets Groups Projects
Select Git revision
  • main default protected
  • next protected
  • UI-EvenMoreTweaks
  • merge/materials_featurette protected
  • merge/webrtc protected
  • darl/linux-sh-installer
  • xenhat/maint/bolt
  • xenhat/features/cinematic-mode-new
  • screensquare
  • ssestuff
  • spdlog
  • 7.1.7.2486-beta
  • 7.1.4.2442-beta
  • 7.1.4.2413-beta
  • 7.1.3.2338-beta
  • 7.1.3.2332-beta
  • 7.1.2.2304-beta
  • 7.1.1.2251-beta
  • 7.0.1.2244-beta
  • 7.0.1.2240-beta
  • 7.0.1.2230-beta
  • 7.0.1.2206-beta
22 results

setenv.h

Blame
    • Nat Goodspeed's avatar
      962ccb4f
      DRTVWR-476: Facilitate debugging test programs with logging. · 962ccb4f
      Nat Goodspeed authored
      On Mac, even if you run a test program with --debug or set LOGTEST=DEBUG, it
      won't log to stderr if you're filtering build output or running the build in
      an emacs compile buffer. This is because, on Mac, a viewer launched by mouse
      rather than from the command line is passed a stderr stream that ultimately
      gets logged to the system Console. The shouldLogToStderr() function is
      intended to avoid spamming the Console with the (voluminous) viewer log
      output. It tests whether stderr isatty() and, if not, suppresses calling
      LLError::logToStderr().
      
      This makes debugging test programs using log output trickier than necessary.
      Change shouldLogToStderr() to permit logging when either stderr isatty() or is
      a pipe. The original intention is preserved in that empirically, a viewer
      launched by mouse is passed a stderr stream identified as a character device
      rather than as a pipe.
      
      Also introduce SetEnv, a class that facilitates setting (e.g.) LOGTEST=DEBUG
      for specific test programs without setting it for all test programs in the
      build. Using the constructor for a static object means you can set environment
      variables before main() is entered, which is important because it's the main()
      function in test.cpp that acts on the LOGTEST and LOGFAIL environment
      variables.
      
      These changes make it unnecessary to retain the temporary change in test.cpp
      to force LOGTEST to DEBUG.
      962ccb4f
      History
      DRTVWR-476: Facilitate debugging test programs with logging.
      Nat Goodspeed authored
      On Mac, even if you run a test program with --debug or set LOGTEST=DEBUG, it
      won't log to stderr if you're filtering build output or running the build in
      an emacs compile buffer. This is because, on Mac, a viewer launched by mouse
      rather than from the command line is passed a stderr stream that ultimately
      gets logged to the system Console. The shouldLogToStderr() function is
      intended to avoid spamming the Console with the (voluminous) viewer log
      output. It tests whether stderr isatty() and, if not, suppresses calling
      LLError::logToStderr().
      
      This makes debugging test programs using log output trickier than necessary.
      Change shouldLogToStderr() to permit logging when either stderr isatty() or is
      a pipe. The original intention is preserved in that empirically, a viewer
      launched by mouse is passed a stderr stream identified as a character device
      rather than as a pipe.
      
      Also introduce SetEnv, a class that facilitates setting (e.g.) LOGTEST=DEBUG
      for specific test programs without setting it for all test programs in the
      build. Using the constructor for a static object means you can set environment
      variables before main() is entered, which is important because it's the main()
      function in test.cpp that acts on the LOGTEST and LOGFAIL environment
      variables.
      
      These changes make it unnecessary to retain the temporary change in test.cpp
      to force LOGTEST to DEBUG.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    setenv.h 2.42 KiB
    /**
     * @file   setenv.h
     * @author Nat Goodspeed
     * @date   2020-04-01
     * @brief  Provide a way for a particular test program to alter the
     *         environment before entry to main().
     * 
     * $LicenseInfo:firstyear=2020&license=viewerlgpl$
     * Copyright (c) 2020, Linden Research, Inc.
     * $/LicenseInfo$
     */
    
    #if ! defined(LL_SETENV_H)
    #define LL_SETENV_H
    
    #include <stdlib.h>                 // setenv()
    
    /**
     * Our test.cpp main program responds to environment variables LOGTEST and
     * LOGFAIL. But if you set (e.g.) LOGTEST=DEBUG before a viewer build, @em
     * every test program in the build emits debug log output. This can be so
     * voluminous as to slow down the build.
     *
     * With an integration test program, you can specifically build (e.g.) the
     * INTEGRATION_TEST_llstring target, and set any environment variables you
     * want for that. But with a unit test program, since executing the program is
     * a side effect rather than an explicit target, specifically building (e.g.)
     * PROJECT_lllogin_TEST_lllogin only builds the executable without running it.
     *
     * To set an environment variable for a particular test program, declare a
     * static instance of SetEnv in its .cpp file. SetEnv's constructor takes
     * pairs of strings, e.g.
     *
     * @code
     * static SetEnv sLOGGING("LOGTEST", "INFO");
     * @endcode
     *
     * Declaring a static instance of SetEnv is important because that ensures
     * that the environment variables are set before main() is entered, since it
     * is main() that examines LOGTEST and LOGFAIL.
     */
    struct SetEnv
    {
        // degenerate constructor, terminate recursion
        SetEnv() {}
    
        /**
         * SetEnv() accepts an arbitrary number of pairs of strings: variable
         * name, value, variable name, value ... Entering the constructor sets
         * those variables in the process environment using Posix setenv(),
         * overriding any previous value. If static SetEnv declarations in
         * different translation units specify overlapping sets of variable names,
         * it is indeterminate which instance will "win."
         */
        template <typename VAR, typename VAL, typename... ARGS>
        SetEnv(VAR&& var, VAL&& val, ARGS&&... rest):
            // constructor forwarding handles the tail of the list
            SetEnv(std::forward<ARGS>(rest)...)
        {
            // set just the first (variable, value) pair
            // 1 means override previous value if any
            setenv(std::forward<VAR>(var), std::forward<VAL>(val), 1);
        }
    };
    
    #endif /* ! defined(LL_SETENV_H) */