text:
FROM mysql:8.0

COPY ./init.sql /docker-entrypoint-initdb.d/
RUN chown -R mysql:mysql /docker-entrypoint-initdb.d/

CMD ["mysqld", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]

redpajama_set_name: RedPajamaGithub


text:
Every contribution is appreciated and welcome. If you're planning to add a new section or page, please create an issue first.

## Setup

* Install [Node.js](https://nodejs.org/) if you have not already.
* Fork the **cncjs.org** repo at [https://github.com/cncjs/cncjs.org](https://github.com/cncjs/cncjs.org).
* `git clone <your-clone-url> && cd cncjs.org`
* `npm install`
* `npm run dev`
* Visit [http://localhost:8000](http://localhost:8000) to preview your changes before making a pull request.

## Production

After you have finished editing the document, run `npm run build` to create a production version of the site, and push your commited changes to GitHub.

## Branching Your Changes

Making a branch in your fork for your contribution is helpful in the following ways:

* It allows you to have multiple contributions in as PRs at once.
* It allows us to identify what your contribution is about from the branch name.

## Submitting Changes

Push to your fork branch and submit a pull request to the [master](https://github.com/cncjs/cncjs.org/tree/master) branch.

> See [GitHub documentation](https://help.github.com/articles/proposing-changes-to-your-work-with-pull-requests/) for more help.

## Contribution Recognition

You can choose to add your GitHub username for recognition at the top of any markdown document you edit:

**example.md**

```markdown
---
title: Some Example Page
contributors:
  - TheLarkInn
  - Sokra
  - bebraw
  - Jhnns
  - SpaceK33z
---

## Some Documentation

```

This will add your name and GitHub profile photo to the document in production. It's a great way to own the awesome work that you do and we encourage you to do this in your PRs.


text:
#ifndef __FP__
#define __FP__
#ifndef __CONDITIONALMACROS__
#include <ConditionalMacros.h>
#endif
#ifndef __MACTYPES__
#include <MacTypes.h>
#endif
/********************************************************************************
*                                                                               *
*    A collection of numerical functions designed to facilitate a wide          *
*    range of numerical programming as required by C9X.                         *
*                                                                               *
*    The <fp.h> declares many functions in support of numerical programming.    *
*    It provides a superset of <math.h> and <SANE.h> functions.  Some           *
*    functionality previously found in <SANE.h> and not in the FPCE <fp.h>      *
*    can be found in this <fp.h> under the heading "__NOEXTENSIONS__".          *
*                                                                               *
*    All of these functions are IEEE 754 aware and treat exceptions, NaNs,      *
*    positive and negative zero and infinity consistent with the floating-      *
*    point standard.                                                            *
*                                                                               *
********************************************************************************/
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_IMPORT
#pragma import on
#endif
#if PRAGMA_STRUCT_ALIGN
    #pragma options align=mac68k
#elif PRAGMA_STRUCT_PACKPUSH
    #pragma pack(push, 2)
#elif PRAGMA_STRUCT_PACK
    #pragma pack(2)
#endif
/********************************************************************************
*                                                                               *
*                            Efficient types                                    *
*                                                                               *
*    float_t         Most efficient type at least as wide as float              *
*    double_t        Most efficient type at least as wide as double             *
*                                                                               *
*      CPU            float_t(bits)                double_t(bits)               *
*    --------        -----------------            -----------------             *
*    PowerPC          float(32)                    double(64)                   *
*    68K              long double(80/96)           long double(80/96)           *
*    x86              long double(80)              long double(80)              *
*                                                                               *
********************************************************************************/
#if defined(__MWERKS__) && defined(__cmath__)
/* these types were already defined in MSL's math.h */
#else
#if TARGET_CPU_PPC
typedef float                           float_t;
typedef double                          double_t;
#elif TARGET_CPU_68K
typedef long double                     float_t;
typedef long double                     double_t;
#elif TARGET_CPU_X86
#if NeXT || TARGET_OS_MAC
typedef double                          float_t;
typedef double                          double_t;
#else
typedef long double                     float_t;
typedef long double                     double_t;
#endif  /* NeXT || TARGET_OS_MAC */
#elif TARGET_CPU_MIPS
typedef double                          float_t;
typedef double                          double_t;
#elif TARGET_CPU_ALPHA
typedef double                          float_t;
typedef double                          double_t;
#elif TARGET_CPU_SPARC
typedef double                          float_t;
typedef double                          double_t;
#else
#error unsupported CPU
#endif  /*  */
/********************************************************************************
*                                                                               *
*                              Define some constants.                           *
*                                                                               *
*    HUGE_VAL            IEEE 754 value of infinity.                            *
*    INFINITY            IEEE 754 value of infinity.                            *
*    NAN                 A generic NaN (Not A Number).                          *
*    DECIMAL_DIG         Satisfies the constraint that the conversion from      *
*                        double to decimal and back is the identity function.   *
*                                                                               *
********************************************************************************/
#if TARGET_OS_MAC
  #if TARGET_RT_MAC_MACHO
    #define   HUGE_VAL                1e500 /* compatible with bsd math.h */
  #else
    #define   HUGE_VAL                __inf()
  #endif
  #define     INFINITY                __inf()
  #define     NAN                     nan("255")
#else
  #define     NAN                     sqrt(-1)
#endif
#if TARGET_CPU_PPC
    #define      DECIMAL_DIG              17 /* does not exist for double-double */
#elif TARGET_CPU_68K
    #define      DECIMAL_DIG              21
#endif
#endif  /* __MWERKS__ && __cmath__ */
#if TARGET_OS_MAC
/* MSL already defines these */
#if !defined(__MWERKS__) || !defined(__cmath__)
/********************************************************************************
*                                                                               *
*                            Trigonometric functions                            *
*                                                                               *
*   acos        result is in [0,pi].                                            *
*   asin        result is in [-pi/2,pi/2].                                      *
*   atan        result is in [-pi/2,pi/2].                                      *
*   atan2       Computes the arc tangent of y/x in [-pi,pi] using the sign of   *
*               both arguments to determine the quadrant of the computed value. *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) cos(double_t x);
EXTERN_API_C( double_t ) sin(double_t x);
EXTERN_API_C( double_t ) tan(double_t x);
EXTERN_API_C( double_t ) acos(double_t x);
EXTERN_API_C( double_t ) asin(double_t x);
EXTERN_API_C( double_t ) atan(double_t x);
EXTERN_API_C( double_t ) atan2(double_t y, double_t x);
/********************************************************************************
*                                                                               *
*                              Hyperbolic functions                             *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) cosh(double_t x);
EXTERN_API_C( double_t ) sinh(double_t x);
EXTERN_API_C( double_t ) tanh(double_t x);
EXTERN_API_C( double_t ) acosh(double_t x);
EXTERN_API_C( double_t ) asinh(double_t x);
EXTERN_API_C( double_t ) atanh(double_t x);
/********************************************************************************
*                                                                               *
*                              Exponential functions                            *
*                                                                               *
*   expm1       expm1(x) = exp(x) - 1.  But, for small enough arguments,        *
*               expm1(x) is expected to be more accurate than exp(x) - 1.       *
*   frexp       Breaks a floating-point number into a normalized fraction       *
*               and an integral power of 2.  It stores the integer in the       *
*               object pointed by *exponent.                                    *
*   ldexp       Multiplies a floating-point number by an integer power of 2.    *
*   log1p       log1p = log(1 + x). But, for small enough arguments,            *
*               log1p is expected to be more accurate than log(1 + x).          *
*   logb        Extracts the exponent of its argument, as a signed integral     *
*               value. A subnormal argument is treated as though it were first  *
*               normalized. Thus:                                               *
*                                  1   <=   x * 2^(-logb(x))   <   2            *
*   modf        Returns fractional part of x as function result and returns     *
*               integral part of x via iptr. Note C9X uses double not double_t. *
*   scalb       Computes x * 2^n efficently.  This is not normally done by      *
*               computing 2^n explicitly.                                       *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) exp(double_t x);
EXTERN_API_C( double_t ) expm1(double_t x);
EXTERN_API_C( double_t ) exp2(double_t x);
EXTERN_API_C( double_t ) frexp(double_t x, int *exponent);
EXTERN_API_C( double_t ) ldexp(double_t x, int n);
EXTERN_API_C( double_t ) log(double_t x);
EXTERN_API_C( double_t ) log2(double_t x);
EXTERN_API_C( double_t ) log1p(double_t x);
EXTERN_API_C( double_t ) log10(double_t x);
EXTERN_API_C( double_t ) logb(double_t x);
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( long double ) modfl(long double x, long double *iptrl);
#endif  /* !TARGET_RT_MAC_MACHO */
EXTERN_API_C( double_t ) modf(double_t x, double_t *iptr);
EXTERN_API_C( float ) modff(float x, float *iptrf);
EXTERN_API_C( double_t ) scalb(double_t x, long n);
/********************************************************************************
*                                                                               *
*                     Power and absolute value functions                        *
*                                                                               *
*   hypot       Computes the square root of the sum of the squares of its       *
*               arguments, without undue overflow or underflow.                 *
*   pow         Returns x raised to the power of y.  Result is more accurate    *
*               than using exp(log(x)*y).                                       *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) fabs(double_t x);
EXTERN_API_C( double_t ) hypot(double_t x, double_t y);
EXTERN_API_C( double_t ) pow(double_t x, double_t y);
EXTERN_API_C( double_t ) sqrt(double_t x);
/********************************************************************************
*                                                                               *
*                        Gamma and Error functions                              *
*                                                                               *
*   erf         The error function.                                             *
*   erfc        Complementary error function.                                   *
*   gamma       The gamma function.                                             *
*   lgamma      Computes the base-e logarithm of the absolute value of          *
*               gamma of its argument x, for x > 0.                             *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) erf(double_t x);
EXTERN_API_C( double_t ) erfc(double_t x);
EXTERN_API_C( double_t ) gamma(double_t x);
EXTERN_API_C( double_t ) lgamma(double_t x);
/********************************************************************************
*                                                                               *
*                        Nearest integer functions                              *
*                                                                               *
*   rint        Rounds its argument to an integral value in floating point      *
*               format, honoring the current rounding direction.                *
*                                                                               *
*   nearbyint   Differs from rint only in that it does not raise the inexact    *
*               exception. It is the nearbyint function recommended by the      *
*               IEEE floating-point standard 854.                               *
*                                                                               *
*   rinttol     Rounds its argument to the nearest long int using the current   *
*               rounding direction.  NOTE: if the rounded value is outside      *
*               the range of long int, then the result is undefined.            *
*                                                                               *
*   round       Rounds the argument to the nearest integral value in floating   *
*               point format similar to the Fortran "anint" function. That is:  *
*               add half to the magnitude and chop.                             *
*                                                                               *
*   roundtol    Similar to the Fortran function nint or to the Pascal round.    *
*               NOTE: if the rounded value is outside the range of long int,    *
*               then the result is undefined.                                   *
*                                                                               *
*   trunc       Computes the integral value, in floating format, nearest to     *
*               but no larger in magnitude than its argument.   NOTE: on 68K    *
*               compilers when using -elems881, trunc must return an int        *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) ceil(double_t x);
EXTERN_API_C( double_t ) floor(double_t x);
EXTERN_API_C( double_t ) rint(double_t x);
EXTERN_API_C( double_t ) nearbyint(double_t x);
EXTERN_API_C( long ) rinttol(double_t x);
EXTERN_API_C( double_t ) round(double_t x);
EXTERN_API_C( long ) roundtol(double_t round);
#if TARGET_RT_MAC_68881
#if CALL_NOT_IN_CARBON
EXTERN_API_C( int ) trunc(double_t x);
#endif  /* CALL_NOT_IN_CARBON */
#else
EXTERN_API_C( double_t ) trunc(double_t x);
#endif  /* TARGET_RT_MAC_68881 */
/********************************************************************************
*                                                                               *
*                            Remainder functions                                *
*                                                                               *
*   remainder       IEEE 754 floating point standard for remainder.             *
*   remquo          SANE remainder.  It stores into 'quotient' the 7 low-order  *
*                   bits of the integer quotient x/y, such that:                *
*                       -127 <= quotient <= 127.                                *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) fmod(double_t x, double_t y);
EXTERN_API_C( double_t ) remainder(double_t x, double_t y);
EXTERN_API_C( double_t ) remquo(double_t x, double_t y, int *quo);
/********************************************************************************
*                                                                               *
*                             Auxiliary functions                               *
*                                                                               *
*   copysign        Produces a value with the magnitude of its first argument   *
*                   and sign of its second argument.  NOTE: the order of the    *
*                   arguments matches the recommendation of the IEEE 754        *
*                   floating point standard,  which is opposite from the SANE   *
*                   copysign function.                                          *
*                                                                               *
*   nan             The call 'nan("n-char-sequence")' returns a quiet NaN       *
*                   with content indicated through tagp in the selected         *
*                   data type format.                                           *
*                                                                               *
*   nextafter       Computes the next representable value after 'x' in the      *
*                   direction of 'y'.  if x == y, then y is returned.           *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) copysign(double_t x, double_t y);
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( long double ) nanl(const char *tagp);
#else
#define nanl(tagp) ((long double)nan(tagp))
#endif  /* !TARGET_RT_MAC_MACHO */
EXTERN_API_C( double ) nan(const char *tagp);
EXTERN_API_C( float ) nanf(const char *tagp);
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( long double ) nextafterl(long double x, long double y);
#else
#define nextafterl(x,y) ((long double)nextafter((double)x,(double)y))
#endif  /* !TARGET_RT_MAC_MACHO */
EXTERN_API_C( double ) nextafterd(double x, double y);
EXTERN_API_C( float ) nextafterf(float x, float y);
/********************************************************************************
*                                                                               *
*                              Inquiry macros                                   *
*                                                                               *
*   fpclassify      Returns one of the FP_* values.                             *
*   isnormal        Non-zero if and only if the argument x is normalized.       *
*   isfinite        Non-zero if and only if the argument x is finite.           *
*   isnan           Non-zero if and only if the argument x is a NaN.            *
*   signbit         Non-zero if and only if the sign of the argument x is       *
*                   negative.  This includes, NaNs, infinities and zeros.       *
*                                                                               *
********************************************************************************/
enum {
    FP_SNAN                     = 0,                            /*      signaling NaN                         */
    FP_QNAN                     = 1,                            /*      quiet NaN                             */
    FP_INFINITE                 = 2,                            /*      + or - infinity                       */
    FP_ZERO                     = 3,                            /*      + or - zero                           */
    FP_NORMAL                   = 4,                            /*      all normal numbers                    */
    FP_SUBNORMAL                = 5                             /*      denormal numbers                      */
};
#if TARGET_RT_MAC_MACHO
#define __fpclassify(x) __fpclassifyd((double)x)
#define __isnormal(x)   __isnormald((double)x)
#define __isfinite(x)   __isfinited((double)x)
#define __isnan(x)      __isnand((double)x)
#define __signbit(x)    __signbitd((double)x)
#endif
#define      fpclassify(x)    ( ( sizeof ( x ) == sizeof(long double) ) ?      \
                              __fpclassify  ( x ) :                            \
                                ( sizeof ( x ) == sizeof(double) ) ?           \
                              __fpclassifyd ( x ) :                            \
                              __fpclassifyf ( x ) )
#define      isnormal(x)      ( ( sizeof ( x ) == sizeof(long double) ) ?      \
                              __isnormal ( x ) :                               \
                                ( sizeof ( x ) == sizeof(double) ) ?           \
                              __isnormald ( x ) :                              \
                              __isnormalf ( x ) )
#define      isfinite(x)      ( ( sizeof ( x ) == sizeof(long double) ) ?      \
                              __isfinite ( x ) :                               \
                                ( sizeof ( x ) == sizeof(double) ) ?           \
                              __isfinited ( x ) :                              \
                              __isfinitef ( x ) )
#define      isnan(x)         ( ( sizeof ( x ) == sizeof(long double) ) ?      \
                              __isnan ( x ) :                                  \
                              ( sizeof ( x ) == sizeof(double) ) ?             \
                              __isnand ( x ) :                                 \
                              __isnanf ( x ) )
#define      signbit(x)       ( ( sizeof ( x ) == sizeof(long double) ) ?      \
                              __signbit ( x ) :                                \
                              ( sizeof ( x ) == sizeof(double) ) ?             \
                              __signbitd ( x ) :                               \
                              __signbitf ( x ) )
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( long ) __fpclassify(long double x);
#endif  /* !TARGET_RT_MAC_MACHO */
EXTERN_API_C( long ) __fpclassifyd(double x);
EXTERN_API_C( long ) __fpclassifyf(float x);
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( long ) __isnormal(long double x);
#endif  /* !TARGET_RT_MAC_MACHO */
EXTERN_API_C( long ) __isnormald(double x);
EXTERN_API_C( long ) __isnormalf(float x);
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( long ) __isfinite(long double x);
#endif  /* !TARGET_RT_MAC_MACHO */
EXTERN_API_C( long ) __isfinited(double x);
EXTERN_API_C( long ) __isfinitef(float x);
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( long ) __isnan(long double x);
#endif  /* !TARGET_RT_MAC_MACHO */
EXTERN_API_C( long ) __isnand(double x);
EXTERN_API_C( long ) __isnanf(float x);
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( long ) __signbit(long double x);
#endif  /* !TARGET_RT_MAC_MACHO */
EXTERN_API_C( long ) __signbitd(double x);
EXTERN_API_C( long ) __signbitf(float x);
EXTERN_API_C( double_t ) __inf(void );
/********************************************************************************
*                                                                               *
*                      Max, Min and Positive Difference                         *
*                                                                               *
*   fdim        Determines the 'positive difference' between its arguments:     *
*               { x - y, if x > y }, { +0, if x <= y }.  If one argument is     *
*               NaN, then fdim returns that NaN.  if both arguments are NaNs,   *
*               then fdim returns the first argument.                           *
*                                                                               *
*   fmax        Returns the maximum of the two arguments.  Corresponds to the   *
*               max function in FORTRAN.  NaN arguments are treated as missing  *
*               data.  If one argument is NaN and the other is a number, then   *
*               the number is returned.  If both are NaNs then the first        *
*               argument is returned.                                           *
*                                                                               *
*   fmin        Returns the minimum of the two arguments.  Corresponds to the   *
*               min function in FORTRAN.  NaN arguments are treated as missing  *
*               data.  If one argument is NaN and the other is a number, then   *
*               the number is returned.  If both are NaNs then the first        *
*               argument is returned.                                           *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) fdim(double_t x, double_t y);
EXTERN_API_C( double_t ) fmax(double_t x, double_t y);
EXTERN_API_C( double_t ) fmin(double_t x, double_t y);
#endif /* !defined(__MWERKS__) || !defined(__cmath__) */
/*******************************************************************************
*                                Constants                                     *
*******************************************************************************/
extern const double_t pi;
/********************************************************************************
*                                                                               *
*                              Non NCEG extensions                              *
*                                                                               *
********************************************************************************/
#ifndef __NOEXTENSIONS__
/********************************************************************************
*                                                                               *
*                              Financial functions                              *
*                                                                               *
*   compound        Computes the compound interest factor "(1 + rate)^periods"  *
*                   more accurately than the straightforward computation with   *
*                   the Power function.  This is SANE's compound function.      *
*                                                                               *
*   annuity         Computes the present value factor for an annuity            *
*                   "(1 - (1 + rate)^(-periods)) /rate" more accurately than    *
*                   the straightforward computation with the Power function.    *
*                   This is SANE's annuity function.                            *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) compound(double_t rate, double_t periods);
EXTERN_API_C( double_t ) annuity(double_t rate, double_t periods);
/********************************************************************************
*                                                                               *
*                              Random function                                  *
*                                                                               *
*   randomx         A pseudorandom number generator.  It uses the iteration:    *
*                               (7^5*x)mod(2^31-1)                              *
*                                                                               *
********************************************************************************/
EXTERN_API_C( double_t ) randomx(double_t *x);
/*******************************************************************************
*                              Relational operator                             *
*******************************************************************************/
/*      relational operator      */
typedef short                           relop;
enum {
    GREATERTHAN                 = 0,
    LESSTHAN                    = 1,
    EQUALTO                     = 2,
    UNORDERED                   = 3
};
#if !defined(__MWERKS__) || !defined(__cmath__)
EXTERN_API_C( relop ) relation(double_t x, double_t y);
#endif /* !defined(__MWERKS__) || !defined(__cmath__) */
/********************************************************************************
*                                                                               *
*                         Binary to decimal conversions                         *
*                                                                               *
*   SIGDIGLEN   Significant decimal digits.                                     *
*                                                                               *
*   decimal     A record which provides an intermediate unpacked form for       *
*               programmers who wish to do their own parsing of numeric input   *
*               or formatting of numeric output.                                *
*                                                                               *
*   decform     Controls each conversion to a decimal string.  The style field  *
*               is either FLOATDECIMAL or FIXEDDECIMAL. If FLOATDECIMAL, the    *
*               value of the field digits is the number of significant digits.  *
*               If FIXEDDECIMAL value of the field digits is the number of      *
*               digits to the right of the decimal point.                       *
*                                                                               *
*   num2dec     Converts a double_t to a decimal record using a decform.        *
*   dec2num     Converts a decimal record d to a double_t value.                *
*   dec2str     Converts a decform and decimal to a string using a decform.     *
*   str2dec     Converts a string to a decimal struct.                          *
*   dec2d       Similar to dec2num except a double is returned (68k only).      *
*   dec2f       Similar to dec2num except a float is returned.                  *
*   dec2s       Similar to dec2num except a short is returned.                  *
*   dec2l       Similar to dec2num except a long is returned.                   *
*                                                                               *
********************************************************************************/
#if TARGET_CPU_PPC
    #define SIGDIGLEN      36
