def setUp(self): """ Construct environment. Here, we adopt the configuration used by the production or development installation and make the necessary changes before writing it to a new file in the etc directory. When we're finished, we'll remove it in the tearDown() function. """ if not os.path.exists(self.client_env['CONFDIR']): # Don't waste time and entropy on keys if we can't write configuration # files -- that's a very distressing experience. assert len(sys.argv) == 2 # Prepare two GPG keypairs; one for the agent, one for the client agent_gpg_dir = os.path.join(self.client_env['CONFDIR'], 'agent_gpg') agent_gpg = GPG(gnupghome=agent_gpg_dir) agent_key = agent_gpg.gen_key(agent_gpg.gen_key_input(**self.gpg_params)) client_gpg_dir = os.path.join(self.client_env['CONFDIR'], 'client_gpg') client_gpg = GPG(gnupghome=client_gpg_dir) client_key = client_gpg.gen_key(client_gpg.gen_key_input(**self.gpg_params)) # Export both public keys; import them into the opposing side agent_key_blob = agent_gpg.export_keys(agent_key.fingerprint) client_gpg.import_keys(agent_key_blob) client_gpg.sign_key(agent_key.fingerprint) client_key_blob = client_gpg.export_keys(client_key.fingerprint) agent_gpg.import_keys(client_key_blob) agent_gpg.sign_key(client_key.fingerprint) # Configure the agent to run in a development-safe configuration. # # Here, we load the base configuration we ship with the application # as the default. All other configuration will be ignored for the # purposes of the test run, since this is outside of our scope. with open(self.agent_env['CONFDIR'], 'w') as f: l = os.path.join(self.client_env['CONFDIR'], 'agent_%s.log') agent_cfg = ConfigurationFactory.get('hypernova.agent', root_dir=sys.argv[1]) agent_cfg.set('server', 'address', self.agent_addr[0]) agent_cfg.set('server', 'port', self.agent_addr[1]) agent_cfg.set('server', 'daemon', 'false') agent_cfg.set('gpg', 'key_store', agent_gpg_dir) agent_cfg.set('gpg', 'fingerprint', agent_key.fingerprint) agent_cfg.set('logging', 'main_log', l %('main')) agent_cfg.set('logging', 'request_log', l %('request')) agent_cfg.set('logging', 'error_log', l %('error')) agent_cfg.write(f) # The client has to use two different configuration files, both in # the same directory. client_cfg_dir = self.client_env['CONFDIR'] # Configure the client to use its temporary key. # # To communicate with the agent (which will be running in a limited # testing mode), we'll need to reconfigure the client with a keypair # we've imported into the agent. This keystore manipulation has # already taken place, so we know the fingerprint of our new private # key. client_cfg_file = os.path.join(client_cfg_dir, 'client.ini') with open(client_cfg_file, 'w') as f: client_cfg = configparser.SafeConfigParser() client_cfg.add_section('client') client_cfg.set('client', 'privkey', client_key.fingerprint) client_cfg.write(f) # Pair the client to the agent. # # We do this manually, since the importer requires that we write the # public key to a file before we import it. This would be a # pointless exercise and an unnecessary complication. client_srv_file = os.path.join(client_cfg_dir, 'servers.ini') with open(client_srv_file, 'w') as f: client_srv_cfg = configparser.SafeConfigParser() client_srv_cfg.add_section('local') client_srv_cfg.set('local', 'addr', ':'.join(self.agent_addr)) client_srv_cfg.set('local', 'pubkey', agent_key.fingerprint) client_srv_cfg.write(f) # TODO: instead of lazily and unreliably falling asleep on the job, # we should probably use a regular expression to check the output. # Time is of the essence, though! # No, we'll use pexpect instead, since it's now shipped as a py3k # dependency. agent_cmd = [ 'hn-agent', self.agent_env['CONFDIR'] ] self.agent_proc = subprocess.Popen(agent_cmd, env=self.agent_env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) time.sleep(self.agent_init_time)