Commit graph

382 commits

Author SHA1 Message Date
a835282a3c tests: Enable thread stack checking (emp_server -s)
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-31 09:27:09 +02:00
adc66a65a6 land: Separate columns x,y and a in output properly
Coordinates run into army when the y coordinate is wider than three
characters.  Has always been broken.  Insert a separating space.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-26 17:14:05 +02:00
6f6bd9fbfe Bump version to 4.3.32
Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
2013-05-20 17:41:08 +02:00
81a3e4c4fb Change econfig key rollover_avail_max from 0 to 50
So you don't have to micromanage workers to maximize useful work.

The previous commit made the problem a bit worse.  If you had a few
workers too many before, you perhaps produced an extra unit.  Now, you
get to keep the extra work instead.  Useless, unless it rolls over.
2013-05-08 14:35:04 +02:00
6f7c93cdad Make sector production more predictable
produce() limits production to how many units the workers can produce,
rounding randomly.  It charges work for the units actually produced,
discarding fractions.

If you get lucky with the random rounding, you may get a bit of extra
work done for free.  Else, you get to keep the unused work, and may
even be undercharged a tiny bit of work.  Has always been that way.

The production command assumes the random rounding rounds up if and
only if the probability to do so is at least 50%.  Thus, it's
frequently off by one for sectors producing at their worker limit.

The budget command runs the update code, and is therefore also off by
one, only differently.

Rather annoying for tech and research centers, where a single unit
matters.  A tech center with full civilian population can produce 37.5
units in 60 etus.  Given enough materials, it'll fluctuate between 37
and 38.  Production consistently predicts 38, and budget randomly
predicts either 37 or 38.  Both are off by one half the time.

Fix this as follows: limit production to the amount the workers can
produce (no rounding).  Work becomes a hard limit, not subject to
random fluctuations.  Randomly round the work charged for actual
production.  On average, this charges exactly the work that's used.

More importantly, production and budget now predict how much gets
produced more accurately.  They're still not exact, as the amount of
work available for production remains slightly random.

This also "fixes" the smoke test on a i686 Debian 6 box for me.  The
root problem is that floating-point subexpressions may either be
computed in double precision or extended precision.  Different
machines (or different compilers, or even different compiler flags)
may use different precision, and get different results.

Example: producing 108 units at one work per unit, sector p.e. 0.4
needs to charge 108 / 0.4 work.  Computed in double precision, this
gets rounded to 270.0, then truncated to 270.  In 80 bit extended
precision, it gets rounded to 269.999999999, then truncated to 269.

With random rounding instead of truncation, the probability for a
different result is vanishingly small.  However, this commit
introduces truncation in another place.  It just happens not to mess
up the smoke test there.  I doubt this is the last time this kind of
problem upsets the smoke test.
2013-05-08 14:23:50 +02:00
4884eddb51 Fix xdump nat column ip for connections from "long" IPv6 addresses
Broken in commit 3a7d7fa, which enlarged struct natstr member
nat_hostaddr[] from 32 to 46 characters, but neglected to update the
ca_len in nat_ca[].  Consequently, the address is truncated in xdump.
Can also break country * ?ip=... and such, but that's exotic.
2013-05-08 06:57:58 +02:00
c016c5fe76 Fix five year old show stopper bugs on big endian hosts
emp_server and empdump refuse to start on most big endian hosts,
because ef_verify_config() chokes on mdchr_ca[]:

Config meta uid 0 field type: value 0 is not in symbol table meta-type
Config meta uid 1 field type: value 0 is not in symbol table meta-type
Config meta uid 2 field type: value 0 is not in symbol table meta-type
Config meta uid 3 field type: value 0 is not in symbol table meta-type
Config meta uid 4 field type: value 0 is not in symbol table meta-type