#elif TARGET_CPU_68K
    #define SIGDIGLEN      20
#elif TARGET_CPU_X86
    #define SIGDIGLEN      20
#endif
#define      DECSTROUTLEN   80               /* max length for dec2str output */
#define      FLOATDECIMAL   ((char)(0))
#define      FIXEDDECIMAL   ((char)(1))
struct decimal {
    char                            sgn;                        /* sign 0 for +, 1 for - */
    char                            unused;
    short                           exp;                        /* decimal exponent */
    struct {
        unsigned char                   length;
        unsigned char                   text[SIGDIGLEN];        /* significant digits */
        unsigned char                   unused;
    }                               sig;
};
typedef struct decimal decimal;
struct decform {
    char                            style;                      /*  FLOATDECIMAL or FIXEDDECIMAL */
    char                            unused;
    short                           digits;
};
typedef struct decform decform;
EXTERN_API_C( void ) num2dec(const decform *f, double_t x, decimal *d);
EXTERN_API_C( double_t ) dec2num(const decimal *d);
EXTERN_API_C( void ) dec2str(const decform *f, const decimal *d, char *s);
EXTERN_API_C( void ) str2dec(const char *s, short *ix, decimal *d, short *vp);
#if TARGET_CPU_68K
#if CALL_NOT_IN_CARBON
EXTERN_API_C( double ) dec2d(const decimal *d);
#endif  /* CALL_NOT_IN_CARBON */
#endif  /* TARGET_CPU_68K */
EXTERN_API_C( float ) dec2f(const decimal *d);
EXTERN_API_C( short ) dec2s(const decimal *d);
EXTERN_API_C( long ) dec2l(const decimal *d);
/********************************************************************************
*                                                                               *
*                         68k-only Transfer Function Prototypes                 *
*                                                                               *
********************************************************************************/
#if TARGET_CPU_68K
#if CALL_NOT_IN_CARBON
EXTERN_API_C( void ) x96tox80(const extended96 *x, extended80 *x80);
EXTERN_API_C( void ) x80tox96(const extended80 *x80, extended96 *x);
#endif  /* CALL_NOT_IN_CARBON */
#endif  /* TARGET_CPU_68K */
#endif  /* !defined(__NOEXTENSIONS__) */
/********************************************************************************
*                                                                               *
*                         PowerPC-only Function Prototypes                      *
*                                                                               *
********************************************************************************/
#if TARGET_CPU_PPC
#if !TARGET_RT_MAC_MACHO
#ifndef __MWERKS__  /* Metrowerks does not support double double */
EXTERN_API_C( long double ) cosl(long double x);
EXTERN_API_C( long double ) sinl(long double x);
EXTERN_API_C( long double ) tanl(long double x);
EXTERN_API_C( long double ) acosl(long double x);
EXTERN_API_C( long double ) asinl(long double x);
EXTERN_API_C( long double ) atanl(long double x);
EXTERN_API_C( long double ) atan2l(long double y, long double x);
EXTERN_API_C( long double ) coshl(long double x);
EXTERN_API_C( long double ) sinhl(long double x);
EXTERN_API_C( long double ) tanhl(long double x);
EXTERN_API_C( long double ) acoshl(long double x);
EXTERN_API_C( long double ) asinhl(long double x);
EXTERN_API_C( long double ) atanhl(long double x);
EXTERN_API_C( long double ) expl(long double x);
EXTERN_API_C( long double ) expm1l(long double x);
EXTERN_API_C( long double ) exp2l(long double x);
EXTERN_API_C( long double ) frexpl(long double x, int *exponent);
EXTERN_API_C( long double ) ldexpl(long double x, int n);
EXTERN_API_C( long double ) logl(long double x);
EXTERN_API_C( long double ) log1pl(long double x);
EXTERN_API_C( long double ) log10l(long double x);
EXTERN_API_C( long double ) log2l(long double x);
EXTERN_API_C( long double ) logbl(long double x);
EXTERN_API_C( long double ) scalbl(long double x, long n);
EXTERN_API_C( long double ) fabsl(long double x);
EXTERN_API_C( long double ) hypotl(long double x, long double y);
EXTERN_API_C( long double ) powl(long double x, long double y);
EXTERN_API_C( long double ) sqrtl(long double x);
EXTERN_API_C( long double ) erfl(long double x);
EXTERN_API_C( long double ) erfcl(long double x);
EXTERN_API_C( long double ) gammal(long double x);
EXTERN_API_C( long double ) lgammal(long double x);
EXTERN_API_C( long double ) ceill(long double x);
EXTERN_API_C( long double ) floorl(long double x);
EXTERN_API_C( long double ) rintl(long double x);
EXTERN_API_C( long double ) nearbyintl(long double x);
EXTERN_API_C( long ) rinttoll(long double x);
EXTERN_API_C( long double ) roundl(long double x);
EXTERN_API_C( long ) roundtoll(long double round);
EXTERN_API_C( long double ) truncl(long double x);
EXTERN_API_C( long double ) remainderl(long double x, long double y);
EXTERN_API_C( long double ) remquol(long double x, long double y, int *quo);
EXTERN_API_C( long double ) copysignl(long double x, long double y);
EXTERN_API_C( long double ) fdiml(long double x, long double y);
EXTERN_API_C( long double ) fmaxl(long double x, long double y);
EXTERN_API_C( long double ) fminl(long double x, long double y);
#endif /* __MWERKS__ */
#else
#define cosl(x)          ((long double) cos((double_t)(x)))
#define sinl(x)          ((long double) sin((double_t)(x)))
#define tanl(x)          ((long double) tan((double_t)(x)))
#define acosl(x)         ((long double) acos((double_t)(x)))
#define asinl(x)         ((long double) asin((double_t)(x)))
#define atanl(x)         ((long double) atan((double_t)(x)))
#define atan2l(y,x)      ((long double) atan2((double_t)(y),(double_t)(x)))
#define coshl(x)         ((long double) cosh((double_t)(x)))
#define sinhl(x)         ((long double) sinh((double_t)(x)))
#define tanhl(x)         ((long double) tanh((double_t)(x)))
#define acoshl(x)        ((long double) acosh((double_t)(x)))
#define asinhl(x)        ((long double) asinh((double_t)(x)))
#define atanhl(x)        ((long double) atanh((double_t)(x)))
#define expl(x)          ((long double) exp((double_t)(x)))
#define expm1l(x)        ((long double) expm1((double_t)(x)))
#define exp2l(x)         ((long double) exp2((double_t)(x)))
#define frexpl(x,exp)    ((long double) frexp((double_t)(x),(exp)))
#define ldexpl(x,n)      ((long double) ldexp((double_t)(x),(n)))
#define logl(x)          ((long double) log((double_t)(x)))
#define log1pl(x)        ((long double) log1p((double_t)(x)))
#define log10l(x)        ((long double) log10((double_t)(x)))
#define log2l(x)         ((long double) log2((double_t)(x)))
#define logbl(x)         ((long double) logb((double_t)(x)))
#define scalbl(x,n)      ((long double) scalb((double_t)(x),(n)))
#define fabsl(x)         ((long double) fabs((double_t)(x)))
#define hypotl(x,y)      ((long double) hypot((double_t)(x),(double_t)(y)))
#define powl(x,y)        ((long double) pow((double_t)(x),(double_t)(y)))
#define sqrtl(x)         ((long double) sqrt((double_t)(x)))
#define erfl(x)          ((long double) erf((double_t)(x)))
#define erfcl(x)         ((long double) erfc((double_t)(x)))
#define gammal(x)        ((long double) gamma((double_t)(x)))
#define lgammal(x)       ((long double) lgamma((double_t)(x)))
#define ceill(x)         ((long double) ceil((double_t)(x)))
#define floorl(x)        ((long double) floor((double_t)(x)))
#define rintl(x)         ((long double) rint((double_t)(x)))
#define nearbyintl(x)    ((long double) nearbyint((double_t)(x)))
#define rinttoll(x)      (rinttol((double_t)(x)))
#define roundl(x)        ((long double) round((double_t)(x)))
#define roundtoll(x)     (roundtol((double_t)(x)))
#define truncl(x)        ((long double) trunc((double_t)(x)))
#define remainderl(x,y)  ((long double) remainder((double_t)(x),(double_t)(y)))
#define remquol(x,y,quo) ((long double) remquo((double_t)(x),(double_t)(y),(quo)))
#define copysignl(x,y)   ((long double) copysign((double_t)(x),(double_t)(y)))
#define fdiml(x,y)       ((long double) fdim((double_t)(x),(double_t)(y)))
#define fmaxl(x,y)       ((long double) fmax((double_t)(x),(double_t)(y)))
#define fminl(x,y)       ((long double) fmin((double_t)(x),(double_t)(y)))
#endif  /* !TARGET_RT_MAC_MACHO */
#ifndef __NOEXTENSIONS__
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( relop ) relationl(long double x, long double y);
EXTERN_API_C( void ) num2decl(const decform *f, long double x, decimal *d);
EXTERN_API_C( long double ) dec2numl(const decimal *d);
#else
       #define relationl(x,y) (relation((double_t)x,(double_t)y))
     #define num2decl(f,x,d) (num2dec(f,(double_t)x,d))
     #define dec2numl(d) ((long double)dec2num(d))

