001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.classic.control; 015 016import java.util.Random; 017 018import ch.qos.logback.classic.Level; 019import ch.qos.logback.classic.corpus.RandomUtil; 020 021public class ScenarioRandomUtil { 022 private final static long SEED = 74130; 023 024 private final static Random random = new Random(SEED); 025 private final static int AVERAGE_ID_LEN = 32; 026 private final static int AVERAGE_ID_DEV = 16; 027 028 private final static int AVERAGE_CHILDREN_COUNT = 30; 029 private final static int CHILDREN_COUNT_VAR = 10; 030 031 public static boolean oneInFreq(int freq) { 032 return (random.nextInt(freq) % freq) == 0; 033 } 034 035 public static Level randomLevel() { 036 int rl = random.nextInt(6); 037 switch (rl) { 038 case 0: 039 return null; 040 case 1: 041 return Level.TRACE; 042 case 2: 043 return Level.DEBUG; 044 case 3: 045 return Level.INFO; 046 case 4: 047 return Level.WARN; 048 case 5: 049 return Level.ERROR; 050 default: 051 throw new IllegalStateException("rl should have been a value between 0 to 5, but it is " + rl); 052 } 053 } 054 055 public static String randomLoggerName(int average, int stdDeviation) { 056 int depth = RandomUtil.gaussianAsPositiveInt(random, average, stdDeviation); 057 StringBuilder buf = new StringBuilder(); 058 for (int i = 0; i < depth; i++) { 059 if (i != 0) { 060 buf.append('.'); 061 } 062 buf.append(randomId()); 063 } 064 return buf.toString(); 065 } 066 067 public static String randomId() { 068 069 int len = RandomUtil.gaussianAsPositiveInt(random, AVERAGE_ID_LEN, AVERAGE_ID_DEV); 070 StringBuilder buf = new StringBuilder(); 071 for (int i = 0; i < len; i++) { 072 int offset = random.nextInt(26); 073 char c = (char) ('a' + offset); 074 buf.append(c); 075 } 076 return buf.toString(); 077 } 078 079 /** 080 * Returns 3 for root, 3 for children of root, 9 for offspring of generation 2 081 * and 3, and for generations 4 and later, return 0 with probability 0.5 and a 082 * gaussian (average=AVERAGE_CHILDREN_COUNT) with probability 0.5. 083 * 084 * @param name 085 * @return 086 */ 087 public static int randomChildrenCount(String name) { 088 int dots = dotCount(name); 089 if (dots <= 1) { 090 return 3; 091 } else if (dots == 2 || dots == 3) { 092 return 9; 093 } else { 094 if (shouldHaveChildrenWithProbabilitz(0.5)) { 095 return RandomUtil.gaussianAsPositiveInt(random, AVERAGE_CHILDREN_COUNT, CHILDREN_COUNT_VAR); 096 } else { 097 return 0; 098 } 099 } 100 101 } 102 103 /** 104 * Returns true with probability p. 105 * 106 * @param p 107 * @return 108 */ 109 static boolean shouldHaveChildrenWithProbabilitz(double p) { 110 if (p < 0 || p > 1.0) { 111 throw new IllegalArgumentException("p must be a value between 0 and 1.0, it was " + p + " instead."); 112 } 113 double r = random.nextDouble(); 114 if (r < p) { 115 return true; 116 } else { 117 return false; 118 } 119 } 120 121 static int dotCount(String s) { 122 int count = 0; 123 int len = s.length(); 124 for (int i = 0; i < len; i++) { 125 char c = s.charAt(i); 126 if (c == '.') { 127 count++; 128 } 129 } 130 return count; 131 } 132}