Broken in commit 06a0036 (v4.3.12), which changed struct castr member
ca_type from packed_nsc_type (typedef'ed to char) to enum nsc_type,
but neglected to update the ca_type in mdchr_ca[].

On little endian hosts, the selector reads the least significant byte,
with sign extension.  Happens to work, because the type values are all
sufficiently small integers.

On big endian hosts, the selector reads the most signiciant byte.
which is always zero (NSC_NOTYPE).  Makes ef_verify_config() fail.

Except when sizeof(enum nsc_notype) == 1.  Then selector type works
fine, and ef_verify_config() succeeds, but we run into the next
problem: the same commit also changed member ca_flags from nsc_flags
(typedef'ed to unsigned char) to int without updating the ca_type in
mdchr_ca[].  This breaks "only" xdump meta column flags.

v4.3.12 was released in April 2008.  Either nobody has tried to run a
game on a big endian host since, or all who did gave up quietly,
without reporting the problem.

We clearly need to test on a wider range of machines.
2013-05-08 06:57:58 +02:00
347d3f3510 Fix xdump trade column type on big endian hosts
Broken in commit 14ea670 (v4.3.8), which changed struct trdstr member
trd_type from char to short, but neglected to update the ca_type in
trade_ca[].

On little endian hosts, the selector reads the least significant byte,
with sign extension.  Happens to work, because the type values are all
sufficiently small integers.

On big endian hosts, the selector reads the most signiciant byte,
which is always zero (EF_SECTOR).  Messes up xdump trade badly.
2013-05-08 06:57:58 +02:00
c64c756eef Fix xdump lost column type on big endian hosts
Broken in commit 09248d0 (v4.3.8), which changed struct loststr member
lost_type from char to short, but neglected to update the ca_type in
lost_ca[].

On little endian hosts, the selector reads the least significant byte,
with sign extension.  Happens to work, because the type values are all
sufficiently small integers.

On big endian hosts, the selector reads the most signiciant byte,
which is always zero (EF_SECTOR).  Messes up xdump lost badly.  Also
breaks lost * ?type=..., but that's exotic.
2013-05-08 06:57:58 +02:00
c3e5fd2375 Log connection attempts 2013-05-08 06:57:56 +02:00
50926766df Log the server's listening address 2013-05-08 06:57:55 +02:00
c798863bd7 Change fairland island size probability distribution
Island size is randomly chosen from the interval [1..2*is+1], with
expected value is.  Use two dice to roll the size instead of one.
This makes extreme sizes much less likely.
2013-05-08 06:57:55 +02:00
afc0ef94ee Make fairland record the island number in the deity territory
Can be useful for deities when further customizing their game setup.
2013-05-08 06:57:55 +02:00
a59e496024 Make smoke test time out instead of hang when server misbehaves
The smoke test waits for the server completing startup by trying to
connect until it works.  Hangs if the server doesn't complete startup
for some reason.  Make it give up after 5s.

Likewise, The smoke test waits for the server to terminate by trying
kill -0 until it fails.  Hangs if the server doesn't terminate.  Make
it give up after 5s.
2013-05-08 06:57:55 +02:00
5f46ced826 Use int instead of long for money
Code dealing with money mixes int and long pretty haphazardly.
Harmless, because practical amounts of money fit into int on any
machine capable of running the server.  Clean up anyway.
2013-05-08 06:57:54 +02:00
74b8b9932d Use int instead of long for military reserves
Code dealing with reserves mixes int and long pretty haphazardly.
Harmless, because practical reserves fit easily on any machine capable
of running the server.  Clean up anyway.
2013-05-08 06:57:54 +02:00
948757cb0c Use int instead of signed char for pln_flags
Just for consistency with other flags members.  Rearrange struct
plnstr to avoid holes.
2013-05-08 06:57:54 +02:00
e51b3fb842 Use int instead of long for flags
As long as symbol_by_value(), show_capab() and togg() support only
int, flags need to fit into int.

Not a problem in practice, because no machine capable of running
Empire has int narrower than 32 bits, and 32 bits suffice.

Some flags members are long instead of int: struct lchrstr member
l_flags, struct natstr member nat_flags, struct mchrstr member m_flags
are long.  Waste of space on machines with long wider than int.
Change them to int.

Rearrange struct lchrstr and struct natstr to avoid holes.
2013-05-08 06:57:51 +02:00
1bbbd5e27f Remove a blank line before "fairland rips open"
One blank line before and after now, looks better.
2013-05-08 06:55:21 +02:00
39c26f4238 Switch PRNG from BSD random() to Mersenne Twister
random() may yield different pseudo-random number sequences for the
same seed on another system.  For instance, at least some versions of
MinGW provide a random() in -liberty that differs from traditional BSD
(see commit c8231b12).  Rather inconvenient for regression testing.

MT19937 Mersenne Twister is a proven, high-quality PRNG.  Actual code
is reference code provided by the inventors[*].  Quick tests show
performance comparable to random().

Like random(), MT is not cryptographically secure: observing enough of
its output permits guessing its state, and thus its future output.  I
don't think players can do that.

Drop the copy of BSD random() we added for Windows.

Like the previous commit, this changes the server's die rolls, and
makes fairland create a different random map for the same seed.  Update
expected smoke test results accordingly.

[*] mt19937ar.sep.tgz downloaded from
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
2013-05-08 06:55:21 +02:00
b5d8806eb1 Fix tiny error in distribution of die rolls
"random() % n" is sound only when n is a power of two.  The error is
hardly relevant in Empire, because random() yields 31 bits, and our n
are always much smaller than 2^31.  Fix it anyway.

Use smallest the 2^m >= n instead of n, and discard numbers exceeding
n.

Bonus: faster for me even in the worst case n = 2^m+1.

Like the recent change to damage(), this changes some of the server's
die rolls, only this time the effect is pretty pervasive.  Worse,
fairland now creates a completely different random map for the same
seed.  Update expected smoke test results accordingly.
2013-05-08 06:55:20 +02:00
c53158eee0 Make damage() use roundavg()
Turns damage() into a one-liner.

damage() now uses random() % 32768 in chance() instead of random() %
100 inline, therefore can round differently for the same pseudo-random
number.  Update expected smoke test results accordingly.

Aside: "random() % n" distributes evenly only when n is a power of
two.  100 isn't.  However, because random() yields at least 31 bits,
and 100 is so much smaller than 2^31, the error is vanishingly small.
2013-05-08 06:55:20 +02:00
cf5ba2cec1 Make smoke test's tech production more robust
The tech center doesn't have enough workers to use all materials in
some updates.  How much get made depends on a die roll then.  Tech
variations are inconvenient because they ripple through the rest of
the smoke test.
2013-05-08 06:55:19 +02:00
df9cc9d9eb Limit che action in smoke test some
Too easily upset by random variations.  Kill them off with anti after
two updates, and occupy with a few more military.

While there, enlist the military in a highway rather than an lcm
plant.
2013-05-08 06:55:19 +02:00
e9fdc200e4 Make smoke test's plane build more robust
The airfield is a sector taken from player 8.  How many updates it
takes to convert is highly variable.  If it converts late, the
airfield may not be constructed in time.  This is currently the case
for me.

Move the airfield to a more dependable sector.

For me, the smoke test now fails frequently, because of differences in
news.  To be fixed next.
2013-05-08 06:55:19 +02:00
b54380938c Remove fairland from smoke test
Import xdump instead.  To decouple the smoke test from future fairland
changes that result in different worlds.
2013-05-08 06:55:19 +02:00
ed8eead0ba Add fairland test to make check 2013-05-08 06:55:18 +02:00
4dd0720fc0 Add files test to make check 2013-05-08 06:55:18 +02:00
d161b6d9e4 Factor tests/test-common.sh out of tests/smoke-test
For reuse by future tests.
2013-05-08 06:55:18 +02:00
108c9408dc Make smoke test check the final empdump -x 2013-05-08 06:55:18 +02:00
56a9d46ab1 Get rid of shell boilerplate in smoke test Empire batch files 2013-05-08 06:55:18 +02:00
49b2b13a90 New make target check
Just a smoke test so far, extracted from src/scripts/nightly/.  This
makes the existing smoke test more easily accessible.  Noteworthy
differences:

* Instead of patching the code to make output more stable, postprocess
  the output to normalize it.

* Compare actual results to expected results instead of the previous
  test run's results.

* Much faster.  The old test harness used sleep liberally to "ensure"
  things always happen in the same order.

Known shortcomings:

* The smoke test hangs when the server fails to complete startup, or
  fails to terminate.

* Normalization of xdump hardcodes columns instead of getting them
  from xdump meta.

* Normalization of time values in xdump is an ugly hack.

* xdump meta column type isn't normalized.  Actual values can vary
  between systems, because the width of enumeration types is
  implementation-defined.  The smoke test works only when they're
  represented as int, which is the case on common systems.

* Currently expected to work only with thread package LWP and a
  random() that behaves exactly like the one on my development system,
  because:

  - Thread scheduling is reliably deterministic only with LWP

  - The PRN sequence produced by random() isn't portable

  - Shell builtin kill appears not to do the job in MinGW

  - The Windows server tries to run as service when -d isn't
    specified

Further work is needed to address these shortcomings.

Getting C programs behave exactly the same on all systems is hard.
We'll likely run into system-dependent differences that upset the
smoke test.  Floating-point computation seems particularly vulnerable.

Instead of updating src/scripts/nightly/ to use "make check", retire
it.  It hasn't been used in quite a while.  Investing more into our
homegrown auto-builder doesn't make sense, as canned auto-builders
such as Travis CI and Jenkins are readily available.

The shell scripts src/scripts/nightly/tests/?? become Empire batch
files tests/smoke/.  The shell scripts are actually shell boilerplate
around Empire batch files.  To make sure git recognizes the move, this
commit moves them unchanged.  tests/smoke-test strips the boilerplate
before it feeds the batch files to the client.  The next commit will
get rid fo that.
2013-05-08 06:55:11 +02:00