#endif  /* !TARGET_RT_MAC_MACHO */
#endif  /* !defined(__NOEXTENSIONS__) */
#endif  /* TARGET_CPU_PPC */
#endif  /* TARGET_OS_MAC */
#ifndef __NOEXTENSIONS__
#if !TARGET_RT_MAC_MACHO
EXTERN_API_C( void ) x80told(const extended80 *x80, long double *x);
EXTERN_API_C( void ) ldtox80(const long double *x, extended80 *x80);
#else
   #define x80told(x80,ld) (*(ld) = x80tod(x80))
  #define ldtox80(ld,x80) do { double d = (double) *(ld); dtox80(&d, (x80)); } while (0)

#endif  /* !TARGET_RT_MAC_MACHO */
/*
        MathLib v2 has two new transfer functions: x80tod and dtox80.  They can
        be used to directly transform 68k 80-bit extended data types to double
        and back for PowerPC based machines without using the functions
        x80told or ldtox80.  Double rounding may occur.
    */
EXTERN_API_C( double ) x80tod(const extended80 *x80);
EXTERN_API_C( void ) dtox80(const double *x, extended80 *x80);
#endif  /* !defined(__NOEXTENSIONS__) */
#if PRAGMA_STRUCT_ALIGN
    #pragma options align=reset
#elif PRAGMA_STRUCT_PACKPUSH
    #pragma pack(pop)
#elif PRAGMA_STRUCT_PACK
    #pragma pack()
#endif
#ifdef PRAGMA_IMPORT_OFF
#pragma import off
#elif PRAGMA_IMPORT
#pragma import reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __FP__ */


text:
package com.seboch.jdbc.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import javax.sql.DataSource;

import org.apache.commons.lang3.event.EventListenerSupport;

import com.seboch.jdbc.proxy.lifecycle.ResourceLifecycleListener;

/**
 * @author sarod
 *
 */
public final class JdbcProxyFactory {

	private static final String CLOSE_METHOD = "close";

	private final EventListenerSupport<ResourceLifecycleListener> lifecycleListenerSupport;

	class DataSourceInvocationHandler implements InvocationHandler {

		private final DataSource wrappedDataSource;

		public DataSourceInvocationHandler(DataSource wrappedDataSource) {
			this.wrappedDataSource = wrappedDataSource;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			if (Connection.class.isAssignableFrom(method.getReturnType())) {
				Connection connection = (Connection) method.invoke(
						wrappedDataSource, args);
				return proxyConnection(connection);
			} else {
				return method.invoke(wrappedDataSource, args);
			}
		}
	}

	class ConnectionInvocationHandler implements InvocationHandler {

		private final Connection connection;

		public ConnectionInvocationHandler(Connection connection) {
			this.connection = connection;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			if (method.getName().equals(CLOSE_METHOD)) {
				method.invoke(connection, args);
				lifecycleListenerSupport.fire().connectionClosed(connection);
				return null;
			} else if (Statement.class.isAssignableFrom(method.getReturnType())) {
				Statement statement = (Statement) method.invoke(connection,
						args);
				lifecycleListenerSupport.fire().statementCreated(statement);
				Class<?>[] interfaces = null;
				if (statement instanceof CallableStatement) {
					interfaces = new Class<?>[] { CallableStatement.class };
				} else if (statement instanceof PreparedStatement) {
					interfaces = new Class<?>[] { PreparedStatement.class };
				} else {
					interfaces = new Class<?>[] { Statement.class };
				}
				return (Statement) Proxy.newProxyInstance(getClassLoader(),
						interfaces, new StatementInvocationHandler(statement));
			} else {
				return method.invoke(connection, args);
			}
		}
	}

	class ResultSetInvocationHandler implements InvocationHandler {
		private final ResultSet resultSet;

		public ResultSetInvocationHandler(ResultSet resultSet) {
			this.resultSet = resultSet;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			if (method.getName().equals(CLOSE_METHOD)) {
				method.invoke(resultSet, args);
				lifecycleListenerSupport.fire().resultSetClosed(resultSet);
				return null;
			} else {
				return method.invoke(resultSet, args);
			}
		}
	}

	class StatementInvocationHandler implements InvocationHandler {
		private final Statement statement;

		public StatementInvocationHandler(Statement statement) {
			this.statement = statement;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			if (method.getName().equals(CLOSE_METHOD)) {
				method.invoke(statement, args);
				lifecycleListenerSupport.fire().statementClosed(statement);
				return null;
			} else if (method.getName().equals("executeQuery")
					&& ResultSet.class.isAssignableFrom(method.getReturnType())) {
				ResultSet resultSet = (ResultSet) method
						.invoke(statement, args);
				lifecycleListenerSupport.fire().resultSetCreated(resultSet);
				return (ResultSet) Proxy.newProxyInstance(getClassLoader(),
						new Class<?>[] { ResultSet.class },
						new ResultSetInvocationHandler(resultSet));
			} else {
				return method.invoke(statement, args);
			}
		}
	}

	public JdbcProxyFactory() {
		lifecycleListenerSupport = new EventListenerSupport<ResourceLifecycleListener>(
				ResourceLifecycleListener.class);
	}

	private ClassLoader getClassLoader() {
		return getClass().getClassLoader();
	}

	public DataSource proxyDatasource(DataSource datasource) {
		return (DataSource) Proxy.newProxyInstance(getClassLoader(),
				new Class<?>[] { DataSource.class },
				new DataSourceInvocationHandler(datasource));
	}

	public Connection proxyConnection(Connection connection) {
		lifecycleListenerSupport.fire().connectionCreated(connection);
		return (Connection) Proxy.newProxyInstance(getClassLoader(),
				new Class<?>[] { Connection.class },
				new ConnectionInvocationHandler(connection));
	}

	public void addResourceLifecycleListener(ResourceLifecycleListener listener) {
		lifecycleListenerSupport.addListener(listener);
	}

	public void removeResourceLifecycleListener(
			ResourceLifecycleListener listener) {
		lifecycleListenerSupport.removeListener(listener);
	}

}


text:
// WikiPathways Java library,
// Copyright 2014-2015 WikiPathways
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package org.pathvisio.wikipathways.webservice;

/**
 * curation tag data object
 * @author msk
 *
 */
public class WSCurationTag {
    private String name;
    private String displayName;
    private WSPathwayInfo pathway;
    private String revision;
    private String text;
    private long timeModified;
    private String userModified;

    public WSCurationTag(String name, String displayName,WSPathwayInfo pathway,
           String revision, String text,long timeModified, String userModified) {
           this.name = name;
           this.displayName = displayName;
           this.pathway = pathway;
           this.revision = revision;
           this.text = text;
           this.timeModified = timeModified;
           this.userModified = userModified;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public WSPathwayInfo getPathway() {
        return pathway;
    }

    public void setPathway(WSPathwayInfo pathway) {
        this.pathway = pathway;
    }

    public String getRevision() {
        return revision;
    }

    public void setRevision(String revision) {
        this.revision = revision;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public long getTimeModified() {
        return timeModified;
    }

    public void setTimeModified(long timeModified) {
        this.timeModified = timeModified;
    }

    public String getUserModified() {
        return userModified;
    }

    public void setUserModified(String userModified) {
        this.userModified = userModified;
    }
}


text:
package com.sequenceiq.cloudbreak.core.bootstrap.service.host.decorator;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Optional;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import com.sequenceiq.cloudbreak.api.endpoint.v4.common.StackType;
import com.sequenceiq.cloudbreak.auth.altus.EntitlementService;
import com.sequenceiq.cloudbreak.auth.altus.model.AltusCredential;
import com.sequenceiq.cloudbreak.auth.altus.model.CdpAccessKeyType;
import com.sequenceiq.cloudbreak.common.mappable.CloudPlatform;
import com.sequenceiq.cloudbreak.domain.stack.Stack;
import com.sequenceiq.cloudbreak.domain.stack.cluster.Cluster;
import com.sequenceiq.cloudbreak.dto.StackDto;
import com.sequenceiq.cloudbreak.service.ComponentConfigProviderService;
import com.sequenceiq.cloudbreak.service.altus.AltusMachineUserService;
import com.sequenceiq.cloudbreak.telemetry.DataBusEndpointProvider;
import com.sequenceiq.cloudbreak.telemetry.VmLogsService;
import com.sequenceiq.cloudbreak.telemetry.context.TelemetryContext;
import com.sequenceiq.cloudbreak.telemetry.fluent.FluentClusterType;
import com.sequenceiq.cloudbreak.telemetry.monitoring.MonitoringConfigService;
import com.sequenceiq.cloudbreak.workspace.model.User;
import com.sequenceiq.common.api.cloudstorage.old.S3CloudStorageV1Parameters;
import com.sequenceiq.common.api.telemetry.model.DataBusCredential;
import com.sequenceiq.common.api.telemetry.model.Logging;
import com.sequenceiq.common.api.telemetry.model.Monitoring;
import com.sequenceiq.common.api.telemetry.model.MonitoringCredential;
import com.sequenceiq.common.api.telemetry.model.Telemetry;

public class TelemetryDecoratorTest {

    private TelemetryDecorator underTest;

    @Mock
    private MonitoringConfigService monitoringConfigService;

    @Mock
    private AltusMachineUserService altusMachineUserService;

    @Mock
    private VmLogsService vmLogsService;

    @Mock
    private EntitlementService entitlementService;

    @Mock
    private DataBusEndpointProvider dataBusEndpointProvider;

    @Mock
    private ComponentConfigProviderService componentConfigProviderService;

    @Mock
    private Telemetry telemetry;

    @Mock
    private Logging logging;

    @Mock
    private Monitoring monitoring;

    @Before
    public void setUp() {
        initMocks();
        underTest = new TelemetryDecorator(altusMachineUserService, vmLogsService, entitlementService,
                dataBusEndpointProvider, monitoringConfigService, componentConfigProviderService, "1.0.0");
    }

    @Test
    public void testCreateTelemetryContext() {
        // GIVEN
        given(telemetry.isAnyDataBusBasedFeatureEnablred()).willReturn(true);
        given(telemetry.isMeteringFeatureEnabled()).willReturn(true);
        given(telemetry.isComputeMonitoringEnabled()).willReturn(true);
        given(telemetry.getLogging()).willReturn(logging);
        given(telemetry.isCloudStorageLoggingEnabled()).willReturn(true);
        given(telemetry.isClusterLogsCollectionEnabled()).willReturn(true);
        given(logging.getS3()).willReturn(new S3CloudStorageV1Parameters());
        given(entitlementService.isComputeMonitoringEnabled(anyString())).willReturn(true);
        given(telemetry.getMonitoring()).willReturn(monitoring);
        given(monitoring.getRemoteWriteUrl()).willReturn("https://remotewrite:80/api/v1/write");
        // WHEN
        TelemetryContext result = underTest.createTelemetryContext(createStack());
        // THEN
        assertEquals(FluentClusterType.DATAHUB, result.getClusterType());
        assertTrue(result.getDatabusContext().isEnabled());
        assertTrue(result.getLogShipperContext().isEnabled());
        assertTrue(result.getMeteringContext().isEnabled());
        assertTrue(result.getMonitoringContext().isEnabled());
        assertTrue(result.getNodeStatusContext().isSaltPingEnabled());
        verify(altusMachineUserService, times(1)).storeDataBusCredential(any(Optional.class), any(Stack.class), any(CdpAccessKeyType.class));
        verify(altusMachineUserService, times(1)).storeMonitoringCredential(any(Optional.class), any(Stack.class), any(CdpAccessKeyType.class));
    }

    @Test
    public void testCreateTelemetryContextWithDatalakeMeteringDisabled() {
        // GIVEN
        given(telemetry.isAnyDataBusBasedFeatureEnablred()).willReturn(true);
        given(telemetry.isMeteringFeatureEnabled()).willReturn(true);
        // WHEN
        TelemetryContext result = underTest.createTelemetryContext(createStack(StackType.DATALAKE));
        // THEN
        assertEquals(FluentClusterType.DATALAKE, result.getClusterType());
        assertTrue(result.getDatabusContext().isEnabled());
        assertFalse(result.getMeteringContext().isEnabled());
    }

    @Test
    public void testCreateTelemetryContextWithMonitoringOnly() {
        // GIVEN
        given(telemetry.isAnyDataBusBasedFeatureEnablred()).willReturn(false);
        given(telemetry.isComputeMonitoringEnabled()).willReturn(true);
        given(entitlementService.isComputeMonitoringEnabled(anyString())).willReturn(true);
        given(telemetry.getMonitoring()).willReturn(monitoring);
        given(monitoring.getRemoteWriteUrl()).willReturn("https://remotewrite:80/api/v1/write");
        // WHEN
        TelemetryContext result = underTest.createTelemetryContext(createStack());
        // THEN
        assertFalse(result.getDatabusContext().isEnabled());
        assertFalse(result.getLogShipperContext().isEnabled());
        assertFalse(result.getMeteringContext().isEnabled());
        assertTrue(result.getMonitoringContext().isEnabled());
        verify(altusMachineUserService, times(1)).storeMonitoringCredential(any(Optional.class), any(Stack.class), any(CdpAccessKeyType.class));
    }

    @Test
    public void testCreateTelemetryContextLoggingWithoutCloudStorage() {
        // GIVEN
        given(telemetry.getLogging()).willReturn(logging);
        given(telemetry.isCloudStorageLoggingEnabled()).willReturn(true);
        given(telemetry.isClusterLogsCollectionEnabled()).willReturn(false);
        // WHEN
        TelemetryContext result = underTest.createTelemetryContext(createStack());
        // THEN
        assertFalse(result.getLogShipperContext().isEnabled());
    }

    @Test
    public void testCreateTelemetryContextWithDefaults() {
        // GIVEN
        // WHEN
        TelemetryContext result = underTest.createTelemetryContext(createStack());
        // THEN
        assertEquals(FluentClusterType.DATAHUB, result.getClusterType());
    }

    private void initMocks() {
        MockitoAnnotations.openMocks(this);
        AltusCredential altusCredential = new AltusCredential("myAccessKey", "mySecretKey".toCharArray());
        DataBusCredential dataBusCredential = new DataBusCredential();
        dataBusCredential.setAccessKey("myAccessKey");
        dataBusCredential.setPrivateKey("mySecretKey");
        MonitoringCredential monitoringCredential = new MonitoringCredential();
        monitoringCredential.setAccessKey("myAccessKey");
        monitoringCredential.setPrivateKey("mySecretKey");
        given(componentConfigProviderService.getTelemetry(anyLong())).willReturn(telemetry);
        given(telemetry.getDatabusEndpoint()).willReturn("https://dbus-dev.com");
        given(altusMachineUserService.isAnyDataBusBasedFeatureSupported(any(Telemetry.class))).willReturn(true);
        given(altusMachineUserService.isAnyMonitoringFeatureSupported(any(Telemetry.class))).willReturn(true);
        given(altusMachineUserService.storeDataBusCredential(any(Optional.class), any(Stack.class), any(CdpAccessKeyType.class)))
                .willReturn(dataBusCredential);
        given(altusMachineUserService.generateDatabusMachineUserForFluent(any(Stack.class), any(Telemetry.class), any(CdpAccessKeyType.class)))
                .willReturn(Optional.of(altusCredential));
        given(altusMachineUserService.generateMonitoringMachineUser(any(Stack.class), any(Telemetry.class), any(CdpAccessKeyType.class)))
                .willReturn(Optional.of(altusCredential));
        given(altusMachineUserService.storeMonitoringCredential(any(Optional.class), any(Stack.class), any(CdpAccessKeyType.class)))
                .willReturn(monitoringCredential);
        given(entitlementService.useDataBusCNameEndpointEnabled(anyString())).willReturn(false);
        given(entitlementService.isDatahubDatabusEndpointValidationEnabled(anyString())).willReturn(true);
        given(entitlementService.nodestatusSaltPingEnabled(anyString())).willReturn(true);
        given(dataBusEndpointProvider.getDataBusEndpoint(anyString(), anyBoolean())).willReturn("https://dbus-dev.com");
        given(dataBusEndpointProvider.getDatabusS3Endpoint(anyString())).willReturn("https://cloudera-dbus-dev.amazonaws.com");
        given(vmLogsService.getVmLogs()).willReturn(new ArrayList<>());
        given(altusMachineUserService.getCdpAccessKeyType(any())).willReturn(CdpAccessKeyType.ECDSA);
    }

    private StackDto createStack() {
        return createStack(StackType.WORKLOAD);
    }

    private StackDto createStack(StackType stackType) {
        StackDto stackDto = spy(StackDto.class);
        Stack stack = new Stack();
        stack.setName("my-stack-name");
        stack.setType(stackType);
        stack.setCloudPlatform("AWS");
        stack.setId(1L);
        Cluster cluster = new Cluster();
        cluster.setName("cl1");
        cluster.setCloudbreakClusterManagerMonitoringUser("myUsr");
        cluster.setCloudbreakClusterManagerMonitoringPassword("myPass");
        cluster.setCdpNodeStatusMonitorUser("nodeUser");
        cluster.setCdpNodeStatusMonitorPassword("nodePassword");
        stack.setCluster(cluster);
        stack.setCloudPlatform(CloudPlatform.AWS.name());
        User creator = new User();
        creator.setUserCrn("crn:cdp:iam:us-west-1:accountId:user:name");
        stack.setCreator(creator);
        stack.setResourceCrn("crn:cdp:cloudbreak:us-west-1:someone:stack:12345");
        when(stackDto.getStack()).thenReturn(stack);
        when(stackDto.getCluster()).thenReturn(cluster);
        return stackDto;
    }
}


text:
package org.estgroup.phphub.common.adapter;

import android.content.Context;
import android.net.Uri;
import android.view.View;
import android.widget.TextView;

import com.facebook.drawee.view.SimpleDraweeView;
import com.ocpsoft.pretty.time.PrettyTime;

import org.estgroup.phphub.R;
import org.estgroup.phphub.api.entity.element.Topic;
import org.estgroup.phphub.common.base.BaseAdapterItemView;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;

import butterknife.Bind;
import cn.bingoogolapple.badgeview.BGABadgeRelativeLayout;
import static org.estgroup.phphub.common.qualifier.ClickType.*;

public class TopicItemView extends BaseAdapterItemView<Topic> {
    @Bind(R.id.bga_rlyt_content)
    BGABadgeRelativeLayout topicContentView;

    @Bind(R.id.tv_title)
    TextView titleView;

    @Bind(R.id.sdv_avatar)
    SimpleDraweeView avatarView;

    @Bind(R.id.tv_description)
    TextView descriptionView;

    public TopicItemView(Context context) {
        super(context);
    }

    @Override
    public int getLayoutId() {
        return R.layout.topic_item;
    }

    @Override
    public void bind(Topic topic) {
        String des = "";

        Uri avatarUri = Uri.parse(topic.getUser().getData().getAvatar());
        String commentCount = String.valueOf(topic.getReplyCount());

        if (topic.getReplyCount() > 99) {
            commentCount = "99+";
        }

        if (topic.getNode() != null) {
            des += topic.getNode().getData().getName();
        }

        if (topic.getLastReplyUser() != null) {
            des += " • " + getResources().getString(R.string.last_for) + " " + topic.getLastReplyUser().getData().getName();
        }

        if (topic.getUpdatedAt() != null) {
            Locale locale = getResources().getConfiguration().locale;
            PrettyTime prettyTime = new PrettyTime(locale);
            String dateStr = topic.getUpdatedAt();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                String prettyTimeString = prettyTime.format(sdf.parse(dateStr));
                des += " • " + prettyTimeString;
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        topicContentView.showTextBadge(commentCount);
        titleView.setText(topic.getTitle());
        avatarView.setImageURI(avatarUri);
        descriptionView.setText(des);

        topicContentView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                notifyItemAction(CLICK_TYPE_TOPIC_CLICKED);
            }
        });

        avatarView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                notifyItemAction(CLICK_TYPE_USER_CLICKED);
            }
        });
    }
}


text:
					系统原型

						4

							4 Tasks to complete

									Software Update
									65%

									Hardware Upgrade
									35%

									Unit Testing
									15%

									Bug Fixes
									90%

								See tasks with details

						8

							8 Notifications

										New Comments

									+12

								Bob just signed up as an editor ...

										New Orders

									+8

										Followers

									+11

								See all notifications

						5

							5 Messages

										Alex:
										Ciao sociis natoque penatibus et auctor ...

										a moment ago

										Susan:
										Vestibulum id ligula porta felis euismod ...

										20 minutes ago

										Bob:
										Nullam quis risus eget urna mollis ornare ...

										3:15 pm

								See all messages

							欢迎您,
							${(session_user.real_name)!}

								设置 Settings

								修改资料 Profile

								安全退出 Logout


text:
/**
 * A callback for when a piped event is triggered.
 *
 * @param event   The source Event causing the trigger.
 */
export type TriggerCallback = (event?: Event) => void;

/**
 * A mapping of events to their key codes, to their callbacks.
 */
export interface TriggerContainer {
    [i: string]: TriggerGroup;
}

/**
 * A mapping of key codes to callbacks.
 */
export interface TriggerGroup {
    [i: string]: TriggerCallback;
    [j: number]: TriggerCallback;
}

/**
 * Known, allowed aliases for triggers.
 */
export interface Aliases {
    [i: string]: any[];
}

/**
 * Determines whether triggering is possible for an event.
 *
 * @param event   The event function (or string alias thereof) to call.
 * @param keyCode   The alias of the event Function under triggers[event],
 *                  if event is a string.
 * @param sourceEvent   The raw event that caused the calling Pipe
 *                      to be triggered, such as a MouseEvent.
 * @returns Whether triggering is possible.
 */
export type CanTrigger = (
    event: Function | string,
    keyCode?: number | string,
    sourceEvent?: Event
) => boolean;

/**
 * A mapping from alias Strings to character code Numbers.
 */
export interface AliasesToCodes {
    [i: string]: number;
}

/**
 * A mapping from character code Numbers to alias Strings.
 */
export interface CodesToAliases {
    [i: number]: string;
}

/**
 * Aliases mapped to their allowed key strings.
 */
export interface AliasKeys {
    [i: string]: string[];
}

/**
 * Pipes an input event to the correct trigger.
 *
 * @param event   An input event.
 */
export type Pipe = (event: Event) => void;

/**
 * Settings to initialize a new InputWritr.
 */
export interface InputWritrSettings {
    /**
     * The mapping of events to their key codes, to their callbacks.
     */
    triggers?: TriggerContainer;

    /**
     * Function to generate a current timestamp, commonly performance.now.
     */
    getTimestamp?(): number;

    /**
     * Known, allowed aliases for triggers.
     */
    aliases?: Aliases;

    /**
     * Whether events are initially allowed to trigger (by default, true).
     */
    canTrigger?: boolean | CanTrigger;
}


text:
package framework

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"path"
	"strings"
	"sync"
	"time"

	"k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/util/intstr"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/informers"
	clientset "k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
	"k8s.io/kubernetes/pkg/kubemark"
	"k8s.io/kubernetes/test/e2e/framework/metrics"
	testutils "k8s.io/kubernetes/test/utils"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const (
	maxKubectlExecRetries = 5
	// TODO(mikedanese): reset this to 5 minutes once #47135 is resolved.
	// ref https://github.com/kubernetes/kubernetes/issues/47135
	DefaultNamespaceDeletionTimeout = 10 * time.Minute
)

// Framework supports common operations used by e2e tests; it will keep a client & a namespace for you.
// Eventual goal is to merge this with integration test framework.
type Framework struct {
	BaseName string

	ClientSet                        clientset.Interface
	KubemarkExternalClusterClientSet clientset.Interface

	InternalClientset *internalclientset.Clientset
	AggregatorClient  *aggregatorclient.Clientset
	ClientPool        dynamic.ClientPool

	SkipNamespaceCreation    bool            // Whether to skip creating a namespace
	Namespace                *v1.Namespace   // Every test has at least one namespace unless creation is skipped
	namespacesToDelete       []*v1.Namespace // Some tests have more than one.
	NamespaceDeletionTimeout time.Duration

	gatherer *containerResourceGatherer
	// Constraints that passed to a check which is executed after data is gathered to
	// see if 99% of results are within acceptable bounds. It has to be injected in the test,
	// as expectations vary greatly. Constraints are grouped by the container names.
	AddonResourceConstraints map[string]ResourceConstraint

	logsSizeWaitGroup    sync.WaitGroup
	logsSizeCloseChannel chan bool
	logsSizeVerifier     *LogsSizeVerifier

	// To make sure that this framework cleans up after itself, no matter what,
	// we install a Cleanup action before each test and clear it after.  If we
	// should abort, the AfterSuite hook should run all Cleanup actions.
	cleanupHandle CleanupActionHandle

	// configuration for framework's client
	Options FrameworkOptions

	// Place where various additional data is stored during test run to be printed to ReportDir,
	// or stdout if ReportDir is not set once test ends.
	TestSummaries []TestDataSummary

	kubemarkControllerCloseChannel chan struct{}

	// Place to keep ClusterAutoscaler metrics from before test in order to compute delta.
	clusterAutoscalerMetricsBeforeTest metrics.MetricsCollection
}

type TestDataSummary interface {
	SummaryKind() string
	PrintHumanReadable() string
	PrintJSON() string
}

type FrameworkOptions struct {
	ClientQPS    float32
	ClientBurst  int
	GroupVersion *schema.GroupVersion
}

// NewFramework makes a new framework and sets up a BeforeEach/AfterEach for
// you (you can write additional before/after each functions).
func NewDefaultFramework(baseName string) *Framework {
	options := FrameworkOptions{
		ClientQPS:   20,
		ClientBurst: 50,
	}
	return NewFramework(baseName, options, nil)
}

func NewFramework(baseName string, options FrameworkOptions, client clientset.Interface) *Framework {
	f := &Framework{
		BaseName:                 baseName,
		AddonResourceConstraints: make(map[string]ResourceConstraint),
		Options:                  options,
		ClientSet:                client,
	}

	BeforeEach(f.BeforeEach)
	AfterEach(f.AfterEach)

	return f
}

// BeforeEach gets a client and makes a namespace.
func (f *Framework) BeforeEach() {
	// The fact that we need this feels like a bug in ginkgo.
	// https://github.com/onsi/ginkgo/issues/222
	f.cleanupHandle = AddCleanupAction(f.AfterEach)
	if f.ClientSet == nil {
		By("Creating a kubernetes client")
		config, err := LoadConfig()
		Expect(err).NotTo(HaveOccurred())
		config.QPS = f.Options.ClientQPS
		config.Burst = f.Options.ClientBurst
		if f.Options.GroupVersion != nil {
			config.GroupVersion = f.Options.GroupVersion
		}
		if TestContext.KubeAPIContentType != "" {
			config.ContentType = TestContext.KubeAPIContentType
		}
		f.ClientSet, err = clientset.NewForConfig(config)
		Expect(err).NotTo(HaveOccurred())
		f.InternalClientset, err = internalclientset.NewForConfig(config)
		Expect(err).NotTo(HaveOccurred())
		f.AggregatorClient, err = aggregatorclient.NewForConfig(config)
		Expect(err).NotTo(HaveOccurred())
		f.ClientPool = dynamic.NewClientPool(config, api.Registry.RESTMapper(), dynamic.LegacyAPIPathResolverFunc)
		if ProviderIs("kubemark") && TestContext.KubemarkExternalKubeConfig != "" && TestContext.CloudConfig.KubemarkController == nil {
			externalConfig, err := clientcmd.BuildConfigFromFlags("", TestContext.KubemarkExternalKubeConfig)
			externalConfig.QPS = f.Options.ClientQPS
			externalConfig.Burst = f.Options.ClientBurst
			Expect(err).NotTo(HaveOccurred())
			externalClient, err := clientset.NewForConfig(externalConfig)
			Expect(err).NotTo(HaveOccurred())
			f.KubemarkExternalClusterClientSet = externalClient
			f.kubemarkControllerCloseChannel = make(chan struct{})
			externalInformerFactory := informers.NewSharedInformerFactory(externalClient, 0)
			kubemarkInformerFactory := informers.NewSharedInformerFactory(f.ClientSet, 0)
			kubemarkNodeInformer := kubemarkInformerFactory.Core().V1().Nodes()
			go kubemarkNodeInformer.Informer().Run(f.kubemarkControllerCloseChannel)
			TestContext.CloudConfig.KubemarkController, err = kubemark.NewKubemarkController(f.KubemarkExternalClusterClientSet, externalInformerFactory, f.ClientSet, kubemarkNodeInformer)
			Expect(err).NotTo(HaveOccurred())
			externalInformerFactory.Start(f.kubemarkControllerCloseChannel)
			Expect(TestContext.CloudConfig.KubemarkController.WaitForCacheSync(f.kubemarkControllerCloseChannel)).To(BeTrue())
			go TestContext.CloudConfig.KubemarkController.Run(f.kubemarkControllerCloseChannel)
		}
	}

	if !f.SkipNamespaceCreation {
		By("Building a namespace api object")
		namespace, err := f.CreateNamespace(f.BaseName, map[string]string{
			"e2e-framework": f.BaseName,
		})
		Expect(err).NotTo(HaveOccurred())

		f.Namespace = namespace

		if TestContext.VerifyServiceAccount {
			By("Waiting for a default service account to be provisioned in namespace")
			err = WaitForDefaultServiceAccountInNamespace(f.ClientSet, namespace.Name)
			Expect(err).NotTo(HaveOccurred())
		} else {
			Logf("Skipping waiting for service account")
		}
	}

	if TestContext.GatherKubeSystemResourceUsageData != "false" && TestContext.GatherKubeSystemResourceUsageData != "none" {
		var err error
		f.gatherer, err = NewResourceUsageGatherer(f.ClientSet, ResourceGathererOptions{
			inKubemark: ProviderIs("kubemark"),
			masterOnly: TestContext.GatherKubeSystemResourceUsageData == "master",
		})
		if err != nil {
			Logf("Error while creating NewResourceUsageGatherer: %v", err)
		} else {
			go f.gatherer.startGatheringData()
		}
	}

	if TestContext.GatherLogsSizes {
		f.logsSizeWaitGroup = sync.WaitGroup{}
		f.logsSizeWaitGroup.Add(1)
		f.logsSizeCloseChannel = make(chan bool)
		f.logsSizeVerifier = NewLogsVerifier(f.ClientSet, f.logsSizeCloseChannel)
		go func() {
			f.logsSizeVerifier.Run()
			f.logsSizeWaitGroup.Done()
		}()
	}

	gatherMetricsAfterTest := TestContext.GatherMetricsAfterTest == "true" || TestContext.GatherMetricsAfterTest == "master"
	if gatherMetricsAfterTest && TestContext.IncludeClusterAutoscalerMetrics {
		grabber, err := metrics.NewMetricsGrabber(f.ClientSet, f.KubemarkExternalClusterClientSet, !ProviderIs("kubemark"), false, false, false, TestContext.IncludeClusterAutoscalerMetrics)
		if err != nil {
			Logf("Failed to create MetricsGrabber (skipping ClusterAutoscaler metrics gathering before test): %v", err)
		} else {
			f.clusterAutoscalerMetricsBeforeTest, err = grabber.Grab()
			if err != nil {
				Logf("MetricsGrabber failed to grab CA metrics before test (skipping metrics gathering): %v", err)
			} else {
				Logf("Gathered ClusterAutoscaler metrics before test")
			}
		}

	}
}

// AfterEach deletes the namespace, after reading its events.
func (f *Framework) AfterEach() {
	RemoveCleanupAction(f.cleanupHandle)

	// DeleteNamespace at the very end in defer, to avoid any
	// expectation failures preventing deleting the namespace.
	defer func() {
		nsDeletionErrors := map[string]error{}
		// Whether to delete namespace is determined by 3 factors: delete-namespace flag, delete-namespace-on-failure flag and the test result
		// if delete-namespace set to false, namespace will always be preserved.
		// if delete-namespace is true and delete-namespace-on-failure is false, namespace will be preserved if test failed.
		if TestContext.DeleteNamespace && (TestContext.DeleteNamespaceOnFailure || !CurrentGinkgoTestDescription().Failed) {
			for _, ns := range f.namespacesToDelete {
				By(fmt.Sprintf("Destroying namespace %q for this suite.", ns.Name))
				timeout := DefaultNamespaceDeletionTimeout
				if f.NamespaceDeletionTimeout != 0 {
					timeout = f.NamespaceDeletionTimeout
				}
				if err := deleteNS(f.ClientSet, f.ClientPool, ns.Name, timeout); err != nil {
					if !apierrors.IsNotFound(err) {
						nsDeletionErrors[ns.Name] = err
					} else {
						Logf("Namespace %v was already deleted", ns.Name)
					}
				}
			}
		} else {
			if !TestContext.DeleteNamespace {
				Logf("Found DeleteNamespace=false, skipping namespace deletion!")
			} else {
				Logf("Found DeleteNamespaceOnFailure=false and current test failed, skipping namespace deletion!")
			}
		}

		// Paranoia-- prevent reuse!
		f.Namespace = nil
		f.ClientSet = nil
		f.namespacesToDelete = nil

		// if we had errors deleting, report them now.
		if len(nsDeletionErrors) != 0 {
			messages := []string{}
			for namespaceKey, namespaceErr := range nsDeletionErrors {
				messages = append(messages, fmt.Sprintf("Couldn't delete ns: %q: %s (%#v)", namespaceKey, namespaceErr, namespaceErr))
			}
			Failf(strings.Join(messages, ","))
		}
	}()

	// Print events if the test failed.
	if CurrentGinkgoTestDescription().Failed && TestContext.DumpLogsOnFailure {
		// Pass both unversioned client and and versioned clientset, till we have removed all uses of the unversioned client.
		if !f.SkipNamespaceCreation {
			DumpAllNamespaceInfo(f.ClientSet, f.Namespace.Name)
		}

		logFunc := Logf
		if TestContext.ReportDir != "" {
			filePath := path.Join(TestContext.ReportDir, "image-puller.txt")
			file, err := os.Create(filePath)
			if err != nil {
				By(fmt.Sprintf("Failed to create a file with image-puller data %v: %v\nPrinting to stdout", filePath, err))
			} else {
				By(fmt.Sprintf("Dumping a list of prepulled images on each node to file %v", filePath))
				defer file.Close()
				if err = file.Chmod(0644); err != nil {
					Logf("Failed to chmod to 644 of %v: %v", filePath, err)
				}
				logFunc = GetLogToFileFunc(file)
			}
		} else {
			By("Dumping a list of prepulled images on each node...")
		}
		LogContainersInPodsWithLabels(f.ClientSet, metav1.NamespaceSystem, ImagePullerLabels, "image-puller", logFunc)
	}

	if TestContext.GatherKubeSystemResourceUsageData != "false" && TestContext.GatherKubeSystemResourceUsageData != "none" && f.gatherer != nil {
		By("Collecting resource usage data")
		summary, resourceViolationError := f.gatherer.stopAndSummarize([]int{90, 99, 100}, f.AddonResourceConstraints)
		defer ExpectNoError(resourceViolationError)
		f.TestSummaries = append(f.TestSummaries, summary)
	}

	if TestContext.GatherLogsSizes {
		By("Gathering log sizes data")
		close(f.logsSizeCloseChannel)
		f.logsSizeWaitGroup.Wait()
		f.TestSummaries = append(f.TestSummaries, f.logsSizeVerifier.GetSummary())
	}

	if TestContext.GatherMetricsAfterTest != "false" {
		By("Gathering metrics")
		// Grab apiserver, scheduler, controller-manager metrics and (optionally) nodes' kubelet metrics.
		grabMetricsFromKubelets := TestContext.GatherMetricsAfterTest != "master" && !ProviderIs("kubemark")
		grabber, err := metrics.NewMetricsGrabber(f.ClientSet, f.KubemarkExternalClusterClientSet, grabMetricsFromKubelets, true, true, true, TestContext.IncludeClusterAutoscalerMetrics)
		if err != nil {
			Logf("Failed to create MetricsGrabber (skipping metrics gathering): %v", err)
		} else {
			received, err := grabber.Grab()
			if err != nil {
				Logf("MetricsGrabber failed to grab some of the metrics: %v", err)
			}
			(*MetricsForE2E)(&received).computeClusterAutoscalerMetricsDelta(f.clusterAutoscalerMetricsBeforeTest)
			f.TestSummaries = append(f.TestSummaries, (*MetricsForE2E)(&received))
		}
	}

	if TestContext.CloudConfig.KubemarkController != nil {
		close(f.kubemarkControllerCloseChannel)
	}

	PrintSummaries(f.TestSummaries, f.BaseName)

	// Check whether all nodes are ready after the test.
	// This is explicitly done at the very end of the test, to avoid
	// e.g. not removing namespace in case of this failure.
	if err := AllNodesReady(f.ClientSet, 3*time.Minute); err != nil {
		Failf("All nodes should be ready after test, %v", err)
	}
}

func (f *Framework) CreateNamespace(baseName string, labels map[string]string) (*v1.Namespace, error) {
	createTestingNS := TestContext.CreateTestingNS
	if createTestingNS == nil {
		createTestingNS = CreateTestingNS
	}
	ns, err := createTestingNS(baseName, f.ClientSet, labels)
	// check ns instead of err to see if it's nil as we may
	// fail to create serviceAccount in it.
	// In this case, we should not forget to delete the namespace.
	if ns != nil {
		f.namespacesToDelete = append(f.namespacesToDelete, ns)
	}
	return ns, err
}

// WaitForPodTerminated waits for the pod to be terminated with the given reason.
func (f *Framework) WaitForPodTerminated(podName, reason string) error {
	return waitForPodTerminatedInNamespace(f.ClientSet, podName, reason, f.Namespace.Name)
}

// WaitForPodRunning waits for the pod to run in the namespace.
func (f *Framework) WaitForPodRunning(podName string) error {
	return WaitForPodNameRunningInNamespace(f.ClientSet, podName, f.Namespace.Name)
}

// WaitForPodReady waits for the pod to flip to ready in the namespace.
func (f *Framework) WaitForPodReady(podName string) error {
	return waitTimeoutForPodReadyInNamespace(f.ClientSet, podName, f.Namespace.Name, PodStartTimeout)
}

// WaitForPodRunningSlow waits for the pod to run in the namespace.
// It has a longer timeout then WaitForPodRunning (util.slowPodStartTimeout).
func (f *Framework) WaitForPodRunningSlow(podName string) error {
	return waitForPodRunningInNamespaceSlow(f.ClientSet, podName, f.Namespace.Name)
}

// WaitForPodNoLongerRunning waits for the pod to no longer be running in the namespace, for either
// success or failure.
func (f *Framework) WaitForPodNoLongerRunning(podName string) error {
	return WaitForPodNoLongerRunningInNamespace(f.ClientSet, podName, f.Namespace.Name)
}

// TestContainerOutput runs the given pod in the given namespace and waits
// for all of the containers in the podSpec to move into the 'Success' status, and tests
// the specified container log against the given expected output using a substring matcher.
func (f *Framework) TestContainerOutput(scenarioName string, pod *v1.Pod, containerIndex int, expectedOutput []string) {
	f.testContainerOutputMatcher(scenarioName, pod, containerIndex, expectedOutput, ContainSubstring)
}

// TestContainerOutputRegexp runs the given pod in the given namespace and waits
// for all of the containers in the podSpec to move into the 'Success' status, and tests
// the specified container log against the given expected output using a regexp matcher.
func (f *Framework) TestContainerOutputRegexp(scenarioName string, pod *v1.Pod, containerIndex int, expectedOutput []string) {
	f.testContainerOutputMatcher(scenarioName, pod, containerIndex, expectedOutput, MatchRegexp)
}

// Write a file using kubectl exec echo <contents> > <path> via specified container
// Because of the primitive technique we're using here, we only allow ASCII alphanumeric characters
func (f *Framework) WriteFileViaContainer(podName, containerName string, path string, contents string) error {
	By("writing a file in the container")
	allowedCharacters := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	for _, c := range contents {
		if !strings.ContainsRune(allowedCharacters, c) {
			return fmt.Errorf("Unsupported character in string to write: %v", c)
		}
	}
	command := fmt.Sprintf("echo '%s' > '%s'", contents, path)
	stdout, stderr, err := kubectlExecWithRetry(f.Namespace.Name, podName, containerName, "--", "/bin/sh", "-c", command)
	if err != nil {
		Logf("error running kubectl exec to write file: %v\nstdout=%v\nstderr=%v)", err, string(stdout), string(stderr))
	}
	return err
}

// Read a file using kubectl exec cat <path>
func (f *Framework) ReadFileViaContainer(podName, containerName string, path string) (string, error) {
	By("reading a file in the container")

	stdout, stderr, err := kubectlExecWithRetry(f.Namespace.Name, podName, containerName, "--", "cat", path)
	if err != nil {
		Logf("error running kubectl exec to read file: %v\nstdout=%v\nstderr=%v)", err, string(stdout), string(stderr))
	}
	return string(stdout), err
}

func (f *Framework) CheckFileSizeViaContainer(podName, containerName, path string) (string, error) {
	By("checking a file size in the container")

	stdout, stderr, err := kubectlExecWithRetry(f.Namespace.Name, podName, containerName, "--", "ls", "-l", path)
	if err != nil {
		Logf("error running kubectl exec to read file: %v\nstdout=%v\nstderr=%v)", err, string(stdout), string(stderr))
	}
	return string(stdout), err
}

// CreateServiceForSimpleAppWithPods is a convenience wrapper to create a service and its matching pods all at once.
func (f *Framework) CreateServiceForSimpleAppWithPods(contPort int, svcPort int, appName string, podSpec func(n v1.Node) v1.PodSpec, count int, block bool) (error, *v1.Service) {
	var err error = nil
	theService := f.CreateServiceForSimpleApp(contPort, svcPort, appName)
	f.CreatePodsPerNodeForSimpleApp(appName, podSpec, count)
	if block {
		err = testutils.WaitForPodsWithLabelRunning(f.ClientSet, f.Namespace.Name, labels.SelectorFromSet(labels.Set(theService.Spec.Selector)))
	}
	return err, theService
}

// CreateServiceForSimpleApp returns a service that selects/exposes pods (send -1 ports if no exposure needed) with an app label.
func (f *Framework) CreateServiceForSimpleApp(contPort, svcPort int, appName string) *v1.Service {
	if appName == "" {
		panic(fmt.Sprintf("no app name provided"))
	}

	serviceSelector := map[string]string{
		"app": appName + "-pod",
	}

	// For convenience, user sending ports are optional.
	portsFunc := func() []v1.ServicePort {
		if contPort < 1 || svcPort < 1 {
			return nil
		} else {
			return []v1.ServicePort{{
				Protocol:   "TCP",
				Port:       int32(svcPort),
				TargetPort: intstr.FromInt(contPort),
			}}
		}
	}
	Logf("Creating a service-for-%v for selecting app=%v-pod", appName, appName)
	service, err := f.ClientSet.Core().Services(f.Namespace.Name).Create(&v1.Service{
		ObjectMeta: metav1.ObjectMeta{
			Name: "service-for-" + appName,
			Labels: map[string]string{
				"app": appName + "-service",
			},
		},
		Spec: v1.ServiceSpec{
			Ports:    portsFunc(),
			Selector: serviceSelector,
		},
	})
	ExpectNoError(err)
	return service
}

// CreatePodsPerNodeForSimpleApp Creates pods w/ labels.  Useful for tests which make a bunch of pods w/o any networking.
func (f *Framework) CreatePodsPerNodeForSimpleApp(appName string, podSpec func(n v1.Node) v1.PodSpec, maxCount int) map[string]string {
	nodes := GetReadySchedulableNodesOrDie(f.ClientSet)
	labels := map[string]string{
		"app": appName + "-pod",
	}
	for i, node := range nodes.Items {
		// one per node, but no more than maxCount.
		if i <= maxCount {
			Logf("%v/%v : Creating container with label app=%v-pod", i, maxCount, appName)
			_, err := f.ClientSet.Core().Pods(f.Namespace.Name).Create(&v1.Pod{
				ObjectMeta: metav1.ObjectMeta{
					Name:   fmt.Sprintf(appName+"-pod-%v", i),
					Labels: labels,
				},
				Spec: podSpec(node),
			})
			ExpectNoError(err)
		}
	}
	return labels
}

type KubeUser struct {
	Name string `yaml:"name"`
	User struct {
		Username string `yaml:"username"`
		Password string `yaml:"password"`
		Token    string `yaml:"token"`
	} `yaml:"user"`
}

type KubeCluster struct {
	Name    string `yaml:"name"`
	Cluster struct {
		CertificateAuthorityData string `yaml:"certificate-authority-data"`
		Server                   string `yaml:"server"`
	} `yaml:"cluster"`
}

type KubeConfig struct {
	Contexts []struct {
		Name    string `yaml:"name"`
		Context struct {
			Cluster string `yaml:"cluster"`
			User    string
		} `yaml:"context"`
	} `yaml:"contexts"`

	Clusters []KubeCluster `yaml:"clusters"`

	Users []KubeUser `yaml:"users"`
}

func (kc *KubeConfig) FindUser(name string) *KubeUser {
	for _, user := range kc.Users {
		if user.Name == name {
			return &user
		}
	}
	return nil
}

func (kc *KubeConfig) FindCluster(name string) *KubeCluster {
	for _, cluster := range kc.Clusters {
		if cluster.Name == name {
			return &cluster
		}
	}
	return nil
}

func kubectlExecWithRetry(namespace string, podName, containerName string, args ...string) ([]byte, []byte, error) {
	for numRetries := 0; numRetries < maxKubectlExecRetries; numRetries++ {
		if numRetries > 0 {
			Logf("Retrying kubectl exec (retry count=%v/%v)", numRetries+1, maxKubectlExecRetries)
		}

		stdOutBytes, stdErrBytes, err := kubectlExec(namespace, podName, containerName, args...)
		if err != nil {
			if strings.Contains(strings.ToLower(string(stdErrBytes)), "i/o timeout") {
				// Retry on "i/o timeout" errors
				Logf("Warning: kubectl exec encountered i/o timeout.\nerr=%v\nstdout=%v\nstderr=%v)", err, string(stdOutBytes), string(stdErrBytes))
				continue
			}
			if strings.Contains(strings.ToLower(string(stdErrBytes)), "container not found") {
				// Retry on "container not found" errors
				Logf("Warning: kubectl exec encountered container not found.\nerr=%v\nstdout=%v\nstderr=%v)", err, string(stdOutBytes), string(stdErrBytes))
				time.Sleep(2 * time.Second)
				continue
			}
		}

		return stdOutBytes, stdErrBytes, err
	}
	err := fmt.Errorf("Failed: kubectl exec failed %d times with \"i/o timeout\". Giving up.", maxKubectlExecRetries)
	return nil, nil, err
}

func kubectlExec(namespace string, podName, containerName string, args ...string) ([]byte, []byte, error) {
	var stdout, stderr bytes.Buffer
	cmdArgs := []string{
		"exec",
		fmt.Sprintf("--namespace=%v", namespace),
		podName,
		fmt.Sprintf("-c=%v", containerName),
	}
	cmdArgs = append(cmdArgs, args...)

	cmd := KubectlCmd(cmdArgs...)
	cmd.Stdout, cmd.Stderr = &stdout, &stderr

	Logf("Running '%s %s'", cmd.Path, strings.Join(cmdArgs, " "))
	err := cmd.Run()
	return stdout.Bytes(), stderr.Bytes(), err
}

// Wrapper function for ginkgo describe.  Adds namespacing.
// TODO: Support type safe tagging as well https://github.com/kubernetes/kubernetes/pull/22401.
func KubeDescribe(text string, body func()) bool {
	return Describe("[k8s.io] "+text, body)
}

// PodStateVerification represents a verification of pod state.
// Any time you have a set of pods that you want to operate against or query,
// this struct can be used to declaratively identify those pods.
type PodStateVerification struct {
	// Optional: only pods that have k=v labels will pass this filter.
	Selectors map[string]string

	// Required: The phases which are valid for your pod.
	ValidPhases []v1.PodPhase

	// Optional: only pods passing this function will pass the filter
	// Verify a pod.
	// As an optimization, in addition to specfying filter (boolean),
	// this function allows specifying an error as well.
	// The error indicates that the polling of the pod spectrum should stop.
	Verify func(v1.Pod) (bool, error)

	// Optional: only pods with this name will pass the filter.
	PodName string
}

type ClusterVerification struct {
	client    clientset.Interface
	namespace *v1.Namespace // pointer rather than string, since ns isn't created until before each.
	podState  PodStateVerification
}

func (f *Framework) NewClusterVerification(namespace *v1.Namespace, filter PodStateVerification) *ClusterVerification {
	return &ClusterVerification{
		f.ClientSet,
		namespace,
		filter,
	}
}

func passesPodNameFilter(pod v1.Pod, name string) bool {
	return name == "" || strings.Contains(pod.Name, name)
}

func passesVerifyFilter(pod v1.Pod, verify func(p v1.Pod) (bool, error)) (bool, error) {
	if verify == nil {
		return true, nil
	} else {
		verified, err := verify(pod)
		// If an error is returned, by definition, pod verification fails
		if err != nil {
			return false, err
		} else {
			return verified, nil
		}
	}
}

func passesPhasesFilter(pod v1.Pod, validPhases []v1.PodPhase) bool {
	passesPhaseFilter := false
	for _, phase := range validPhases {
		if pod.Status.Phase == phase {
			passesPhaseFilter = true
		}
	}
	return passesPhaseFilter
}

// filterLabels returns a list of pods which have labels.
func filterLabels(selectors map[string]string, cli clientset.Interface, ns string) (*v1.PodList, error) {
	var err error
	var selector labels.Selector
	var pl *v1.PodList
	// List pods based on selectors.  This might be a tiny optimization rather then filtering
	// everything manually.
	if len(selectors) > 0 {
		selector = labels.SelectorFromSet(labels.Set(selectors))
		options := metav1.ListOptions{LabelSelector: selector.String()}
		pl, err = cli.Core().Pods(ns).List(options)
	} else {
		pl, err = cli.Core().Pods(ns).List(metav1.ListOptions{})
	}
	return pl, err
}

// filter filters pods which pass a filter.  It can be used to compose
// the more useful abstractions like ForEach, WaitFor, and so on, which
// can be used directly by tests.
func (p *PodStateVerification) filter(c clientset.Interface, namespace *v1.Namespace) ([]v1.Pod, error) {
	if len(p.ValidPhases) == 0 || namespace == nil {
		panic(fmt.Errorf("Need to specify a valid pod phases (%v) and namespace (%v). ", p.ValidPhases, namespace))
	}

	ns := namespace.Name
	pl, err := filterLabels(p.Selectors, c, ns) // Build an v1.PodList to operate against.
	Logf("Selector matched %v pods for %v", len(pl.Items), p.Selectors)
	if len(pl.Items) == 0 || err != nil {
		return pl.Items, err
	}

	unfilteredPods := pl.Items
	filteredPods := []v1.Pod{}
ReturnPodsSoFar:
	// Next: Pod must match at least one of the states that the user specified
	for _, pod := range unfilteredPods {
		if !(passesPhasesFilter(pod, p.ValidPhases) && passesPodNameFilter(pod, p.PodName)) {
			continue
		}
		passesVerify, err := passesVerifyFilter(pod, p.Verify)
		if err != nil {
			Logf("Error detected on %v : %v !", pod.Name, err)
			break ReturnPodsSoFar
		}
		if passesVerify {
			filteredPods = append(filteredPods, pod)
		}
	}
	return filteredPods, err
}

// WaitFor waits for some minimum number of pods to be verified, according to the PodStateVerification
// definition.
func (cl *ClusterVerification) WaitFor(atLeast int, timeout time.Duration) ([]v1.Pod, error) {
	pods := []v1.Pod{}
	var returnedErr error

	err := wait.Poll(1*time.Second, timeout, func() (bool, error) {
		pods, returnedErr = cl.podState.filter(cl.client, cl.namespace)

		// Failure
		if returnedErr != nil {
			Logf("Cutting polling short: We got an error from the pod filtering layer.")
			// stop polling if the pod filtering returns an error.  that should never happen.
			// it indicates, for example, that the client is broken or something non-pod related.
			return false, returnedErr
		}
		Logf("Found %v / %v", len(pods), atLeast)

		// Success
		if len(pods) >= atLeast {
			return true, nil
		}
		// Keep trying...
		return false, nil
	})
	Logf("WaitFor completed with timeout %v.  Pods found = %v out of %v", timeout, len(pods), atLeast)
	return pods, err
}

// WaitForOrFail provides a shorthand WaitFor with failure as an option if anything goes wrong.
func (cl *ClusterVerification) WaitForOrFail(atLeast int, timeout time.Duration) {
	pods, err := cl.WaitFor(atLeast, timeout)
	if err != nil || len(pods) < atLeast {
		Failf("Verified %v of %v pods , error : %v", len(pods), atLeast, err)
	}
}

// ForEach runs a function against every verifiable pod.  Be warned that this doesn't wait for "n" pods to verifiy,
// so it may return very quickly if you have strict pod state requirements.
//
// For example, if you require at least 5 pods to be running before your test will pass,
// its smart to first call "clusterVerification.WaitFor(5)" before you call clusterVerification.ForEach.
func (cl *ClusterVerification) ForEach(podFunc func(v1.Pod)) error {
	pods, err := cl.podState.filter(cl.client, cl.namespace)
	if err == nil {
		if len(pods) == 0 {
			Failf("No pods matched the filter.")
		}
		Logf("ForEach: Found %v pods from the filter.  Now looping through them.", len(pods))
		for _, p := range pods {
			podFunc(p)
		}
	} else {
		Logf("ForEach: Something went wrong when filtering pods to execute against: %v", err)
	}

	return err
}

// GetLogToFileFunc is a convenience function that returns a function that have the same interface as
// Logf, but writes to a specified file.
func GetLogToFileFunc(file *os.File) func(format string, args ...interface{}) {
	return func(format string, args ...interface{}) {
		writer := bufio.NewWriter(file)
		if _, err := fmt.Fprintf(writer, format, args...); err != nil {
			Logf("Failed to write file %v with test performance data: %v", file.Name(), err)
		}
		writer.Flush()
	}
}


text:
package config

import (
	"fmt"
	"strings"

	"github.com/openconfig/gnmi/proto/gnmi"
	"github.com/openconfig/gnmic/api"
	"github.com/openconfig/gnmic/types"
	"github.com/spf13/cobra"
)

func (c *Config) CreateDiffSubscribeRequest(cmd *cobra.Command) (*gnmi.SubscribeRequest, error) {
	sc := &types.SubscriptionConfig{
		Name:     "diff-sub",
		Models:   c.DiffModel,
		Prefix:   c.DiffPrefix,
		Target:   c.DiffTarget,
		Paths:    c.DiffPath,
		Mode:     "ONCE",
		Encoding: c.Encoding,
	}
	if flagIsSet(cmd, "qos") {
		sc.Qos = &c.DiffQos
	}
	return c.CreateSubscribeRequest(sc, "")
}

func (c *Config) CreateDiffGetRequest() (*gnmi.GetRequest, error) {
	if c == nil {
		return nil, fmt.Errorf("%w", ErrInvalidConfig)
	}
	gnmiOpts := make([]api.GNMIOption, 0, 4+len(c.LocalFlags.DiffPath))
	gnmiOpts = append(gnmiOpts,
		api.Encoding(c.Encoding),
		api.DataType(c.LocalFlags.DiffType),
		api.Prefix(c.LocalFlags.DiffPrefix),
		api.Target(c.LocalFlags.DiffTarget),
	)
	for _, p := range c.LocalFlags.DiffPath {
		gnmiOpts = append(gnmiOpts, api.Path(strings.TrimSpace(p)))
	}
	return api.NewGetRequest(gnmiOpts...)
}